From: Sasha Levin Date: Mon, 11 Mar 2019 19:14:10 +0000 (-0400) Subject: autosel patches for 4.20 X-Git-Tag: v5.0.2~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=941c5db0b094471af0969cc3bddf239e1338bcd8;p=thirdparty%2Fkernel%2Fstable-queue.git autosel patches for 4.20 Signed-off-by: Sasha Levin --- diff --git a/queue-4.20/apparmor-fix-aa_label_build-error-handling-for-faile.patch b/queue-4.20/apparmor-fix-aa_label_build-error-handling-for-faile.patch new file mode 100644 index 00000000000..6ba3fc46647 --- /dev/null +++ b/queue-4.20/apparmor-fix-aa_label_build-error-handling-for-faile.patch @@ -0,0 +1,36 @@ +From 14c3a24cfbc2cbf27d7a2fafc02fcae198652b86 Mon Sep 17 00:00:00 2001 +From: John Johansen +Date: Thu, 24 Jan 2019 13:53:05 -0800 +Subject: apparmor: Fix aa_label_build() error handling for failed merges + +[ Upstream commit d6d478aee003e19ef90321176552a8ad2929a47f ] + +aa_label_merge() can return NULL for memory allocations failures +make sure to handle and set the correct error in this case. + +Reported-by: Peng Hao +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/domain.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c +index 08c88de0ffda..11975ec8d566 100644 +--- a/security/apparmor/domain.c ++++ b/security/apparmor/domain.c +@@ -1444,7 +1444,10 @@ int aa_change_profile(const char *fqname, int flags) + new = aa_label_merge(label, target, GFP_KERNEL); + if (IS_ERR_OR_NULL(new)) { + info = "failed to build target label"; +- error = PTR_ERR(new); ++ if (!new) ++ error = -ENOMEM; ++ else ++ error = PTR_ERR(new); + new = NULL; + perms.allow = 0; + goto audit; +-- +2.19.1 + diff --git a/queue-4.20/apparmor-fix-warning-about-unused-function-apparmor_.patch b/queue-4.20/apparmor-fix-warning-about-unused-function-apparmor_.patch new file mode 100644 index 00000000000..9ad62bcc834 --- /dev/null +++ b/queue-4.20/apparmor-fix-warning-about-unused-function-apparmor_.patch @@ -0,0 +1,46 @@ +From f43f22d16d2749f556fcd4efeb90347bf6e9afec Mon Sep 17 00:00:00 2001 +From: Petr Vorel +Date: Mon, 12 Nov 2018 11:59:12 +0100 +Subject: apparmor: Fix warning about unused function apparmor_ipv6_postroute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit a1a02062ad466052a34a8c4323143ccf9726eb52 ] + +when compiled without CONFIG_IPV6: +security/apparmor/lsm.c:1601:21: warning: ‘apparmor_ipv6_postroute’ defined but not used [-Wunused-function] + static unsigned int apparmor_ipv6_postroute(void *priv, + ^~~~~~~~~~~~~~~~~~~~~~~ + +Reported-by: Jordan Glover +Tested-by: Jordan Glover +Signed-off-by: Petr Vorel +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 42446a216f3b..7d1eeb084968 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -1598,12 +1598,14 @@ static unsigned int apparmor_ipv4_postroute(void *priv, + return apparmor_ip_postroute(priv, skb, state); + } + ++#if IS_ENABLED(CONFIG_IPV6) + static unsigned int apparmor_ipv6_postroute(void *priv, + struct sk_buff *skb, + const struct nf_hook_state *state) + { + return apparmor_ip_postroute(priv, skb, state); + } ++#endif + + static const struct nf_hook_ops apparmor_nf_ops[] = { + { +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-am335x-shc.dts-fix-wrong-cd-pin-level.patch b/queue-4.20/arm-dts-am335x-shc.dts-fix-wrong-cd-pin-level.patch new file mode 100644 index 00000000000..f20f5ab4055 --- /dev/null +++ b/queue-4.20/arm-dts-am335x-shc.dts-fix-wrong-cd-pin-level.patch @@ -0,0 +1,33 @@ +From 3d4de3f41dbfb3109895ccb8829e188b2ff6cbf7 Mon Sep 17 00:00:00 2001 +From: Heiko Schocher +Date: Tue, 22 Jan 2019 06:26:23 +0100 +Subject: ARM: dts: am335x-shc.dts: fix wrong cd pin level + +[ Upstream commit 063c20e12f8bbbc10cabc2413606b140085beb62 ] + +cd pin on mmc1 is GPIO_ACTIVE_LOW not GPIO_ACTIVE_HIGH + +Fixes: e63201f19438 ("mmc: omap_hsmmc: Delete platform data GPIO CD and WP") +Signed-off-by: Heiko Schocher +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/am335x-shc.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/am335x-shc.dts b/arch/arm/boot/dts/am335x-shc.dts +index 1d925ed2b102..8fbbad11a80c 100644 +--- a/arch/arm/boot/dts/am335x-shc.dts ++++ b/arch/arm/boot/dts/am335x-shc.dts +@@ -215,7 +215,7 @@ + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + bus-width = <0x4>; +- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; ++ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + cd-inverted; + max-frequency = <26000000>; + vmmc-supply = <&vmmcsd_fixed>; +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-imx6sx-correct-backward-compatible-of-gpt.patch b/queue-4.20/arm-dts-imx6sx-correct-backward-compatible-of-gpt.patch new file mode 100644 index 00000000000..d0598caddfb --- /dev/null +++ b/queue-4.20/arm-dts-imx6sx-correct-backward-compatible-of-gpt.patch @@ -0,0 +1,36 @@ +From d2ee2f745b3f956d3658c4c83306f3600484541a Mon Sep 17 00:00:00 2001 +From: Anson Huang +Date: Sat, 29 Dec 2018 10:01:18 +0000 +Subject: ARM: dts: imx6sx: correct backward compatible of gpt + +[ Upstream commit ba0f4560526ba19300c07ed5a3c1df7592815dc6 ] + +i.MX6SX has same GPT type as i.MX6DL, in GPT driver, it uses +below TIMER_OF_DECLARE, so the backward compatible should be +"fsl,imx6dl-gpt", correct it. + +TIMER_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt); + +Signed-off-by: Anson Huang +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/imx6sx.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi +index 95a3c1cb877d..89ba48f4273b 100644 +--- a/arch/arm/boot/dts/imx6sx.dtsi ++++ b/arch/arm/boot/dts/imx6sx.dtsi +@@ -462,7 +462,7 @@ + }; + + gpt: gpt@2098000 { +- compatible = "fsl,imx6sx-gpt", "fsl,imx31-gpt"; ++ compatible = "fsl,imx6sx-gpt", "fsl,imx6dl-gpt"; + reg = <0x02098000 0x4000>; + interrupts = ; + clocks = <&clks IMX6SX_CLK_GPT_BUS>, +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-meson-fix-irq-trigger-type-for-macirq.patch b/queue-4.20/arm-dts-meson-fix-irq-trigger-type-for-macirq.patch new file mode 100644 index 00000000000..d7136f29e6e --- /dev/null +++ b/queue-4.20/arm-dts-meson-fix-irq-trigger-type-for-macirq.patch @@ -0,0 +1,62 @@ +From 2f2029a5c1d9f85bae0ad8121c3401d531fe5036 Mon Sep 17 00:00:00 2001 +From: Carlo Caione +Date: Fri, 7 Dec 2018 10:52:31 +0000 +Subject: arm: dts: meson: Fix IRQ trigger type for macirq + +[ Upstream commit e35e26b26e955c53e61c154ba26b9bb15da6b858 ] + +A long running stress test on a custom board shipping an AXG SoCs and a +Realtek RTL8211F PHY revealed that after a few hours the connection +speed would drop drastically, from ~1000Mbps to ~3Mbps. At the same time +the 'macirq' (eth0) IRQ would stop being triggered at all and as +consequence the GMAC IRQs never ACKed. + +After a painful investigation the problem seemed to be due to a wrong +defined IRQ type for the GMAC IRQ that should be LEVEL_HIGH instead of +EDGE_RISING. + +The change in the macirq IRQ type also solved another long standing +issue affecting this SoC/PHY where EEE was causing the network +connection to die after stressing it with iperf3 (even though much +sooner). It's now possible to remove the 'eee-broken-1000t' quirk as +well. + +Fixes: 9c15795a4f96 ("ARM: dts: meson8b-odroidc1: ethernet support") +Signed-off-by: Carlo Caione +Reviewed-by: Martin Blumenstingl +Tested-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/meson.dtsi | 2 +- + arch/arm/boot/dts/meson8b-odroidc1.dts | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi +index 0d9faf1a51ea..a86b89086334 100644 +--- a/arch/arm/boot/dts/meson.dtsi ++++ b/arch/arm/boot/dts/meson.dtsi +@@ -263,7 +263,7 @@ + compatible = "amlogic,meson6-dwmac", "snps,dwmac"; + reg = <0xc9410000 0x10000 + 0xc1108108 0x4>; +- interrupts = ; ++ interrupts = ; + interrupt-names = "macirq"; + status = "disabled"; + }; +diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts +index 58669abda259..a951a6632d0c 100644 +--- a/arch/arm/boot/dts/meson8b-odroidc1.dts ++++ b/arch/arm/boot/dts/meson8b-odroidc1.dts +@@ -221,7 +221,6 @@ + /* Realtek RTL8211F (0x001cc916) */ + eth_phy: ethernet-phy@0 { + reg = <0>; +- eee-broken-1000t; + interrupt-parent = <&gpio_intc>; + /* GPIOH_3 */ + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-meson8b-ec100-mark-the-sd-card-detection-gpi.patch b/queue-4.20/arm-dts-meson8b-ec100-mark-the-sd-card-detection-gpi.patch new file mode 100644 index 00000000000..732edf058c5 --- /dev/null +++ b/queue-4.20/arm-dts-meson8b-ec100-mark-the-sd-card-detection-gpi.patch @@ -0,0 +1,45 @@ +From 159c53e924c359864488830962e594c6364ce31c Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 29 Dec 2018 13:57:10 +0100 +Subject: ARM: dts: meson8b: ec100: mark the SD card detection GPIO active-low + +[ Upstream commit c8bfe65fb1fb7a43d766df1dfa379406112cba61 ] + +After commit 89a5e15bcba87d ("gpio/mmc/of: Respect polarity in the device +tree") SD cards are not detected anymore. + +The CD GPIO is "active low" on the EC-100. The MMC dt-bindings specify: +"[...] using the "cd-inverted" property means, that the CD line is active +high, i.e. it is high, when a card is inserted". + +Fix the description of the SD card by marking it as GPIO_ACTIVE_LOW and +drop the "cd-inverted" property. This makes the definition consistent +with the existing dt-bindings and fixes the check whether an SD card is +inserted. + +Fixes: bbedc1f1d90e33 ("ARM: dts: meson8b: Add support for the Endless Mini (EC-100)") +Signed-off-by: Martin Blumenstingl +Reviewed-by: Linus Walleij +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/meson8b-ec100.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/meson8b-ec100.dts b/arch/arm/boot/dts/meson8b-ec100.dts +index 0872f6e3abf5..d50fc2f60fa3 100644 +--- a/arch/arm/boot/dts/meson8b-ec100.dts ++++ b/arch/arm/boot/dts/meson8b-ec100.dts +@@ -205,8 +205,7 @@ + cap-sd-highspeed; + disable-wp; + +- cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; +- cd-inverted; ++ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vcc_3v3>; + }; +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-meson8b-odroidc1-mark-the-sd-card-detection-.patch b/queue-4.20/arm-dts-meson8b-odroidc1-mark-the-sd-card-detection-.patch new file mode 100644 index 00000000000..a665c3a8d15 --- /dev/null +++ b/queue-4.20/arm-dts-meson8b-odroidc1-mark-the-sd-card-detection-.patch @@ -0,0 +1,47 @@ +From b3317cf5fb62b1f08ef5fe0ad5458169b9a9464d Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 29 Dec 2018 13:57:09 +0100 +Subject: ARM: dts: meson8b: odroidc1: mark the SD card detection GPIO + active-low + +[ Upstream commit 3fb348e030319f20ebbde082a449d4bf8a96f2fd ] + +After commit 89a5e15bcba87d ("gpio/mmc/of: Respect polarity in the device +tree") SD cards are not detected anymore. + +The CD GPIO is "active low" on Odroid-C1. The MMC dt-bindings specify: +"[...] using the "cd-inverted" property means, that the CD line is active +high, i.e. it is high, when a card is inserted". + +Fix the description of the SD card by marking it as GPIO_ACTIVE_LOW and +drop the "cd-inverted" property. This makes the definition consistent +with the existing dt-bindings and fixes the check whether an SD card is +inserted. + +Fixes: e03efbce6bebf5 ("ARM: dts: meson8b-odroidc1: add microSD support") +Signed-off-by: Martin Blumenstingl +Reviewed-by: Linus Walleij +Tested-by: Anand Moon +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/meson8b-odroidc1.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts +index a951a6632d0c..0f0a46ddf3ff 100644 +--- a/arch/arm/boot/dts/meson8b-odroidc1.dts ++++ b/arch/arm/boot/dts/meson8b-odroidc1.dts +@@ -272,8 +272,7 @@ + cap-sd-highspeed; + disable-wp; + +- cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; +- cd-inverted; ++ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&tflash_vdd>; + vqmmc-supply = <&tf_io>; +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-meson8m2-mxiii-plus-mark-the-sd-card-detecti.patch b/queue-4.20/arm-dts-meson8m2-mxiii-plus-mark-the-sd-card-detecti.patch new file mode 100644 index 00000000000..57b8d3e8de2 --- /dev/null +++ b/queue-4.20/arm-dts-meson8m2-mxiii-plus-mark-the-sd-card-detecti.patch @@ -0,0 +1,46 @@ +From 2ec8a39becb71c46011b205ea9f294ffbc1bec74 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 29 Dec 2018 13:57:11 +0100 +Subject: ARM: dts: meson8m2: mxiii-plus: mark the SD card detection GPIO + active-low + +[ Upstream commit 8615f5596335db0978cea593dcd0070dc5f8b116 ] + +After commit 89a5e15bcba87d ("gpio/mmc/of: Respect polarity in the device +tree") SD cards are not detected anymore. + +The CD GPIO is "active low" on the MXIII-Plus. The MMC dt-bindings +specify: "[...] using the "cd-inverted" property means, that the CD line +is active high, i.e. it is high, when a card is inserted". + +Fix the description of the SD card by marking it as GPIO_ACTIVE_LOW and +drop the "cd-inverted" property. This makes the definition consistent +with the existing dt-bindings and fixes the check whether an SD card is +inserted. + +Fixes: 35ee52bea66c74 ("ARM: dts: meson8m2: add support for the Tronsmart MXIII Plus") +Signed-off-by: Martin Blumenstingl +Reviewed-by: Linus Walleij +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/meson8m2-mxiii-plus.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/meson8m2-mxiii-plus.dts b/arch/arm/boot/dts/meson8m2-mxiii-plus.dts +index f5853610b20b..6ac02beb5fa7 100644 +--- a/arch/arm/boot/dts/meson8m2-mxiii-plus.dts ++++ b/arch/arm/boot/dts/meson8m2-mxiii-plus.dts +@@ -206,8 +206,7 @@ + cap-sd-highspeed; + disable-wp; + +- cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; +- cd-inverted; ++ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vcc_3v3>; + }; +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-n900-fix-mmc1-card-detect-gpio-polarity.patch b/queue-4.20/arm-dts-n900-fix-mmc1-card-detect-gpio-polarity.patch new file mode 100644 index 00000000000..bb7dc02ce69 --- /dev/null +++ b/queue-4.20/arm-dts-n900-fix-mmc1-card-detect-gpio-polarity.patch @@ -0,0 +1,41 @@ +From 5e907d2b309e21307210f5113aa5e12867c375dd Mon Sep 17 00:00:00 2001 +From: Arthur Demchenkov +Date: Mon, 21 Jan 2019 06:21:09 +0300 +Subject: ARM: dts: n900: fix mmc1 card detect gpio polarity + +[ Upstream commit ac9c908eecde3ed252cb1d67fc79b3c1346f76bc ] + +Wrong polarity of card detect GPIO pin leads to the system not +booting from external mmc, if the back cover of N900 is closed. +When the cover is open the system boots fine. + +This wasn't noticed before, because of a bug, which was fixed +by commit e63201f19 (mmc: omap_hsmmc: Delete platform data GPIO +CD and WP). + +Kernels up to 4.19 ignored the card detect GPIO from DT. + +Fixes: e63201f19438 ("mmc: omap_hsmmc: Delete platform data GPIO CD and WP") +Signed-off-by: Arthur Demchenkov +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/omap3-n900.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts +index 182a53991c90..826920e6b878 100644 +--- a/arch/arm/boot/dts/omap3-n900.dts ++++ b/arch/arm/boot/dts/omap3-n900.dts +@@ -814,7 +814,7 @@ + /* For debugging, it is often good idea to remove this GPIO. + It means you can remove back cover (to reboot by removing + battery) and still use the MMC card. */ +- cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */ ++ cd-gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* 160 */ + }; + + /* most boards use vaux3, only some old versions use vmmc2 instead */ +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-omap3-gta04-fix-graph_port-warning.patch b/queue-4.20/arm-dts-omap3-gta04-fix-graph_port-warning.patch new file mode 100644 index 00000000000..3982271717d --- /dev/null +++ b/queue-4.20/arm-dts-omap3-gta04-fix-graph_port-warning.patch @@ -0,0 +1,41 @@ +From db46fac1dced1493d16a29514013a404ecc83e86 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Wed, 9 Jan 2019 20:01:56 +0100 +Subject: ARM: dts: omap3-gta04: Fix graph_port warning + +[ Upstream commit 5b90df44fd9b415d8c5d11b92746212a63d3c47f ] + +We're currently getting a warning with make dtbs: + +arch/arm/boot/dts/omap3-gta04.dtsi:720.7-727.4: Warning (graph_port): +/ocp@68000000/dss@48050000/encoder@48050c0 0/port: graph node unit +address error, expected "0" + +Tested-by: H. Nikolaus Schaller +Acked-by: Rob Herring +Signed-off-by: H. Nikolaus Schaller +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/omap3-gta04.dtsi | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi +index d5fe55392230..68e675258906 100644 +--- a/arch/arm/boot/dts/omap3-gta04.dtsi ++++ b/arch/arm/boot/dts/omap3-gta04.dtsi +@@ -714,11 +714,7 @@ + + vdda-supply = <&vdac>; + +- #address-cells = <1>; +- #size-cells = <0>; +- + port { +- reg = <0>; + venc_out: endpoint { + remote-endpoint = <&opa_in>; + ti,channels = <1>; +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-omap4-droid4-fix-typo-in-cpcap-irq-flags.patch b/queue-4.20/arm-dts-omap4-droid4-fix-typo-in-cpcap-irq-flags.patch new file mode 100644 index 00000000000..c2727b01cf5 --- /dev/null +++ b/queue-4.20/arm-dts-omap4-droid4-fix-typo-in-cpcap-irq-flags.patch @@ -0,0 +1,38 @@ +From 00112f54839fbc025f702cda119d3963cf0d2518 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Mon, 7 Jan 2019 09:52:43 -0800 +Subject: ARM: dts: omap4-droid4: Fix typo in cpcap IRQ flags + +[ Upstream commit ef4a55b9197a8f844ea0663138e902dcce3e2f36 ] + +We're now getting the following error: + +genirq: Setting trigger mode 1 for irq 230 failed +(regmap_irq_set_type+0x0/0x15c) +cpcap-usb-phy cpcap-usb-phy.0: could not get irq dp: -524 + +Cc: Sebastian Reichel +Reported-by: Pavel Machek +Tested-by: Pavel Machek +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi +index ddc7a7bb33c0..f57acf8f66b9 100644 +--- a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi ++++ b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi +@@ -105,7 +105,7 @@ + interrupts-extended = < + &cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0 + &cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0 +- &cpcap 48 1 ++ &cpcap 48 0 + >; + interrupt-names = + "id_ground", "id_float", "se0conn", "vbusvld", +-- +2.19.1 + diff --git a/queue-4.20/arm-dts-sun8i-h3-add-ethernet0-alias-to-beelink-x2.patch b/queue-4.20/arm-dts-sun8i-h3-add-ethernet0-alias-to-beelink-x2.patch new file mode 100644 index 00000000000..ee466baede0 --- /dev/null +++ b/queue-4.20/arm-dts-sun8i-h3-add-ethernet0-alias-to-beelink-x2.patch @@ -0,0 +1,38 @@ +From 9e35eaee5c526b2fe44b47a2b7dbfe5127e19a63 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Tue, 8 Jan 2019 20:18:40 +0100 +Subject: ARM: dts: sun8i: h3: Add ethernet0 alias to Beelink X2 + +[ Upstream commit cc4bddade114b696ab27c1a77cfc7040151306da ] + +Because "ethernet0" alias is missing, U-Boot doesn't generate board +specific MAC address. Effect of this is random MAC address every boot +and thus new IP address is assigned to the board. + +Fix this by adding alias. + +Fixes: 7389172fc3ed ("ARM: dts: sun8i: h3: Enable dwmac-sun8i on the Beelink X2") +Signed-off-by: Jernej Skrabec +[Maxime: Removed unneeded comment] +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts +index 5d23667dc2d2..25540b7694d5 100644 +--- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts ++++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts +@@ -53,7 +53,7 @@ + + aliases { + serial0 = &uart0; +- /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */ ++ ethernet0 = &emac; + ethernet1 = &sdiowifi; + }; + +-- +2.19.1 + diff --git a/queue-4.20/arm-omap-dts-n950-n9-fix-onenand-timings.patch b/queue-4.20/arm-omap-dts-n950-n9-fix-onenand-timings.patch new file mode 100644 index 00000000000..ce388c86b9f --- /dev/null +++ b/queue-4.20/arm-omap-dts-n950-n9-fix-onenand-timings.patch @@ -0,0 +1,90 @@ +From 3964d01b52146d71ffe80ca4a04e0394eddbe521 Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Sun, 23 Dec 2018 20:24:13 +0200 +Subject: ARM: OMAP: dts: N950/N9: fix onenand timings + +[ Upstream commit 8443e4843e1c2594bf5664e1d993a1be71d1befb ] + +Commit a758f50f10cf ("mtd: onenand: omap2: Configure driver from DT") +started using DT specified timings for GPMC, and as a result the +OneNAND stopped working on N950/N9 as we had wrong values in the DT. +Fix by updating the values to bootloader timings that have been tested +to be working on both Nokia N950 and N9. + +Fixes: a758f50f10cf ("mtd: onenand: omap2: Configure driver from DT") +Signed-off-by: Aaro Koskinen +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/omap3-n950-n9.dtsi | 42 ++++++++++++++++++---------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi +index 0d9b85317529..e142e6c70a59 100644 +--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi ++++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi +@@ -370,6 +370,19 @@ + compatible = "ti,omap2-onenand"; + reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ + ++ /* ++ * These timings are based on CONFIG_OMAP_GPMC_DEBUG=y reported ++ * bootloader set values when booted with v4.19 using both N950 ++ * and N9 devices (OneNAND Manufacturer: Samsung): ++ * ++ * gpmc cs0 before gpmc_cs_program_settings: ++ * cs0 GPMC_CS_CONFIG1: 0xfd001202 ++ * cs0 GPMC_CS_CONFIG2: 0x00181800 ++ * cs0 GPMC_CS_CONFIG3: 0x00030300 ++ * cs0 GPMC_CS_CONFIG4: 0x18001804 ++ * cs0 GPMC_CS_CONFIG5: 0x03171d1d ++ * cs0 GPMC_CS_CONFIG6: 0x97080000 ++ */ + gpmc,sync-read; + gpmc,sync-write; + gpmc,burst-length = <16>; +@@ -379,26 +392,27 @@ + gpmc,device-width = <2>; + gpmc,mux-add-data = <2>; + gpmc,cs-on-ns = <0>; +- gpmc,cs-rd-off-ns = <87>; +- gpmc,cs-wr-off-ns = <87>; ++ gpmc,cs-rd-off-ns = <122>; ++ gpmc,cs-wr-off-ns = <122>; + gpmc,adv-on-ns = <0>; +- gpmc,adv-rd-off-ns = <10>; +- gpmc,adv-wr-off-ns = <10>; +- gpmc,oe-on-ns = <15>; +- gpmc,oe-off-ns = <87>; ++ gpmc,adv-rd-off-ns = <15>; ++ gpmc,adv-wr-off-ns = <15>; ++ gpmc,oe-on-ns = <20>; ++ gpmc,oe-off-ns = <122>; + gpmc,we-on-ns = <0>; +- gpmc,we-off-ns = <87>; +- gpmc,rd-cycle-ns = <112>; +- gpmc,wr-cycle-ns = <112>; +- gpmc,access-ns = <81>; ++ gpmc,we-off-ns = <122>; ++ gpmc,rd-cycle-ns = <148>; ++ gpmc,wr-cycle-ns = <148>; ++ gpmc,access-ns = <117>; + gpmc,page-burst-access-ns = <15>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,wait-monitoring-ns = <0>; +- gpmc,clk-activation-ns = <5>; +- gpmc,wr-data-mux-bus-ns = <30>; +- gpmc,wr-access-ns = <81>; +- gpmc,sync-clk-ps = <15000>; ++ gpmc,clk-activation-ns = <10>; ++ gpmc,wr-data-mux-bus-ns = <40>; ++ gpmc,wr-access-ns = <117>; ++ ++ gpmc,sync-clk-ps = <15000>; /* TBC; Where this value came? */ + + /* + * MTD partition table corresponding to Nokia's MeeGo 1.2 +-- +2.19.1 + diff --git a/queue-4.20/arm-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch b/queue-4.20/arm-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch new file mode 100644 index 00000000000..bda52782ce4 --- /dev/null +++ b/queue-4.20/arm-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch @@ -0,0 +1,43 @@ +From c6c4a3cb2ed6202ae4dd6dbf65d9d171e8f3c9a9 Mon Sep 17 00:00:00 2001 +From: Peng Hao +Date: Sat, 29 Dec 2018 13:10:06 +0800 +Subject: ARM: pxa: ssp: unneeded to free devm_ allocated data + +[ Upstream commit ba16adeb346387eb2d1ada69003588be96f098fa ] + +devm_ allocated data will be automatically freed. The free +of devm_ allocated data is invalid. + +Fixes: 1c459de1e645 ("ARM: pxa: ssp: use devm_ functions") +Signed-off-by: Peng Hao +[title's prefix changed] +Signed-off-by: Robert Jarzmik +Signed-off-by: Sasha Levin +--- + arch/arm/plat-pxa/ssp.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c +index ed36dcab80f1..f51919974183 100644 +--- a/arch/arm/plat-pxa/ssp.c ++++ b/arch/arm/plat-pxa/ssp.c +@@ -190,8 +190,6 @@ static int pxa_ssp_remove(struct platform_device *pdev) + if (ssp == NULL) + return -ENODEV; + +- iounmap(ssp->mmio_base); +- + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + +@@ -201,7 +199,6 @@ static int pxa_ssp_remove(struct platform_device *pdev) + list_del(&ssp->node); + mutex_unlock(&ssp_lock); + +- kfree(ssp); + return 0; + } + +-- +2.19.1 + diff --git a/queue-4.20/arm64-dts-add-msm8996-compatible-to-gicv3.patch b/queue-4.20/arm64-dts-add-msm8996-compatible-to-gicv3.patch new file mode 100644 index 00000000000..4dc5d96356d --- /dev/null +++ b/queue-4.20/arm64-dts-add-msm8996-compatible-to-gicv3.patch @@ -0,0 +1,38 @@ +From 1342992d8b109f517c9d2d674d72589b894196a1 Mon Sep 17 00:00:00 2001 +From: Srinivas Kandagatla +Date: Mon, 10 Dec 2018 13:56:33 +0000 +Subject: arm64: dts: add msm8996 compatible to gicv3 + +[ Upstream commit 2a81efb0de0e33f2d2c83154af0bd3ce389b3269 ] + +Add compatible to gicv3 node to enable quirk required to restrict writing +to GICR_WAKER register which is restricted on msm8996 SoC in Hypervisor. + +With this quirk MSM8996 can at least boot out of mainline, which can help +community to work with boards based on MSM8996. + +Without this patch Qualcomm DB820c board reboots on mainline. + +Signed-off-by: Srinivas Kandagatla +Signed-off-by: Andy Gross +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index b29fe80d7288..461612a5ab5e 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -397,7 +397,7 @@ + }; + + intc: interrupt-controller@9bc0000 { +- compatible = "arm,gic-v3"; ++ compatible = "qcom,msm8996-gic-v3", "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + #redistributor-regions = <1>; +-- +2.19.1 + diff --git a/queue-4.20/arm64-dts-renesas-r8a7796-enable-dma-for-scif2.patch b/queue-4.20/arm64-dts-renesas-r8a7796-enable-dma-for-scif2.patch new file mode 100644 index 00000000000..83628d687e8 --- /dev/null +++ b/queue-4.20/arm64-dts-renesas-r8a7796-enable-dma-for-scif2.patch @@ -0,0 +1,34 @@ +From b5a64f9972ad4766490f99e72fc2e0d988268d49 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Thu, 10 Jan 2019 14:39:15 +0100 +Subject: arm64: dts: renesas: r8a7796: Enable DMA for SCIF2 + +[ Upstream commit 97f26702bc95b5c3a72671d5c6675e4d6ee0a2f4 ] + +SCIF2 on R-Car M3-W can be used with both DMAC1 and DMAC2. + +Fixes: dbcae5ea4bd27409 ("arm64: dts: r8a7796: Enable SCIF DMA") +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Simon Horman +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a7796.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi +index 1ec6aaa520c1..09320caea54e 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi +@@ -1160,6 +1160,9 @@ + <&cpg CPG_CORE R8A7796_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x13>, <&dmac1 0x12>, ++ <&dmac2 0x13>, <&dmac2 0x12>; ++ dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 310>; + status = "disabled"; +-- +2.19.1 + diff --git a/queue-4.20/arm64-dts-renesas-r8a77965-enable-dma-for-scif2.patch b/queue-4.20/arm64-dts-renesas-r8a77965-enable-dma-for-scif2.patch new file mode 100644 index 00000000000..f3e7dbac4ca --- /dev/null +++ b/queue-4.20/arm64-dts-renesas-r8a77965-enable-dma-for-scif2.patch @@ -0,0 +1,34 @@ +From c8ed3780b986abd1986f65861640c26f19fa058c Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Thu, 10 Jan 2019 14:39:16 +0100 +Subject: arm64: dts: renesas: r8a77965: Enable DMA for SCIF2 + +[ Upstream commit 05c8478abd485507c25aa565afab604af8d8fe46 ] + +SCIF2 on R-Car M3-N can be used with both DMAC1 and DMAC2. + +Fixes: 0ea5b2fd38db56aa ("arm64: dts: renesas: r8a77965: Add SCIF device nodes") +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Simon Horman +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a77965.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi +index 83946ca2eba5..d59dada13722 100644 +--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi +@@ -1028,6 +1028,9 @@ + <&cpg CPG_CORE R8A77965_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; ++ dmas = <&dmac1 0x13>, <&dmac1 0x12>, ++ <&dmac2 0x13>, <&dmac2 0x12>; ++ dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 310>; + status = "disabled"; +-- +2.19.1 + diff --git a/queue-4.20/arm64-kprobe-always-blacklist-the-kvm-world-switch-c.patch b/queue-4.20/arm64-kprobe-always-blacklist-the-kvm-world-switch-c.patch new file mode 100644 index 00000000000..832c97b2cb3 --- /dev/null +++ b/queue-4.20/arm64-kprobe-always-blacklist-the-kvm-world-switch-c.patch @@ -0,0 +1,56 @@ +From b4c415f2450ce739d1a9c9108b74f37d239f8157 Mon Sep 17 00:00:00 2001 +From: James Morse +Date: Thu, 24 Jan 2019 16:32:55 +0000 +Subject: arm64: kprobe: Always blacklist the KVM world-switch code + +[ Upstream commit f2b3d8566d81deaca31f4e3163def0bea7746e11 ] + +On systems with VHE the kernel and KVM's world-switch code run at the +same exception level. Code that is only used on a VHE system does not +need to be annotated as __hyp_text as it can reside anywhere in the + kernel text. + +__hyp_text was also used to prevent kprobes from patching breakpoint +instructions into this region, as this code runs at a different +exception level. While this is no longer true with VHE, KVM still +switches VBAR_EL1, meaning a kprobe's breakpoint executed in the +world-switch code will cause a hyp-panic. + +Move the __hyp_text check in the kprobes blacklist so it applies on +VHE systems too, to cover the common code and guest enter/exit +assembly. + +Fixes: 888b3c8720e0 ("arm64: Treat all entry code as non-kprobe-able") +Reviewed-by: Christoffer Dall +Signed-off-by: James Morse +Acked-by: Masami Hiramatsu +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + arch/arm64/kernel/probes/kprobes.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c +index 2a5b338b2542..f17afb99890c 100644 +--- a/arch/arm64/kernel/probes/kprobes.c ++++ b/arch/arm64/kernel/probes/kprobes.c +@@ -478,13 +478,13 @@ bool arch_within_kprobe_blacklist(unsigned long addr) + addr < (unsigned long)__entry_text_end) || + (addr >= (unsigned long)__idmap_text_start && + addr < (unsigned long)__idmap_text_end) || ++ (addr >= (unsigned long)__hyp_text_start && ++ addr < (unsigned long)__hyp_text_end) || + !!search_exception_tables(addr)) + return true; + + if (!is_kernel_in_hyp_mode()) { +- if ((addr >= (unsigned long)__hyp_text_start && +- addr < (unsigned long)__hyp_text_end) || +- (addr >= (unsigned long)__hyp_idmap_text_start && ++ if ((addr >= (unsigned long)__hyp_idmap_text_start && + addr < (unsigned long)__hyp_idmap_text_end)) + return true; + } +-- +2.19.1 + diff --git a/queue-4.20/ath10k-correct-bus-type-for-wcn3990.patch b/queue-4.20/ath10k-correct-bus-type-for-wcn3990.patch new file mode 100644 index 00000000000..18aa482e643 --- /dev/null +++ b/queue-4.20/ath10k-correct-bus-type-for-wcn3990.patch @@ -0,0 +1,34 @@ +From 11850e2f6661e1105933d14bf2a0319a8efe45f4 Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Tue, 29 Jan 2019 15:12:01 -0800 +Subject: ath10k: correct bus type for WCN3990 + +[ Upstream commit 2c2008a63e482654ab137c84d3c61c03b75e7df6 ] + +WCN3990 is SNOC, not PCI. This prevents probing WCN3990. + +Fixes: 367c899f622c ("ath10k: add bus type check in ath10k_init_hw_params") +Signed-off-by: Brian Norris +Reviewed-by: Bjorn Andersson +Signed-off-by: Kalle Valo +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 59fdda67f89f..0a3b2c45549e 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -548,7 +548,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + { + .id = WCN3990_HW_1_0_DEV_VERSION, + .dev_id = 0, +- .bus = ATH10K_BUS_PCI, ++ .bus = ATH10K_BUS_SNOC, + .name = "wcn3990 hw1.0", + .continuous_frag_desc = true, + .tx_chain_mask = 0x7, +-- +2.19.1 + diff --git a/queue-4.20/autofs-drop-dentry-reference-only-when-it-is-never-u.patch b/queue-4.20/autofs-drop-dentry-reference-only-when-it-is-never-u.patch new file mode 100644 index 00000000000..3746538fb86 --- /dev/null +++ b/queue-4.20/autofs-drop-dentry-reference-only-when-it-is-never-u.patch @@ -0,0 +1,46 @@ +From 4f23ac1861f52bc488aebc42aad6c4cca8b66a30 Mon Sep 17 00:00:00 2001 +From: Pan Bian +Date: Fri, 1 Feb 2019 14:21:26 -0800 +Subject: autofs: drop dentry reference only when it is never used + +[ Upstream commit 63ce5f552beb9bdb41546b3a26c4374758b21815 ] + +autofs_expire_run() calls dput(dentry) to drop the reference count of +dentry. However, dentry is read via autofs_dentry_ino(dentry) after +that. This may result in a use-free-bug. The patch drops the reference +count of dentry only when it is never used. + +Link: http://lkml.kernel.org/r/154725122396.11260.16053424107144453867.stgit@pluto-themaw-net +Signed-off-by: Pan Bian +Signed-off-by: Ian Kent +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + fs/autofs/expire.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c +index d441244b79df..28d9c2b1b3bb 100644 +--- a/fs/autofs/expire.c ++++ b/fs/autofs/expire.c +@@ -596,7 +596,6 @@ int autofs_expire_run(struct super_block *sb, + pkt.len = dentry->d_name.len; + memcpy(pkt.name, dentry->d_name.name, pkt.len); + pkt.name[pkt.len] = '\0'; +- dput(dentry); + + if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire))) + ret = -EFAULT; +@@ -609,6 +608,8 @@ int autofs_expire_run(struct super_block *sb, + complete_all(&ino->expire_complete); + spin_unlock(&sbi->fs_lock); + ++ dput(dentry); ++ + return ret; + } + +-- +2.19.1 + diff --git a/queue-4.20/autofs-fix-error-return-in-autofs_fill_super.patch b/queue-4.20/autofs-fix-error-return-in-autofs_fill_super.patch new file mode 100644 index 00000000000..0c73eb871bc --- /dev/null +++ b/queue-4.20/autofs-fix-error-return-in-autofs_fill_super.patch @@ -0,0 +1,39 @@ +From 5920eef9d34dbc1812b321eb0d086e32c67fd4ed Mon Sep 17 00:00:00 2001 +From: Ian Kent +Date: Fri, 1 Feb 2019 14:21:29 -0800 +Subject: autofs: fix error return in autofs_fill_super() + +[ Upstream commit f585b283e3f025754c45bbe7533fc6e5c4643700 ] + +In autofs_fill_super() on error of get inode/make root dentry the return +should be ENOMEM as this is the only failure case of the called +functions. + +Link: http://lkml.kernel.org/r/154725123240.11260.796773942606871359.stgit@pluto-themaw-net +Signed-off-by: Ian Kent +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + fs/autofs/inode.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c +index 846c052569dd..3c14a8e45ffb 100644 +--- a/fs/autofs/inode.c ++++ b/fs/autofs/inode.c +@@ -255,8 +255,10 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) + } + root_inode = autofs_get_inode(s, S_IFDIR | 0755); + root = d_make_root(root_inode); +- if (!root) ++ if (!root) { ++ ret = -ENOMEM; + goto fail_ino; ++ } + pipe = NULL; + + root->d_fsdata = ino; +-- +2.19.1 + diff --git a/queue-4.20/batman-adv-release-station-info-tidstats.patch b/queue-4.20/batman-adv-release-station-info-tidstats.patch new file mode 100644 index 00000000000..6af250564d9 --- /dev/null +++ b/queue-4.20/batman-adv-release-station-info-tidstats.patch @@ -0,0 +1,43 @@ +From 129bad15113a189b57234962a14689a164b24841 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 25 Jan 2019 08:21:26 +0100 +Subject: batman-adv: release station info tidstats + +[ Upstream commit 7d652669b61d702c6e62a39579d17f6881670ab6 ] + +With the addition of TXQ stats in the per-tid statistics the struct +station_info grew significantly. This resulted in stack size warnings +due to the structure itself being above the limit for the warnings. + +To work around this, the TID array was allocated dynamically. Also a +function to free this content was introduced with commit 7ea3e110f2f8 +("cfg80211: release station info tidstats where needed") but the necessary +changes were not provided for batman-adv's B.A.T.M.A.N. V implementation. + +Signed-off-by: Felix Fietkau +Fixes: 8689c051a201 ("cfg80211: dynamically allocate per-tid stats for station info") +[sven@narfation.org: add commit message] +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Sasha Levin +--- + net/batman-adv/bat_v_elp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c +index e8090f099eb8..ef0dec20c7d8 100644 +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -104,6 +104,9 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + + ret = cfg80211_get_station(real_netdev, neigh->addr, &sinfo); + ++ /* free the TID stats immediately */ ++ cfg80211_sinfo_release_content(&sinfo); ++ + dev_put(real_netdev); + if (ret == -ENOENT) { + /* Node is not associated anymore! It would be +-- +2.19.1 + diff --git a/queue-4.20/blk-iolatency-fix-io-hang-due-to-negative-inflight-c.patch b/queue-4.20/blk-iolatency-fix-io-hang-due-to-negative-inflight-c.patch new file mode 100644 index 00000000000..e4ea07aa347 --- /dev/null +++ b/queue-4.20/blk-iolatency-fix-io-hang-due-to-negative-inflight-c.patch @@ -0,0 +1,193 @@ +From 77602407b85afb471bbab5cdf1f564330c30b2f4 Mon Sep 17 00:00:00 2001 +From: Liu Bo +Date: Fri, 25 Jan 2019 08:12:47 +0800 +Subject: blk-iolatency: fix IO hang due to negative inflight counter + +[ Upstream commit 8c772a9bfc7c07c76f4a58b58910452fbb20843b ] + +Our test reported the following stack, and vmcore showed that +->inflight counter is -1. + +[ffffc9003fcc38d0] __schedule at ffffffff8173d95d +[ffffc9003fcc3958] schedule at ffffffff8173de26 +[ffffc9003fcc3970] io_schedule at ffffffff810bb6b6 +[ffffc9003fcc3988] blkcg_iolatency_throttle at ffffffff813911cb +[ffffc9003fcc3a20] rq_qos_throttle at ffffffff813847f3 +[ffffc9003fcc3a48] blk_mq_make_request at ffffffff8137468a +[ffffc9003fcc3b08] generic_make_request at ffffffff81368b49 +[ffffc9003fcc3b68] submit_bio at ffffffff81368d7d +[ffffc9003fcc3bb8] ext4_io_submit at ffffffffa031be00 [ext4] +[ffffc9003fcc3c00] ext4_writepages at ffffffffa03163de [ext4] +[ffffc9003fcc3d68] do_writepages at ffffffff811c49ae +[ffffc9003fcc3d78] __filemap_fdatawrite_range at ffffffff811b6188 +[ffffc9003fcc3e30] filemap_write_and_wait_range at ffffffff811b6301 +[ffffc9003fcc3e60] ext4_sync_file at ffffffffa030cee8 [ext4] +[ffffc9003fcc3ea8] vfs_fsync_range at ffffffff8128594b +[ffffc9003fcc3ee8] do_fsync at ffffffff81285abd +[ffffc9003fcc3f18] sys_fsync at ffffffff81285d50 +[ffffc9003fcc3f28] do_syscall_64 at ffffffff81003c04 +[ffffc9003fcc3f50] entry_SYSCALL_64_after_swapgs at ffffffff81742b8e + +The ->inflight counter may be negative (-1) if + +1) blk-iolatency was disabled when the IO was issued, + +2) blk-iolatency was enabled before this IO reached its endio, + +3) the ->inflight counter is decreased from 0 to -1 in endio() + +In fact the hang can be easily reproduced by the below script, + +H=/sys/fs/cgroup/unified/ +P=/sys/fs/cgroup/unified/test + +echo "+io" > $H/cgroup.subtree_control +mkdir -p $P + +echo $$ > $P/cgroup.procs + +xfs_io -f -d -c "pwrite 0 4k" /dev/sdg + +echo "`cat /sys/block/sdg/dev` target=1000000" > $P/io.latency + +xfs_io -f -d -c "pwrite 0 4k" /dev/sdg + +This fixes the problem by freezing the queue so that while +enabling/disabling iolatency, there is no inflight rq running. + +Note that quiesce_queue is not needed as this only updating iolatency +configuration about which dispatching request_queue doesn't care. + +Signed-off-by: Liu Bo +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-iolatency.c | 52 +++++++++++++++++++++++++++++++++++++------ + 1 file changed, 45 insertions(+), 7 deletions(-) + +diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c +index 38c35c32aff2..c1c72b42dda0 100644 +--- a/block/blk-iolatency.c ++++ b/block/blk-iolatency.c +@@ -72,6 +72,7 @@ + #include + #include + #include ++#include + #include "blk-rq-qos.h" + #include "blk-stat.h" + +@@ -648,6 +649,9 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) + return; + + enabled = blk_iolatency_enabled(iolat->blkiolat); ++ if (!enabled) ++ return; ++ + while (blkg && blkg->parent) { + iolat = blkg_to_lat(blkg); + if (!iolat) { +@@ -657,7 +661,7 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) + rqw = &iolat->rq_wait; + + atomic_dec(&rqw->inflight); +- if (!enabled || iolat->min_lat_nsec == 0) ++ if (iolat->min_lat_nsec == 0) + goto next; + iolatency_record_time(iolat, &bio->bi_issue, now, + issue_as_root); +@@ -801,10 +805,13 @@ int blk_iolatency_init(struct request_queue *q) + return 0; + } + +-static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) ++/* ++ * return 1 for enabling iolatency, return -1 for disabling iolatency, otherwise ++ * return 0. ++ */ ++static int iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) + { + struct iolatency_grp *iolat = blkg_to_lat(blkg); +- struct blk_iolatency *blkiolat = iolat->blkiolat; + u64 oldval = iolat->min_lat_nsec; + + iolat->min_lat_nsec = val; +@@ -813,9 +820,10 @@ static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) + BLKIOLATENCY_MAX_WIN_SIZE); + + if (!oldval && val) +- atomic_inc(&blkiolat->enabled); ++ return 1; + if (oldval && !val) +- atomic_dec(&blkiolat->enabled); ++ return -1; ++ return 0; + } + + static void iolatency_clear_scaling(struct blkcg_gq *blkg) +@@ -847,6 +855,7 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, + u64 lat_val = 0; + u64 oldval; + int ret; ++ int enable = 0; + + ret = blkg_conf_prep(blkcg, &blkcg_policy_iolatency, buf, &ctx); + if (ret) +@@ -881,7 +890,12 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, + blkg = ctx.blkg; + oldval = iolat->min_lat_nsec; + +- iolatency_set_min_lat_nsec(blkg, lat_val); ++ enable = iolatency_set_min_lat_nsec(blkg, lat_val); ++ if (enable) { ++ WARN_ON_ONCE(!blk_get_queue(blkg->q)); ++ blkg_get(blkg); ++ } ++ + if (oldval != iolat->min_lat_nsec) { + iolatency_clear_scaling(blkg); + } +@@ -889,6 +903,24 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, + ret = 0; + out: + blkg_conf_finish(&ctx); ++ if (ret == 0 && enable) { ++ struct iolatency_grp *tmp = blkg_to_lat(blkg); ++ struct blk_iolatency *blkiolat = tmp->blkiolat; ++ ++ blk_mq_freeze_queue(blkg->q); ++ ++ if (enable == 1) ++ atomic_inc(&blkiolat->enabled); ++ else if (enable == -1) ++ atomic_dec(&blkiolat->enabled); ++ else ++ WARN_ON_ONCE(1); ++ ++ blk_mq_unfreeze_queue(blkg->q); ++ ++ blkg_put(blkg); ++ blk_put_queue(blkg->q); ++ } + return ret ?: nbytes; + } + +@@ -1024,8 +1056,14 @@ static void iolatency_pd_offline(struct blkg_policy_data *pd) + { + struct iolatency_grp *iolat = pd_to_lat(pd); + struct blkcg_gq *blkg = lat_to_blkg(iolat); ++ struct blk_iolatency *blkiolat = iolat->blkiolat; ++ int ret; + +- iolatency_set_min_lat_nsec(blkg, 0); ++ ret = iolatency_set_min_lat_nsec(blkg, 0); ++ if (ret == 1) ++ atomic_inc(&blkiolat->enabled); ++ if (ret == -1) ++ atomic_dec(&blkiolat->enabled); + iolatency_clear_scaling(blkg); + } + +-- +2.19.1 + diff --git a/queue-4.20/bpf-fix-lockdep-false-positive-in-percpu_freelist.patch b/queue-4.20/bpf-fix-lockdep-false-positive-in-percpu_freelist.patch new file mode 100644 index 00000000000..7beee3d7d16 --- /dev/null +++ b/queue-4.20/bpf-fix-lockdep-false-positive-in-percpu_freelist.patch @@ -0,0 +1,305 @@ +From 046f3555ab1e5e7583d9f4444e191a1f79b8f508 Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov +Date: Wed, 30 Jan 2019 18:12:43 -0800 +Subject: bpf: fix lockdep false positive in percpu_freelist + +[ Upstream commit a89fac57b5d080771efd4d71feaae19877cf68f0 ] + +Lockdep warns about false positive: +[ 12.492084] 00000000e6b28347 (&head->lock){+...}, at: pcpu_freelist_push+0x2a/0x40 +[ 12.492696] but this lock was taken by another, HARDIRQ-safe lock in the past: +[ 12.493275] (&rq->lock){-.-.} +[ 12.493276] +[ 12.493276] +[ 12.493276] and interrupts could create inverse lock ordering between them. +[ 12.493276] +[ 12.494435] +[ 12.494435] other info that might help us debug this: +[ 12.494979] Possible interrupt unsafe locking scenario: +[ 12.494979] +[ 12.495518] CPU0 CPU1 +[ 12.495879] ---- ---- +[ 12.496243] lock(&head->lock); +[ 12.496502] local_irq_disable(); +[ 12.496969] lock(&rq->lock); +[ 12.497431] lock(&head->lock); +[ 12.497890] +[ 12.498104] lock(&rq->lock); +[ 12.498368] +[ 12.498368] *** DEADLOCK *** +[ 12.498368] +[ 12.498837] 1 lock held by dd/276: +[ 12.499110] #0: 00000000c58cb2ee (rcu_read_lock){....}, at: trace_call_bpf+0x5e/0x240 +[ 12.499747] +[ 12.499747] the shortest dependencies between 2nd lock and 1st lock: +[ 12.500389] -> (&rq->lock){-.-.} { +[ 12.500669] IN-HARDIRQ-W at: +[ 12.500934] _raw_spin_lock+0x2f/0x40 +[ 12.501373] scheduler_tick+0x4c/0xf0 +[ 12.501812] update_process_times+0x40/0x50 +[ 12.502294] tick_periodic+0x27/0xb0 +[ 12.502723] tick_handle_periodic+0x1f/0x60 +[ 12.503203] timer_interrupt+0x11/0x20 +[ 12.503651] __handle_irq_event_percpu+0x43/0x2c0 +[ 12.504167] handle_irq_event_percpu+0x20/0x50 +[ 12.504674] handle_irq_event+0x37/0x60 +[ 12.505139] handle_level_irq+0xa7/0x120 +[ 12.505601] handle_irq+0xa1/0x150 +[ 12.506018] do_IRQ+0x77/0x140 +[ 12.506411] ret_from_intr+0x0/0x1d +[ 12.506834] _raw_spin_unlock_irqrestore+0x53/0x60 +[ 12.507362] __setup_irq+0x481/0x730 +[ 12.507789] setup_irq+0x49/0x80 +[ 12.508195] hpet_time_init+0x21/0x32 +[ 12.508644] x86_late_time_init+0xb/0x16 +[ 12.509106] start_kernel+0x390/0x42a +[ 12.509554] secondary_startup_64+0xa4/0xb0 +[ 12.510034] IN-SOFTIRQ-W at: +[ 12.510305] _raw_spin_lock+0x2f/0x40 +[ 12.510772] try_to_wake_up+0x1c7/0x4e0 +[ 12.511220] swake_up_locked+0x20/0x40 +[ 12.511657] swake_up_one+0x1a/0x30 +[ 12.512070] rcu_process_callbacks+0xc5/0x650 +[ 12.512553] __do_softirq+0xe6/0x47b +[ 12.512978] irq_exit+0xc3/0xd0 +[ 12.513372] smp_apic_timer_interrupt+0xa9/0x250 +[ 12.513876] apic_timer_interrupt+0xf/0x20 +[ 12.514343] default_idle+0x1c/0x170 +[ 12.514765] do_idle+0x199/0x240 +[ 12.515159] cpu_startup_entry+0x19/0x20 +[ 12.515614] start_kernel+0x422/0x42a +[ 12.516045] secondary_startup_64+0xa4/0xb0 +[ 12.516521] INITIAL USE at: +[ 12.516774] _raw_spin_lock_irqsave+0x38/0x50 +[ 12.517258] rq_attach_root+0x16/0xd0 +[ 12.517685] sched_init+0x2f2/0x3eb +[ 12.518096] start_kernel+0x1fb/0x42a +[ 12.518525] secondary_startup_64+0xa4/0xb0 +[ 12.518986] } +[ 12.519132] ... key at: [] __key.71384+0x0/0x8 +[ 12.519649] ... acquired at: +[ 12.519892] pcpu_freelist_pop+0x7b/0xd0 +[ 12.520221] bpf_get_stackid+0x1d2/0x4d0 +[ 12.520563] ___bpf_prog_run+0x8b4/0x11a0 +[ 12.520887] +[ 12.521008] -> (&head->lock){+...} { +[ 12.521292] HARDIRQ-ON-W at: +[ 12.521539] _raw_spin_lock+0x2f/0x40 +[ 12.521950] pcpu_freelist_push+0x2a/0x40 +[ 12.522396] bpf_get_stackid+0x494/0x4d0 +[ 12.522828] ___bpf_prog_run+0x8b4/0x11a0 +[ 12.523296] INITIAL USE at: +[ 12.523537] _raw_spin_lock+0x2f/0x40 +[ 12.523944] pcpu_freelist_populate+0xc0/0x120 +[ 12.524417] htab_map_alloc+0x405/0x500 +[ 12.524835] __do_sys_bpf+0x1a3/0x1a90 +[ 12.525253] do_syscall_64+0x4a/0x180 +[ 12.525659] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 12.526167] } +[ 12.526311] ... key at: [] __key.13130+0x0/0x8 +[ 12.526812] ... acquired at: +[ 12.527047] __lock_acquire+0x521/0x1350 +[ 12.527371] lock_acquire+0x98/0x190 +[ 12.527680] _raw_spin_lock+0x2f/0x40 +[ 12.527994] pcpu_freelist_push+0x2a/0x40 +[ 12.528325] bpf_get_stackid+0x494/0x4d0 +[ 12.528645] ___bpf_prog_run+0x8b4/0x11a0 +[ 12.528970] +[ 12.529092] +[ 12.529092] stack backtrace: +[ 12.529444] CPU: 0 PID: 276 Comm: dd Not tainted 5.0.0-rc3-00018-g2fa53f892422 #475 +[ 12.530043] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2.el7 04/01/2014 +[ 12.530750] Call Trace: +[ 12.530948] dump_stack+0x5f/0x8b +[ 12.531248] check_usage_backwards+0x10c/0x120 +[ 12.531598] ? ___bpf_prog_run+0x8b4/0x11a0 +[ 12.531935] ? mark_lock+0x382/0x560 +[ 12.532229] mark_lock+0x382/0x560 +[ 12.532496] ? print_shortest_lock_dependencies+0x180/0x180 +[ 12.532928] __lock_acquire+0x521/0x1350 +[ 12.533271] ? find_get_entry+0x17f/0x2e0 +[ 12.533586] ? find_get_entry+0x19c/0x2e0 +[ 12.533902] ? lock_acquire+0x98/0x190 +[ 12.534196] lock_acquire+0x98/0x190 +[ 12.534482] ? pcpu_freelist_push+0x2a/0x40 +[ 12.534810] _raw_spin_lock+0x2f/0x40 +[ 12.535099] ? pcpu_freelist_push+0x2a/0x40 +[ 12.535432] pcpu_freelist_push+0x2a/0x40 +[ 12.535750] bpf_get_stackid+0x494/0x4d0 +[ 12.536062] ___bpf_prog_run+0x8b4/0x11a0 + +It has been explained that is a false positive here: +https://lkml.org/lkml/2018/7/25/756 +Recap: +- stackmap uses pcpu_freelist +- The lock in pcpu_freelist is a percpu lock +- stackmap is only used by tracing bpf_prog +- A tracing bpf_prog cannot be run if another bpf_prog + has already been running (ensured by the percpu bpf_prog_active counter). + +Eric pointed out that this lockdep splats stops other +legit lockdep splats in selftests/bpf/test_progs.c. + +Fix this by calling local_irq_save/restore for stackmap. + +Another false positive had also been worked around by calling +local_irq_save in commit 89ad2fa3f043 ("bpf: fix lockdep splat"). +That commit added unnecessary irq_save/restore to fast path of +bpf hash map. irqs are already disabled at that point, since htab +is holding per bucket spin_lock with irqsave. + +Let's reduce overhead for htab by introducing __pcpu_freelist_push/pop +function w/o irqsave and convert pcpu_freelist_push/pop to irqsave +to be used elsewhere (right now only in stackmap). +It stops lockdep false positive in stackmap with a bit of acceptable overhead. + +Fixes: 557c0c6e7df8 ("bpf: convert stackmap to pre-allocation") +Reported-by: Naresh Kamboju +Reported-by: Eric Dumazet +Acked-by: Martin KaFai Lau +Signed-off-by: Alexei Starovoitov +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 4 ++-- + kernel/bpf/percpu_freelist.c | 41 +++++++++++++++++++++++++----------- + kernel/bpf/percpu_freelist.h | 4 ++++ + 3 files changed, 35 insertions(+), 14 deletions(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index 2c1790288138..3388c0b85a57 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -677,7 +677,7 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) + } + + if (htab_is_prealloc(htab)) { +- pcpu_freelist_push(&htab->freelist, &l->fnode); ++ __pcpu_freelist_push(&htab->freelist, &l->fnode); + } else { + atomic_dec(&htab->count); + l->htab = htab; +@@ -739,7 +739,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, + } else { + struct pcpu_freelist_node *l; + +- l = pcpu_freelist_pop(&htab->freelist); ++ l = __pcpu_freelist_pop(&htab->freelist); + if (!l) + return ERR_PTR(-E2BIG); + l_new = container_of(l, struct htab_elem, fnode); +diff --git a/kernel/bpf/percpu_freelist.c b/kernel/bpf/percpu_freelist.c +index 673fa6fe2d73..0c1b4ba9e90e 100644 +--- a/kernel/bpf/percpu_freelist.c ++++ b/kernel/bpf/percpu_freelist.c +@@ -28,8 +28,8 @@ void pcpu_freelist_destroy(struct pcpu_freelist *s) + free_percpu(s->freelist); + } + +-static inline void __pcpu_freelist_push(struct pcpu_freelist_head *head, +- struct pcpu_freelist_node *node) ++static inline void ___pcpu_freelist_push(struct pcpu_freelist_head *head, ++ struct pcpu_freelist_node *node) + { + raw_spin_lock(&head->lock); + node->next = head->first; +@@ -37,12 +37,22 @@ static inline void __pcpu_freelist_push(struct pcpu_freelist_head *head, + raw_spin_unlock(&head->lock); + } + +-void pcpu_freelist_push(struct pcpu_freelist *s, ++void __pcpu_freelist_push(struct pcpu_freelist *s, + struct pcpu_freelist_node *node) + { + struct pcpu_freelist_head *head = this_cpu_ptr(s->freelist); + +- __pcpu_freelist_push(head, node); ++ ___pcpu_freelist_push(head, node); ++} ++ ++void pcpu_freelist_push(struct pcpu_freelist *s, ++ struct pcpu_freelist_node *node) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ __pcpu_freelist_push(s, node); ++ local_irq_restore(flags); + } + + void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, +@@ -63,7 +73,7 @@ void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, + for_each_possible_cpu(cpu) { + again: + head = per_cpu_ptr(s->freelist, cpu); +- __pcpu_freelist_push(head, buf); ++ ___pcpu_freelist_push(head, buf); + i++; + buf += elem_size; + if (i == nr_elems) +@@ -74,14 +84,12 @@ void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, + local_irq_restore(flags); + } + +-struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) ++struct pcpu_freelist_node *__pcpu_freelist_pop(struct pcpu_freelist *s) + { + struct pcpu_freelist_head *head; + struct pcpu_freelist_node *node; +- unsigned long flags; + int orig_cpu, cpu; + +- local_irq_save(flags); + orig_cpu = cpu = raw_smp_processor_id(); + while (1) { + head = per_cpu_ptr(s->freelist, cpu); +@@ -89,16 +97,25 @@ struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) + node = head->first; + if (node) { + head->first = node->next; +- raw_spin_unlock_irqrestore(&head->lock, flags); ++ raw_spin_unlock(&head->lock); + return node; + } + raw_spin_unlock(&head->lock); + cpu = cpumask_next(cpu, cpu_possible_mask); + if (cpu >= nr_cpu_ids) + cpu = 0; +- if (cpu == orig_cpu) { +- local_irq_restore(flags); ++ if (cpu == orig_cpu) + return NULL; +- } + } + } ++ ++struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) ++{ ++ struct pcpu_freelist_node *ret; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ret = __pcpu_freelist_pop(s); ++ local_irq_restore(flags); ++ return ret; ++} +diff --git a/kernel/bpf/percpu_freelist.h b/kernel/bpf/percpu_freelist.h +index 3049aae8ea1e..c3960118e617 100644 +--- a/kernel/bpf/percpu_freelist.h ++++ b/kernel/bpf/percpu_freelist.h +@@ -22,8 +22,12 @@ struct pcpu_freelist_node { + struct pcpu_freelist_node *next; + }; + ++/* pcpu_freelist_* do spin_lock_irqsave. */ + void pcpu_freelist_push(struct pcpu_freelist *, struct pcpu_freelist_node *); + struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *); ++/* __pcpu_freelist_* do spin_lock only. caller must disable irqs. */ ++void __pcpu_freelist_push(struct pcpu_freelist *, struct pcpu_freelist_node *); ++struct pcpu_freelist_node *__pcpu_freelist_pop(struct pcpu_freelist *); + void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size, + u32 nr_elems); + int pcpu_freelist_init(struct pcpu_freelist *); +-- +2.19.1 + diff --git a/queue-4.20/bpf-fix-potential-deadlock-in-bpf_prog_register.patch b/queue-4.20/bpf-fix-potential-deadlock-in-bpf_prog_register.patch new file mode 100644 index 00000000000..6f3efcc05c3 --- /dev/null +++ b/queue-4.20/bpf-fix-potential-deadlock-in-bpf_prog_register.patch @@ -0,0 +1,167 @@ +From 94988b66ad400b891c866a011e3f18c99560b92d Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov +Date: Wed, 30 Jan 2019 18:12:44 -0800 +Subject: bpf: fix potential deadlock in bpf_prog_register + +[ Upstream commit e16ec34039c701594d55d08a5aa49ee3e1abc821 ] + +Lockdep found a potential deadlock between cpu_hotplug_lock, bpf_event_mutex, and cpuctx_mutex: +[ 13.007000] WARNING: possible circular locking dependency detected +[ 13.007587] 5.0.0-rc3-00018-g2fa53f892422-dirty #477 Not tainted +[ 13.008124] ------------------------------------------------------ +[ 13.008624] test_progs/246 is trying to acquire lock: +[ 13.009030] 0000000094160d1d (tracepoints_mutex){+.+.}, at: tracepoint_probe_register_prio+0x2d/0x300 +[ 13.009770] +[ 13.009770] but task is already holding lock: +[ 13.010239] 00000000d663ef86 (bpf_event_mutex){+.+.}, at: bpf_probe_register+0x1d/0x60 +[ 13.010877] +[ 13.010877] which lock already depends on the new lock. +[ 13.010877] +[ 13.011532] +[ 13.011532] the existing dependency chain (in reverse order) is: +[ 13.012129] +[ 13.012129] -> #4 (bpf_event_mutex){+.+.}: +[ 13.012582] perf_event_query_prog_array+0x9b/0x130 +[ 13.013016] _perf_ioctl+0x3aa/0x830 +[ 13.013354] perf_ioctl+0x2e/0x50 +[ 13.013668] do_vfs_ioctl+0x8f/0x6a0 +[ 13.014003] ksys_ioctl+0x70/0x80 +[ 13.014320] __x64_sys_ioctl+0x16/0x20 +[ 13.014668] do_syscall_64+0x4a/0x180 +[ 13.015007] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 13.015469] +[ 13.015469] -> #3 (&cpuctx_mutex){+.+.}: +[ 13.015910] perf_event_init_cpu+0x5a/0x90 +[ 13.016291] perf_event_init+0x1b2/0x1de +[ 13.016654] start_kernel+0x2b8/0x42a +[ 13.016995] secondary_startup_64+0xa4/0xb0 +[ 13.017382] +[ 13.017382] -> #2 (pmus_lock){+.+.}: +[ 13.017794] perf_event_init_cpu+0x21/0x90 +[ 13.018172] cpuhp_invoke_callback+0xb3/0x960 +[ 13.018573] _cpu_up+0xa7/0x140 +[ 13.018871] do_cpu_up+0xa4/0xc0 +[ 13.019178] smp_init+0xcd/0xd2 +[ 13.019483] kernel_init_freeable+0x123/0x24f +[ 13.019878] kernel_init+0xa/0x110 +[ 13.020201] ret_from_fork+0x24/0x30 +[ 13.020541] +[ 13.020541] -> #1 (cpu_hotplug_lock.rw_sem){++++}: +[ 13.021051] static_key_slow_inc+0xe/0x20 +[ 13.021424] tracepoint_probe_register_prio+0x28c/0x300 +[ 13.021891] perf_trace_event_init+0x11f/0x250 +[ 13.022297] perf_trace_init+0x6b/0xa0 +[ 13.022644] perf_tp_event_init+0x25/0x40 +[ 13.023011] perf_try_init_event+0x6b/0x90 +[ 13.023386] perf_event_alloc+0x9a8/0xc40 +[ 13.023754] __do_sys_perf_event_open+0x1dd/0xd30 +[ 13.024173] do_syscall_64+0x4a/0x180 +[ 13.024519] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 13.024968] +[ 13.024968] -> #0 (tracepoints_mutex){+.+.}: +[ 13.025434] __mutex_lock+0x86/0x970 +[ 13.025764] tracepoint_probe_register_prio+0x2d/0x300 +[ 13.026215] bpf_probe_register+0x40/0x60 +[ 13.026584] bpf_raw_tracepoint_open.isra.34+0xa4/0x130 +[ 13.027042] __do_sys_bpf+0x94f/0x1a90 +[ 13.027389] do_syscall_64+0x4a/0x180 +[ 13.027727] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 13.028171] +[ 13.028171] other info that might help us debug this: +[ 13.028171] +[ 13.028807] Chain exists of: +[ 13.028807] tracepoints_mutex --> &cpuctx_mutex --> bpf_event_mutex +[ 13.028807] +[ 13.029666] Possible unsafe locking scenario: +[ 13.029666] +[ 13.030140] CPU0 CPU1 +[ 13.030510] ---- ---- +[ 13.030875] lock(bpf_event_mutex); +[ 13.031166] lock(&cpuctx_mutex); +[ 13.031645] lock(bpf_event_mutex); +[ 13.032135] lock(tracepoints_mutex); +[ 13.032441] +[ 13.032441] *** DEADLOCK *** +[ 13.032441] +[ 13.032911] 1 lock held by test_progs/246: +[ 13.033239] #0: 00000000d663ef86 (bpf_event_mutex){+.+.}, at: bpf_probe_register+0x1d/0x60 +[ 13.033909] +[ 13.033909] stack backtrace: +[ 13.034258] CPU: 1 PID: 246 Comm: test_progs Not tainted 5.0.0-rc3-00018-g2fa53f892422-dirty #477 +[ 13.034964] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2.el7 04/01/2014 +[ 13.035657] Call Trace: +[ 13.035859] dump_stack+0x5f/0x8b +[ 13.036130] print_circular_bug.isra.37+0x1ce/0x1db +[ 13.036526] __lock_acquire+0x1158/0x1350 +[ 13.036852] ? lock_acquire+0x98/0x190 +[ 13.037154] lock_acquire+0x98/0x190 +[ 13.037447] ? tracepoint_probe_register_prio+0x2d/0x300 +[ 13.037876] __mutex_lock+0x86/0x970 +[ 13.038167] ? tracepoint_probe_register_prio+0x2d/0x300 +[ 13.038600] ? tracepoint_probe_register_prio+0x2d/0x300 +[ 13.039028] ? __mutex_lock+0x86/0x970 +[ 13.039337] ? __mutex_lock+0x24a/0x970 +[ 13.039649] ? bpf_probe_register+0x1d/0x60 +[ 13.039992] ? __bpf_trace_sched_wake_idle_without_ipi+0x10/0x10 +[ 13.040478] ? tracepoint_probe_register_prio+0x2d/0x300 +[ 13.040906] tracepoint_probe_register_prio+0x2d/0x300 +[ 13.041325] bpf_probe_register+0x40/0x60 +[ 13.041649] bpf_raw_tracepoint_open.isra.34+0xa4/0x130 +[ 13.042068] ? __might_fault+0x3e/0x90 +[ 13.042374] __do_sys_bpf+0x94f/0x1a90 +[ 13.042678] do_syscall_64+0x4a/0x180 +[ 13.042975] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 13.043382] RIP: 0033:0x7f23b10a07f9 +[ 13.045155] RSP: 002b:00007ffdef42fdd8 EFLAGS: 00000202 ORIG_RAX: 0000000000000141 +[ 13.045759] RAX: ffffffffffffffda RBX: 00007ffdef42ff70 RCX: 00007f23b10a07f9 +[ 13.046326] RDX: 0000000000000070 RSI: 00007ffdef42fe10 RDI: 0000000000000011 +[ 13.046893] RBP: 00007ffdef42fdf0 R08: 0000000000000038 R09: 00007ffdef42fe10 +[ 13.047462] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000 +[ 13.048029] R13: 0000000000000016 R14: 00007f23b1db4690 R15: 0000000000000000 + +Since tracepoints_mutex will be taken in tracepoint_probe_register/unregister() +there is no need to take bpf_event_mutex too. +bpf_event_mutex is protecting modifications to prog array used in kprobe/perf bpf progs. +bpf_raw_tracepoints don't need to take this mutex. + +Fixes: c4f6699dfcb8 ("bpf: introduce BPF_RAW_TRACEPOINT") +Acked-by: Martin KaFai Lau +Signed-off-by: Alexei Starovoitov +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + kernel/trace/bpf_trace.c | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index 9864a35c8bb5..6c28d519447d 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -1158,22 +1158,12 @@ static int __bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog * + + int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog) + { +- int err; +- +- mutex_lock(&bpf_event_mutex); +- err = __bpf_probe_register(btp, prog); +- mutex_unlock(&bpf_event_mutex); +- return err; ++ return __bpf_probe_register(btp, prog); + } + + int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog) + { +- int err; +- +- mutex_lock(&bpf_event_mutex); +- err = tracepoint_probe_unregister(btp->tp, (void *)btp->bpf_func, prog); +- mutex_unlock(&bpf_event_mutex); +- return err; ++ return tracepoint_probe_unregister(btp->tp, (void *)btp->bpf_func, prog); + } + + int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, +-- +2.19.1 + diff --git a/queue-4.20/bpf-fix-syscall-s-stackmap-lookup-potential-deadlock.patch b/queue-4.20/bpf-fix-syscall-s-stackmap-lookup-potential-deadlock.patch new file mode 100644 index 00000000000..313e8891470 --- /dev/null +++ b/queue-4.20/bpf-fix-syscall-s-stackmap-lookup-potential-deadlock.patch @@ -0,0 +1,80 @@ +From 98f37270e918a5ee3320588e801dc7064de7ba3e Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau +Date: Wed, 30 Jan 2019 18:12:45 -0800 +Subject: bpf: Fix syscall's stackmap lookup potential deadlock + +[ Upstream commit 7c4cd051add3d00bbff008a133c936c515eaa8fe ] + +The map_lookup_elem used to not acquiring spinlock +in order to optimize the reader. + +It was true until commit 557c0c6e7df8 ("bpf: convert stackmap to pre-allocation") +The syscall's map_lookup_elem(stackmap) calls bpf_stackmap_copy(). +bpf_stackmap_copy() may find the elem no longer needed after the copy is done. +If that is the case, pcpu_freelist_push() saves this elem for reuse later. +This push requires a spinlock. + +If a tracing bpf_prog got run in the middle of the syscall's +map_lookup_elem(stackmap) and this tracing bpf_prog is calling +bpf_get_stackid(stackmap) which also requires the same pcpu_freelist's +spinlock, it may end up with a dead lock situation as reported by +Eric Dumazet in https://patchwork.ozlabs.org/patch/1030266/ + +The situation is the same as the syscall's map_update_elem() which +needs to acquire the pcpu_freelist's spinlock and could race +with tracing bpf_prog. Hence, this patch fixes it by protecting +bpf_stackmap_copy() with this_cpu_inc(bpf_prog_active) +to prevent tracing bpf_prog from running. + +A later syscall's map_lookup_elem commit f1a2e44a3aec ("bpf: add queue and stack maps") +also acquires a spinlock and races with tracing bpf_prog similarly. +Hence, this patch is forward looking and protects the majority +of the map lookups. bpf_map_offload_lookup_elem() is the exception +since it is for network bpf_prog only (i.e. never called by tracing +bpf_prog). + +Fixes: 557c0c6e7df8 ("bpf: convert stackmap to pre-allocation") +Reported-by: Eric Dumazet +Acked-by: Alexei Starovoitov +Signed-off-by: Martin KaFai Lau +Signed-off-by: Alexei Starovoitov +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + kernel/bpf/syscall.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index cf5040fd5434..5f03ddf7b615 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -712,8 +712,13 @@ static int map_lookup_elem(union bpf_attr *attr) + + if (bpf_map_is_dev_bound(map)) { + err = bpf_map_offload_lookup_elem(map, key, value); +- } else if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || +- map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { ++ goto done; ++ } ++ ++ preempt_disable(); ++ this_cpu_inc(bpf_prog_active); ++ if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || ++ map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { + err = bpf_percpu_hash_copy(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { + err = bpf_percpu_array_copy(map, key, value); +@@ -743,7 +748,10 @@ static int map_lookup_elem(union bpf_attr *attr) + } + rcu_read_unlock(); + } ++ this_cpu_dec(bpf_prog_active); ++ preempt_enable(); + ++done: + if (err) + goto free_value; + +-- +2.19.1 + diff --git a/queue-4.20/bpf-run-bpf-programs-with-preemption-disabled.patch b/queue-4.20/bpf-run-bpf-programs-with-preemption-disabled.patch new file mode 100644 index 00000000000..16b94b2b0d2 --- /dev/null +++ b/queue-4.20/bpf-run-bpf-programs-with-preemption-disabled.patch @@ -0,0 +1,92 @@ +From 63d808447e0e75c1323a020fbe03bb5aafeff0b9 Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov +Date: Mon, 28 Jan 2019 18:43:34 -0800 +Subject: bpf: run bpf programs with preemption disabled + +[ Upstream commit 6cab5e90ab2bd323c9f3811b6c70a4687df51e27 ] + +Disabled preemption is necessary for proper access to per-cpu maps +from BPF programs. + +But the sender side of socket filters didn't have preemption disabled: +unix_dgram_sendmsg->sk_filter->sk_filter_trim_cap->bpf_prog_run_save_cb->BPF_PROG_RUN + +and a combination of af_packet with tun device didn't disable either: +tpacket_snd->packet_direct_xmit->packet_pick_tx_queue->ndo_select_queue-> + tun_select_queue->tun_ebpf_select_queue->bpf_prog_run_clear_cb->BPF_PROG_RUN + +Disable preemption before executing BPF programs (both classic and extended). + +Reported-by: Jann Horn +Signed-off-by: Alexei Starovoitov +Acked-by: Song Liu +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 21 ++++++++++++++++++--- + kernel/bpf/cgroup.c | 2 +- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index b776626aeb84..958eddbc44d3 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -591,8 +591,8 @@ static inline u8 *bpf_skb_cb(struct sk_buff *skb) + return qdisc_skb_cb(skb)->data; + } + +-static inline u32 bpf_prog_run_save_cb(const struct bpf_prog *prog, +- struct sk_buff *skb) ++static inline u32 __bpf_prog_run_save_cb(const struct bpf_prog *prog, ++ struct sk_buff *skb) + { + u8 *cb_data = bpf_skb_cb(skb); + u8 cb_saved[BPF_SKB_CB_LEN]; +@@ -611,15 +611,30 @@ static inline u32 bpf_prog_run_save_cb(const struct bpf_prog *prog, + return res; + } + ++static inline u32 bpf_prog_run_save_cb(const struct bpf_prog *prog, ++ struct sk_buff *skb) ++{ ++ u32 res; ++ ++ preempt_disable(); ++ res = __bpf_prog_run_save_cb(prog, skb); ++ preempt_enable(); ++ return res; ++} ++ + static inline u32 bpf_prog_run_clear_cb(const struct bpf_prog *prog, + struct sk_buff *skb) + { + u8 *cb_data = bpf_skb_cb(skb); ++ u32 res; + + if (unlikely(prog->cb_access)) + memset(cb_data, 0, BPF_SKB_CB_LEN); + +- return BPF_PROG_RUN(prog, skb); ++ preempt_disable(); ++ res = BPF_PROG_RUN(prog, skb); ++ preempt_enable(); ++ return res; + } + + static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog, +diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c +index 9425c2fb872f..6c24b1fb2db8 100644 +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -572,7 +572,7 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk, + bpf_compute_and_save_data_end(skb, &saved_data_end); + + ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], skb, +- bpf_prog_run_save_cb); ++ __bpf_prog_run_save_cb); + bpf_restore_data_end(skb, saved_data_end); + __skb_pull(skb, offset); + skb->sk = save_sk; +-- +2.19.1 + diff --git a/queue-4.20/bpf-selftests-fix-handling-of-sparse-cpu-allocations.patch b/queue-4.20/bpf-selftests-fix-handling-of-sparse-cpu-allocations.patch new file mode 100644 index 00000000000..d3eca249df7 --- /dev/null +++ b/queue-4.20/bpf-selftests-fix-handling-of-sparse-cpu-allocations.patch @@ -0,0 +1,79 @@ +From 4b591d13c12926373a48d2d96abd2ef0c4388584 Mon Sep 17 00:00:00 2001 +From: Martynas Pumputis +Date: Thu, 31 Jan 2019 10:19:33 +0100 +Subject: bpf, selftests: fix handling of sparse CPU allocations + +[ Upstream commit 1bb54c4071f585ebef56ce8fdfe6026fa2cbcddd ] + +Previously, bpf_num_possible_cpus() had a bug when calculating a +number of possible CPUs in the case of sparse CPU allocations, as +it was considering only the first range or element of +/sys/devices/system/cpu/possible. + +E.g. in the case of "0,2-3" (CPU 1 is not available), the function +returned 1 instead of 3. + +This patch fixes the function by making it parse all CPU ranges and +elements. + +Signed-off-by: Martynas Pumputis +Acked-by: Yonghong Song +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/bpf_util.h | 30 +++++++++++++++++--------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h +index 315a44fa32af..84fd6f1bf33e 100644 +--- a/tools/testing/selftests/bpf/bpf_util.h ++++ b/tools/testing/selftests/bpf/bpf_util.h +@@ -13,7 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void) + unsigned int start, end, possible_cpus = 0; + char buff[128]; + FILE *fp; +- int n; ++ int len, n, i, j = 0; + + fp = fopen(fcpu, "r"); + if (!fp) { +@@ -21,17 +21,27 @@ static inline unsigned int bpf_num_possible_cpus(void) + exit(1); + } + +- while (fgets(buff, sizeof(buff), fp)) { +- n = sscanf(buff, "%u-%u", &start, &end); +- if (n == 0) { +- printf("Failed to retrieve # possible CPUs!\n"); +- exit(1); +- } else if (n == 1) { +- end = start; ++ if (!fgets(buff, sizeof(buff), fp)) { ++ printf("Failed to read %s!\n", fcpu); ++ exit(1); ++ } ++ ++ len = strlen(buff); ++ for (i = 0; i <= len; i++) { ++ if (buff[i] == ',' || buff[i] == '\0') { ++ buff[i] = '\0'; ++ n = sscanf(&buff[j], "%u-%u", &start, &end); ++ if (n <= 0) { ++ printf("Failed to retrieve # possible CPUs!\n"); ++ exit(1); ++ } else if (n == 1) { ++ end = start; ++ } ++ possible_cpus += end - start + 1; ++ j = i + 1; + } +- possible_cpus = start == 0 ? end + 1 : 0; +- break; + } ++ + fclose(fp); + + return possible_cpus; +-- +2.19.1 + diff --git a/queue-4.20/bpf-sock-recvbuff-must-be-limited-by-rmem_max-in-bpf.patch b/queue-4.20/bpf-sock-recvbuff-must-be-limited-by-rmem_max-in-bpf.patch new file mode 100644 index 00000000000..c03740c63c3 --- /dev/null +++ b/queue-4.20/bpf-sock-recvbuff-must-be-limited-by-rmem_max-in-bpf.patch @@ -0,0 +1,40 @@ +From 1d9d7e9e712524543502fc78fcb5d1ff642b67bb Mon Sep 17 00:00:00 2001 +From: Yafang Shao +Date: Wed, 23 Jan 2019 12:37:19 +0800 +Subject: bpf: sock recvbuff must be limited by rmem_max in bpf_setsockopt() + +[ Upstream commit c9e4576743eeda8d24dedc164d65b78877f9a98c ] + +When sock recvbuff is set by bpf_setsockopt(), the value must by +limited by rmem_max. It is the same with sendbuff. + +Fixes: 8c4b4c7e9ff0 ("bpf: Add setsockopt helper function to bpf") +Signed-off-by: Yafang Shao +Acked-by: Martin KaFai Lau +Acked-by: Lawrence Brakmo +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 16350f8c8815..821050957aca 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -3927,10 +3927,12 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, + /* Only some socketops are supported */ + switch (optname) { + case SO_RCVBUF: ++ val = min_t(u32, val, sysctl_rmem_max); + sk->sk_userlocks |= SOCK_RCVBUF_LOCK; + sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); + break; + case SO_SNDBUF: ++ val = min_t(u32, val, sysctl_wmem_max); + sk->sk_userlocks |= SOCK_SNDBUF_LOCK; + sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); + break; +-- +2.19.1 + diff --git a/queue-4.20/bpftool-fix-percpu-maps-updating.patch b/queue-4.20/bpftool-fix-percpu-maps-updating.patch new file mode 100644 index 00000000000..021529b8951 --- /dev/null +++ b/queue-4.20/bpftool-fix-percpu-maps-updating.patch @@ -0,0 +1,65 @@ +From 2f5419fbb696b882513bdcb4a0262487c6c8fbe6 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Mon, 21 Jan 2019 12:36:12 +0100 +Subject: bpftool: fix percpu maps updating + +[ Upstream commit b0ca5ecb8e2279d706261f525f1bd0ba9e3fe800 ] + +When updating a percpu map, bpftool currently copies the provided +value only into the first per CPU copy of the specified value, +all others instances are left zeroed. + +This change explicitly copies the user-provided bytes to all the +per CPU instances, keeping the sub-command syntax unchanged. + +v2 -> v3: + - drop unused argument, as per Quentin's suggestion +v1 -> v2: + - rename the helper as per Quentin's suggestion + +Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") +Signed-off-by: Paolo Abeni +Reviewed-by: Quentin Monnet +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/map.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c +index 9988d5c126b6..94094168c4a6 100644 +--- a/tools/bpf/bpftool/map.c ++++ b/tools/bpf/bpftool/map.c +@@ -439,6 +439,20 @@ static char **parse_bytes(char **argv, const char *name, unsigned char *val, + return argv + i; + } + ++/* on per cpu maps we must copy the provided value on all value instances */ ++static void fill_per_cpu_value(struct bpf_map_info *info, void *value) ++{ ++ unsigned int i, n, step; ++ ++ if (!map_is_per_cpu(info->type)) ++ return; ++ ++ n = get_possible_cpus(); ++ step = round_up(info->value_size, 8); ++ for (i = 1; i < n; i++) ++ memcpy(value + i * step, value, info->value_size); ++} ++ + static int parse_elem(char **argv, struct bpf_map_info *info, + void *key, void *value, __u32 key_size, __u32 value_size, + __u32 *flags, __u32 **value_fd) +@@ -518,6 +532,8 @@ static int parse_elem(char **argv, struct bpf_map_info *info, + argv = parse_bytes(argv, "value", value, value_size); + if (!argv) + return -1; ++ ++ fill_per_cpu_value(info, value); + } + + return parse_elem(argv, info, key, NULL, key_size, value_size, +-- +2.19.1 + diff --git a/queue-4.20/bpftool-fix-prog-dump-by-tag.patch b/queue-4.20/bpftool-fix-prog-dump-by-tag.patch new file mode 100644 index 00000000000..1de706be08f --- /dev/null +++ b/queue-4.20/bpftool-fix-prog-dump-by-tag.patch @@ -0,0 +1,70 @@ +From 0cbefb0d5897c56f8305bf6c265e0851625114c9 Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Fri, 18 Jan 2019 13:58:17 +0100 +Subject: bpftool: Fix prog dump by tag + +[ Upstream commit 752bcf80f5549c9901b2e8bc77b2138de55b1026 ] + +Lance reported an issue with bpftool not being able to +dump program if there are more programs loaded and you +want to dump any but the first program, like: + + # bpftool prog + 28: kprobe name trace_req_start tag 1dfc28ba8b3dd597 gpl + loaded_at 2019-01-18T17:02:40+1100 uid 0 + xlated 112B jited 109B memlock 4096B map_ids 13 + 29: kprobe name trace_req_compl tag 5b6a5ecc6030a683 gpl + loaded_at 2019-01-18T17:02:40+1100 uid 0 + xlated 928B jited 575B memlock 4096B map_ids 13,14 + # bpftool prog dum jited tag 1dfc28ba8b3dd597 + 0: push %rbp + 1: mov %rsp,%rbp + ... + + # bpftool prog dum jited tag 5b6a5ecc6030a683 + Error: can't get prog info (29): Bad address + +The problem is in the prog_fd_by_tag function not cleaning +the struct bpf_prog_info before another request, so the +previous program length is still in there and kernel assumes +it needs to dump the program, which fails because there's no +user pointer set. + +Moving the struct bpf_prog_info declaration into the loop, +so it gets cleaned before each query. + +Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") +Reported-by: Lance Digby +Signed-off-by: Jiri Olsa +Reviewed-by: Quentin Monnet +Acked-by: Jakub Kicinski +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/prog.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c +index 69b01a6158bd..91b9de5f4e17 100644 +--- a/tools/bpf/bpftool/prog.c ++++ b/tools/bpf/bpftool/prog.c +@@ -130,13 +130,14 @@ static void print_boot_time(__u64 nsecs, char *buf, unsigned int size) + + static int prog_fd_by_tag(unsigned char *tag) + { +- struct bpf_prog_info info = {}; +- __u32 len = sizeof(info); + unsigned int id = 0; + int err; + int fd; + + while (true) { ++ struct bpf_prog_info info = {}; ++ __u32 len = sizeof(info); ++ + err = bpf_prog_get_next_id(id, &id); + if (err) { + p_err("%s", strerror(errno)); +-- +2.19.1 + diff --git a/queue-4.20/cifs-fix-computation-for-max_smb2_hdr_size.patch b/queue-4.20/cifs-fix-computation-for-max_smb2_hdr_size.patch new file mode 100644 index 00000000000..91c5491ed1e --- /dev/null +++ b/queue-4.20/cifs-fix-computation-for-max_smb2_hdr_size.patch @@ -0,0 +1,35 @@ +From 252a9219ec1e7ef218f5f276a0b34c6ee061a04e Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Tue, 29 Jan 2019 12:46:16 +1000 +Subject: cifs: fix computation for MAX_SMB2_HDR_SIZE + +[ Upstream commit 58d15ed1203f4d858c339ea4d7dafa94bd2a56d3 ] + +The size of the fixed part of the create response is 88 bytes not 56. + +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +Signed-off-by: Sasha Levin +--- + fs/cifs/smb2pdu.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h +index 5671d5ee7f58..eaf39fb71f8b 100644 +--- a/fs/cifs/smb2pdu.h ++++ b/fs/cifs/smb2pdu.h +@@ -84,8 +84,8 @@ + + #define NUMBER_OF_SMB2_COMMANDS 0x0013 + +-/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */ +-#define MAX_SMB2_HDR_SIZE 0x00b0 ++/* 52 transform hdr + 64 hdr + 88 create rsp */ ++#define MAX_SMB2_HDR_SIZE 204 + + #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) + #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) +-- +2.19.1 + diff --git a/queue-4.20/clk-qcom-gcc-use-active-only-source-for-cpuss-clocks.patch b/queue-4.20/clk-qcom-gcc-use-active-only-source-for-cpuss-clocks.patch new file mode 100644 index 00000000000..dfc107a8fdf --- /dev/null +++ b/queue-4.20/clk-qcom-gcc-use-active-only-source-for-cpuss-clocks.patch @@ -0,0 +1,69 @@ +From 3faeeec934664ac24cfe95bc97d1b5ac6bc96327 Mon Sep 17 00:00:00 2001 +From: Taniya Das +Date: Tue, 18 Dec 2018 23:49:41 +0530 +Subject: clk: qcom: gcc: Use active only source for CPUSS clocks + +[ Upstream commit 9ff1a3b4912528f853048ccd9757ba6a2cc75557 ] + +The clocks of the CPUSS such as "gcc_cpuss_ahb_clk_src" is a CRITICAL +clock and needs to vote on the active only source of XO, so as to keep +the vote as long as CPUSS is active. Similar rbcpr_clk_src is also has +the same requirement. + +Signed-off-by: Taniya Das +Fixes: 06391eddb60a ("clk: qcom: Add Global Clock controller (GCC) driver for SDM845") +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sdm845.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c +index f133b7f5652f..26110e74e086 100644 +--- a/drivers/clk/qcom/gcc-sdm845.c ++++ b/drivers/clk/qcom/gcc-sdm845.c +@@ -115,8 +115,8 @@ static const char * const gcc_parent_names_6[] = { + "core_bi_pll_test_se", + }; + +-static const char * const gcc_parent_names_7[] = { +- "bi_tcxo", ++static const char * const gcc_parent_names_7_ao[] = { ++ "bi_tcxo_ao", + "gpll0", + "gpll0_out_even", + "core_bi_pll_test_se", +@@ -128,6 +128,12 @@ static const char * const gcc_parent_names_8[] = { + "core_bi_pll_test_se", + }; + ++static const char * const gcc_parent_names_8_ao[] = { ++ "bi_tcxo_ao", ++ "gpll0", ++ "core_bi_pll_test_se", ++}; ++ + static const struct parent_map gcc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, +@@ -210,7 +216,7 @@ static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk_src", +- .parent_names = gcc_parent_names_7, ++ .parent_names = gcc_parent_names_7_ao, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +@@ -229,7 +235,7 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = { + .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_rbcpr_clk_src", +- .parent_names = gcc_parent_names_8, ++ .parent_names = gcc_parent_names_8_ao, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +-- +2.19.1 + diff --git a/queue-4.20/clk-ti-fix-error-handling-in-ti_clk_parse_divider_da.patch b/queue-4.20/clk-ti-fix-error-handling-in-ti_clk_parse_divider_da.patch new file mode 100644 index 00000000000..0830001bab6 --- /dev/null +++ b/queue-4.20/clk-ti-fix-error-handling-in-ti_clk_parse_divider_da.patch @@ -0,0 +1,66 @@ +From d17f298264024547963e4441c2d0d4df0f4f94ac Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 15 Jan 2019 22:46:25 +0300 +Subject: clk: ti: Fix error handling in ti_clk_parse_divider_data() + +[ Upstream commit 303aef8b84272d73999a3207dd05bbe10ed89dc5 ] + +The ti_clk_parse_divider_data() function is only called from +_get_div_table_from_setup(). That function doesn't look at the return +value but instead looks at the "*table" pointer. In this case, if the +kcalloc() fails then *table is NULL (which means success). It should +instead be an error pointer. + +The ti_clk_parse_divider_data() function has two callers. One checks +for errors and the other doesn't. I have fixed it so now both handle +errors. + +Fixes: 4f6be5655dc9 ("clk: ti: divider: add driver internal API for parsing divider data") +Signed-off-by: Dan Carpenter +Acked-by: Tero Kristo +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/ti/divider.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c +index 8d77090ad94a..0241450f3eb3 100644 +--- a/drivers/clk/ti/divider.c ++++ b/drivers/clk/ti/divider.c +@@ -403,8 +403,10 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, + num_dividers = i; + + tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL); +- if (!tmp) ++ if (!tmp) { ++ *table = ERR_PTR(-ENOMEM); + return -ENOMEM; ++ } + + valid_div = 0; + *width = 0; +@@ -439,6 +441,7 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup) + { + struct clk_omap_divider *div; + struct clk_omap_reg *reg; ++ int ret; + + if (!setup) + return NULL; +@@ -458,6 +461,12 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup) + div->flags |= CLK_DIVIDER_POWER_OF_TWO; + + div->table = _get_div_table_from_setup(setup, &div->width); ++ if (IS_ERR(div->table)) { ++ ret = PTR_ERR(div->table); ++ kfree(div); ++ return ERR_PTR(ret); ++ } ++ + + div->shift = setup->bit_shift; + div->latch = -EINVAL; +-- +2.19.1 + diff --git a/queue-4.20/dmaengine-at_xdmac-fix-wrongfull-report-of-a-channel.patch b/queue-4.20/dmaengine-at_xdmac-fix-wrongfull-report-of-a-channel.patch new file mode 100644 index 00000000000..f24bca24bff --- /dev/null +++ b/queue-4.20/dmaengine-at_xdmac-fix-wrongfull-report-of-a-channel.patch @@ -0,0 +1,100 @@ +From f08e8a4d233945282e5c93e8ca23532d3dedb00e Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu +Date: Wed, 23 Jan 2019 16:33:47 +0000 +Subject: dmaengine: at_xdmac: Fix wrongfull report of a channel as in use + +[ Upstream commit dc3f595b6617ebc0307e0ce151e8f2f2b2489b95 ] + +atchan->status variable is used to store two different information: + - pass channel interrupts status from interrupt handler to tasklet; + - channel information like whether it is cyclic or paused; + +This causes a bug when device_terminate_all() is called, +(AT_XDMAC_CHAN_IS_CYCLIC cleared on atchan->status) and then a late End +of Block interrupt arrives (AT_XDMAC_CIS_BIS), which sets bit 0 of +atchan->status. Bit 0 is also used for AT_XDMAC_CHAN_IS_CYCLIC, so when +a new descriptor for a cyclic transfer is created, the driver reports +the channel as in use: + +if (test_and_set_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status)) { + dev_err(chan2dev(chan), "channel currently used\n"); + return NULL; +} + +This patch fixes the bug by adding a different struct member to keep +the interrupts status separated from the channel status bits. + +Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver") +Signed-off-by: Codrin Ciubotariu +Acked-by: Ludovic Desroches +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/at_xdmac.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c +index 4e557684f792..fe69dccfa0c0 100644 +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -203,6 +203,7 @@ struct at_xdmac_chan { + u32 save_cim; + u32 save_cnda; + u32 save_cndc; ++ u32 irq_status; + unsigned long status; + struct tasklet_struct tasklet; + struct dma_slave_config sconfig; +@@ -1580,8 +1581,8 @@ static void at_xdmac_tasklet(unsigned long data) + struct at_xdmac_desc *desc; + u32 error_mask; + +- dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08lx\n", +- __func__, atchan->status); ++ dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08x\n", ++ __func__, atchan->irq_status); + + error_mask = AT_XDMAC_CIS_RBEIS + | AT_XDMAC_CIS_WBEIS +@@ -1589,15 +1590,15 @@ static void at_xdmac_tasklet(unsigned long data) + + if (at_xdmac_chan_is_cyclic(atchan)) { + at_xdmac_handle_cyclic(atchan); +- } else if ((atchan->status & AT_XDMAC_CIS_LIS) +- || (atchan->status & error_mask)) { ++ } else if ((atchan->irq_status & AT_XDMAC_CIS_LIS) ++ || (atchan->irq_status & error_mask)) { + struct dma_async_tx_descriptor *txd; + +- if (atchan->status & AT_XDMAC_CIS_RBEIS) ++ if (atchan->irq_status & AT_XDMAC_CIS_RBEIS) + dev_err(chan2dev(&atchan->chan), "read bus error!!!"); +- if (atchan->status & AT_XDMAC_CIS_WBEIS) ++ if (atchan->irq_status & AT_XDMAC_CIS_WBEIS) + dev_err(chan2dev(&atchan->chan), "write bus error!!!"); +- if (atchan->status & AT_XDMAC_CIS_ROIS) ++ if (atchan->irq_status & AT_XDMAC_CIS_ROIS) + dev_err(chan2dev(&atchan->chan), "request overflow error!!!"); + + spin_lock(&atchan->lock); +@@ -1652,7 +1653,7 @@ static irqreturn_t at_xdmac_interrupt(int irq, void *dev_id) + atchan = &atxdmac->chan[i]; + chan_imr = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); + chan_status = at_xdmac_chan_read(atchan, AT_XDMAC_CIS); +- atchan->status = chan_status & chan_imr; ++ atchan->irq_status = chan_status & chan_imr; + dev_vdbg(atxdmac->dma.dev, + "%s: chan%d: imr=0x%x, status=0x%x\n", + __func__, i, chan_imr, chan_status); +@@ -1666,7 +1667,7 @@ static irqreturn_t at_xdmac_interrupt(int irq, void *dev_id) + at_xdmac_chan_read(atchan, AT_XDMAC_CDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CUBC)); + +- if (atchan->status & (AT_XDMAC_CIS_RBEIS | AT_XDMAC_CIS_WBEIS)) ++ if (atchan->irq_status & (AT_XDMAC_CIS_RBEIS | AT_XDMAC_CIS_WBEIS)) + at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); + + tasklet_schedule(&atchan->tasklet); +-- +2.19.1 + diff --git a/queue-4.20/dmaengine-dmatest-abort-test-in-case-of-mapping-erro.patch b/queue-4.20/dmaengine-dmatest-abort-test-in-case-of-mapping-erro.patch new file mode 100644 index 00000000000..4b3ab2ec0a6 --- /dev/null +++ b/queue-4.20/dmaengine-dmatest-abort-test-in-case-of-mapping-erro.patch @@ -0,0 +1,121 @@ +From 528248ed94377ecf437c81536cb45baf54d4f21b Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Wed, 30 Jan 2019 21:48:44 +0200 +Subject: dmaengine: dmatest: Abort test in case of mapping error + +[ Upstream commit 6454368a804c4955ccd116236037536f81e5b1f1 ] + +In case of mapping error the DMA addresses are invalid and continuing +will screw system memory or potentially something else. + +[ 222.480310] dmatest: dma0chan7-copy0: summary 1 tests, 3 failures 6 iops 349 KB/s (0) +... +[ 240.912725] check: Corrupted low memory at 00000000c7c75ac9 (2940 phys) = 5656000000000000 +[ 240.921998] check: Corrupted low memory at 000000005715a1cd (2948 phys) = 279f2aca5595ab2b +[ 240.931280] check: Corrupted low memory at 000000002f4024c0 (2950 phys) = 5e5624f349e793cf +... + +Abort any test if mapping failed. + +Fixes: 4076e755dbec ("dmatest: convert to dmaengine_unmap_data") +Cc: Dan Williams +Signed-off-by: Andy Shevchenko +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/dmatest.c | 28 ++++++++++++---------------- + 1 file changed, 12 insertions(+), 16 deletions(-) + +diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c +index aa1712beb0cc..7b7fba0c9253 100644 +--- a/drivers/dma/dmatest.c ++++ b/drivers/dma/dmatest.c +@@ -642,11 +642,9 @@ static int dmatest_func(void *data) + srcs[i] = um->addr[i] + src_off; + ret = dma_mapping_error(dev->dev, um->addr[i]); + if (ret) { +- dmaengine_unmap_put(um); + result("src mapping error", total_tests, + src_off, dst_off, len, ret); +- failed_tests++; +- continue; ++ goto error_unmap_continue; + } + um->to_cnt++; + } +@@ -661,11 +659,9 @@ static int dmatest_func(void *data) + DMA_BIDIRECTIONAL); + ret = dma_mapping_error(dev->dev, dsts[i]); + if (ret) { +- dmaengine_unmap_put(um); + result("dst mapping error", total_tests, + src_off, dst_off, len, ret); +- failed_tests++; +- continue; ++ goto error_unmap_continue; + } + um->bidi_cnt++; + } +@@ -693,12 +689,10 @@ static int dmatest_func(void *data) + } + + if (!tx) { +- dmaengine_unmap_put(um); + result("prep error", total_tests, src_off, + dst_off, len, ret); + msleep(100); +- failed_tests++; +- continue; ++ goto error_unmap_continue; + } + + done->done = false; +@@ -707,12 +701,10 @@ static int dmatest_func(void *data) + cookie = tx->tx_submit(tx); + + if (dma_submit_error(cookie)) { +- dmaengine_unmap_put(um); + result("submit error", total_tests, src_off, + dst_off, len, ret); + msleep(100); +- failed_tests++; +- continue; ++ goto error_unmap_continue; + } + dma_async_issue_pending(chan); + +@@ -725,16 +717,14 @@ static int dmatest_func(void *data) + dmaengine_unmap_put(um); + result("test timed out", total_tests, src_off, dst_off, + len, 0); +- failed_tests++; +- continue; ++ goto error_unmap_continue; + } else if (status != DMA_COMPLETE) { + dmaengine_unmap_put(um); + result(status == DMA_ERROR ? + "completion error status" : + "completion busy status", total_tests, src_off, + dst_off, len, ret); +- failed_tests++; +- continue; ++ goto error_unmap_continue; + } + + dmaengine_unmap_put(um); +@@ -779,6 +769,12 @@ static int dmatest_func(void *data) + verbose_result("test passed", total_tests, src_off, + dst_off, len, 0); + } ++ ++ continue; ++ ++error_unmap_continue: ++ dmaengine_unmap_put(um); ++ failed_tests++; + } + ktime = ktime_sub(ktime_get(), ktime); + ktime = ktime_sub(ktime, comparetime); +-- +2.19.1 + diff --git a/queue-4.20/drm-amdgpu-add-missing-power-attribute-to-apu-check.patch b/queue-4.20/drm-amdgpu-add-missing-power-attribute-to-apu-check.patch new file mode 100644 index 00000000000..64c3f1da086 --- /dev/null +++ b/queue-4.20/drm-amdgpu-add-missing-power-attribute-to-apu-check.patch @@ -0,0 +1,34 @@ +From c131bf0dfa9819962115140d175faafd7b9b3f8d Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 9 Jan 2019 22:19:28 -0500 +Subject: drm/amdgpu: Add missing power attribute to APU check + +[ Upstream commit dc14eb12f6bb3e779c5461429c1889a339c67aab ] + +Add missing power_average to visible check for power +attributes for APUs. Was missed before. + +Reviewed-by: Evan Quan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +index 59cc678de8c1..bbac15fd8caa 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +@@ -1671,7 +1671,8 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, + effective_mode &= ~S_IWUSR; + + if ((adev->flags & AMD_IS_APU) && +- (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || ++ (attr == &sensor_dev_attr_power1_average.dev_attr.attr || ++ attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || + attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr|| + attr == &sensor_dev_attr_power1_cap.dev_attr.attr)) + return 0; +-- +2.19.1 + diff --git a/queue-4.20/drm-amdgpu-fix-the-incorrect-external-id-for-raven-s.patch b/queue-4.20/drm-amdgpu-fix-the-incorrect-external-id-for-raven-s.patch new file mode 100644 index 00000000000..576fc8e6c39 --- /dev/null +++ b/queue-4.20/drm-amdgpu-fix-the-incorrect-external-id-for-raven-s.patch @@ -0,0 +1,44 @@ +From d5613c960c1759dcf6ce0a2f86fb118c093ae252 Mon Sep 17 00:00:00 2001 +From: Huang Rui +Date: Wed, 30 Jan 2019 19:50:04 +0800 +Subject: drm/amdgpu: fix the incorrect external id for raven series + +[ Upstream commit 7e4545d372b560df10fa47281ef0783a479ce435 ] + +This patch fixes the incorrect external id that kernel reports to user mode +driver. Raven2's rev_id is starts from 0x8, so its external id (0x81) should +start from rev_id + 0x79 (0x81 - 0x8). And Raven's rev_id should be 0x21 while +rev_id == 1. + +Reported-by: Crystal Jin +Signed-off-by: Huang Rui +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/soc15.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index 4cc0dcb1a187..825d1cae85ab 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -705,11 +705,13 @@ static int soc15_common_early_init(void *handle) + break; + case CHIP_RAVEN: + if (adev->rev_id >= 0x8) +- adev->external_rev_id = adev->rev_id + 0x81; ++ adev->external_rev_id = adev->rev_id + 0x79; + else if (adev->pdev->device == 0x15d8) + adev->external_rev_id = adev->rev_id + 0x41; ++ else if (adev->rev_id == 1) ++ adev->external_rev_id = adev->rev_id + 0x20; + else +- adev->external_rev_id = 0x1; ++ adev->external_rev_id = adev->rev_id + 0x01; + + if (adev->rev_id >= 0x8) { + adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | +-- +2.19.1 + diff --git a/queue-4.20/drm-amdgpu-implement-doorbell-self-ring-for-nbio-7.4.patch b/queue-4.20/drm-amdgpu-implement-doorbell-self-ring-for-nbio-7.4.patch new file mode 100644 index 00000000000..96492ab5b9f --- /dev/null +++ b/queue-4.20/drm-amdgpu-implement-doorbell-self-ring-for-nbio-7.4.patch @@ -0,0 +1,46 @@ +From a32cf1349cbab8279e90a7713fb05ad154bcb380 Mon Sep 17 00:00:00 2001 +From: Jay Cornwall +Date: Wed, 30 Jan 2019 12:53:29 -0600 +Subject: drm/amdgpu: Implement doorbell self-ring for NBIO 7.4 + +[ Upstream commit 12292519d919ecde92e7e7c8acbcdb9f0c7c6013 ] + +Fixes doorbell reflection on Vega20. + +Change-Id: I0495139d160a9032dff5977289b1eec11c16f781 +Signed-off-by: Jay Cornwall +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +index f8cee95d61cc..7d5cbadbe1cb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c ++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +@@ -92,7 +92,20 @@ static void nbio_v7_4_enable_doorbell_aperture(struct amdgpu_device *adev, + static void nbio_v7_4_enable_doorbell_selfring_aperture(struct amdgpu_device *adev, + bool enable) + { ++ u32 tmp = 0; + ++ if (enable) { ++ tmp = REG_SET_FIELD(tmp, DOORBELL_SELFRING_GPA_APER_CNTL, DOORBELL_SELFRING_GPA_APER_EN, 1) | ++ REG_SET_FIELD(tmp, DOORBELL_SELFRING_GPA_APER_CNTL, DOORBELL_SELFRING_GPA_APER_MODE, 1) | ++ REG_SET_FIELD(tmp, DOORBELL_SELFRING_GPA_APER_CNTL, DOORBELL_SELFRING_GPA_APER_SIZE, 0); ++ ++ WREG32_SOC15(NBIO, 0, mmDOORBELL_SELFRING_GPA_APER_BASE_LOW, ++ lower_32_bits(adev->doorbell.base)); ++ WREG32_SOC15(NBIO, 0, mmDOORBELL_SELFRING_GPA_APER_BASE_HIGH, ++ upper_32_bits(adev->doorbell.base)); ++ } ++ ++ WREG32_SOC15(NBIO, 0, mmDOORBELL_SELFRING_GPA_APER_CNTL, tmp); + } + + static void nbio_v7_4_ih_doorbell_range(struct amdgpu_device *adev, +-- +2.19.1 + diff --git a/queue-4.20/drm-amdgpu-transfer-fences-to-dmabuf-importer.patch b/queue-4.20/drm-amdgpu-transfer-fences-to-dmabuf-importer.patch new file mode 100644 index 00000000000..c87fa051408 --- /dev/null +++ b/queue-4.20/drm-amdgpu-transfer-fences-to-dmabuf-importer.patch @@ -0,0 +1,129 @@ +From 908d7220b7e4f1cf889a433f1512e394d62d82a9 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 30 Jan 2019 10:55:17 +0000 +Subject: drm/amdgpu: Transfer fences to dmabuf importer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 6e11ea9de9576a644045ffdc2067c09bc2012eda ] + +amdgpu only uses shared-fences internally, but dmabuf importers rely on +implicit write hazard tracking via the reservation_object.fence_excl. +For example, the importer use the write hazard for timing a page flip to +only occur after the exporter has finished flushing its write into the +surface. As such, on exporting a dmabuf, we must either flush all +outstanding fences (for we do not know which are writes and should have +been exclusive) or alternatively create a new exclusive fence that is +the composite of all the existing shared fences, and so will only be +signaled when all earlier fences are signaled (ensuring that we can not +be signaled before the completion of any earlier write). + +v2: reservation_object is already locked by amdgpu_bo_reserve() +v3: Replace looping with get_fences_rcu and special case the promotion +of a single shared fence directly to an exclusive fence, bypassing the +fence array. +v4: Drop the fence array ref after assigning to reservation_object + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107341 +Testcase: igt/amd_prime/amd-to-i915 +References: 8e94a46c1770 ("drm/amdgpu: Attach exclusive fence to prime exported bo's. (v5)") +Signed-off-by: Chris Wilson +Cc: Alex Deucher +Cc: "Christian König" +Reviewed-by: "Christian König" +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 59 ++++++++++++++++++++--- + 1 file changed, 51 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +index e45e929aaab5..90a5970af4b7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +@@ -38,6 +38,7 @@ + #include "amdgpu_gem.h" + #include + #include ++#include + + static const struct dma_buf_ops amdgpu_dmabuf_ops; + +@@ -189,6 +190,48 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, + return ERR_PTR(ret); + } + ++static int ++__reservation_object_make_exclusive(struct reservation_object *obj) ++{ ++ struct dma_fence **fences; ++ unsigned int count; ++ int r; ++ ++ if (!reservation_object_get_list(obj)) /* no shared fences to convert */ ++ return 0; ++ ++ r = reservation_object_get_fences_rcu(obj, NULL, &count, &fences); ++ if (r) ++ return r; ++ ++ if (count == 0) { ++ /* Now that was unexpected. */ ++ } else if (count == 1) { ++ reservation_object_add_excl_fence(obj, fences[0]); ++ dma_fence_put(fences[0]); ++ kfree(fences); ++ } else { ++ struct dma_fence_array *array; ++ ++ array = dma_fence_array_create(count, fences, ++ dma_fence_context_alloc(1), 0, ++ false); ++ if (!array) ++ goto err_fences_put; ++ ++ reservation_object_add_excl_fence(obj, &array->base); ++ dma_fence_put(&array->base); ++ } ++ ++ return 0; ++ ++err_fences_put: ++ while (count--) ++ dma_fence_put(fences[count]); ++ kfree(fences); ++ return -ENOMEM; ++} ++ + /** + * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation + * @dma_buf: Shared DMA buffer +@@ -220,16 +263,16 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf, + + if (attach->dev->driver != adev->dev->driver) { + /* +- * Wait for all shared fences to complete before we switch to future +- * use of exclusive fence on this prime shared bo. ++ * We only create shared fences for internal use, but importers ++ * of the dmabuf rely on exclusive fences for implicitly ++ * tracking write hazards. As any of the current fences may ++ * correspond to a write, we need to convert all existing ++ * fences on the reservation object into a single exclusive ++ * fence. + */ +- r = reservation_object_wait_timeout_rcu(bo->tbo.resv, +- true, false, +- MAX_SCHEDULE_TIMEOUT); +- if (unlikely(r < 0)) { +- DRM_DEBUG_PRIME("Fence wait failed: %li\n", r); ++ r = __reservation_object_make_exclusive(bo->tbo.resv); ++ if (r) + goto error_unreserve; +- } + } + + /* pin buffer into GTT */ +-- +2.19.1 + diff --git a/queue-4.20/drm-amdgpu-use-spin_lock_irqsave-to-protect-vm_manag.patch b/queue-4.20/drm-amdgpu-use-spin_lock_irqsave-to-protect-vm_manag.patch new file mode 100644 index 00000000000..ea10422ec29 --- /dev/null +++ b/queue-4.20/drm-amdgpu-use-spin_lock_irqsave-to-protect-vm_manag.patch @@ -0,0 +1,46 @@ +From b07a64b7f4935c7479e9e474119cbe0ccdb3e09d Mon Sep 17 00:00:00 2001 +From: Philip Yang +Date: Wed, 30 Jan 2019 15:21:16 -0500 +Subject: drm/amdgpu: use spin_lock_irqsave to protect vm_manager.pasid_idr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 0a5f49cbf9d6ad3721c16f8a6d823363ea7a160f ] + +amdgpu_vm_get_task_info is called from interrupt handler and sched timeout +workqueue, we should use irq version spin_lock to avoid deadlock. + +Signed-off-by: Philip Yang +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index 62df4bd0a0fc..16c83155ef5c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -3405,14 +3405,15 @@ void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid, + struct amdgpu_task_info *task_info) + { + struct amdgpu_vm *vm; ++ unsigned long flags; + +- spin_lock(&adev->vm_manager.pasid_lock); ++ spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); + + vm = idr_find(&adev->vm_manager.pasid_idr, pasid); + if (vm) + *task_info = vm->task_info; + +- spin_unlock(&adev->vm_manager.pasid_lock); ++ spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); + } + + /** +-- +2.19.1 + diff --git a/queue-4.20/drm-omap-dsi-fix-crash-in-dsi-debug-dumps.patch b/queue-4.20/drm-omap-dsi-fix-crash-in-dsi-debug-dumps.patch new file mode 100644 index 00000000000..39e2486ccf2 --- /dev/null +++ b/queue-4.20/drm-omap-dsi-fix-crash-in-dsi-debug-dumps.patch @@ -0,0 +1,75 @@ +From ca5907f43313b2274d62cb0948c5422d8cf97e80 Mon Sep 17 00:00:00 2001 +From: Tomi Valkeinen +Date: Fri, 11 Jan 2019 05:50:33 +0200 +Subject: drm/omap: dsi: Fix crash in DSI debug dumps + +[ Upstream commit 4df04ac9b37f278c48bb696289aff8f81226af4b ] + +Reading any of the DSI debugfs files results in a crash, as wrong +pointer is passed to the dump functions, and the dump functions use a +wrong pointer. This patch fixes DSI debug dumps. + +Fixes: f3ed97f9ae7d ("drm/omap: dsi: Simplify debugfs implementation") +Signed-off-by: Tomi Valkeinen +Reviewed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20190111035120.20668-3-laurent.pinchart@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/omapdrm/dss/dsi.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c +index 00a9c2ab9e6c..277f9dd2ec8c 100644 +--- a/drivers/gpu/drm/omapdrm/dss/dsi.c ++++ b/drivers/gpu/drm/omapdrm/dss/dsi.c +@@ -1406,7 +1406,7 @@ static void dsi_pll_disable(struct dss_pll *pll) + + static int dsi_dump_dsi_clocks(struct seq_file *s, void *p) + { +- struct dsi_data *dsi = p; ++ struct dsi_data *dsi = s->private; + struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo; + enum dss_clk_source dispc_clk_src, dsi_clk_src; + int dsi_module = dsi->module_id; +@@ -1467,7 +1467,7 @@ static int dsi_dump_dsi_clocks(struct seq_file *s, void *p) + #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) + { +- struct dsi_data *dsi = p; ++ struct dsi_data *dsi = s->private; + unsigned long flags; + struct dsi_irq_stats stats; + +@@ -1558,7 +1558,7 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) + + static int dsi_dump_dsi_regs(struct seq_file *s, void *p) + { +- struct dsi_data *dsi = p; ++ struct dsi_data *dsi = s->private; + + if (dsi_runtime_get(dsi)) + return 0; +@@ -5083,15 +5083,15 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) + + snprintf(name, sizeof(name), "dsi%u_regs", dsi->module_id + 1); + dsi->debugfs.regs = dss_debugfs_create_file(dss, name, +- dsi_dump_dsi_regs, &dsi); ++ dsi_dump_dsi_regs, dsi); + #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + snprintf(name, sizeof(name), "dsi%u_irqs", dsi->module_id + 1); + dsi->debugfs.irqs = dss_debugfs_create_file(dss, name, +- dsi_dump_dsi_irqs, &dsi); ++ dsi_dump_dsi_irqs, dsi); + #endif + snprintf(name, sizeof(name), "dsi%u_clks", dsi->module_id + 1); + dsi->debugfs.clks = dss_debugfs_create_file(dss, name, +- dsi_dump_dsi_clocks, &dsi); ++ dsi_dump_dsi_clocks, dsi); + + return 0; + } +-- +2.19.1 + diff --git a/queue-4.20/drm-omap-dsi-fix-of-platform-depopulate.patch b/queue-4.20/drm-omap-dsi-fix-of-platform-depopulate.patch new file mode 100644 index 00000000000..17f38f9323b --- /dev/null +++ b/queue-4.20/drm-omap-dsi-fix-of-platform-depopulate.patch @@ -0,0 +1,49 @@ +From 794500dbeb87efc1af6260b029a6119aca15dc71 Mon Sep 17 00:00:00 2001 +From: Tomi Valkeinen +Date: Fri, 11 Jan 2019 05:50:34 +0200 +Subject: drm/omap: dsi: Fix OF platform depopulate + +[ Upstream commit 0940c52742de0d2f70ba687bfd5fe8aa38c5f27d ] + +Commit edb715dffdee ("drm/omap: dss: dsi: Move initialization code from +bind to probe") moved the of_platform_populate() call from dsi_bind() to +dsi_probe(), but failed to move the corresponding +of_platform_depopulate() from dsi_unbind() to dsi_remove(). This results +in OF child devices being potentially removed multiple times. Fix it by +placing the of_platform_depopulate() call where it belongs. + +Fixes: edb715dffdee ("drm/omap: dss: dsi: Move initialization code from bind to probe") +Signed-off-by: Laurent Pinchart +Reviewed-by: Laurent Pinchart +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20190111035120.20668-4-laurent.pinchart@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/omapdrm/dss/dsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c +index 277f9dd2ec8c..b5685018d830 100644 +--- a/drivers/gpu/drm/omapdrm/dss/dsi.c ++++ b/drivers/gpu/drm/omapdrm/dss/dsi.c +@@ -5104,8 +5104,6 @@ static void dsi_unbind(struct device *dev, struct device *master, void *data) + dss_debugfs_remove_file(dsi->debugfs.irqs); + dss_debugfs_remove_file(dsi->debugfs.regs); + +- of_platform_depopulate(dev); +- + WARN_ON(dsi->scp_clk_refcount > 0); + + dss_pll_unregister(&dsi->pll); +@@ -5457,6 +5455,8 @@ static int dsi_remove(struct platform_device *pdev) + + dsi_uninit_output(dsi); + ++ of_platform_depopulate(&pdev->dev); ++ + pm_runtime_disable(&pdev->dev); + + if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) { +-- +2.19.1 + diff --git a/queue-4.20/drm-omap-dsi-hack-fix-dsi-bus-flags.patch b/queue-4.20/drm-omap-dsi-hack-fix-dsi-bus-flags.patch new file mode 100644 index 00000000000..21ac08ed871 --- /dev/null +++ b/queue-4.20/drm-omap-dsi-hack-fix-dsi-bus-flags.patch @@ -0,0 +1,54 @@ +From ce71f14bae32f0a9112e6602a7bb48f953f7f626 Mon Sep 17 00:00:00 2001 +From: Tomi Valkeinen +Date: Fri, 11 Jan 2019 05:50:35 +0200 +Subject: drm/omap: dsi: Hack-fix DSI bus flags + +[ Upstream commit 6297388e1eddd2f1345cea5892156223995bcf2d ] + +Since commit b4935e3a3cfa ("drm/omap: Store bus flags in the +omap_dss_device structure") video mode flags are managed by the omapdss +(and later omapdrm) core based on bus flags stored in omap_dss_device. +This works fine for all devices whose video modes are set by the omapdss +and omapdrm core, but breaks DSI operation as the DSI still uses legacy +code paths and sets the DISPC timings manually. + +To fix the problem properly we should move the DSI encoder to the new +encoder model. This will however require a considerable amount of work. +Restore DSI operation by adding back video mode flags handling in the +DSI encoder driver as a hack in the meantime. + +Fixes: b4935e3a3cfa ("drm/omap: Store bus flags in the omap_dss_device structure") +Signed-off-by: Laurent Pinchart +Reviewed-by: Laurent Pinchart +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20190111035120.20668-5-laurent.pinchart@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/omapdrm/dss/dsi.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c +index b5685018d830..64fb788b6647 100644 +--- a/drivers/gpu/drm/omapdrm/dss/dsi.c ++++ b/drivers/gpu/drm/omapdrm/dss/dsi.c +@@ -4751,6 +4751,17 @@ static int dsi_set_config(struct omap_dss_device *dssdev, + dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH; + dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW; + dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH; ++ /* ++ * HACK: These flags should be handled through the omap_dss_device bus ++ * flags, but this will only be possible when the DSI encoder will be ++ * converted to the omapdrm-managed encoder model. ++ */ ++ dsi->vm.flags &= ~DISPLAY_FLAGS_PIXDATA_NEGEDGE; ++ dsi->vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE; ++ dsi->vm.flags &= ~DISPLAY_FLAGS_DE_LOW; ++ dsi->vm.flags |= DISPLAY_FLAGS_DE_HIGH; ++ dsi->vm.flags &= ~DISPLAY_FLAGS_SYNC_POSEDGE; ++ dsi->vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE; + + dss_mgr_set_timings(&dsi->output, &dsi->vm); + +-- +2.19.1 + diff --git a/queue-4.20/drm-radeon-check-if-device-is-root-before-getting-pc.patch b/queue-4.20/drm-radeon-check-if-device-is-root-before-getting-pc.patch new file mode 100644 index 00000000000..2273b329c5d --- /dev/null +++ b/queue-4.20/drm-radeon-check-if-device-is-root-before-getting-pc.patch @@ -0,0 +1,69 @@ +From 40c72d663916e1d7802bc949b6a442217fb5ff29 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 15 Jan 2019 12:05:16 -0500 +Subject: drm/radeon: check if device is root before getting pci speed caps + +[ Upstream commit afeff4c16edaa6275b903f82b0561406259aa3a3 ] + +Check if the device is root rather before attempting to see what +speeds the pcie port supports. Fixes a crash with pci passthrough +in a VM. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=109366 +Reviewed-by: Evan Quan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/ci_dpm.c | 5 +++-- + drivers/gpu/drm/radeon/si_dpm.c | 5 +++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c +index d587779a80b4..a97294ac96d5 100644 +--- a/drivers/gpu/drm/radeon/ci_dpm.c ++++ b/drivers/gpu/drm/radeon/ci_dpm.c +@@ -5676,7 +5676,7 @@ int ci_dpm_init(struct radeon_device *rdev) + u16 data_offset, size; + u8 frev, crev; + struct ci_power_info *pi; +- enum pci_bus_speed speed_cap; ++ enum pci_bus_speed speed_cap = PCI_SPEED_UNKNOWN; + struct pci_dev *root = rdev->pdev->bus->self; + int ret; + +@@ -5685,7 +5685,8 @@ int ci_dpm_init(struct radeon_device *rdev) + return -ENOMEM; + rdev->pm.dpm.priv = pi; + +- speed_cap = pcie_get_speed_cap(root); ++ if (!pci_is_root_bus(rdev->pdev->bus)) ++ speed_cap = pcie_get_speed_cap(root); + if (speed_cap == PCI_SPEED_UNKNOWN) { + pi->sys_pcie_mask = 0; + } else { +diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c +index 8fb60b3af015..0a785ef0ab66 100644 +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -6899,7 +6899,7 @@ int si_dpm_init(struct radeon_device *rdev) + struct ni_power_info *ni_pi; + struct si_power_info *si_pi; + struct atom_clock_dividers dividers; +- enum pci_bus_speed speed_cap; ++ enum pci_bus_speed speed_cap = PCI_SPEED_UNKNOWN; + struct pci_dev *root = rdev->pdev->bus->self; + int ret; + +@@ -6911,7 +6911,8 @@ int si_dpm_init(struct radeon_device *rdev) + eg_pi = &ni_pi->eg; + pi = &eg_pi->rv7xx; + +- speed_cap = pcie_get_speed_cap(root); ++ if (!pci_is_root_bus(rdev->pdev->bus)) ++ speed_cap = pcie_get_speed_cap(root); + if (speed_cap == PCI_SPEED_UNKNOWN) { + si_pi->sys_pcie_mask = 0; + } else { +-- +2.19.1 + diff --git a/queue-4.20/drm-sun4i-tcon-prepare-and-enable-tcon-channel-0-clo.patch b/queue-4.20/drm-sun4i-tcon-prepare-and-enable-tcon-channel-0-clo.patch new file mode 100644 index 00000000000..642b2f0b5ef --- /dev/null +++ b/queue-4.20/drm-sun4i-tcon-prepare-and-enable-tcon-channel-0-clo.patch @@ -0,0 +1,50 @@ +From c3a78b9f050d794d843cbf87f4b58771bfc3cf0f Mon Sep 17 00:00:00 2001 +From: Paul Kocialkowski +Date: Thu, 31 Jan 2019 14:25:50 +0100 +Subject: drm/sun4i: tcon: Prepare and enable TCON channel 0 clock at init + +[ Upstream commit b14e945bda8ae227d1bf2b1837c0c4a61721cd1a ] + +When initializing clocks, a reference to the TCON channel 0 clock is +obtained. However, the clock is never prepared and enabled later. +Switching from simplefb to DRM actually disables the clock (that was +usually configured by U-Boot) because of that. + +On the V3s, this results in a hang when writing to some mixer registers +when switching over to DRM from simplefb. + +Fix this by preparing and enabling the clock when initializing other +clocks. Waiting for sun4i_tcon_channel_enable to enable the clock is +apparently too late and results in the same mixer register access hang. + +Signed-off-by: Paul Kocialkowski +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20190131132550.26355-1-paul.kocialkowski@bootlin.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/sun4i/sun4i_tcon.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c +index f949287d926c..4e0562aa2cc9 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -760,6 +760,7 @@ static int sun4i_tcon_init_clocks(struct device *dev, + return PTR_ERR(tcon->sclk0); + } + } ++ clk_prepare_enable(tcon->sclk0); + + if (tcon->quirks->has_channel_1) { + tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); +@@ -774,6 +775,7 @@ static int sun4i_tcon_init_clocks(struct device *dev, + + static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) + { ++ clk_disable_unprepare(tcon->sclk0); + clk_disable_unprepare(tcon->clk); + } + +-- +2.19.1 + diff --git a/queue-4.20/dts-ci20-fix-bugs-in-ci20-s-device-tree.patch b/queue-4.20/dts-ci20-fix-bugs-in-ci20-s-device-tree.patch new file mode 100644 index 00000000000..7712b25b2ed --- /dev/null +++ b/queue-4.20/dts-ci20-fix-bugs-in-ci20-s-device-tree.patch @@ -0,0 +1,58 @@ +From d81f84a0c8499ebca6608a9d900794acbe5a25f3 Mon Sep 17 00:00:00 2001 +From: Zhou Yanjie +Date: Fri, 25 Jan 2019 02:22:15 +0800 +Subject: DTS: CI20: Fix bugs in ci20's device tree. + +[ Upstream commit 1ca1c87f91d9dc50d6a38e2177b2032996e7901c ] + +According to the Schematic, the hardware of ci20 leads to uart3, +but not to uart2. Uart2 is miswritten in the original code. + +Signed-off-by: Zhou Yanjie +Signed-off-by: Paul Burton +Cc: linux-mips +Cc: linux-kernel +Cc: devicetree@vger.kernel.org +Cc: robh+dt@kernel.org +Cc: ralf@linux-mips.org +Cc: jhogan@kernel.org +Cc: mark.rutland@arm.com +Cc: malat@debian.org +Cc: ezequiel@collabora.co.uk +Cc: ulf.hansson@linaro.org +Cc: syq +Cc: jiaxun.yang +Signed-off-by: Sasha Levin +--- + arch/mips/boot/dts/ingenic/ci20.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts +index 50cff3cbcc6d..4f7b1fa31cf5 100644 +--- a/arch/mips/boot/dts/ingenic/ci20.dts ++++ b/arch/mips/boot/dts/ingenic/ci20.dts +@@ -76,7 +76,7 @@ + status = "okay"; + + pinctrl-names = "default"; +- pinctrl-0 = <&pins_uart2>; ++ pinctrl-0 = <&pins_uart3>; + }; + + &uart4 { +@@ -196,9 +196,9 @@ + bias-disable; + }; + +- pins_uart2: uart2 { +- function = "uart2"; +- groups = "uart2-data", "uart2-hwflow"; ++ pins_uart3: uart3 { ++ function = "uart3"; ++ groups = "uart3-data", "uart3-hwflow"; + bias-disable; + }; + +-- +2.19.1 + diff --git a/queue-4.20/fs-drop_caches.c-avoid-softlockups-in-drop_pagecache.patch b/queue-4.20/fs-drop_caches.c-avoid-softlockups-in-drop_pagecache.patch new file mode 100644 index 00000000000..869629436d0 --- /dev/null +++ b/queue-4.20/fs-drop_caches.c-avoid-softlockups-in-drop_pagecache.patch @@ -0,0 +1,57 @@ +From 39c0764c86765afa2604338d298d38203c993de9 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 1 Feb 2019 14:21:23 -0800 +Subject: fs/drop_caches.c: avoid softlockups in drop_pagecache_sb() + +[ Upstream commit c27d82f52f75fc9d8d9d40d120d2a96fdeeada5e ] + +When superblock has lots of inodes without any pagecache (like is the +case for /proc), drop_pagecache_sb() will iterate through all of them +without dropping sb->s_inode_list_lock which can lead to softlockups +(one of our customers hit this). + +Fix the problem by going to the slow path and doing cond_resched() in +case the process needs rescheduling. + +Link: http://lkml.kernel.org/r/20190114085343.15011-1-jack@suse.cz +Signed-off-by: Jan Kara +Acked-by: Michal Hocko +Reviewed-by: Andrew Morton +Cc: Al Viro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + fs/drop_caches.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/drop_caches.c b/fs/drop_caches.c +index 82377017130f..d31b6c72b476 100644 +--- a/fs/drop_caches.c ++++ b/fs/drop_caches.c +@@ -21,8 +21,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) + spin_lock(&sb->s_inode_list_lock); + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + spin_lock(&inode->i_lock); ++ /* ++ * We must skip inodes in unusual state. We may also skip ++ * inodes without pages but we deliberately won't in case ++ * we need to reschedule to avoid softlockups. ++ */ + if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) || +- (inode->i_mapping->nrpages == 0)) { ++ (inode->i_mapping->nrpages == 0 && !need_resched())) { + spin_unlock(&inode->i_lock); + continue; + } +@@ -30,6 +35,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) + spin_unlock(&inode->i_lock); + spin_unlock(&sb->s_inode_list_lock); + ++ cond_resched(); + invalidate_mapping_pages(inode->i_mapping, 0, -1); + iput(toput_inode); + toput_inode = inode; +-- +2.19.1 + diff --git a/queue-4.20/fs-ratelimit-__find_get_block_slow-failure-message.patch b/queue-4.20/fs-ratelimit-__find_get_block_slow-failure-message.patch new file mode 100644 index 00000000000..aa5fa1ddc24 --- /dev/null +++ b/queue-4.20/fs-ratelimit-__find_get_block_slow-failure-message.patch @@ -0,0 +1,76 @@ +From 046e91ead9d81161b1f91ee546eab62ec656896f Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 21 Jan 2019 22:49:37 +0900 +Subject: fs: ratelimit __find_get_block_slow() failure message. + +[ Upstream commit 43636c804df0126da669c261fc820fb22f62bfc2 ] + +When something let __find_get_block_slow() hit all_mapped path, it calls +printk() for 100+ times per a second. But there is no need to print same +message with such high frequency; it is just asking for stall warning, or +at least bloating log files. + + [ 399.866302][T15342] __find_get_block_slow() failed. block=1, b_blocknr=8 + [ 399.873324][T15342] b_state=0x00000029, b_size=512 + [ 399.878403][T15342] device loop0 blocksize: 4096 + [ 399.883296][T15342] __find_get_block_slow() failed. block=1, b_blocknr=8 + [ 399.890400][T15342] b_state=0x00000029, b_size=512 + [ 399.895595][T15342] device loop0 blocksize: 4096 + [ 399.900556][T15342] __find_get_block_slow() failed. block=1, b_blocknr=8 + [ 399.907471][T15342] b_state=0x00000029, b_size=512 + [ 399.912506][T15342] device loop0 blocksize: 4096 + +This patch reduces frequency to up to once per a second, in addition to +concatenating three lines into one. + + [ 399.866302][T15342] __find_get_block_slow() failed. block=1, b_blocknr=8, b_state=0x00000029, b_size=512, device loop0 blocksize: 4096 + +Signed-off-by: Tetsuo Handa +Reviewed-by: Jan Kara +Cc: Dmitry Vyukov +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + fs/buffer.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/fs/buffer.c b/fs/buffer.c +index 1286c2b95498..72e33ffa00ff 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -200,6 +200,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t block) + struct buffer_head *head; + struct page *page; + int all_mapped = 1; ++ static DEFINE_RATELIMIT_STATE(last_warned, HZ, 1); + + index = block >> (PAGE_SHIFT - bd_inode->i_blkbits); + page = find_get_page_flags(bd_mapping, index, FGP_ACCESSED); +@@ -227,15 +228,15 @@ __find_get_block_slow(struct block_device *bdev, sector_t block) + * file io on the block device and getblk. It gets dealt with + * elsewhere, don't buffer_error if we had some unmapped buffers + */ +- if (all_mapped) { +- printk("__find_get_block_slow() failed. " +- "block=%llu, b_blocknr=%llu\n", +- (unsigned long long)block, +- (unsigned long long)bh->b_blocknr); +- printk("b_state=0x%08lx, b_size=%zu\n", +- bh->b_state, bh->b_size); +- printk("device %pg blocksize: %d\n", bdev, +- 1 << bd_inode->i_blkbits); ++ ratelimit_set_flags(&last_warned, RATELIMIT_MSG_ON_RELEASE); ++ if (all_mapped && __ratelimit(&last_warned)) { ++ printk("__find_get_block_slow() failed. block=%llu, " ++ "b_blocknr=%llu, b_state=0x%08lx, b_size=%zu, " ++ "device %pg blocksize: %d\n", ++ (unsigned long long)block, ++ (unsigned long long)bh->b_blocknr, ++ bh->b_state, bh->b_size, bdev, ++ 1 << bd_inode->i_blkbits); + } + out_unlock: + spin_unlock(&bd_mapping->private_lock); +-- +2.19.1 + diff --git a/queue-4.20/gpio-vf610-mask-all-gpio-interrupts.patch b/queue-4.20/gpio-vf610-mask-all-gpio-interrupts.patch new file mode 100644 index 00000000000..64fb46b6e52 --- /dev/null +++ b/queue-4.20/gpio-vf610-mask-all-gpio-interrupts.patch @@ -0,0 +1,52 @@ +From df6732b00914005e4f523b8b7b35cd81fbeb85a9 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Sun, 27 Jan 2019 22:58:00 +0100 +Subject: gpio: vf610: Mask all GPIO interrupts + +[ Upstream commit 7ae710f9f8b2cf95297e7bbfe1c09789a7dc43d4 ] + +On SoC reset all GPIO interrupts are disable. However, if kexec is +used to boot into a new kernel, the SoC does not experience a +reset. Hence GPIO interrupts can be left enabled from the previous +kernel. It is then possible for the interrupt to fire before an +interrupt handler is registered, resulting in the kernel complaining +of an "unexpected IRQ trap", the interrupt is never cleared, and so +fires again, resulting in an interrupt storm. + +Disable all GPIO interrupts before registering the GPIO IRQ chip. + +Fixes: 7f2691a19627 ("gpio: vf610: add gpiolib/IRQ chip driver for Vybrid") +Signed-off-by: Andrew Lunn +Acked-by: Stefan Agner +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-vf610.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c +index 5960396c8d9a..222170a1715f 100644 +--- a/drivers/gpio/gpio-vf610.c ++++ b/drivers/gpio/gpio-vf610.c +@@ -250,6 +250,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) + struct vf610_gpio_port *port; + struct resource *iores; + struct gpio_chip *gc; ++ int i; + int ret; + + port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); +@@ -289,6 +290,10 @@ static int vf610_gpio_probe(struct platform_device *pdev) + if (ret < 0) + return ret; + ++ /* Mask all GPIO interrupts */ ++ for (i = 0; i < gc->ngpio; i++) ++ vf610_gpio_writel(0, port->base + PORT_PCR(i)); ++ + /* Clear the interrupt status register for all GPIO's */ + vf610_gpio_writel(~0, port->base + PORT_ISFR); + +-- +2.19.1 + diff --git a/queue-4.20/i2c-omap-use-noirq-system-sleep-pm-ops-to-idle-devic.patch b/queue-4.20/i2c-omap-use-noirq-system-sleep-pm-ops-to-idle-devic.patch new file mode 100644 index 00000000000..dcae156c4a4 --- /dev/null +++ b/queue-4.20/i2c-omap-use-noirq-system-sleep-pm-ops-to-idle-devic.patch @@ -0,0 +1,92 @@ +From 71985839891b0cb4909a2151d1d74acf3de50d31 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Thu, 10 Jan 2019 07:59:16 -0800 +Subject: i2c: omap: Use noirq system sleep pm ops to idle device for suspend + +[ Upstream commit c6e2bd956936d925748581e4d0294f10f1d92f2c ] + +We currently get the following error with pixcir_ts driver during a +suspend resume cycle: + +omap_i2c 4802a000.i2c: controller timed out +pixcir_ts 1-005c: pixcir_int_enable: can't read reg 0x34 : -110 +pixcir_ts 1-005c: Failed to disable interrupt generation: -110 +pixcir_ts 1-005c: Failed to stop +dpm_run_callback(): pixcir_i2c_ts_resume+0x0/0x98 +[pixcir_i2c_ts] returns -110 +PM: Device 1-005c failed to resume: error -110 + +And at least am437x based devices with pixcir_ts will fail to resume +to a touchscreen that is configured as the wakeup-source in device +tree for these devices. + +This is because pixcir_ts tries to reconfigure it's registers for +noirq suspend which fails. This also leaves i2c-omap in enabled state +for suspend. + +Let's fix the pixcir_ts issue and make sure i2c-omap is suspended by +adding SET_NOIRQ_SYSTEM_SLEEP_PM_OPS. + +Let's also get rid of some ifdefs while at it and replace them with +__maybe_unused as SET_RUNTIME_PM_OPS and SET_NOIRQ_SYSTEM_SLEEP_PM_OPS +already deal with the various PM Kconfig options. + +Reported-by: Keerthy +Signed-off-by: Tony Lindgren +Acked-by: Vignesh R +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-omap.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c +index b1086bfb0465..cd9c65f3d404 100644 +--- a/drivers/i2c/busses/i2c-omap.c ++++ b/drivers/i2c/busses/i2c-omap.c +@@ -1500,8 +1500,7 @@ static int omap_i2c_remove(struct platform_device *pdev) + return 0; + } + +-#ifdef CONFIG_PM +-static int omap_i2c_runtime_suspend(struct device *dev) ++static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev) + { + struct omap_i2c_dev *omap = dev_get_drvdata(dev); + +@@ -1527,7 +1526,7 @@ static int omap_i2c_runtime_suspend(struct device *dev) + return 0; + } + +-static int omap_i2c_runtime_resume(struct device *dev) ++static int __maybe_unused omap_i2c_runtime_resume(struct device *dev) + { + struct omap_i2c_dev *omap = dev_get_drvdata(dev); + +@@ -1542,20 +1541,18 @@ static int omap_i2c_runtime_resume(struct device *dev) + } + + static const struct dev_pm_ops omap_i2c_pm_ops = { ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, ++ pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend, + omap_i2c_runtime_resume, NULL) + }; +-#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) +-#else +-#define OMAP_I2C_PM_OPS NULL +-#endif /* CONFIG_PM */ + + static struct platform_driver omap_i2c_driver = { + .probe = omap_i2c_probe, + .remove = omap_i2c_remove, + .driver = { + .name = "omap_i2c", +- .pm = OMAP_I2C_PM_OPS, ++ .pm = &omap_i2c_pm_ops, + .of_match_table = of_match_ptr(omap_i2c_of_match), + }, + }; +-- +2.19.1 + diff --git a/queue-4.20/ib-hfi1-qib-fix-wc.byte_len-calculation-for-ud_send_.patch b/queue-4.20/ib-hfi1-qib-fix-wc.byte_len-calculation-for-ud_send_.patch new file mode 100644 index 00000000000..81523863a59 --- /dev/null +++ b/queue-4.20/ib-hfi1-qib-fix-wc.byte_len-calculation-for-ud_send_.patch @@ -0,0 +1,57 @@ +From dcf4be43c418ea31a80b5f09fa42e4bc60a11b1e Mon Sep 17 00:00:00 2001 +From: Brian Welty +Date: Thu, 17 Jan 2019 12:41:32 -0800 +Subject: IB/{hfi1, qib}: Fix WC.byte_len calculation for UD_SEND_WITH_IMM + +[ Upstream commit 904bba211acc2112fdf866e5a2bc6cd9ecd0de1b ] + +The work completion length for a receiving a UD send with immediate is +short by 4 bytes causing application using this opcode to fail. + +The UD receive logic incorrectly subtracts 4 bytes for immediate +value. These bytes are already included in header length and are used to +calculate header/payload split, so the result is these 4 bytes are +subtracted twice, once when the header length subtracted from the overall +length and once again in the UD opcode specific path. + +Remove the extra subtraction when handling the opcode. + +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Reviewed-by: Michael J. Ruhl +Signed-off-by: Brian Welty +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/ud.c | 1 - + drivers/infiniband/hw/qib/qib_ud.c | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c +index 4baa8f4d49de..46bf74375ea6 100644 +--- a/drivers/infiniband/hw/hfi1/ud.c ++++ b/drivers/infiniband/hw/hfi1/ud.c +@@ -980,7 +980,6 @@ void hfi1_ud_rcv(struct hfi1_packet *packet) + opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { + wc.ex.imm_data = packet->ohdr->u.ud.imm_data; + wc.wc_flags = IB_WC_WITH_IMM; +- tlen -= sizeof(u32); + } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { + wc.ex.imm_data = 0; + wc.wc_flags = 0; +diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c +index 4d4c31ea4e2d..90268b838d4e 100644 +--- a/drivers/infiniband/hw/qib/qib_ud.c ++++ b/drivers/infiniband/hw/qib/qib_ud.c +@@ -513,7 +513,6 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct ib_header *hdr, + opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { + wc.ex.imm_data = ohdr->u.ud.imm_data; + wc.wc_flags = IB_WC_WITH_IMM; +- tlen -= sizeof(u32); + } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { + wc.ex.imm_data = 0; + wc.wc_flags = 0; +-- +2.19.1 + diff --git a/queue-4.20/ib-ipoib-fix-for-use-after-free-in-ipoib_cm_tx_start.patch b/queue-4.20/ib-ipoib-fix-for-use-after-free-in-ipoib_cm_tx_start.patch new file mode 100644 index 00000000000..28cd905730f --- /dev/null +++ b/queue-4.20/ib-ipoib-fix-for-use-after-free-in-ipoib_cm_tx_start.patch @@ -0,0 +1,146 @@ +From 3c5627e41d6cd5994849967ade5e3a9e39a07258 Mon Sep 17 00:00:00 2001 +From: Feras Daoud +Date: Thu, 24 Jan 2019 14:33:19 +0200 +Subject: IB/ipoib: Fix for use-after-free in ipoib_cm_tx_start + +[ Upstream commit 6ab4aba00f811a5265acc4d3eb1863bb3ca60562 ] + +The following BUG was reported by kasan: + + BUG: KASAN: use-after-free in ipoib_cm_tx_start+0x430/0x1390 [ib_ipoib] + Read of size 80 at addr ffff88034c30bcd0 by task kworker/u16:1/24020 + + Workqueue: ipoib_wq ipoib_cm_tx_start [ib_ipoib] + Call Trace: + dump_stack+0x9a/0xeb + print_address_description+0xe3/0x2e0 + kasan_report+0x18a/0x2e0 + ? ipoib_cm_tx_start+0x430/0x1390 [ib_ipoib] + memcpy+0x1f/0x50 + ipoib_cm_tx_start+0x430/0x1390 [ib_ipoib] + ? kvm_clock_read+0x1f/0x30 + ? ipoib_cm_skb_reap+0x610/0x610 [ib_ipoib] + ? __lock_is_held+0xc2/0x170 + ? process_one_work+0x880/0x1960 + ? process_one_work+0x912/0x1960 + process_one_work+0x912/0x1960 + ? wq_pool_ids_show+0x310/0x310 + ? lock_acquire+0x145/0x440 + worker_thread+0x87/0xbb0 + ? process_one_work+0x1960/0x1960 + kthread+0x314/0x3d0 + ? kthread_create_worker_on_cpu+0xc0/0xc0 + ret_from_fork+0x3a/0x50 + + Allocated by task 0: + kasan_kmalloc+0xa0/0xd0 + kmem_cache_alloc_trace+0x168/0x3e0 + path_rec_create+0xa2/0x1f0 [ib_ipoib] + ipoib_start_xmit+0xa98/0x19e0 [ib_ipoib] + dev_hard_start_xmit+0x159/0x8d0 + sch_direct_xmit+0x226/0xb40 + __dev_queue_xmit+0x1d63/0x2950 + neigh_update+0x889/0x1770 + arp_process+0xc47/0x21f0 + arp_rcv+0x462/0x760 + __netif_receive_skb_core+0x1546/0x2da0 + netif_receive_skb_internal+0xf2/0x590 + napi_gro_receive+0x28e/0x390 + ipoib_ib_handle_rx_wc_rss+0x873/0x1b60 [ib_ipoib] + ipoib_rx_poll_rss+0x17d/0x320 [ib_ipoib] + net_rx_action+0x427/0xe30 + __do_softirq+0x28e/0xc42 + + Freed by task 26680: + __kasan_slab_free+0x11d/0x160 + kfree+0xf5/0x360 + ipoib_flush_paths+0x532/0x9d0 [ib_ipoib] + ipoib_set_mode_rss+0x1ad/0x560 [ib_ipoib] + set_mode+0xc8/0x150 [ib_ipoib] + kernfs_fop_write+0x279/0x440 + __vfs_write+0xd8/0x5c0 + vfs_write+0x15e/0x470 + ksys_write+0xb8/0x180 + do_syscall_64+0x9b/0x420 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + + The buggy address belongs to the object at ffff88034c30bcc8 + which belongs to the cache kmalloc-512 of size 512 + The buggy address is located 8 bytes inside of + 512-byte region [ffff88034c30bcc8, ffff88034c30bec8) + The buggy address belongs to the page: + +The following race between change mode and xmit flow is the reason for +this use-after-free: + +Change mode Send packet 1 to GID XX Send packet 2 to GID XX + | | | + start | | + | | | + | | | + | Create new path for GID XX | + | and update neigh path | + | | | + | | | + | | | + flush_paths | | + | | + queue_work(cm.start_task) | + | Path for GID XX not found + | create new path + | + | + start_task runs with old + released path + +There is no locking to protect the lifetime of the path through the +ipoib_cm_tx struct, so delete it entirely and always use the newly looked +up path under the priv->lock. + +Fixes: 546481c2816e ("IB/ipoib: Fix memory corruption in ipoib cm mode connect flow") +Signed-off-by: Feras Daoud +Reviewed-by: Erez Shitrit +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/ipoib/ipoib.h | 1 - + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 3 +-- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h +index 1da119d901a9..73e808c1e6ad 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib.h ++++ b/drivers/infiniband/ulp/ipoib/ipoib.h +@@ -248,7 +248,6 @@ struct ipoib_cm_tx { + struct list_head list; + struct net_device *dev; + struct ipoib_neigh *neigh; +- struct ipoib_path *path; + struct ipoib_tx_buf *tx_ring; + unsigned int tx_head; + unsigned int tx_tail; +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +index 0428e01e8f69..aa9dcfc36cd3 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +@@ -1312,7 +1312,6 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path + + neigh->cm = tx; + tx->neigh = neigh; +- tx->path = path; + tx->dev = dev; + list_add(&tx->list, &priv->cm.start_list); + set_bit(IPOIB_FLAG_INITIALIZED, &tx->flags); +@@ -1371,7 +1370,7 @@ static void ipoib_cm_tx_start(struct work_struct *work) + neigh->daddr + QPN_AND_OPTIONS_OFFSET); + goto free_neigh; + } +- memcpy(&pathrec, &p->path->pathrec, sizeof(pathrec)); ++ memcpy(&pathrec, &path->pathrec, sizeof(pathrec)); + + spin_unlock_irqrestore(&priv->lock, flags); + netif_tx_unlock_bh(dev); +-- +2.19.1 + diff --git a/queue-4.20/iomap-fix-a-use-after-free-in-iomap_dio_rw.patch b/queue-4.20/iomap-fix-a-use-after-free-in-iomap_dio_rw.patch new file mode 100644 index 00000000000..e7a8736d91d --- /dev/null +++ b/queue-4.20/iomap-fix-a-use-after-free-in-iomap_dio_rw.patch @@ -0,0 +1,105 @@ +From f46312dc8bf3a5e29ba25f84dbe9f111db3f593f Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Thu, 17 Jan 2019 08:58:58 -0800 +Subject: iomap: fix a use after free in iomap_dio_rw + +[ Upstream commit 4ea899ead2786a30aaa8181fefa81a3df4ad28f6 ] + +Introduce a local wait_for_completion variable to avoid an access to the +potentially freed dio struture after dropping the last reference count. + +Also use the chance to document the completion behavior to make the +refcounting clear to the reader of the code. + +Fixes: ff6a9292e6 ("iomap: implement direct I/O") +Reported-by: Chandan Rajendra +Reported-by: Darrick J. Wong +Signed-off-by: Christoph Hellwig +Tested-by: Chandan Rajendra +Tested-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + fs/iomap.c | 28 +++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/fs/iomap.c b/fs/iomap.c +index 7793e9e42ad5..83d9a196fe3e 100644 +--- a/fs/iomap.c ++++ b/fs/iomap.c +@@ -1806,6 +1806,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + loff_t pos = iocb->ki_pos, start = pos; + loff_t end = iocb->ki_pos + count - 1, ret = 0; + unsigned int flags = IOMAP_DIRECT; ++ bool wait_for_completion = is_sync_kiocb(iocb); + struct blk_plug plug; + struct iomap_dio *dio; + +@@ -1825,7 +1826,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + dio->end_io = end_io; + dio->error = 0; + dio->flags = 0; +- dio->wait_for_completion = is_sync_kiocb(iocb); + + dio->submit.iter = iter; + dio->submit.waiter = current; +@@ -1880,7 +1880,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + dio_warn_stale_pagecache(iocb->ki_filp); + ret = 0; + +- if (iov_iter_rw(iter) == WRITE && !dio->wait_for_completion && ++ if (iov_iter_rw(iter) == WRITE && !wait_for_completion && + !inode->i_sb->s_dio_done_wq) { + ret = sb_init_dio_done_wq(inode->i_sb); + if (ret < 0) +@@ -1896,7 +1896,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + if (ret <= 0) { + /* magic error code to fall back to buffered I/O */ + if (ret == -ENOTBLK) { +- dio->wait_for_completion = true; ++ wait_for_completion = true; + ret = 0; + } + break; +@@ -1918,8 +1918,24 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + if (dio->flags & IOMAP_DIO_WRITE_FUA) + dio->flags &= ~IOMAP_DIO_NEED_SYNC; + ++ /* ++ * We are about to drop our additional submission reference, which ++ * might be the last reference to the dio. There are three three ++ * different ways we can progress here: ++ * ++ * (a) If this is the last reference we will always complete and free ++ * the dio ourselves. ++ * (b) If this is not the last reference, and we serve an asynchronous ++ * iocb, we must never touch the dio after the decrement, the ++ * I/O completion handler will complete and free it. ++ * (c) If this is not the last reference, but we serve a synchronous ++ * iocb, the I/O completion handler will wake us up on the drop ++ * of the final reference, and we will complete and free it here ++ * after we got woken by the I/O completion handler. ++ */ ++ dio->wait_for_completion = wait_for_completion; + if (!atomic_dec_and_test(&dio->ref)) { +- if (!dio->wait_for_completion) ++ if (!wait_for_completion) + return -EIOCBQUEUED; + + for (;;) { +@@ -1936,9 +1952,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + __set_current_state(TASK_RUNNING); + } + +- ret = iomap_dio_complete(dio); +- +- return ret; ++ return iomap_dio_complete(dio); + + out_free_dio: + kfree(dio); +-- +2.19.1 + diff --git a/queue-4.20/iomap-get-put-the-page-in-iomap_page_create-release.patch b/queue-4.20/iomap-get-put-the-page-in-iomap_page_create-release.patch new file mode 100644 index 00000000000..ef53d69ae44 --- /dev/null +++ b/queue-4.20/iomap-get-put-the-page-in-iomap_page_create-release.patch @@ -0,0 +1,77 @@ +From 59edb1ddf748a20e9aebca93a2b403de250d8875 Mon Sep 17 00:00:00 2001 +From: Piotr Jaroszynski +Date: Sun, 27 Jan 2019 08:46:45 -0800 +Subject: iomap: get/put the page in iomap_page_create/release() + +[ Upstream commit 8e47a457321ca1a74ad194ab5dcbca764bc70731 ] + +migrate_page_move_mapping() expects pages with private data set to have +a page_count elevated by 1. This is what used to happen for xfs through +the buffer_heads code before the switch to iomap in commit 82cb14175e7d +("xfs: add support for sub-pagesize writeback without buffer_heads"). +Not having the count elevated causes move_pages() to fail on memory +mapped files coming from xfs. + +Make iomap compatible with the migrate_page_move_mapping() assumption by +elevating the page count as part of iomap_page_create() and lowering it +in iomap_page_release(). + +It causes the move_pages() syscall to misbehave on memory mapped files +from xfs. It does not not move any pages, which I suppose is "just" a +perf issue, but it also ends up returning a positive number which is out +of spec for the syscall. Talking to Michal Hocko, it sounds like +returning positive numbers might be a necessary update to move_pages() +anyway though. + +Fixes: 82cb14175e7d ("xfs: add support for sub-pagesize writeback without buffer_heads") +Signed-off-by: Piotr Jaroszynski +[hch: actually get/put the page iomap_migrate_page() to make it work + properly] +Signed-off-by: Christoph Hellwig +Reviewed-by: Dave Chinner +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + fs/iomap.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/fs/iomap.c b/fs/iomap.c +index ce837d962d47..7793e9e42ad5 100644 +--- a/fs/iomap.c ++++ b/fs/iomap.c +@@ -116,6 +116,12 @@ iomap_page_create(struct inode *inode, struct page *page) + atomic_set(&iop->read_count, 0); + atomic_set(&iop->write_count, 0); + bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE); ++ ++ /* ++ * migrate_page_move_mapping() assumes that pages with private data have ++ * their count elevated by 1. ++ */ ++ get_page(page); + set_page_private(page, (unsigned long)iop); + SetPagePrivate(page); + return iop; +@@ -132,6 +138,7 @@ iomap_page_release(struct page *page) + WARN_ON_ONCE(atomic_read(&iop->write_count)); + ClearPagePrivate(page); + set_page_private(page, 0); ++ put_page(page); + kfree(iop); + } + +@@ -569,8 +576,10 @@ iomap_migrate_page(struct address_space *mapping, struct page *newpage, + + if (page_has_private(page)) { + ClearPagePrivate(page); ++ get_page(newpage); + set_page_private(newpage, page_private(page)); + set_page_private(page, 0); ++ put_page(page); + SetPagePrivate(newpage); + } + +-- +2.19.1 + diff --git a/queue-4.20/iommu-amd-call-free_iova_fast-with-pfn-in-map_sg.patch b/queue-4.20/iommu-amd-call-free_iova_fast-with-pfn-in-map_sg.patch new file mode 100644 index 00000000000..28c4e6f6446 --- /dev/null +++ b/queue-4.20/iommu-amd-call-free_iova_fast-with-pfn-in-map_sg.patch @@ -0,0 +1,38 @@ +From a515cb44888483e11542052310ea9f360a4f2118 Mon Sep 17 00:00:00 2001 +From: Jerry Snitselaar +Date: Thu, 17 Jan 2019 12:29:02 -0700 +Subject: iommu/amd: Call free_iova_fast with pfn in map_sg + +[ Upstream commit 51d8838d66d3249508940d8f59b07701f2129723 ] + +In the error path of map_sg, free_iova_fast is being called with +address instead of the pfn. This results in a bad value getting into +the rcache, and can result in hitting a BUG_ON when +iova_magazine_free_pfns is called. + +Cc: Joerg Roedel +Cc: Suravee Suthikulpanit +Signed-off-by: Jerry Snitselaar +Fixes: 80187fd39dcb ("iommu/amd: Optimize map_sg and unmap_sg") +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 325f3bad118b..5f33f843d30a 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -2561,7 +2561,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, + } + + out_free_iova: +- free_iova_fast(&dma_dom->iovad, address, npages); ++ free_iova_fast(&dma_dom->iovad, address >> PAGE_SHIFT, npages); + + out_err: + return 0; +-- +2.19.1 + diff --git a/queue-4.20/iommu-amd-fix-iommu-page-flush-when-detach-device-fr.patch b/queue-4.20/iommu-amd-fix-iommu-page-flush-when-detach-device-fr.patch new file mode 100644 index 00000000000..1ae9d1f0723 --- /dev/null +++ b/queue-4.20/iommu-amd-fix-iommu-page-flush-when-detach-device-fr.patch @@ -0,0 +1,80 @@ +From 30ad183c480e0ce050278fff0656c3a48cd047fc Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Thu, 24 Jan 2019 04:16:45 +0000 +Subject: iommu/amd: Fix IOMMU page flush when detach device from a domain + +[ Upstream commit 9825bd94e3a2baae1f4874767ae3a7d4c049720e ] + +When a VM is terminated, the VFIO driver detaches all pass-through +devices from VFIO domain by clearing domain id and page table root +pointer from each device table entry (DTE), and then invalidates +the DTE. Then, the VFIO driver unmap pages and invalidate IOMMU pages. + +Currently, the IOMMU driver keeps track of which IOMMU and how many +devices are attached to the domain. When invalidate IOMMU pages, +the driver checks if the IOMMU is still attached to the domain before +issuing the invalidate page command. + +However, since VFIO has already detached all devices from the domain, +the subsequent INVALIDATE_IOMMU_PAGES commands are being skipped as +there is no IOMMU attached to the domain. This results in data +corruption and could cause the PCI device to end up in indeterministic +state. + +Fix this by invalidate IOMMU pages when detach a device, and +before decrementing the per-domain device reference counts. + +Cc: Boris Ostrovsky +Suggested-by: Joerg Roedel +Co-developed-by: Brijesh Singh +Signed-off-by: Brijesh Singh +Signed-off-by: Suravee Suthikulpanit +Fixes: 6de8ad9b9ee0 ('x86/amd-iommu: Make iommu_flush_pages aware of multiple IOMMUs') +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index ca3a250d8fa7..4d2c5d4f586f 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -1929,16 +1929,13 @@ static void do_attach(struct iommu_dev_data *dev_data, + + static void do_detach(struct iommu_dev_data *dev_data) + { ++ struct protection_domain *domain = dev_data->domain; + struct amd_iommu *iommu; + u16 alias; + + iommu = amd_iommu_rlookup_table[dev_data->devid]; + alias = dev_data->alias; + +- /* decrease reference counters */ +- dev_data->domain->dev_iommu[iommu->index] -= 1; +- dev_data->domain->dev_cnt -= 1; +- + /* Update data structures */ + dev_data->domain = NULL; + list_del(&dev_data->list); +@@ -1948,6 +1945,16 @@ static void do_detach(struct iommu_dev_data *dev_data) + + /* Flush the DTE entry */ + device_flush_dte(dev_data); ++ ++ /* Flush IOTLB */ ++ domain_flush_tlb_pde(domain); ++ ++ /* Wait for the flushes to finish */ ++ domain_flush_complete(domain); ++ ++ /* decrease reference counters - needs to happen after the flushes */ ++ domain->dev_iommu[iommu->index] -= 1; ++ domain->dev_cnt -= 1; + } + + /* +-- +2.19.1 + diff --git a/queue-4.20/iommu-amd-unmap-all-mapped-pages-in-error-path-of-ma.patch b/queue-4.20/iommu-amd-unmap-all-mapped-pages-in-error-path-of-ma.patch new file mode 100644 index 00000000000..d3f0311be90 --- /dev/null +++ b/queue-4.20/iommu-amd-unmap-all-mapped-pages-in-error-path-of-ma.patch @@ -0,0 +1,40 @@ +From d97a653be05ea5366a6ab5e7dfa6ce3717ed80ef Mon Sep 17 00:00:00 2001 +From: Jerry Snitselaar +Date: Sat, 19 Jan 2019 10:38:05 -0700 +Subject: iommu/amd: Unmap all mapped pages in error path of map_sg + +[ Upstream commit f1724c0883bb0ce93b8dcb94b53dcca3b75ac9a7 ] + +In the error path of map_sg there is an incorrect if condition +for breaking out of the loop that searches the scatterlist +for mapped pages to unmap. Instead of breaking out of the +loop once all the pages that were mapped have been unmapped, +it will break out of the loop after it has unmapped 1 page. +Fix the condition, so it breaks out of the loop only after +all the mapped pages have been unmapped. + +Fixes: 80187fd39dcb ("iommu/amd: Optimize map_sg and unmap_sg") +Cc: Joerg Roedel +Signed-off-by: Jerry Snitselaar +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 5f33f843d30a..ca3a250d8fa7 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -2555,7 +2555,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, + bus_addr = address + s->dma_address + (j << PAGE_SHIFT); + iommu_unmap_page(domain, bus_addr, PAGE_SIZE); + +- if (--mapped_pages) ++ if (--mapped_pages == 0) + goto out_free_iova; + } + } +-- +2.19.1 + diff --git a/queue-4.20/ipvs-fix-signed-integer-overflow-when-setsockopt-tim.patch b/queue-4.20/ipvs-fix-signed-integer-overflow-when-setsockopt-tim.patch new file mode 100644 index 00000000000..871c766dfcb --- /dev/null +++ b/queue-4.20/ipvs-fix-signed-integer-overflow-when-setsockopt-tim.patch @@ -0,0 +1,91 @@ +From 4771a328f83009faa8e373166d204fff4f80445a Mon Sep 17 00:00:00 2001 +From: ZhangXiaoxu +Date: Thu, 10 Jan 2019 16:39:06 +0800 +Subject: ipvs: Fix signed integer overflow when setsockopt timeout + +[ Upstream commit 53ab60baa1ac4f20b080a22c13b77b6373922fd7 ] + +There is a UBSAN bug report as below: +UBSAN: Undefined behaviour in net/netfilter/ipvs/ip_vs_ctl.c:2227:21 +signed integer overflow: +-2147483647 * 1000 cannot be represented in type 'int' + +Reproduce program: + #include + #include + #include + + #define IPPROTO_IP 0 + #define IPPROTO_RAW 255 + + #define IP_VS_BASE_CTL (64+1024+64) + #define IP_VS_SO_SET_TIMEOUT (IP_VS_BASE_CTL+10) + + /* The argument to IP_VS_SO_GET_TIMEOUT */ + struct ipvs_timeout_t { + int tcp_timeout; + int tcp_fin_timeout; + int udp_timeout; + }; + + int main() { + int ret = -1; + int sockfd = -1; + struct ipvs_timeout_t to; + + sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (sockfd == -1) { + printf("socket init error\n"); + return -1; + } + + to.tcp_timeout = -2147483647; + to.tcp_fin_timeout = -2147483647; + to.udp_timeout = -2147483647; + + ret = setsockopt(sockfd, + IPPROTO_IP, + IP_VS_SO_SET_TIMEOUT, + (char *)(&to), + sizeof(to)); + + printf("setsockopt return %d\n", ret); + return ret; + } + +Return -EINVAL if the timeout value is negative or max than 'INT_MAX / HZ'. + +Signed-off-by: ZhangXiaoxu +Acked-by: Simon Horman +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_ctl.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 432141f04af3..7d6318664eb2 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -2220,6 +2220,18 @@ static int ip_vs_set_timeout(struct netns_ipvs *ipvs, struct ip_vs_timeout_user + u->tcp_fin_timeout, + u->udp_timeout); + ++#ifdef CONFIG_IP_VS_PROTO_TCP ++ if (u->tcp_timeout < 0 || u->tcp_timeout > (INT_MAX / HZ) || ++ u->tcp_fin_timeout < 0 || u->tcp_fin_timeout > (INT_MAX / HZ)) { ++ return -EINVAL; ++ } ++#endif ++ ++#ifdef CONFIG_IP_VS_PROTO_UDP ++ if (u->udp_timeout < 0 || u->udp_timeout > (INT_MAX / HZ)) ++ return -EINVAL; ++#endif ++ + #ifdef CONFIG_IP_VS_PROTO_TCP + if (u->tcp_timeout) { + pd = ip_vs_proto_data_get(ipvs, IPPROTO_TCP); +-- +2.19.1 + diff --git a/queue-4.20/irqchip-gic-v3-its-fix-itt_entry_size-accessor.patch b/queue-4.20/irqchip-gic-v3-its-fix-itt_entry_size-accessor.patch new file mode 100644 index 00000000000..56b0e7bc0e0 --- /dev/null +++ b/queue-4.20/irqchip-gic-v3-its-fix-itt_entry_size-accessor.patch @@ -0,0 +1,37 @@ +From ae4167c054aef03d23b48120867d253e88148525 Mon Sep 17 00:00:00 2001 +From: Zenghui Yu +Date: Thu, 31 Jan 2019 11:19:43 +0000 +Subject: irqchip/gic-v3-its: Fix ITT_entry_size accessor + +[ Upstream commit 56841070ccc87b463ac037d2d1f2beb8e5e35f0c ] + +According to ARM IHI 0069C (ID070116), we should use GITS_TYPER's +bits [7:4] as ITT_entry_size instead of [8:4]. Although this is +pretty annoying, it only results in a potential over-allocation +of memory, and nothing bad happens. + +Fixes: 3dfa576bfb45 ("irqchip/gic-v3-its: Add probing for VLPI properties") +Signed-off-by: Zenghui Yu +[maz: massaged subject and commit message] +Signed-off-by: Marc Zyngier +Signed-off-by: Sasha Levin +--- + include/linux/irqchip/arm-gic-v3.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h +index 071b4cbdf010..c848a7cc502e 100644 +--- a/include/linux/irqchip/arm-gic-v3.h ++++ b/include/linux/irqchip/arm-gic-v3.h +@@ -319,7 +319,7 @@ + #define GITS_TYPER_PLPIS (1UL << 0) + #define GITS_TYPER_VLPIS (1UL << 1) + #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 +-#define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0x1f) + 1) ++#define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0xf) + 1) + #define GITS_TYPER_IDBITS_SHIFT 8 + #define GITS_TYPER_DEVBITS_SHIFT 13 + #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) +-- +2.19.1 + diff --git a/queue-4.20/irqchip-gic-v3-its-gracefully-fail-on-lpi-exhaustion.patch b/queue-4.20/irqchip-gic-v3-its-gracefully-fail-on-lpi-exhaustion.patch new file mode 100644 index 00000000000..ad242a8ce24 --- /dev/null +++ b/queue-4.20/irqchip-gic-v3-its-gracefully-fail-on-lpi-exhaustion.patch @@ -0,0 +1,35 @@ +From 2d570661b9af0af18c9419c45c26a0dbaf231c6b Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Tue, 29 Jan 2019 15:19:23 +0000 +Subject: irqchip/gic-v3-its: Gracefully fail on LPI exhaustion + +[ Upstream commit 45725e0fc3e7fe52fedb94f59806ec50e9618682 ] + +In the unlikely event that we cannot find any available LPI in the +system, we should gracefully return an error instead of carrying +on with no LPI allocated at all. + +Fixes: 38dd7c494cf6 ("irqchip/gic-v3-its: Drop chunk allocation compatibility") +Signed-off-by: Marc Zyngier +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-gic-v3-its.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index f25ec92f23ee..c3aba3fc818d 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -1586,6 +1586,9 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids) + nr_irqs /= 2; + } while (nr_irqs > 0); + ++ if (!nr_irqs) ++ err = -ENOSPC; ++ + if (err) + goto out; + +-- +2.19.1 + diff --git a/queue-4.20/irqchip-gic-v4-fix-occasional-vlpi-drop.patch b/queue-4.20/irqchip-gic-v4-fix-occasional-vlpi-drop.patch new file mode 100644 index 00000000000..b408af12a4c --- /dev/null +++ b/queue-4.20/irqchip-gic-v4-fix-occasional-vlpi-drop.patch @@ -0,0 +1,138 @@ +From ce1cb7f4cb920296ef9444a27003005ca94533c4 Mon Sep 17 00:00:00 2001 +From: Heyi Guo +Date: Thu, 24 Jan 2019 21:37:08 +0800 +Subject: irqchip/gic-v4: Fix occasional VLPI drop + +[ Upstream commit 6479450f72c1391c03f08affe0d0110f41ae7ca0 ] + +1. In current implementation, every VLPI will temporarily be mapped to +the first CPU in system (normally CPU0) and then moved to the real +scheduled CPU later. + +2. So there is a time window and a VLPI may be sent to CPU0 instead of +the real scheduled vCPU, in a multi-CPU virtual machine. + +3. However, CPU0 may have not been scheduled as a virtual CPU after +system boots up, so the value of its GICR_VPROPBASER is unknown at +that moment. + +4. If the INTID of VLPI is larger than 2^(GICR_VPROPBASER.IDbits+1), +while IDbits is also in unknown state, GIC will behave as if the VLPI +is out of range and simply drop it, which results in interrupt missing +in Guest. + +As no code will clear GICR_VPROPBASER at runtime, we can safely +initialize the IDbits field at boot time for each CPU to get rid of +this issue. + +We also clear Valid bit of GICR_VPENDBASER in case any ancient +programming gets left in and causes memory corrupting. A new function +its_clear_vpend_valid() is added to reuse the code in +its_vpe_deschedule(). + +Fixes: e643d8034036 ("irqchip/gic-v3-its: Add VPE scheduling") +Signed-off-by: Heyi Guo +Signed-off-by: Heyi Guo +Signed-off-by: Marc Zyngier +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-gic-v3-its.c | 66 ++++++++++++++++++++++++-------- + 1 file changed, 49 insertions(+), 17 deletions(-) + +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index 350f999d205b..f25ec92f23ee 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -2065,6 +2065,29 @@ static int __init allocate_lpi_tables(void) + return 0; + } + ++static u64 its_clear_vpend_valid(void __iomem *vlpi_base) ++{ ++ u32 count = 1000000; /* 1s! */ ++ bool clean; ++ u64 val; ++ ++ val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); ++ val &= ~GICR_VPENDBASER_Valid; ++ gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); ++ ++ do { ++ val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); ++ clean = !(val & GICR_VPENDBASER_Dirty); ++ if (!clean) { ++ count--; ++ cpu_relax(); ++ udelay(1); ++ } ++ } while (!clean && count); ++ ++ return val; ++} ++ + static void its_cpu_init_lpis(void) + { + void __iomem *rbase = gic_data_rdist_rd_base(); +@@ -2150,6 +2173,30 @@ static void its_cpu_init_lpis(void) + val |= GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + ++ if (gic_rdists->has_vlpis) { ++ void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); ++ ++ /* ++ * It's possible for CPU to receive VLPIs before it is ++ * sheduled as a vPE, especially for the first CPU, and the ++ * VLPI with INTID larger than 2^(IDbits+1) will be considered ++ * as out of range and dropped by GIC. ++ * So we initialize IDbits to known value to avoid VLPI drop. ++ */ ++ val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK; ++ pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n", ++ smp_processor_id(), val); ++ gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER); ++ ++ /* ++ * Also clear Valid bit of GICR_VPENDBASER, in case some ++ * ancient programming gets left in and has possibility of ++ * corrupting memory. ++ */ ++ val = its_clear_vpend_valid(vlpi_base); ++ WARN_ON(val & GICR_VPENDBASER_Dirty); ++ } ++ + /* Make sure the GIC has seen the above */ + dsb(sy); + out: +@@ -2776,26 +2823,11 @@ static void its_vpe_schedule(struct its_vpe *vpe) + static void its_vpe_deschedule(struct its_vpe *vpe) + { + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); +- u32 count = 1000000; /* 1s! */ +- bool clean; + u64 val; + +- /* We're being scheduled out */ +- val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); +- val &= ~GICR_VPENDBASER_Valid; +- gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); +- +- do { +- val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); +- clean = !(val & GICR_VPENDBASER_Dirty); +- if (!clean) { +- count--; +- cpu_relax(); +- udelay(1); +- } +- } while (!clean && count); ++ val = its_clear_vpend_valid(vlpi_base); + +- if (unlikely(!clean && !count)) { ++ if (unlikely(val & GICR_VPENDBASER_Dirty)) { + pr_err_ratelimited("ITS virtual pending table not cleaning\n"); + vpe->idai = false; + vpe->pending_last = true; +-- +2.19.1 + diff --git a/queue-4.20/irqchip-mmp-only-touch-the-pj4-irq-fiq-bits-on-enabl.patch b/queue-4.20/irqchip-mmp-only-touch-the-pj4-irq-fiq-bits-on-enabl.patch new file mode 100644 index 00000000000..431a4a1ec65 --- /dev/null +++ b/queue-4.20/irqchip-mmp-only-touch-the-pj4-irq-fiq-bits-on-enabl.patch @@ -0,0 +1,55 @@ +From 5bd71939c31eb19ca762ea3d8b70dfa6c5866807 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Mon, 28 Jan 2019 16:59:35 +0100 +Subject: irqchip/mmp: Only touch the PJ4 IRQ & FIQ bits on enable/disable + +[ Upstream commit 2380a22b60ce6f995eac806e69c66e397b59d045 ] + +Resetting bit 4 disables the interrupt delivery to the "secure +processor" core. This breaks the keyboard on a OLPC XO 1.75 laptop, +where the firmware running on the "secure processor" bit-bangs the +PS/2 protocol over the GPIO lines. + +It is not clear what the rest of the bits are and Marvell was unhelpful +when asked for documentation. Aside from the SP bit, there are probably +priority bits. + +Leaving the unknown bits as the firmware set them up seems to be a wiser +course of action compared to just turning them off. + +Signed-off-by: Lubomir Rintel +Acked-by: Pavel Machek +[maz: fixed-up subject and commit message] +Signed-off-by: Marc Zyngier +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-mmp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c +index 25f32e1d7764..3496b61a312a 100644 +--- a/drivers/irqchip/irq-mmp.c ++++ b/drivers/irqchip/irq-mmp.c +@@ -34,6 +34,9 @@ + #define SEL_INT_PENDING (1 << 6) + #define SEL_INT_NUM_MASK 0x3f + ++#define MMP2_ICU_INT_ROUTE_PJ4_IRQ (1 << 5) ++#define MMP2_ICU_INT_ROUTE_PJ4_FIQ (1 << 6) ++ + struct icu_chip_data { + int nr_irqs; + unsigned int virq_base; +@@ -190,7 +193,8 @@ static const struct mmp_intc_conf mmp_conf = { + static const struct mmp_intc_conf mmp2_conf = { + .conf_enable = 0x20, + .conf_disable = 0x0, +- .conf_mask = 0x7f, ++ .conf_mask = MMP2_ICU_INT_ROUTE_PJ4_IRQ | ++ MMP2_ICU_INT_ROUTE_PJ4_FIQ, + }; + + static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs) +-- +2.19.1 + diff --git a/queue-4.20/lib-test_kmod.c-potential-double-free-in-error-handl.patch b/queue-4.20/lib-test_kmod.c-potential-double-free-in-error-handl.patch new file mode 100644 index 00000000000..fa4d961fa1c --- /dev/null +++ b/queue-4.20/lib-test_kmod.c-potential-double-free-in-error-handl.patch @@ -0,0 +1,40 @@ +From 08bc128793c4ecd9fe91c4f4ae690e531ae8399e Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 1 Feb 2019 14:20:58 -0800 +Subject: lib/test_kmod.c: potential double free in error handling + +[ Upstream commit db7ddeab3ce5d64c9696e70d61f45ea9909cd196 ] + +There is a copy and paste bug so we set "config->test_driver" to NULL +twice instead of setting "config->test_fs". Smatch complains that it +leads to a double free: + + lib/test_kmod.c:840 __kmod_config_init() warn: 'config->test_fs' double freed + +Link: http://lkml.kernel.org/r/20190121140011.GA14283@kadam +Fixes: d9c6a72d6fa2 ("kmod: add test driver to stress test the module loader") +Signed-off-by: Dan Carpenter +Acked-by: Luis Chamberlain +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + lib/test_kmod.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/test_kmod.c b/lib/test_kmod.c +index d82d022111e0..9cf77628fc91 100644 +--- a/lib/test_kmod.c ++++ b/lib/test_kmod.c +@@ -632,7 +632,7 @@ static void __kmod_config_free(struct test_config *config) + config->test_driver = NULL; + + kfree_const(config->test_fs); +- config->test_driver = NULL; ++ config->test_fs = NULL; + } + + static void kmod_config_free(struct kmod_test_device *test_dev) +-- +2.19.1 + diff --git a/queue-4.20/mips-dts-jz4740-correct-interrupt-number-of-dma-core.patch b/queue-4.20/mips-dts-jz4740-correct-interrupt-number-of-dma-core.patch new file mode 100644 index 00000000000..dea7ebf123b --- /dev/null +++ b/queue-4.20/mips-dts-jz4740-correct-interrupt-number-of-dma-core.patch @@ -0,0 +1,40 @@ +From 06aa7240dbe32cf64303e5d1f87cd57010ee3db9 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 25 Jan 2019 15:12:45 -0300 +Subject: MIPS: DTS: jz4740: Correct interrupt number of DMA core + +[ Upstream commit 70999ec1c9d3f783a7232973cfc26971e5732758 ] + +The interrupt number set in the devicetree node of the DMA driver was +wrong. + +Signed-off-by: Paul Cercueil +Signed-off-by: Paul Burton +Cc: Rob Herring +Cc: Mark Rutland +Cc: Ralf Baechle +Cc: James Hogan +Cc: devicetree@vger.kernel.org +Cc: linux-mips@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Sasha Levin +--- + arch/mips/boot/dts/ingenic/jz4740.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi +index 6fb16fd24035..2beb78a62b7d 100644 +--- a/arch/mips/boot/dts/ingenic/jz4740.dtsi ++++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi +@@ -161,7 +161,7 @@ + #dma-cells = <2>; + + interrupt-parent = <&intc>; +- interrupts = <29>; ++ interrupts = <20>; + + clocks = <&cgu JZ4740_CLK_DMA>; + +-- +2.19.1 + diff --git a/queue-4.20/mips-loongson-introduce-and-use-loongson_llsc_mb.patch b/queue-4.20/mips-loongson-introduce-and-use-loongson_llsc_mb.patch new file mode 100644 index 00000000000..ea561d1d7ec --- /dev/null +++ b/queue-4.20/mips-loongson-introduce-and-use-loongson_llsc_mb.patch @@ -0,0 +1,393 @@ +From efc8526485a1d5c3431b8c7867e6c5ef1bfbadb9 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Tue, 15 Jan 2019 16:04:54 +0800 +Subject: MIPS: Loongson: Introduce and use loongson_llsc_mb() + +[ Upstream commit e02e07e3127d8aec1f4bcdfb2fc52a2d99b4859e ] + +On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and +lld/scd is very weak ordering. We should add sync instructions "before +each ll/lld" and "at the branch-target between ll/sc" to workaround. +Otherwise, this flaw will cause deadlock occasionally (e.g. when doing +heavy load test with LTP). + +Below is the explaination of CPU designer: + +"For Loongson 3 family, when a memory access instruction (load, store, +or prefetch)'s executing occurs between the execution of LL and SC, the +success or failure of SC is not predictable. Although programmer would +not insert memory access instructions between LL and SC, the memory +instructions before LL in program-order, may dynamically executed +between the execution of LL/SC, so a memory fence (SYNC) is needed +before LL/LLD to avoid this situation. + +Since Loongson-3A R2 (3A2000), we have improved our hardware design to +handle this case. But we later deduce a rarely circumstance that some +speculatively executed memory instructions due to branch misprediction +between LL/SC still fall into the above case, so a memory fence (SYNC) +at branch-target (if its target is not between LL/SC) is needed for +Loongson 3A1000, 3B1500, 3A2000 and 3A3000. + +Our processor is continually evolving and we aim to to remove all these +workaround-SYNCs around LL/SC for new-come processor." + +Here is an example: + +Both cpu1 and cpu2 simutaneously run atomic_add by 1 on same atomic var, +this bug cause both 'sc' run by two cpus (in atomic_add) succeed at same +time('sc' return 1), and the variable is only *added by 1*, sometimes, +which is wrong and unacceptable(it should be added by 2). + +Why disable fix-loongson3-llsc in compiler? +Because compiler fix will cause problems in kernel's __ex_table section. + +This patch fix all the cases in kernel, but: + ++. the fix at the end of futex_atomic_cmpxchg_inatomic is for branch-target +of 'bne', there other cases which smp_mb__before_llsc() and smp_llsc_mb() fix +the ll and branch-target coincidently such as atomic_sub_if_positive/ +cmpxchg/xchg, just like this one. + ++. Loongson 3 does support CONFIG_EDAC_ATOMIC_SCRUB, so no need to touch +edac.h + ++. local_ops and cmpxchg_local should not be affected by this bug since +only the owner can write. + ++. mips_atomic_set for syscall.c is deprecated and rarely used, just let +it go + +Signed-off-by: Huacai Chen +Signed-off-by: Huang Pei +[paul.burton@mips.com: + - Simplify the addition of -mno-fix-loongson3-llsc to cflags, and add + a comment describing why it's there. + - Make loongson_llsc_mb() a no-op when + CONFIG_CPU_LOONGSON3_WORKAROUNDS=n, rather than a compiler memory + barrier. + - Add a comment describing the bug & how loongson_llsc_mb() helps + in asm/barrier.h.] +Signed-off-by: Paul Burton +Cc: Ralf Baechle +Cc: ambrosehua@gmail.com +Cc: Steven J . Hill +Cc: linux-mips@linux-mips.org +Cc: Fuxin Zhang +Cc: Zhangjin Wu +Cc: Li Xuefeng +Cc: Xu Chenghua +Signed-off-by: Sasha Levin +--- + arch/mips/Kconfig | 15 ++++++++++++++ + arch/mips/include/asm/atomic.h | 6 ++++++ + arch/mips/include/asm/barrier.h | 36 +++++++++++++++++++++++++++++++++ + arch/mips/include/asm/bitops.h | 5 +++++ + arch/mips/include/asm/futex.h | 3 +++ + arch/mips/include/asm/pgtable.h | 2 ++ + arch/mips/loongson64/Platform | 23 +++++++++++++++++++++ + arch/mips/mm/tlbex.c | 10 +++++++++ + 8 files changed, 100 insertions(+) + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index bfb3d8451c0a..0fbd88489c04 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -1400,6 +1400,21 @@ config LOONGSON3_ENHANCEMENT + please say 'N' here. If you want a high-performance kernel to run on + new Loongson 3 machines only, please say 'Y' here. + ++config CPU_LOONGSON3_WORKAROUNDS ++ bool "Old Loongson 3 LLSC Workarounds" ++ default y if SMP ++ depends on CPU_LOONGSON3 ++ help ++ Loongson 3 processors have the llsc issues which require workarounds. ++ Without workarounds the system may hang unexpectedly. ++ ++ Newer Loongson 3 will fix these issues and no workarounds are needed. ++ The workarounds have no significant side effect on them but may ++ decrease the performance of the system so this option should be ++ disabled unless the kernel is intended to be run on old systems. ++ ++ If unsure, please say Y. ++ + config CPU_LOONGSON2E + bool "Loongson 2E" + depends on SYS_HAS_CPU_LOONGSON2E +diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h +index 9e805317847d..1fc6f04e85a1 100644 +--- a/arch/mips/include/asm/atomic.h ++++ b/arch/mips/include/asm/atomic.h +@@ -58,6 +58,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \ + if (kernel_uses_llsc) { \ + int temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %0, %1 # atomic_" #op " \n" \ +@@ -84,6 +85,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \ + if (kernel_uses_llsc) { \ + int temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %1, %2 # atomic_" #op "_return \n" \ +@@ -116,6 +118,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \ + if (kernel_uses_llsc) { \ + int temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %1, %2 # atomic_fetch_" #op " \n" \ +@@ -251,6 +254,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \ + if (kernel_uses_llsc) { \ + long temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %0, %1 # atomic64_" #op " \n" \ +@@ -277,6 +281,7 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \ + if (kernel_uses_llsc) { \ + long temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %1, %2 # atomic64_" #op "_return\n" \ +@@ -309,6 +314,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \ + if (kernel_uses_llsc) { \ + long temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %1, %2 # atomic64_fetch_" #op "\n" \ +diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h +index a5eb1bb199a7..b7f6ac5e513c 100644 +--- a/arch/mips/include/asm/barrier.h ++++ b/arch/mips/include/asm/barrier.h +@@ -222,6 +222,42 @@ + #define __smp_mb__before_atomic() __smp_mb__before_llsc() + #define __smp_mb__after_atomic() smp_llsc_mb() + ++/* ++ * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load, ++ * store or pref) in between an ll & sc can cause the sc instruction to ++ * erroneously succeed, breaking atomicity. Whilst it's unusual to write code ++ * containing such sequences, this bug bites harder than we might otherwise ++ * expect due to reordering & speculation: ++ * ++ * 1) A memory access appearing prior to the ll in program order may actually ++ * be executed after the ll - this is the reordering case. ++ * ++ * In order to avoid this we need to place a memory barrier (ie. a sync ++ * instruction) prior to every ll instruction, in between it & any earlier ++ * memory access instructions. Many of these cases are already covered by ++ * smp_mb__before_llsc() but for the remaining cases, typically ones in ++ * which multiple CPUs may operate on a memory location but ordering is not ++ * usually guaranteed, we use loongson_llsc_mb() below. ++ * ++ * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later. ++ * ++ * 2) If a conditional branch exists between an ll & sc with a target outside ++ * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg() ++ * or similar, then misprediction of the branch may allow speculative ++ * execution of memory accesses from outside of the ll-sc loop. ++ * ++ * In order to avoid this we need a memory barrier (ie. a sync instruction) ++ * at each affected branch target, for which we also use loongson_llsc_mb() ++ * defined below. ++ * ++ * This case affects all current Loongson 3 CPUs. ++ */ ++#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */ ++#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") ++#else ++#define loongson_llsc_mb() do { } while (0) ++#endif ++ + #include + + #endif /* __ASM_BARRIER_H */ +diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h +index da1b8718861e..2a40ecd69ac4 100644 +--- a/arch/mips/include/asm/bitops.h ++++ b/arch/mips/include/asm/bitops.h +@@ -68,6 +68,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) + : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)); + #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) + } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " " __LL "%0, %1 # set_bit \n" +@@ -78,6 +79,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) + } while (unlikely(!temp)); + #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ + } else if (kernel_uses_llsc) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " .set "MIPS_ISA_ARCH_LEVEL" \n" +@@ -120,6 +122,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) + : "ir" (~(1UL << bit))); + #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) + } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " " __LL "%0, %1 # clear_bit \n" +@@ -130,6 +133,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) + } while (unlikely(!temp)); + #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ + } else if (kernel_uses_llsc) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " .set "MIPS_ISA_ARCH_LEVEL" \n" +@@ -188,6 +192,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) + unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); + unsigned long temp; + ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " .set "MIPS_ISA_ARCH_LEVEL" \n" +diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h +index a9e61ea54ca9..0a62a91b592d 100644 +--- a/arch/mips/include/asm/futex.h ++++ b/arch/mips/include/asm/futex.h +@@ -50,6 +50,7 @@ + "i" (-EFAULT) \ + : "memory"); \ + } else if (cpu_has_llsc) { \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ +@@ -162,6 +163,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + "i" (-EFAULT) + : "memory"); + } else if (cpu_has_llsc) { ++ loongson_llsc_mb(); + __asm__ __volatile__( + "# futex_atomic_cmpxchg_inatomic \n" + " .set push \n" +@@ -190,6 +192,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), + "i" (-EFAULT) + : "memory"); ++ loongson_llsc_mb(); + } else + return -ENOSYS; + +diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h +index 129e0328367f..6a35bbf46b93 100644 +--- a/arch/mips/include/asm/pgtable.h ++++ b/arch/mips/include/asm/pgtable.h +@@ -229,6 +229,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) + : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) + : [global] "r" (page_global)); + } else if (kernel_uses_llsc) { ++ loongson_llsc_mb(); + __asm__ __volatile__ ( + " .set "MIPS_ISA_ARCH_LEVEL" \n" + " .set push \n" +@@ -244,6 +245,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) + " .set mips0 \n" + : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) + : [global] "r" (page_global)); ++ loongson_llsc_mb(); + } + #else /* !CONFIG_SMP */ + if (pte_none(*buddy)) +diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform +index 0fce4608aa88..c1a4d4dc4665 100644 +--- a/arch/mips/loongson64/Platform ++++ b/arch/mips/loongson64/Platform +@@ -23,6 +23,29 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS + endif + + cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap ++ ++# ++# Some versions of binutils, not currently mainline as of 2019/02/04, support ++# an -mfix-loongson3-llsc flag which emits a sync prior to each ll instruction ++# to work around a CPU bug (see loongson_llsc_mb() in asm/barrier.h for a ++# description). ++# ++# We disable this in order to prevent the assembler meddling with the ++# instruction that labels refer to, ie. if we label an ll instruction: ++# ++# 1: ll v0, 0(a0) ++# ++# ...then with the assembler fix applied the label may actually point at a sync ++# instruction inserted by the assembler, and if we were using the label in an ++# exception table the table would no longer contain the address of the ll ++# instruction. ++# ++# Avoid this by explicitly disabling that assembler behaviour. If upstream ++# binutils does not merge support for the flag then we can revisit & remove ++# this later - for now it ensures vendor toolchains don't cause problems. ++# ++cflags-$(CONFIG_CPU_LOONGSON3) += $(call as-option,-Wa$(comma)-mno-fix-loongson3-llsc,) ++ + # + # binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a + # as MIPS64 R2; older versions as just R1. This leaves the possibility open +diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c +index 067714291643..64db0400a8be 100644 +--- a/arch/mips/mm/tlbex.c ++++ b/arch/mips/mm/tlbex.c +@@ -931,6 +931,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, + * to mimic that here by taking a load/istream page + * fault. + */ ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(p, 0); + UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0); + uasm_i_jr(p, ptr); + +@@ -1645,6 +1647,8 @@ static void + iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) + { + #ifdef CONFIG_SMP ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(p, 0); + # ifdef CONFIG_PHYS_ADDR_T_64BIT + if (cpu_has_64bits) + uasm_i_lld(p, pte, 0, ptr); +@@ -2258,6 +2262,8 @@ static void build_r4000_tlb_load_handler(void) + #endif + + uasm_l_nopage_tlbl(&l, p); ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(&p, 0); + build_restore_work_registers(&p); + #ifdef CONFIG_CPU_MICROMIPS + if ((unsigned long)tlb_do_page_fault_0 & 1) { +@@ -2312,6 +2318,8 @@ static void build_r4000_tlb_store_handler(void) + #endif + + uasm_l_nopage_tlbs(&l, p); ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(&p, 0); + build_restore_work_registers(&p); + #ifdef CONFIG_CPU_MICROMIPS + if ((unsigned long)tlb_do_page_fault_1 & 1) { +@@ -2367,6 +2375,8 @@ static void build_r4000_tlb_modify_handler(void) + #endif + + uasm_l_nopage_tlbm(&l, p); ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(&p, 0); + build_restore_work_registers(&p); + #ifdef CONFIG_CPU_MICROMIPS + if ((unsigned long)tlb_do_page_fault_1 & 1) { +-- +2.19.1 + diff --git a/queue-4.20/mips-remove-function-size-check-in-get_frame_info.patch b/queue-4.20/mips-remove-function-size-check-in-get_frame_info.patch new file mode 100644 index 00000000000..95c46c591a7 --- /dev/null +++ b/queue-4.20/mips-remove-function-size-check-in-get_frame_info.patch @@ -0,0 +1,64 @@ +From 890edad3fec5ecb478f7fe3e8ad735a798ec4f4e Mon Sep 17 00:00:00 2001 +From: Jun-Ru Chang +Date: Tue, 29 Jan 2019 11:56:07 +0800 +Subject: MIPS: Remove function size check in get_frame_info() + +[ Upstream commit 2b424cfc69728224fcb5fad138ea7260728e0901 ] + +Patch (b6c7a324df37b "MIPS: Fix get_frame_info() handling of +microMIPS function size.") introduces additional function size +check for microMIPS by only checking insn between ip and ip + func_size. +However, func_size in get_frame_info() is always 0 if KALLSYMS is not +enabled. This causes get_frame_info() to return immediately without +calculating correct frame_size, which in turn causes "Can't analyze +schedule() prologue" warning messages at boot time. + +This patch removes func_size check, and let the frame_size check run +up to 128 insns for both MIPS and microMIPS. + +Signed-off-by: Jun-Ru Chang +Signed-off-by: Tony Wu +Signed-off-by: Paul Burton +Fixes: b6c7a324df37b ("MIPS: Fix get_frame_info() handling of microMIPS function size.") +Cc: +Cc: +Cc: +Cc: +Cc: +Cc: +Cc: +Cc: +Signed-off-by: Sasha Levin +--- + arch/mips/kernel/process.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c +index d4f7fd4550e1..85522c137f19 100644 +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -371,7 +371,7 @@ static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size) + static int get_frame_info(struct mips_frame_info *info) + { + bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); +- union mips_instruction insn, *ip, *ip_end; ++ union mips_instruction insn, *ip; + const unsigned int max_insns = 128; + unsigned int last_insn_size = 0; + unsigned int i; +@@ -384,10 +384,9 @@ static int get_frame_info(struct mips_frame_info *info) + if (!ip) + goto err; + +- ip_end = (void *)ip + info->func_size; +- +- for (i = 0; i < max_insns && ip < ip_end; i++) { ++ for (i = 0; i < max_insns; i++) { + ip = (void *)ip + last_insn_size; ++ + if (is_mmips && mm_insn_16bit(ip->halfword[0])) { + insn.word = ip->halfword[0] << 16; + last_insn_size = 2; +-- +2.19.1 + diff --git a/queue-4.20/mm-memory_hotplug-fix-off-by-one-in-is_pageblock_rem.patch b/queue-4.20/mm-memory_hotplug-fix-off-by-one-in-is_pageblock_rem.patch new file mode 100644 index 00000000000..018d3fe8a77 --- /dev/null +++ b/queue-4.20/mm-memory_hotplug-fix-off-by-one-in-is_pageblock_rem.patch @@ -0,0 +1,138 @@ +From 7f571cb07b1318b70a6025edf510e8eae0d8148b Mon Sep 17 00:00:00 2001 +From: Michal Hocko +Date: Wed, 20 Feb 2019 22:20:46 -0800 +Subject: mm, memory_hotplug: fix off-by-one in is_pageblock_removable + +[ Upstream commit 891cb2a72d821f930a39d5900cb7a3aa752c1d5b ] + +Rong Chen has reported the following boot crash: + + PGD 0 P4D 0 + Oops: 0000 [#1] PREEMPT SMP PTI + CPU: 1 PID: 239 Comm: udevd Not tainted 5.0.0-rc4-00149-gefad4e4 #1 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 + RIP: 0010:page_mapping+0x12/0x80 + Code: 5d c3 48 89 df e8 0e ad 02 00 85 c0 75 da 89 e8 5b 5d c3 0f 1f 44 00 00 53 48 89 fb 48 8b 43 08 48 8d 50 ff a8 01 48 0f 45 da <48> 8b 53 08 48 8d 42 ff 83 e2 01 48 0f 44 c3 48 83 38 ff 74 2f 48 + RSP: 0018:ffff88801fa87cd8 EFLAGS: 00010202 + RAX: ffffffffffffffff RBX: fffffffffffffffe RCX: 000000000000000a + RDX: fffffffffffffffe RSI: ffffffff820b9a20 RDI: ffff88801e5c0000 + RBP: 6db6db6db6db6db7 R08: ffff88801e8bb000 R09: 0000000001b64d13 + R10: ffff88801fa87cf8 R11: 0000000000000001 R12: ffff88801e640000 + R13: ffffffff820b9a20 R14: ffff88801f145258 R15: 0000000000000001 + FS: 00007fb2079817c0(0000) GS:ffff88801dd00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000006 CR3: 000000001fa82000 CR4: 00000000000006a0 + Call Trace: + __dump_page+0x14/0x2c0 + is_mem_section_removable+0x24c/0x2c0 + removable_show+0x87/0xa0 + dev_attr_show+0x25/0x60 + sysfs_kf_seq_show+0xba/0x110 + seq_read+0x196/0x3f0 + __vfs_read+0x34/0x180 + vfs_read+0xa0/0x150 + ksys_read+0x44/0xb0 + do_syscall_64+0x5e/0x4a0 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +and bisected it down to commit efad4e475c31 ("mm, memory_hotplug: +is_mem_section_removable do not pass the end of a zone"). + +The reason for the crash is that the mapping is garbage for poisoned +(uninitialized) page. This shouldn't happen as all pages in the zone's +boundary should be initialized. + +Later debugging revealed that the actual problem is an off-by-one when +evaluating the end_page. 'start_pfn + nr_pages' resp 'zone_end_pfn' +refers to a pfn after the range and as such it might belong to a +differen memory section. + +This along with CONFIG_SPARSEMEM then makes the loop condition +completely bogus because a pointer arithmetic doesn't work for pages +from two different sections in that memory model. + +Fix the issue by reworking is_pageblock_removable to be pfn based and +only use struct page where necessary. This makes the code slightly +easier to follow and we will remove the problematic pointer arithmetic +completely. + +Link: http://lkml.kernel.org/r/20190218181544.14616-1-mhocko@kernel.org +Fixes: efad4e475c31 ("mm, memory_hotplug: is_mem_section_removable do not pass the end of a zone") +Signed-off-by: Michal Hocko +Reported-by: +Tested-by: +Acked-by: Mike Rapoport +Reviewed-by: Oscar Salvador +Cc: Matthew Wilcox +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/memory_hotplug.c | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 488aa11495d2..cb201163666f 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1189,11 +1189,13 @@ static inline int pageblock_free(struct page *page) + return PageBuddy(page) && page_order(page) >= pageblock_order; + } + +-/* Return the start of the next active pageblock after a given page */ +-static struct page *next_active_pageblock(struct page *page) ++/* Return the pfn of the start of the next active pageblock after a given pfn */ ++static unsigned long next_active_pageblock(unsigned long pfn) + { ++ struct page *page = pfn_to_page(pfn); ++ + /* Ensure the starting page is pageblock-aligned */ +- BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1)); ++ BUG_ON(pfn & (pageblock_nr_pages - 1)); + + /* If the entire pageblock is free, move to the end of free page */ + if (pageblock_free(page)) { +@@ -1201,16 +1203,16 @@ static struct page *next_active_pageblock(struct page *page) + /* be careful. we don't have locks, page_order can be changed.*/ + order = page_order(page); + if ((order < MAX_ORDER) && (order >= pageblock_order)) +- return page + (1 << order); ++ return pfn + (1 << order); + } + +- return page + pageblock_nr_pages; ++ return pfn + pageblock_nr_pages; + } + +-static bool is_pageblock_removable_nolock(struct page *page) ++static bool is_pageblock_removable_nolock(unsigned long pfn) + { ++ struct page *page = pfn_to_page(pfn); + struct zone *zone; +- unsigned long pfn; + + /* + * We have to be careful here because we are iterating over memory +@@ -1233,13 +1235,14 @@ static bool is_pageblock_removable_nolock(struct page *page) + /* Checks if this range of memory is likely to be hot-removable. */ + bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) + { +- struct page *page = pfn_to_page(start_pfn); +- unsigned long end_pfn = min(start_pfn + nr_pages, zone_end_pfn(page_zone(page))); +- struct page *end_page = pfn_to_page(end_pfn); ++ unsigned long end_pfn, pfn; ++ ++ end_pfn = min(start_pfn + nr_pages, ++ zone_end_pfn(page_zone(pfn_to_page(start_pfn)))); + + /* Check the starting page of each pageblock within the range */ +- for (; page < end_page; page = next_active_pageblock(page)) { +- if (!is_pageblock_removable_nolock(page)) ++ for (pfn = start_pfn; pfn < end_pfn; pfn = next_active_pageblock(pfn)) { ++ if (!is_pageblock_removable_nolock(pfn)) + return false; + cond_resched(); + } +-- +2.19.1 + diff --git a/queue-4.20/mm-memory_hotplug-is_mem_section_removable-do-not-pa.patch b/queue-4.20/mm-memory_hotplug-is_mem_section_removable-do-not-pa.patch new file mode 100644 index 00000000000..5011b198763 --- /dev/null +++ b/queue-4.20/mm-memory_hotplug-is_mem_section_removable-do-not-pa.patch @@ -0,0 +1,90 @@ +From 4ed0c1ae9ea5dfad80c692a0f8dc7991f98d7ba6 Mon Sep 17 00:00:00 2001 +From: Michal Hocko +Date: Fri, 1 Feb 2019 14:20:34 -0800 +Subject: mm, memory_hotplug: is_mem_section_removable do not pass the end of a + zone + +[ Upstream commit efad4e475c312456edb3c789d0996d12ed744c13 ] + +Patch series "mm, memory_hotplug: fix uninitialized pages fallouts", v2. + +Mikhail Zaslonko has posted fixes for the two bugs quite some time ago +[1]. I have pushed back on those fixes because I believed that it is +much better to plug the problem at the initialization time rather than +play whack-a-mole all over the hotplug code and find all the places +which expect the full memory section to be initialized. + +We have ended up with commit 2830bf6f05fb ("mm, memory_hotplug: +initialize struct pages for the full memory section") merged and cause a +regression [2][3]. The reason is that there might be memory layouts +when two NUMA nodes share the same memory section so the merged fix is +simply incorrect. + +In order to plug this hole we really have to be zone range aware in +those handlers. I have split up the original patch into two. One is +unchanged (patch 2) and I took a different approach for `removable' +crash. + +[1] http://lkml.kernel.org/r/20181105150401.97287-2-zaslonko@linux.ibm.com +[2] https://bugzilla.redhat.com/show_bug.cgi?id=1666948 +[3] http://lkml.kernel.org/r/20190125163938.GA20411@dhcp22.suse.cz + +This patch (of 2): + +Mikhail has reported the following VM_BUG_ON triggered when reading sysfs +removable state of a memory block: + + page:000003d08300c000 is uninitialized and poisoned + page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) + Call Trace: + is_mem_section_removable+0xb4/0x190 + show_mem_removable+0x9a/0xd8 + dev_attr_show+0x34/0x70 + sysfs_kf_seq_show+0xc8/0x148 + seq_read+0x204/0x480 + __vfs_read+0x32/0x178 + vfs_read+0x82/0x138 + ksys_read+0x5a/0xb0 + system_call+0xdc/0x2d8 + Last Breaking-Event-Address: + is_mem_section_removable+0xb4/0x190 + Kernel panic - not syncing: Fatal exception: panic_on_oops + +The reason is that the memory block spans the zone boundary and we are +stumbling over an unitialized struct page. Fix this by enforcing zone +range in is_mem_section_removable so that we never run away from a zone. + +Link: http://lkml.kernel.org/r/20190128144506.15603-2-mhocko@kernel.org +Signed-off-by: Michal Hocko +Reported-by: Mikhail Zaslonko +Debugged-by: Mikhail Zaslonko +Tested-by: Gerald Schaefer +Tested-by: Mikhail Gavrilov +Reviewed-by: Oscar Salvador +Cc: Pavel Tatashin +Cc: Heiko Carstens +Cc: Martin Schwidefsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/memory_hotplug.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 21d94b5677e8..5ce0d929ff48 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1234,7 +1234,8 @@ static bool is_pageblock_removable_nolock(struct page *page) + bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) + { + struct page *page = pfn_to_page(start_pfn); +- struct page *end_page = page + nr_pages; ++ unsigned long end_pfn = min(start_pfn + nr_pages, zone_end_pfn(page_zone(page))); ++ struct page *end_page = pfn_to_page(end_pfn); + + /* Check the starting page of each pageblock within the range */ + for (; page < end_page; page = next_active_pageblock(page)) { +-- +2.19.1 + diff --git a/queue-4.20/mm-memory_hotplug-test_pages_in_a_zone-do-not-pass-t.patch b/queue-4.20/mm-memory_hotplug-test_pages_in_a_zone-do-not-pass-t.patch new file mode 100644 index 00000000000..380eb2d50a8 --- /dev/null +++ b/queue-4.20/mm-memory_hotplug-test_pages_in_a_zone-do-not-pass-t.patch @@ -0,0 +1,73 @@ +From 34c5a4b0da382ce8a69b12c2e60297670aee4211 Mon Sep 17 00:00:00 2001 +From: Mikhail Zaslonko +Date: Fri, 1 Feb 2019 14:20:38 -0800 +Subject: mm, memory_hotplug: test_pages_in_a_zone do not pass the end of zone + +[ Upstream commit 24feb47c5fa5b825efb0151f28906dfdad027e61 ] + +If memory end is not aligned with the sparse memory section boundary, +the mapping of such a section is only partly initialized. This may lead +to VM_BUG_ON due to uninitialized struct pages access from +test_pages_in_a_zone() function triggered by memory_hotplug sysfs +handlers. + +Here are the the panic examples: + CONFIG_DEBUG_VM_PGFLAGS=y + kernel parameter mem=2050M + -------------------------- + page:000003d082008000 is uninitialized and poisoned + page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) + Call Trace: + test_pages_in_a_zone+0xde/0x160 + show_valid_zones+0x5c/0x190 + dev_attr_show+0x34/0x70 + sysfs_kf_seq_show+0xc8/0x148 + seq_read+0x204/0x480 + __vfs_read+0x32/0x178 + vfs_read+0x82/0x138 + ksys_read+0x5a/0xb0 + system_call+0xdc/0x2d8 + Last Breaking-Event-Address: + test_pages_in_a_zone+0xde/0x160 + Kernel panic - not syncing: Fatal exception: panic_on_oops + +Fix this by checking whether the pfn to check is within the zone. + +[mhocko@suse.com: separated this change from http://lkml.kernel.org/r/20181105150401.97287-2-zaslonko@linux.ibm.com] +Link: http://lkml.kernel.org/r/20190128144506.15603-3-mhocko@kernel.org + +[mhocko@suse.com: separated this change from +http://lkml.kernel.org/r/20181105150401.97287-2-zaslonko@linux.ibm.com] +Signed-off-by: Michal Hocko +Signed-off-by: Mikhail Zaslonko +Tested-by: Mikhail Gavrilov +Reviewed-by: Oscar Salvador +Tested-by: Gerald Schaefer +Cc: Heiko Carstens +Cc: Martin Schwidefsky +Cc: Mikhail Gavrilov +Cc: Pavel Tatashin +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/memory_hotplug.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 5ce0d929ff48..488aa11495d2 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1275,6 +1275,9 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, + i++; + if (i == MAX_ORDER_NR_PAGES || pfn + i >= end_pfn) + continue; ++ /* Check if we got outside of the zone */ ++ if (zone && !zone_spans_pfn(zone, pfn + i)) ++ return 0; + page = pfn_to_page(pfn + i); + if (zone && page_zone(page) != zone) + return 0; +-- +2.19.1 + diff --git a/queue-4.20/net-altera_tse-fix-msgdma_tx_completion-on-non-zero-.patch b/queue-4.20/net-altera_tse-fix-msgdma_tx_completion-on-non-zero-.patch new file mode 100644 index 00000000000..7cc60dcc942 --- /dev/null +++ b/queue-4.20/net-altera_tse-fix-msgdma_tx_completion-on-non-zero-.patch @@ -0,0 +1,40 @@ +From 0c5544e3ccdf614521928f8f6959ca6c06fe7463 Mon Sep 17 00:00:00 2001 +From: Tomonori Sakita +Date: Fri, 25 Jan 2019 11:02:22 +0900 +Subject: net: altera_tse: fix msgdma_tx_completion on non-zero fill_level case + +[ Upstream commit 6571ebce112a21ec9be68ef2f53b96fcd41fd81b ] + +If fill_level was not zero and status was not BUSY, +result of "tx_prod - tx_cons - inuse" might be zero. +Subtracting 1 unconditionally results invalid negative return value +on this case. +Make sure not to return an negative value. + +Signed-off-by: Tomonori Sakita +Signed-off-by: Atsushi Nemoto +Reviewed-by: Dalon L Westergreen +Acked-by: Thor Thayer +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/altera/altera_msgdma.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c +index 0fb986ba3290..0ae723f75341 100644 +--- a/drivers/net/ethernet/altera/altera_msgdma.c ++++ b/drivers/net/ethernet/altera/altera_msgdma.c +@@ -145,7 +145,8 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv) + & 0xffff; + + if (inuse) { /* Tx FIFO is not empty */ +- ready = priv->tx_prod - priv->tx_cons - inuse - 1; ++ ready = max_t(int, ++ priv->tx_prod - priv->tx_cons - inuse - 1, 0); + } else { + /* Check for buffered last packet */ + status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status)); +-- +2.19.1 + diff --git a/queue-4.20/net-hns-fix-for-missing-of_node_put-after-of_parse_p.patch b/queue-4.20/net-hns-fix-for-missing-of_node_put-after-of_parse_p.patch new file mode 100644 index 00000000000..7757ff53f67 --- /dev/null +++ b/queue-4.20/net-hns-fix-for-missing-of_node_put-after-of_parse_p.patch @@ -0,0 +1,51 @@ +From 3d39497f85d2a43c2d43a1d5e45dc85353008662 Mon Sep 17 00:00:00 2001 +From: Yonglong Liu +Date: Sat, 26 Jan 2019 17:18:25 +0800 +Subject: net: hns: Fix for missing of_node_put() after of_parse_phandle() + +[ Upstream commit 263c6d75f9a544a3c2f8f6a26de4f4808d8f59cf ] + +In hns enet driver, we use of_parse_handle() to get hold of the +device node related to "ae-handle" but we have missed to put +the node reference using of_node_put() after we are done using +the node. This patch fixes it. + +Note: +This problem is stated in Link: https://lkml.org/lkml/2018/12/22/217 + +Fixes: 48189d6aaf1e ("net: hns: enet specifies a reference to dsaf") +Reported-by: Alexey Khoroshilov +Signed-off-by: Yonglong Liu +Signed-off-by: Peng Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns/hns_enet.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +index 6242249c9f4c..b043370c2685 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +@@ -2419,6 +2419,8 @@ static int hns_nic_dev_probe(struct platform_device *pdev) + out_notify_fail: + (void)cancel_work_sync(&priv->service_task); + out_read_prop_fail: ++ /* safe for ACPI FW */ ++ of_node_put(to_of_node(priv->fwnode)); + free_netdev(ndev); + return ret; + } +@@ -2448,6 +2450,9 @@ static int hns_nic_dev_remove(struct platform_device *pdev) + set_bit(NIC_STATE_REMOVING, &priv->state); + (void)cancel_work_sync(&priv->service_task); + ++ /* safe for ACPI FW */ ++ of_node_put(to_of_node(priv->fwnode)); ++ + free_netdev(ndev); + return 0; + } +-- +2.19.1 + diff --git a/queue-4.20/net-hns-fix-wrong-read-accesses-via-clause-45-mdio-p.patch b/queue-4.20/net-hns-fix-wrong-read-accesses-via-clause-45-mdio-p.patch new file mode 100644 index 00000000000..21582fd6c65 --- /dev/null +++ b/queue-4.20/net-hns-fix-wrong-read-accesses-via-clause-45-mdio-p.patch @@ -0,0 +1,35 @@ +From cac90af55dc2a4eb9a9292fc43465b2ed5d20e85 Mon Sep 17 00:00:00 2001 +From: Yonglong Liu +Date: Sat, 26 Jan 2019 17:18:27 +0800 +Subject: net: hns: Fix wrong read accesses via Clause 45 MDIO protocol + +[ Upstream commit cec8abba13e6a26729dfed41019720068eeeff2b ] + +When reading phy registers via Clause 45 MDIO protocol, after write +address operation, the driver use another write address operation, so +can not read the right value of any phy registers. This patch fixes it. + +Signed-off-by: Yonglong Liu +Signed-off-by: Peng Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns_mdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c b/drivers/net/ethernet/hisilicon/hns_mdio.c +index 017e08452d8c..baf5cc251f32 100644 +--- a/drivers/net/ethernet/hisilicon/hns_mdio.c ++++ b/drivers/net/ethernet/hisilicon/hns_mdio.c +@@ -321,7 +321,7 @@ static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum) + } + + hns_mdio_cmd_write(mdio_dev, is_c45, +- MDIO_C45_WRITE_ADDR, phy_id, devad); ++ MDIO_C45_READ, phy_id, devad); + } + + /* Step 5: waitting for MDIO_COMMAND_REG 's mdio_start==0,*/ +-- +2.19.1 + diff --git a/queue-4.20/net-hns-restart-autoneg-need-return-failed-when-auto.patch b/queue-4.20/net-hns-restart-autoneg-need-return-failed-when-auto.patch new file mode 100644 index 00000000000..15753d0c5c5 --- /dev/null +++ b/queue-4.20/net-hns-restart-autoneg-need-return-failed-when-auto.patch @@ -0,0 +1,52 @@ +From 45c8d20ca17d488230ff36a896fa369243acfc8b Mon Sep 17 00:00:00 2001 +From: Yonglong Liu +Date: Sat, 26 Jan 2019 17:18:26 +0800 +Subject: net: hns: Restart autoneg need return failed when autoneg off + +[ Upstream commit ed29ca8b9592562559c64d027fb5eb126e463e2c ] + +The hns driver of earlier devices, when autoneg off, restart autoneg +will return -EINVAL, so make the hns driver for the latest devices +do the same. + +Signed-off-by: Yonglong Liu +Signed-off-by: Peng Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +index 774beda040a1..e2710ff48fb0 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +@@ -1157,16 +1157,18 @@ static int hns_get_regs_len(struct net_device *net_dev) + */ + static int hns_nic_nway_reset(struct net_device *netdev) + { +- int ret = 0; + struct phy_device *phy = netdev->phydev; + +- if (netif_running(netdev)) { +- /* if autoneg is disabled, don't restart auto-negotiation */ +- if (phy && phy->autoneg == AUTONEG_ENABLE) +- ret = genphy_restart_aneg(phy); +- } ++ if (!netif_running(netdev)) ++ return 0; + +- return ret; ++ if (!phy) ++ return -EOPNOTSUPP; ++ ++ if (phy->autoneg != AUTONEG_ENABLE) ++ return -EINVAL; ++ ++ return genphy_restart_aneg(phy); + } + + static u32 +-- +2.19.1 + diff --git a/queue-4.20/net-macb-apply-rxubr-workaround-only-to-versions-wit.patch b/queue-4.20/net-macb-apply-rxubr-workaround-only-to-versions-wit.patch new file mode 100644 index 00000000000..65cb1f710f3 --- /dev/null +++ b/queue-4.20/net-macb-apply-rxubr-workaround-only-to-versions-wit.patch @@ -0,0 +1,155 @@ +From d60db81221394e63787a95e1ef3013105c419314 Mon Sep 17 00:00:00 2001 +From: Harini Katakam +Date: Tue, 29 Jan 2019 15:20:03 +0530 +Subject: net: macb: Apply RXUBR workaround only to versions with errata + +[ Upstream commit e501070e4db0b67a4c17a5557d1e9d098f3db310 ] + +The interrupt handler contains a workaround for RX hang applicable +to Zynq and AT91RM9200 only. Subsequent versions do not need this +workaround. This workaround unnecessarily resets RX whenever RX used +bit read is observed, which can be often under heavy traffic. There +is no other action performed on RX UBR interrupt. Hence introduce a +CAPS mask; enable this interrupt and workaround only on affected +versions. + +Signed-off-by: Harini Katakam +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cadence/macb.h | 3 +++ + drivers/net/ethernet/cadence/macb_main.c | 28 ++++++++++++++---------- + 2 files changed, 20 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index 3d45f4c92cf6..9bbaad9f3d63 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -643,6 +643,7 @@ + #define MACB_CAPS_JUMBO 0x00000020 + #define MACB_CAPS_GEM_HAS_PTP 0x00000040 + #define MACB_CAPS_BD_RD_PREFETCH 0x00000080 ++#define MACB_CAPS_NEEDS_RSTONUBR 0x00000100 + #define MACB_CAPS_FIFO_MODE 0x10000000 + #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 + #define MACB_CAPS_SG_DISABLED 0x40000000 +@@ -1214,6 +1215,8 @@ struct macb { + + int rx_bd_rd_prefetch; + int tx_bd_rd_prefetch; ++ ++ u32 rx_intr_mask; + }; + + #ifdef CONFIG_MACB_USE_HWSTAMP +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 4c816e5a841f..73aa7969db96 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -56,8 +56,7 @@ + /* level of occupied TX descriptors under which we wake up TX process */ + #define MACB_TX_WAKEUP_THRESH(bp) (3 * (bp)->tx_ring_size / 4) + +-#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ +- | MACB_BIT(ISR_ROVR)) ++#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(ISR_ROVR)) + #define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \ + | MACB_BIT(ISR_RLE) \ + | MACB_BIT(TXERR)) +@@ -1270,7 +1269,7 @@ static int macb_poll(struct napi_struct *napi, int budget) + queue_writel(queue, ISR, MACB_BIT(RCOMP)); + napi_reschedule(napi); + } else { +- queue_writel(queue, IER, MACB_RX_INT_FLAGS); ++ queue_writel(queue, IER, bp->rx_intr_mask); + } + } + +@@ -1288,7 +1287,7 @@ static void macb_hresp_error_task(unsigned long data) + u32 ctrl; + + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { +- queue_writel(queue, IDR, MACB_RX_INT_FLAGS | ++ queue_writel(queue, IDR, bp->rx_intr_mask | + MACB_TX_INT_FLAGS | + MACB_BIT(HRESP)); + } +@@ -1318,7 +1317,7 @@ static void macb_hresp_error_task(unsigned long data) + + /* Enable interrupts */ + queue_writel(queue, IER, +- MACB_RX_INT_FLAGS | ++ bp->rx_intr_mask | + MACB_TX_INT_FLAGS | + MACB_BIT(HRESP)); + } +@@ -1372,14 +1371,14 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) + (unsigned int)(queue - bp->queues), + (unsigned long)status); + +- if (status & MACB_RX_INT_FLAGS) { ++ if (status & bp->rx_intr_mask) { + /* There's no point taking any more interrupts + * until we have processed the buffers. The + * scheduling call may fail if the poll routine + * is already scheduled, so disable interrupts + * now. + */ +- queue_writel(queue, IDR, MACB_RX_INT_FLAGS); ++ queue_writel(queue, IDR, bp->rx_intr_mask); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(RCOMP)); + +@@ -1412,8 +1411,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) + /* There is a hardware issue under heavy load where DMA can + * stop, this causes endless "used buffer descriptor read" + * interrupts but it can be cleared by re-enabling RX. See +- * the at91 manual, section 41.3.1 or the Zynq manual +- * section 16.7.4 for details. ++ * the at91rm9200 manual, section 41.3.1 or the Zynq manual ++ * section 16.7.4 for details. RXUBR is only enabled for ++ * these two versions. + */ + if (status & MACB_BIT(RXUBR)) { + ctrl = macb_readl(bp, NCR); +@@ -2263,7 +2263,7 @@ static void macb_init_hw(struct macb *bp) + + /* Enable interrupts */ + queue_writel(queue, IER, +- MACB_RX_INT_FLAGS | ++ bp->rx_intr_mask | + MACB_TX_INT_FLAGS | + MACB_BIT(HRESP)); + } +@@ -3911,6 +3911,7 @@ static const struct macb_config sama5d4_config = { + }; + + static const struct macb_config emac_config = { ++ .caps = MACB_CAPS_NEEDS_RSTONUBR, + .clk_init = at91ether_clk_init, + .init = at91ether_init, + }; +@@ -3932,7 +3933,8 @@ static const struct macb_config zynqmp_config = { + }; + + static const struct macb_config zynq_config = { +- .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_NO_GIGABIT_HALF, ++ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_NO_GIGABIT_HALF | ++ MACB_CAPS_NEEDS_RSTONUBR, + .dma_burst_length = 16, + .clk_init = macb_clk_init, + .init = macb_init, +@@ -4087,6 +4089,10 @@ static int macb_probe(struct platform_device *pdev) + macb_dma_desc_get_size(bp); + } + ++ bp->rx_intr_mask = MACB_RX_INT_FLAGS; ++ if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR) ++ bp->rx_intr_mask |= MACB_BIT(RXUBR); ++ + mac = of_get_mac_address(np); + if (mac) { + ether_addr_copy(bp->dev->dev_addr, mac); +-- +2.19.1 + diff --git a/queue-4.20/net-stmmac-disable-eee-mode-earlier-in-xmit-callback.patch b/queue-4.20/net-stmmac-disable-eee-mode-earlier-in-xmit-callback.patch new file mode 100644 index 00000000000..8e7013c2b70 --- /dev/null +++ b/queue-4.20/net-stmmac-disable-eee-mode-earlier-in-xmit-callback.patch @@ -0,0 +1,51 @@ +From 37445634bf865d82e2855b884d94d957944f7af6 Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Wed, 30 Jan 2019 15:54:21 +0100 +Subject: net: stmmac: Disable EEE mode earlier in XMIT callback + +[ Upstream commit e2cd682deb231ba6f80524bb84e57e7138261149 ] + +In stmmac xmit callback we use a different flow for TSO packets but TSO +xmit callback is not disabling the EEE mode. + +Fix this by disabling earlier the EEE mode, i.e. before calling the TSO +xmit callback. + +Signed-off-by: Jose Abreu +Cc: Joao Pinto +Cc: David S. Miller +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index f76f6ae3fa87..9340526d2a9a 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -3031,6 +3031,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) + + tx_q = &priv->tx_queue[queue]; + ++ if (priv->tx_path_in_lpi_mode) ++ stmmac_disable_eee_mode(priv); ++ + /* Manage oversized TCP frames for GMAC4 device */ + if (skb_is_gso(skb) && priv->tso) { + if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { +@@ -3058,9 +3061,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_BUSY; + } + +- if (priv->tx_path_in_lpi_mode) +- stmmac_disable_eee_mode(priv); +- + entry = tx_q->cur_tx; + first_entry = entry; + WARN_ON(tx_q->tx_skbuff[first_entry]); +-- +2.19.1 + diff --git a/queue-4.20/net-stmmac-dwmac-rk-fix-error-handling-in-rk_gmac_po.patch b/queue-4.20/net-stmmac-dwmac-rk-fix-error-handling-in-rk_gmac_po.patch new file mode 100644 index 00000000000..3076c192db9 --- /dev/null +++ b/queue-4.20/net-stmmac-dwmac-rk-fix-error-handling-in-rk_gmac_po.patch @@ -0,0 +1,37 @@ +From db82647d8511c007598ce9857853b95c287131dd Mon Sep 17 00:00:00 2001 +From: Alexey Khoroshilov +Date: Sat, 26 Jan 2019 22:48:57 +0300 +Subject: net: stmmac: dwmac-rk: fix error handling in rk_gmac_powerup() + +[ Upstream commit c69c29a1a0a8f68cd87e98ba4a5a79fb8ef2a58c ] + +If phy_power_on() fails in rk_gmac_powerup(), clocks are left enabled. + +Found by Linux Driver Verification project (linuxtesting.org). + +Signed-off-by: Alexey Khoroshilov +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +index 7b923362ee55..3b174eae77c1 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -1342,8 +1342,10 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) + } + + ret = phy_power_on(bsp_priv, true); +- if (ret) ++ if (ret) { ++ gmac_clk_enable(bsp_priv, false); + return ret; ++ } + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); +-- +2.19.1 + diff --git a/queue-4.20/net-stmmac-fallback-to-platform-data-clock-in-watchd.patch b/queue-4.20/net-stmmac-fallback-to-platform-data-clock-in-watchd.patch new file mode 100644 index 00000000000..a6a4d40f236 --- /dev/null +++ b/queue-4.20/net-stmmac-fallback-to-platform-data-clock-in-watchd.patch @@ -0,0 +1,71 @@ +From 9f27ec4f2fa03545da6bbaa44e99253f1b29639e Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Wed, 30 Jan 2019 15:54:19 +0100 +Subject: net: stmmac: Fallback to Platform Data clock in Watchdog conversion + +[ Upstream commit 4ec5302fa906ec9d86597b236f62315bacdb9622 ] + +If we don't have DT then stmmac_clk will not be available. Let's add a +new Platform Data field so that we can specify the refclk by this mean. + +This way we can still use the coalesce command in PCI based setups. + +Signed-off-by: Jose Abreu +Cc: Joao Pinto +Cc: David S. Miller +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 14 ++++++++++---- + include/linux/stmmac.h | 1 + + 2 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index 9caf79ba5ef1..4d5fb4b51cc4 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -719,8 +719,11 @@ static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv) + { + unsigned long clk = clk_get_rate(priv->plat->stmmac_clk); + +- if (!clk) +- return 0; ++ if (!clk) { ++ clk = priv->plat->clk_ref_rate; ++ if (!clk) ++ return 0; ++ } + + return (usec * (clk / 1000000)) / 256; + } +@@ -729,8 +732,11 @@ static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv) + { + unsigned long clk = clk_get_rate(priv->plat->stmmac_clk); + +- if (!clk) +- return 0; ++ if (!clk) { ++ clk = priv->plat->clk_ref_rate; ++ if (!clk) ++ return 0; ++ } + + return (riwt * 256) / (clk / 1000000); + } +diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h +index 7ddfc65586b0..4335bd771ce5 100644 +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -184,6 +184,7 @@ struct plat_stmmacenet_data { + struct clk *pclk; + struct clk *clk_ptp_ref; + unsigned int clk_ptp_rate; ++ unsigned int clk_ref_rate; + struct reset_control *stmmac_rst; + struct stmmac_axi *axi; + int has_gmac4; +-- +2.19.1 + diff --git a/queue-4.20/net-stmmac-send-tso-packets-always-from-queue-0.patch b/queue-4.20/net-stmmac-send-tso-packets-always-from-queue-0.patch new file mode 100644 index 00000000000..1a1993749ae --- /dev/null +++ b/queue-4.20/net-stmmac-send-tso-packets-always-from-queue-0.patch @@ -0,0 +1,51 @@ +From efd9a8d9741fdcb5501ae7a0a6a516c797d323b4 Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Wed, 30 Jan 2019 15:54:20 +0100 +Subject: net: stmmac: Send TSO packets always from Queue 0 + +[ Upstream commit c5acdbee22a1b200dde07effd26fd1f649e9ab8a ] + +The number of TSO enabled channels in HW can be different than the +number of total channels. There is no way to determined, at runtime, the +number of TSO capable channels and its safe to assume that if TSO is +enabled then at least channel 0 will be TSO capable. + +Lets always send TSO packets from Queue 0. + +Signed-off-by: Jose Abreu +Cc: Joao Pinto +Cc: David S. Miller +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 5d83d6a7694b..f76f6ae3fa87 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -3033,8 +3033,17 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) + + /* Manage oversized TCP frames for GMAC4 device */ + if (skb_is_gso(skb) && priv->tso) { +- if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) ++ if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { ++ /* ++ * There is no way to determine the number of TSO ++ * capable Queues. Let's use always the Queue 0 ++ * because if TSO is supported then at least this ++ * one will be capable. ++ */ ++ skb_set_queue_mapping(skb, 0); ++ + return stmmac_tso_xmit(skb, dev); ++ } + } + + if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) { +-- +2.19.1 + diff --git a/queue-4.20/netfilter-ebtables-compat-un-break-32bit-setsockopt-.patch b/queue-4.20/netfilter-ebtables-compat-un-break-32bit-setsockopt-.patch new file mode 100644 index 00000000000..24149ff1e96 --- /dev/null +++ b/queue-4.20/netfilter-ebtables-compat-un-break-32bit-setsockopt-.patch @@ -0,0 +1,49 @@ +From 2f7f11e098125e6dc37dfa2fce7545808e8e2f66 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 21 Jan 2019 21:54:36 +0100 +Subject: netfilter: ebtables: compat: un-break 32bit setsockopt when no rules + are present + +[ Upstream commit 2035f3ff8eaa29cfb5c8e2160b0f6e85eeb21a95 ] + +Unlike ip(6)tables ebtables only counts user-defined chains. + +The effect is that a 32bit ebtables binary on a 64bit kernel can do +'ebtables -N FOO' only after adding at least one rule, else the request +fails with -EINVAL. + +This is a similar fix as done in +3f1e53abff84 ("netfilter: ebtables: don't attempt to allocate 0-sized compat array"). + +Fixes: 7d7d7e02111e9 ("netfilter: compat: reject huge allocation requests") +Reported-by: Francesco Ruggeri +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/bridge/netfilter/ebtables.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c +index 5e55cef0cec3..6693e209efe8 100644 +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -2293,9 +2293,12 @@ static int compat_do_replace(struct net *net, void __user *user, + + xt_compat_lock(NFPROTO_BRIDGE); + +- ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries); +- if (ret < 0) +- goto out_unlock; ++ if (tmp.nentries) { ++ ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries); ++ if (ret < 0) ++ goto out_unlock; ++ } ++ + ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); + if (ret < 0) + goto out_unlock; +-- +2.19.1 + diff --git a/queue-4.20/netfilter-nf_nat-skip-nat-clash-resolution-for-same-.patch b/queue-4.20/netfilter-nf_nat-skip-nat-clash-resolution-for-same-.patch new file mode 100644 index 00000000000..5d5219ed356 --- /dev/null +++ b/queue-4.20/netfilter-nf_nat-skip-nat-clash-resolution-for-same-.patch @@ -0,0 +1,71 @@ +From fb7ca02f3dad2cf653d20dcc9c397120a3741551 Mon Sep 17 00:00:00 2001 +From: Martynas Pumputis +Date: Tue, 29 Jan 2019 15:51:42 +0100 +Subject: netfilter: nf_nat: skip nat clash resolution for same-origin entries + +[ Upstream commit 4e35c1cb9460240e983a01745b5f29fe3a4d8e39 ] + +It is possible that two concurrent packets originating from the same +socket of a connection-less protocol (e.g. UDP) can end up having +different IP_CT_DIR_REPLY tuples which results in one of the packets +being dropped. + +To illustrate this, consider the following simplified scenario: + +1. Packet A and B are sent at the same time from two different threads + by same UDP socket. No matching conntrack entry exists yet. + Both packets cause allocation of a new conntrack entry. +2. get_unique_tuple gets called for A. No clashing entry found. + conntrack entry for A is added to main conntrack table. +3. get_unique_tuple is called for B and will find that the reply + tuple of B is already taken by A. + It will allocate a new UDP source port for B to resolve the clash. +4. conntrack entry for B cannot be added to main conntrack table + because its ORIGINAL direction is clashing with A and the REPLY + directions of A and B are not the same anymore due to UDP source + port reallocation done in step 3. + +This patch modifies nf_conntrack_tuple_taken so it doesn't consider +colliding reply tuples if the IP_CT_DIR_ORIGINAL tuples are equal. + +[ Florian: simplify patch to not use .allow_clash setting + and always ignore identical flows ] + +Signed-off-by: Martynas Pumputis +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_core.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index e92e749aff53..830b1328fe97 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -1007,6 +1007,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, + } + + if (nf_ct_key_equal(h, tuple, zone, net)) { ++ /* Tuple is taken already, so caller will need to find ++ * a new source port to use. ++ * ++ * Only exception: ++ * If the *original tuples* are identical, then both ++ * conntracks refer to the same flow. ++ * This is a rare situation, it can occur e.g. when ++ * more than one UDP packet is sent from same socket ++ * in different threads. ++ * ++ * Let nf_ct_resolve_clash() deal with this later. ++ */ ++ if (nf_ct_tuple_equal(&ignored_conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple, ++ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)) ++ continue; ++ + NF_CT_STAT_INC_ATOMIC(net, found); + rcu_read_unlock(); + return 1; +-- +2.19.1 + diff --git a/queue-4.20/netfilter-nf_tables-unbind-set-in-rule-from-commit-p.patch b/queue-4.20/netfilter-nf_tables-unbind-set-in-rule-from-commit-p.patch new file mode 100644 index 00000000000..eba163a8bc7 --- /dev/null +++ b/queue-4.20/netfilter-nf_tables-unbind-set-in-rule-from-commit-p.patch @@ -0,0 +1,450 @@ +From ca93049b5a26469d7d65df9bbf15ac71213ca801 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Sat, 2 Feb 2019 10:49:13 +0100 +Subject: netfilter: nf_tables: unbind set in rule from commit path + +[ Upstream commit f6ac8585897684374a19863fff21186a05805286 ] + +Anonymous sets that are bound to rules from the same transaction trigger +a kernel splat from the abort path due to double set list removal and +double free. + +This patch updates the logic to search for the transaction that is +responsible for creating the set and disable the set list removal and +release, given the rule is now responsible for this. Lookup is reverse +since the transaction that adds the set is likely to be at the tail of +the list. + +Moreover, this patch adds the unbind step to deliver the event from the +commit path. This should not be done from the worker thread, since we +have no guarantees of in-order delivery to the listener. + +This patch removes the assumption that both activate and deactivate +callbacks need to be provided. + +Fixes: cd5125d8f518 ("netfilter: nf_tables: split set destruction in deactivate and destroy phase") +Reported-by: Mikhail Morfikov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 17 +++++-- + net/netfilter/nf_tables_api.c | 85 +++++++++++++++---------------- + net/netfilter/nft_compat.c | 6 ++- + net/netfilter/nft_dynset.c | 18 +++---- + net/netfilter/nft_immediate.c | 6 ++- + net/netfilter/nft_lookup.c | 18 +++---- + net/netfilter/nft_objref.c | 18 +++---- + 7 files changed, 85 insertions(+), 83 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 841835a387e1..b4984bbbe157 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -469,9 +469,7 @@ struct nft_set_binding { + int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, + struct nft_set_binding *binding); + void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, +- struct nft_set_binding *binding); +-void nf_tables_rebind_set(const struct nft_ctx *ctx, struct nft_set *set, +- struct nft_set_binding *binding); ++ struct nft_set_binding *binding, bool commit); + void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set); + + /** +@@ -721,6 +719,13 @@ struct nft_expr_type { + #define NFT_EXPR_STATEFUL 0x1 + #define NFT_EXPR_GC 0x2 + ++enum nft_trans_phase { ++ NFT_TRANS_PREPARE, ++ NFT_TRANS_ABORT, ++ NFT_TRANS_COMMIT, ++ NFT_TRANS_RELEASE ++}; ++ + /** + * struct nft_expr_ops - nf_tables expression operations + * +@@ -750,7 +755,8 @@ struct nft_expr_ops { + void (*activate)(const struct nft_ctx *ctx, + const struct nft_expr *expr); + void (*deactivate)(const struct nft_ctx *ctx, +- const struct nft_expr *expr); ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase); + void (*destroy)(const struct nft_ctx *ctx, + const struct nft_expr *expr); + void (*destroy_clone)(const struct nft_ctx *ctx, +@@ -1323,12 +1329,15 @@ struct nft_trans_rule { + struct nft_trans_set { + struct nft_set *set; + u32 set_id; ++ bool bound; + }; + + #define nft_trans_set(trans) \ + (((struct nft_trans_set *)trans->data)->set) + #define nft_trans_set_id(trans) \ + (((struct nft_trans_set *)trans->data)->set_id) ++#define nft_trans_set_bound(trans) \ ++ (((struct nft_trans_set *)trans->data)->bound) + + struct nft_trans_chain { + bool update; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 5114a0d2a41e..36d4717fee3b 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -116,6 +116,23 @@ static void nft_trans_destroy(struct nft_trans *trans) + kfree(trans); + } + ++static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set) ++{ ++ struct net *net = ctx->net; ++ struct nft_trans *trans; ++ ++ if (!nft_set_is_anonymous(set)) ++ return; ++ ++ list_for_each_entry_reverse(trans, &net->nft.commit_list, list) { ++ if (trans->msg_type == NFT_MSG_NEWSET && ++ nft_trans_set(trans) == set) { ++ nft_trans_set_bound(trans) = true; ++ break; ++ } ++ } ++} ++ + static int nf_tables_register_hook(struct net *net, + const struct nft_table *table, + struct nft_chain *chain) +@@ -211,18 +228,6 @@ static int nft_delchain(struct nft_ctx *ctx) + return err; + } + +-/* either expr ops provide both activate/deactivate, or neither */ +-static bool nft_expr_check_ops(const struct nft_expr_ops *ops) +-{ +- if (!ops) +- return true; +- +- if (WARN_ON_ONCE((!ops->activate ^ !ops->deactivate))) +- return false; +- +- return true; +-} +- + static void nft_rule_expr_activate(const struct nft_ctx *ctx, + struct nft_rule *rule) + { +@@ -238,14 +243,15 @@ static void nft_rule_expr_activate(const struct nft_ctx *ctx, + } + + static void nft_rule_expr_deactivate(const struct nft_ctx *ctx, +- struct nft_rule *rule) ++ struct nft_rule *rule, ++ enum nft_trans_phase phase) + { + struct nft_expr *expr; + + expr = nft_expr_first(rule); + while (expr != nft_expr_last(rule) && expr->ops) { + if (expr->ops->deactivate) +- expr->ops->deactivate(ctx, expr); ++ expr->ops->deactivate(ctx, expr, phase); + + expr = nft_expr_next(expr); + } +@@ -296,7 +302,7 @@ static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule) + nft_trans_destroy(trans); + return err; + } +- nft_rule_expr_deactivate(ctx, rule); ++ nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_PREPARE); + + return 0; + } +@@ -1932,9 +1938,6 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, + */ + int nft_register_expr(struct nft_expr_type *type) + { +- if (!nft_expr_check_ops(type->ops)) +- return -EINVAL; +- + nfnl_lock(NFNL_SUBSYS_NFTABLES); + if (type->family == NFPROTO_UNSPEC) + list_add_tail_rcu(&type->list, &nf_tables_expressions); +@@ -2082,10 +2085,6 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx, + err = PTR_ERR(ops); + goto err1; + } +- if (!nft_expr_check_ops(ops)) { +- err = -EINVAL; +- goto err1; +- } + } else + ops = type->ops; + +@@ -2482,7 +2481,7 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx, + static void nf_tables_rule_release(const struct nft_ctx *ctx, + struct nft_rule *rule) + { +- nft_rule_expr_deactivate(ctx, rule); ++ nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE); + nf_tables_rule_destroy(ctx, rule); + } + +@@ -3679,39 +3678,30 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, + bind: + binding->chain = ctx->chain; + list_add_tail_rcu(&binding->list, &set->bindings); ++ nft_set_trans_bind(ctx, set); ++ + return 0; + } + EXPORT_SYMBOL_GPL(nf_tables_bind_set); + +-void nf_tables_rebind_set(const struct nft_ctx *ctx, struct nft_set *set, +- struct nft_set_binding *binding) +-{ +- if (list_empty(&set->bindings) && nft_set_is_anonymous(set) && +- nft_is_active(ctx->net, set)) +- list_add_tail_rcu(&set->list, &ctx->table->sets); +- +- list_add_tail_rcu(&binding->list, &set->bindings); +-} +-EXPORT_SYMBOL_GPL(nf_tables_rebind_set); +- + void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, +- struct nft_set_binding *binding) ++ struct nft_set_binding *binding, bool event) + { + list_del_rcu(&binding->list); + +- if (list_empty(&set->bindings) && nft_set_is_anonymous(set) && +- nft_is_active(ctx->net, set)) ++ if (list_empty(&set->bindings) && nft_set_is_anonymous(set)) { + list_del_rcu(&set->list); ++ if (event) ++ nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, ++ GFP_KERNEL); ++ } + } + EXPORT_SYMBOL_GPL(nf_tables_unbind_set); + + void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set) + { +- if (list_empty(&set->bindings) && nft_set_is_anonymous(set) && +- nft_is_active(ctx->net, set)) { +- nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC); ++ if (list_empty(&set->bindings) && nft_set_is_anonymous(set)) + nft_set_destroy(set); +- } + } + EXPORT_SYMBOL_GPL(nf_tables_destroy_set); + +@@ -6504,6 +6494,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + nf_tables_rule_notify(&trans->ctx, + nft_trans_rule(trans), + NFT_MSG_DELRULE); ++ nft_rule_expr_deactivate(&trans->ctx, ++ nft_trans_rule(trans), ++ NFT_TRANS_COMMIT); + break; + case NFT_MSG_NEWSET: + nft_clear(net, nft_trans_set(trans)); +@@ -6590,7 +6583,8 @@ static void nf_tables_abort_release(struct nft_trans *trans) + nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); + break; + case NFT_MSG_NEWSET: +- nft_set_destroy(nft_trans_set(trans)); ++ if (!nft_trans_set_bound(trans)) ++ nft_set_destroy(nft_trans_set(trans)); + break; + case NFT_MSG_NEWSETELEM: + nft_set_elem_destroy(nft_trans_elem_set(trans), +@@ -6651,7 +6645,9 @@ static int __nf_tables_abort(struct net *net) + case NFT_MSG_NEWRULE: + trans->ctx.chain->use--; + list_del_rcu(&nft_trans_rule(trans)->list); +- nft_rule_expr_deactivate(&trans->ctx, nft_trans_rule(trans)); ++ nft_rule_expr_deactivate(&trans->ctx, ++ nft_trans_rule(trans), ++ NFT_TRANS_ABORT); + break; + case NFT_MSG_DELRULE: + trans->ctx.chain->use++; +@@ -6661,7 +6657,8 @@ static int __nf_tables_abort(struct net *net) + break; + case NFT_MSG_NEWSET: + trans->ctx.table->use--; +- list_del_rcu(&nft_trans_set(trans)->list); ++ if (!nft_trans_set_bound(trans)) ++ list_del_rcu(&nft_trans_set(trans)->list); + break; + case NFT_MSG_DELSET: + trans->ctx.table->use++; +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index a354e9771697..5fd94f7fdb94 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -588,10 +588,14 @@ static void nft_compat_activate_tg(const struct nft_ctx *ctx, + } + + static void nft_compat_deactivate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase) + { + struct nft_xt *xt = container_of(expr->ops, struct nft_xt, ops); + ++ if (phase == NFT_TRANS_COMMIT) ++ return; ++ + if (--xt->listcnt == 0) + list_del_init(&xt->head); + } +diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c +index 07d4efd3d851..f1172f99752b 100644 +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -235,20 +235,17 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + return err; + } + +-static void nft_dynset_activate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) +-{ +- struct nft_dynset *priv = nft_expr_priv(expr); +- +- nf_tables_rebind_set(ctx, priv->set, &priv->binding); +-} +- + static void nft_dynset_deactivate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase) + { + struct nft_dynset *priv = nft_expr_priv(expr); + +- nf_tables_unbind_set(ctx, priv->set, &priv->binding); ++ if (phase == NFT_TRANS_PREPARE) ++ return; ++ ++ nf_tables_unbind_set(ctx, priv->set, &priv->binding, ++ phase == NFT_TRANS_COMMIT); + } + + static void nft_dynset_destroy(const struct nft_ctx *ctx, +@@ -296,7 +293,6 @@ static const struct nft_expr_ops nft_dynset_ops = { + .eval = nft_dynset_eval, + .init = nft_dynset_init, + .destroy = nft_dynset_destroy, +- .activate = nft_dynset_activate, + .deactivate = nft_dynset_deactivate, + .dump = nft_dynset_dump, + }; +diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c +index 0777a93211e2..3f6d1d2a6281 100644 +--- a/net/netfilter/nft_immediate.c ++++ b/net/netfilter/nft_immediate.c +@@ -72,10 +72,14 @@ static void nft_immediate_activate(const struct nft_ctx *ctx, + } + + static void nft_immediate_deactivate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase) + { + const struct nft_immediate_expr *priv = nft_expr_priv(expr); + ++ if (phase == NFT_TRANS_COMMIT) ++ return; ++ + return nft_data_release(&priv->data, nft_dreg_to_type(priv->dreg)); + } + +diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c +index 227b2b15a19c..14496da5141d 100644 +--- a/net/netfilter/nft_lookup.c ++++ b/net/netfilter/nft_lookup.c +@@ -121,20 +121,17 @@ static int nft_lookup_init(const struct nft_ctx *ctx, + return 0; + } + +-static void nft_lookup_activate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) +-{ +- struct nft_lookup *priv = nft_expr_priv(expr); +- +- nf_tables_rebind_set(ctx, priv->set, &priv->binding); +-} +- + static void nft_lookup_deactivate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase) + { + struct nft_lookup *priv = nft_expr_priv(expr); + +- nf_tables_unbind_set(ctx, priv->set, &priv->binding); ++ if (phase == NFT_TRANS_PREPARE) ++ return; ++ ++ nf_tables_unbind_set(ctx, priv->set, &priv->binding, ++ phase == NFT_TRANS_COMMIT); + } + + static void nft_lookup_destroy(const struct nft_ctx *ctx, +@@ -225,7 +222,6 @@ static const struct nft_expr_ops nft_lookup_ops = { + .size = NFT_EXPR_SIZE(sizeof(struct nft_lookup)), + .eval = nft_lookup_eval, + .init = nft_lookup_init, +- .activate = nft_lookup_activate, + .deactivate = nft_lookup_deactivate, + .destroy = nft_lookup_destroy, + .dump = nft_lookup_dump, +diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c +index a3185ca2a3a9..ae178e914486 100644 +--- a/net/netfilter/nft_objref.c ++++ b/net/netfilter/nft_objref.c +@@ -155,20 +155,17 @@ static int nft_objref_map_dump(struct sk_buff *skb, const struct nft_expr *expr) + return -1; + } + +-static void nft_objref_map_activate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) +-{ +- struct nft_objref_map *priv = nft_expr_priv(expr); +- +- nf_tables_rebind_set(ctx, priv->set, &priv->binding); +-} +- + static void nft_objref_map_deactivate(const struct nft_ctx *ctx, +- const struct nft_expr *expr) ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase) + { + struct nft_objref_map *priv = nft_expr_priv(expr); + +- nf_tables_unbind_set(ctx, priv->set, &priv->binding); ++ if (phase == NFT_TRANS_PREPARE) ++ return; ++ ++ nf_tables_unbind_set(ctx, priv->set, &priv->binding, ++ phase == NFT_TRANS_COMMIT); + } + + static void nft_objref_map_destroy(const struct nft_ctx *ctx, +@@ -185,7 +182,6 @@ static const struct nft_expr_ops nft_objref_map_ops = { + .size = NFT_EXPR_SIZE(sizeof(struct nft_objref_map)), + .eval = nft_objref_map_eval, + .init = nft_objref_map_init, +- .activate = nft_objref_map_activate, + .deactivate = nft_objref_map_deactivate, + .destroy = nft_objref_map_destroy, + .dump = nft_objref_map_dump, +-- +2.19.1 + diff --git a/queue-4.20/netfilter-nft_compat-destroy-function-must-not-have-.patch b/queue-4.20/netfilter-nft_compat-destroy-function-must-not-have-.patch new file mode 100644 index 00000000000..d3c4cbf6f28 --- /dev/null +++ b/queue-4.20/netfilter-nft_compat-destroy-function-must-not-have-.patch @@ -0,0 +1,138 @@ +From e3f12f561dce3894f02b6e353d4534e6153d5a80 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 14 Jan 2019 14:28:50 +0100 +Subject: netfilter: nft_compat: destroy function must not have side effects + +[ Upstream commit b2e3d68d1251a051a620f9086e18f7ffa6833b5b ] + +The nft_compat destroy function deletes the nft_xt object from a list. +This isn't allowed anymore. Destroy functions are called asynchronously, +i.e. next batch can find the object that has a pending ->destroy() +invocation: + +cpu0 cpu1 + worker + ->destroy for_each_entry() + if (x == ... + return x->ops; + list_del(x) + kfree_rcu(x) + expr->ops->... // ops was free'd + +To resolve this, the list_del needs to occur before the transaction +mutex gets released. nf_tables has a 'deactivate' hook for this +purpose, so use that to unlink the object from the list. + +Fixes: 0935d5588400 ("netfilter: nf_tables: asynchronous release") +Reported-by: Taehee Yoo +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_compat.c | 48 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 47 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index d3412138e000..a354e9771697 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -29,6 +29,9 @@ struct nft_xt { + struct nft_expr_ops ops; + refcount_t refcnt; + ++ /* used only when transaction mutex is locked */ ++ unsigned int listcnt; ++ + /* Unlike other expressions, ops doesn't have static storage duration. + * nft core assumes they do. We use kfree_rcu so that nft core can + * can check expr->ops->size even after nft_compat->destroy() frees +@@ -61,7 +64,7 @@ static struct nft_compat_net *nft_compat_pernet(struct net *net) + static bool nft_xt_put(struct nft_xt *xt) + { + if (refcount_dec_and_test(&xt->refcnt)) { +- list_del(&xt->head); ++ WARN_ON_ONCE(!list_empty(&xt->head)); + kfree_rcu(xt, rcu_head); + return true; + } +@@ -556,6 +559,43 @@ nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) + __nft_match_destroy(ctx, expr, nft_expr_priv(expr)); + } + ++static void nft_compat_activate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr, ++ struct list_head *h) ++{ ++ struct nft_xt *xt = container_of(expr->ops, struct nft_xt, ops); ++ ++ if (xt->listcnt == 0) ++ list_add(&xt->head, h); ++ ++ xt->listcnt++; ++} ++ ++static void nft_compat_activate_mt(const struct nft_ctx *ctx, ++ const struct nft_expr *expr) ++{ ++ struct nft_compat_net *cn = nft_compat_pernet(ctx->net); ++ ++ nft_compat_activate(ctx, expr, &cn->nft_match_list); ++} ++ ++static void nft_compat_activate_tg(const struct nft_ctx *ctx, ++ const struct nft_expr *expr) ++{ ++ struct nft_compat_net *cn = nft_compat_pernet(ctx->net); ++ ++ nft_compat_activate(ctx, expr, &cn->nft_target_list); ++} ++ ++static void nft_compat_deactivate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr) ++{ ++ struct nft_xt *xt = container_of(expr->ops, struct nft_xt, ops); ++ ++ if (--xt->listcnt == 0) ++ list_del_init(&xt->head); ++} ++ + static void + nft_match_large_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) + { +@@ -809,6 +849,8 @@ nft_match_select_ops(const struct nft_ctx *ctx, + nft_match->ops.eval = nft_match_eval; + nft_match->ops.init = nft_match_init; + nft_match->ops.destroy = nft_match_destroy; ++ nft_match->ops.activate = nft_compat_activate_mt; ++ nft_match->ops.deactivate = nft_compat_deactivate; + nft_match->ops.dump = nft_match_dump; + nft_match->ops.validate = nft_match_validate; + nft_match->ops.data = match; +@@ -825,6 +867,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, + + nft_match->ops.size = matchsize; + ++ nft_match->listcnt = 1; + list_add(&nft_match->head, &cn->nft_match_list); + + return &nft_match->ops; +@@ -911,6 +954,8 @@ nft_target_select_ops(const struct nft_ctx *ctx, + nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); + nft_target->ops.init = nft_target_init; + nft_target->ops.destroy = nft_target_destroy; ++ nft_target->ops.activate = nft_compat_activate_tg; ++ nft_target->ops.deactivate = nft_compat_deactivate; + nft_target->ops.dump = nft_target_dump; + nft_target->ops.validate = nft_target_validate; + nft_target->ops.data = target; +@@ -920,6 +965,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, + else + nft_target->ops.eval = nft_target_eval_xt; + ++ nft_target->listcnt = 1; + list_add(&nft_target->head, &cn->nft_target_list); + + return &nft_target->ops; +-- +2.19.1 + diff --git a/queue-4.20/netfilter-nft_compat-don-t-use-refcount_inc-on-newly.patch b/queue-4.20/netfilter-nft_compat-don-t-use-refcount_inc-on-newly.patch new file mode 100644 index 00000000000..601e44fba6b --- /dev/null +++ b/queue-4.20/netfilter-nft_compat-don-t-use-refcount_inc-on-newly.patch @@ -0,0 +1,164 @@ +From 998c1eb43f8ea522a08fea1e866dfa68208c5a7c Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 5 Feb 2019 12:16:18 +0100 +Subject: netfilter: nft_compat: don't use refcount_inc on newly allocated + entry + +[ Upstream commit 947e492c0fc2132ae5fca081a9c2952ccaab0404 ] + +When I moved the refcount to refcount_t type I missed the fact that +refcount_inc() will result in use-after-free warning with +CONFIG_REFCOUNT_FULL=y builds. + +The correct fix would be to init the reference count to 1 at allocation +time, but, unfortunately we cannot do this, as we can't undo that +in case something else fails later in the batch. + +So only solution I see is to special-case the 'new entry' condition +and replace refcount_inc() with a "delayed" refcount_set(1) in this case, +as done here. + +The .activate callback can be removed to simplify things, we only +need to make sure that deactivate() decrements/unlinks the entry +from the list at end of transaction phase (commit or abort). + +Fixes: 12c44aba6618 ("netfilter: nft_compat: use refcnt_t type for nft_xt reference count") +Reported-by: Jordan Glover +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_compat.c | 62 ++++++++++++++------------------------ + 1 file changed, 23 insertions(+), 39 deletions(-) + +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index 5fd94f7fdb94..0a4bad55a8aa 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -61,6 +61,21 @@ static struct nft_compat_net *nft_compat_pernet(struct net *net) + return net_generic(net, nft_compat_net_id); + } + ++static void nft_xt_get(struct nft_xt *xt) ++{ ++ /* refcount_inc() warns on 0 -> 1 transition, but we can't ++ * init the reference count to 1 in .select_ops -- we can't ++ * undo such an increase when another expression inside the same ++ * rule fails afterwards. ++ */ ++ if (xt->listcnt == 0) ++ refcount_set(&xt->refcnt, 1); ++ else ++ refcount_inc(&xt->refcnt); ++ ++ xt->listcnt++; ++} ++ + static bool nft_xt_put(struct nft_xt *xt) + { + if (refcount_dec_and_test(&xt->refcnt)) { +@@ -291,7 +306,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + return -EINVAL; + + nft_xt = container_of(expr->ops, struct nft_xt, ops); +- refcount_inc(&nft_xt->refcnt); ++ nft_xt_get(nft_xt); + return 0; + } + +@@ -505,7 +520,7 @@ __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + return ret; + + nft_xt = container_of(expr->ops, struct nft_xt, ops); +- refcount_inc(&nft_xt->refcnt); ++ nft_xt_get(nft_xt); + return 0; + } + +@@ -559,45 +574,16 @@ nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) + __nft_match_destroy(ctx, expr, nft_expr_priv(expr)); + } + +-static void nft_compat_activate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- struct list_head *h) +-{ +- struct nft_xt *xt = container_of(expr->ops, struct nft_xt, ops); +- +- if (xt->listcnt == 0) +- list_add(&xt->head, h); +- +- xt->listcnt++; +-} +- +-static void nft_compat_activate_mt(const struct nft_ctx *ctx, +- const struct nft_expr *expr) +-{ +- struct nft_compat_net *cn = nft_compat_pernet(ctx->net); +- +- nft_compat_activate(ctx, expr, &cn->nft_match_list); +-} +- +-static void nft_compat_activate_tg(const struct nft_ctx *ctx, +- const struct nft_expr *expr) +-{ +- struct nft_compat_net *cn = nft_compat_pernet(ctx->net); +- +- nft_compat_activate(ctx, expr, &cn->nft_target_list); +-} +- + static void nft_compat_deactivate(const struct nft_ctx *ctx, + const struct nft_expr *expr, + enum nft_trans_phase phase) + { + struct nft_xt *xt = container_of(expr->ops, struct nft_xt, ops); + +- if (phase == NFT_TRANS_COMMIT) +- return; +- +- if (--xt->listcnt == 0) +- list_del_init(&xt->head); ++ if (phase == NFT_TRANS_ABORT || phase == NFT_TRANS_COMMIT) { ++ if (--xt->listcnt == 0) ++ list_del_init(&xt->head); ++ } + } + + static void +@@ -853,7 +839,6 @@ nft_match_select_ops(const struct nft_ctx *ctx, + nft_match->ops.eval = nft_match_eval; + nft_match->ops.init = nft_match_init; + nft_match->ops.destroy = nft_match_destroy; +- nft_match->ops.activate = nft_compat_activate_mt; + nft_match->ops.deactivate = nft_compat_deactivate; + nft_match->ops.dump = nft_match_dump; + nft_match->ops.validate = nft_match_validate; +@@ -871,7 +856,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, + + nft_match->ops.size = matchsize; + +- nft_match->listcnt = 1; ++ nft_match->listcnt = 0; + list_add(&nft_match->head, &cn->nft_match_list); + + return &nft_match->ops; +@@ -958,7 +943,6 @@ nft_target_select_ops(const struct nft_ctx *ctx, + nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); + nft_target->ops.init = nft_target_init; + nft_target->ops.destroy = nft_target_destroy; +- nft_target->ops.activate = nft_compat_activate_tg; + nft_target->ops.deactivate = nft_compat_deactivate; + nft_target->ops.dump = nft_target_dump; + nft_target->ops.validate = nft_target_validate; +@@ -969,7 +953,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, + else + nft_target->ops.eval = nft_target_eval_xt; + +- nft_target->listcnt = 1; ++ nft_target->listcnt = 0; + list_add(&nft_target->head, &cn->nft_target_list); + + return &nft_target->ops; +-- +2.19.1 + diff --git a/queue-4.20/netfilter-nft_compat-make-lists-per-netns.patch b/queue-4.20/netfilter-nft_compat-make-lists-per-netns.patch new file mode 100644 index 00000000000..d18c2690fc3 --- /dev/null +++ b/queue-4.20/netfilter-nft_compat-make-lists-per-netns.patch @@ -0,0 +1,293 @@ +From 70b1c39b02ec25dbd7a5b541fda38fede1f4c523 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 14 Jan 2019 14:28:49 +0100 +Subject: netfilter: nft_compat: make lists per netns + +[ Upstream commit cf52572ebbd7189a1966c2b5fc34b97078cd1dce ] + +There are two problems with nft_compat since the netlink config +plane uses a per-netns mutex: + +1. Concurrent add/del accesses to the same list +2. accesses to a list element after it has been free'd already. + +This patch fixes the first problem. + +Freeing occurs from a work queue, after transaction mutexes have been +released, i.e., it still possible for a new transaction (even from +same net ns) to find the to-be-deleted expression in the list. + +The ->destroy functions are not allowed to have any such side effects, +i.e. the list_del() in the destroy function is not allowed. + +This part of the problem is solved in the next patch. +I tried to make this work by serializing list access via mutex +and by moving list_del() to a deactivate callback, but +Taehee spotted following race on this approach: + + NET #0 NET #1 + >select_ops() + ->init() + ->select_ops() + ->deactivate() + ->destroy() + nft_xt_put() + kfree_rcu(xt, rcu_head); + ->init() <-- use-after-free occurred. + +Unfortunately, we can't increment reference count in +select_ops(), because we can't undo the refcount increase in +case a different expression fails in the same batch. + +(The destroy hook will only be called in case the expression + was initialized successfully). + +Fixes: f102d66b335a ("netfilter: nf_tables: use dedicated mutex to guard transactions") +Reported-by: Taehee Yoo +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_compat.c | 129 +++++++++++++++++++++++++------------ + 1 file changed, 89 insertions(+), 40 deletions(-) + +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index 791f3e693e3d..d3412138e000 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + struct nft_xt { + struct list_head head; +@@ -43,6 +44,20 @@ struct nft_xt_match_priv { + void *info; + }; + ++struct nft_compat_net { ++ struct list_head nft_target_list; ++ struct list_head nft_match_list; ++}; ++ ++static unsigned int nft_compat_net_id __read_mostly; ++static struct nft_expr_type nft_match_type; ++static struct nft_expr_type nft_target_type; ++ ++static struct nft_compat_net *nft_compat_pernet(struct net *net) ++{ ++ return net_generic(net, nft_compat_net_id); ++} ++ + static bool nft_xt_put(struct nft_xt *xt) + { + if (refcount_dec_and_test(&xt->refcnt)) { +@@ -735,10 +750,6 @@ static const struct nfnetlink_subsystem nfnl_compat_subsys = { + .cb = nfnl_nft_compat_cb, + }; + +-static LIST_HEAD(nft_match_list); +- +-static struct nft_expr_type nft_match_type; +- + static bool nft_match_cmp(const struct xt_match *match, + const char *name, u32 rev, u32 family) + { +@@ -750,6 +761,7 @@ static const struct nft_expr_ops * + nft_match_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) + { ++ struct nft_compat_net *cn; + struct nft_xt *nft_match; + struct xt_match *match; + unsigned int matchsize; +@@ -766,8 +778,10 @@ nft_match_select_ops(const struct nft_ctx *ctx, + rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV])); + family = ctx->family; + ++ cn = nft_compat_pernet(ctx->net); ++ + /* Re-use the existing match if it's already loaded. */ +- list_for_each_entry(nft_match, &nft_match_list, head) { ++ list_for_each_entry(nft_match, &cn->nft_match_list, head) { + struct xt_match *match = nft_match->ops.data; + + if (nft_match_cmp(match, mt_name, rev, family)) +@@ -811,7 +825,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, + + nft_match->ops.size = matchsize; + +- list_add(&nft_match->head, &nft_match_list); ++ list_add(&nft_match->head, &cn->nft_match_list); + + return &nft_match->ops; + err: +@@ -827,10 +841,6 @@ static struct nft_expr_type nft_match_type __read_mostly = { + .owner = THIS_MODULE, + }; + +-static LIST_HEAD(nft_target_list); +- +-static struct nft_expr_type nft_target_type; +- + static bool nft_target_cmp(const struct xt_target *tg, + const char *name, u32 rev, u32 family) + { +@@ -842,6 +852,7 @@ static const struct nft_expr_ops * + nft_target_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) + { ++ struct nft_compat_net *cn; + struct nft_xt *nft_target; + struct xt_target *target; + char *tg_name; +@@ -862,8 +873,9 @@ nft_target_select_ops(const struct nft_ctx *ctx, + strcmp(tg_name, "standard") == 0) + return ERR_PTR(-EINVAL); + ++ cn = nft_compat_pernet(ctx->net); + /* Re-use the existing target if it's already loaded. */ +- list_for_each_entry(nft_target, &nft_target_list, head) { ++ list_for_each_entry(nft_target, &cn->nft_target_list, head) { + struct xt_target *target = nft_target->ops.data; + + if (!target->target) +@@ -908,7 +920,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, + else + nft_target->ops.eval = nft_target_eval_xt; + +- list_add(&nft_target->head, &nft_target_list); ++ list_add(&nft_target->head, &cn->nft_target_list); + + return &nft_target->ops; + err: +@@ -924,13 +936,74 @@ static struct nft_expr_type nft_target_type __read_mostly = { + .owner = THIS_MODULE, + }; + ++static int __net_init nft_compat_init_net(struct net *net) ++{ ++ struct nft_compat_net *cn = nft_compat_pernet(net); ++ ++ INIT_LIST_HEAD(&cn->nft_target_list); ++ INIT_LIST_HEAD(&cn->nft_match_list); ++ ++ return 0; ++} ++ ++static void __net_exit nft_compat_exit_net(struct net *net) ++{ ++ struct nft_compat_net *cn = nft_compat_pernet(net); ++ struct nft_xt *xt, *next; ++ ++ if (list_empty(&cn->nft_match_list) && ++ list_empty(&cn->nft_target_list)) ++ return; ++ ++ /* If there was an error that caused nft_xt expr to not be initialized ++ * fully and noone else requested the same expression later, the lists ++ * contain 0-refcount entries that still hold module reference. ++ * ++ * Clean them here. ++ */ ++ mutex_lock(&net->nft.commit_mutex); ++ list_for_each_entry_safe(xt, next, &cn->nft_target_list, head) { ++ struct xt_target *target = xt->ops.data; ++ ++ list_del_init(&xt->head); ++ ++ if (refcount_read(&xt->refcnt)) ++ continue; ++ module_put(target->me); ++ kfree(xt); ++ } ++ ++ list_for_each_entry_safe(xt, next, &cn->nft_match_list, head) { ++ struct xt_match *match = xt->ops.data; ++ ++ list_del_init(&xt->head); ++ ++ if (refcount_read(&xt->refcnt)) ++ continue; ++ module_put(match->me); ++ kfree(xt); ++ } ++ mutex_unlock(&net->nft.commit_mutex); ++} ++ ++static struct pernet_operations nft_compat_net_ops = { ++ .init = nft_compat_init_net, ++ .exit = nft_compat_exit_net, ++ .id = &nft_compat_net_id, ++ .size = sizeof(struct nft_compat_net), ++}; ++ + static int __init nft_compat_module_init(void) + { + int ret; + ++ ret = register_pernet_subsys(&nft_compat_net_ops); ++ if (ret < 0) ++ goto err_target; ++ + ret = nft_register_expr(&nft_match_type); + if (ret < 0) +- return ret; ++ goto err_pernet; + + ret = nft_register_expr(&nft_target_type); + if (ret < 0) +@@ -943,45 +1016,21 @@ static int __init nft_compat_module_init(void) + } + + return ret; +- + err_target: + nft_unregister_expr(&nft_target_type); + err_match: + nft_unregister_expr(&nft_match_type); ++err_pernet: ++ unregister_pernet_subsys(&nft_compat_net_ops); + return ret; + } + + static void __exit nft_compat_module_exit(void) + { +- struct nft_xt *xt, *next; +- +- /* list should be empty here, it can be non-empty only in case there +- * was an error that caused nft_xt expr to not be initialized fully +- * and noone else requested the same expression later. +- * +- * In this case, the lists contain 0-refcount entries that still +- * hold module reference. +- */ +- list_for_each_entry_safe(xt, next, &nft_target_list, head) { +- struct xt_target *target = xt->ops.data; +- +- if (WARN_ON_ONCE(refcount_read(&xt->refcnt))) +- continue; +- module_put(target->me); +- kfree(xt); +- } +- +- list_for_each_entry_safe(xt, next, &nft_match_list, head) { +- struct xt_match *match = xt->ops.data; +- +- if (WARN_ON_ONCE(refcount_read(&xt->refcnt))) +- continue; +- module_put(match->me); +- kfree(xt); +- } + nfnetlink_subsys_unregister(&nfnl_compat_subsys); + nft_unregister_expr(&nft_target_type); + nft_unregister_expr(&nft_match_type); ++ unregister_pernet_subsys(&nft_compat_net_ops); + } + + MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT); +-- +2.19.1 + diff --git a/queue-4.20/netfilter-nft_compat-use-refcnt_t-type-for-nft_xt-re.patch b/queue-4.20/netfilter-nft_compat-use-refcnt_t-type-for-nft_xt-re.patch new file mode 100644 index 00000000000..7dbffeec3f3 --- /dev/null +++ b/queue-4.20/netfilter-nft_compat-use-refcnt_t-type-for-nft_xt-re.patch @@ -0,0 +1,115 @@ +From 25598d51a7f11bbdfba9af7e72e0e59645ce4552 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 14 Jan 2019 14:28:48 +0100 +Subject: netfilter: nft_compat: use refcnt_t type for nft_xt reference count + +[ Upstream commit 12c44aba6618b7f6c437076e5722237190f6cd5f ] + +Using standard integer type was fine while all operations on it were +guarded by the nftnl subsys mutex. + +This isn't true anymore: +1. transactions are guarded only by a pernet mutex, so concurrent + rule manipulation in different netns is racy +2. the ->destroy hook runs from a work queue after the transaction + mutex has been released already. + +cpu0 cpu1 (net 1) cpu2 (net 2) + kworker + nft_compat->destroy nft_compat->init nft_compat->init + if (--nft_xt->ref == 0) nft_xt->ref++ nft_xt->ref++ + +Switch to refcount_t. Doing this however only fixes a minor aspect, +nft_compat also performs linked-list operations in an unsafe way. + +This is addressed in the next two patches. + +Fixes: f102d66b335a ("netfilter: nf_tables: use dedicated mutex to guard transactions") +Fixes: 0935d5588400 ("netfilter: nf_tables: asynchronous release") +Reported-by: Taehee Yoo +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_compat.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index c90a4640723f..791f3e693e3d 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -26,7 +26,7 @@ + struct nft_xt { + struct list_head head; + struct nft_expr_ops ops; +- unsigned int refcnt; ++ refcount_t refcnt; + + /* Unlike other expressions, ops doesn't have static storage duration. + * nft core assumes they do. We use kfree_rcu so that nft core can +@@ -45,7 +45,7 @@ struct nft_xt_match_priv { + + static bool nft_xt_put(struct nft_xt *xt) + { +- if (--xt->refcnt == 0) { ++ if (refcount_dec_and_test(&xt->refcnt)) { + list_del(&xt->head); + kfree_rcu(xt, rcu_head); + return true; +@@ -273,7 +273,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + return -EINVAL; + + nft_xt = container_of(expr->ops, struct nft_xt, ops); +- nft_xt->refcnt++; ++ refcount_inc(&nft_xt->refcnt); + return 0; + } + +@@ -487,7 +487,7 @@ __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + return ret; + + nft_xt = container_of(expr->ops, struct nft_xt, ops); +- nft_xt->refcnt++; ++ refcount_inc(&nft_xt->refcnt); + return 0; + } + +@@ -790,7 +790,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, + goto err; + } + +- nft_match->refcnt = 0; ++ refcount_set(&nft_match->refcnt, 0); + nft_match->ops.type = &nft_match_type; + nft_match->ops.eval = nft_match_eval; + nft_match->ops.init = nft_match_init; +@@ -894,7 +894,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, + goto err; + } + +- nft_target->refcnt = 0; ++ refcount_set(&nft_target->refcnt, 0); + nft_target->ops.type = &nft_target_type; + nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); + nft_target->ops.init = nft_target_init; +@@ -965,7 +965,7 @@ static void __exit nft_compat_module_exit(void) + list_for_each_entry_safe(xt, next, &nft_target_list, head) { + struct xt_target *target = xt->ops.data; + +- if (WARN_ON_ONCE(xt->refcnt)) ++ if (WARN_ON_ONCE(refcount_read(&xt->refcnt))) + continue; + module_put(target->me); + kfree(xt); +@@ -974,7 +974,7 @@ static void __exit nft_compat_module_exit(void) + list_for_each_entry_safe(xt, next, &nft_match_list, head) { + struct xt_match *match = xt->ops.data; + +- if (WARN_ON_ONCE(xt->refcnt)) ++ if (WARN_ON_ONCE(refcount_read(&xt->refcnt))) + continue; + module_put(match->me); + kfree(xt); +-- +2.19.1 + diff --git a/queue-4.20/nfs-fix-null-pointer-dereference-of-dev_name.patch b/queue-4.20/nfs-fix-null-pointer-dereference-of-dev_name.patch new file mode 100644 index 00000000000..5faf68b2eb1 --- /dev/null +++ b/queue-4.20/nfs-fix-null-pointer-dereference-of-dev_name.patch @@ -0,0 +1,56 @@ +From a54eac99e24880448a424ff36e88b3e418899e0d Mon Sep 17 00:00:00 2001 +From: Yao Liu +Date: Mon, 28 Jan 2019 19:44:14 +0800 +Subject: nfs: Fix NULL pointer dereference of dev_name + +[ Upstream commit 80ff00172407e0aad4b10b94ef0816fc3e7813cb ] + +There is a NULL pointer dereference of dev_name in nfs_parse_devname() + +The oops looks something like: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + ... + RIP: 0010:nfs_fs_mount+0x3b6/0xc20 [nfs] + ... + Call Trace: + ? ida_alloc_range+0x34b/0x3d0 + ? nfs_clone_super+0x80/0x80 [nfs] + ? nfs_free_parsed_mount_data+0x60/0x60 [nfs] + mount_fs+0x52/0x170 + ? __init_waitqueue_head+0x3b/0x50 + vfs_kern_mount+0x6b/0x170 + do_mount+0x216/0xdc0 + ksys_mount+0x83/0xd0 + __x64_sys_mount+0x25/0x30 + do_syscall_64+0x65/0x220 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Fix this by adding a NULL check on dev_name + +Signed-off-by: Yao Liu +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/super.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index 5ef2c71348bd..6b666d187907 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -1906,6 +1906,11 @@ static int nfs_parse_devname(const char *dev_name, + size_t len; + char *end; + ++ if (unlikely(!dev_name || !*dev_name)) { ++ dfprintk(MOUNT, "NFS: device name not specified\n"); ++ return -EINVAL; ++ } ++ + /* Is the host name protected with square brakcets? */ + if (*dev_name == '[') { + end = strchr(++dev_name, ']'); +-- +2.19.1 + diff --git a/queue-4.20/nvme-lock-ns-list-changes-while-handling-command-eff.patch b/queue-4.20/nvme-lock-ns-list-changes-while-handling-command-eff.patch new file mode 100644 index 00000000000..2fefd09e364 --- /dev/null +++ b/queue-4.20/nvme-lock-ns-list-changes-while-handling-command-eff.patch @@ -0,0 +1,96 @@ +From 92b83a6a6df05cdfe8b77fec1cec329e94bccc46 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Mon, 28 Jan 2019 09:46:07 -0700 +Subject: nvme: lock NS list changes while handling command effects + +[ Upstream commit e7ad43c3eda6a1690c4c3c341f95dc1c6898da83 ] + +If a controller supports the NS Change Notification, the namespace +scan_work is automatically triggered after attaching a new namespace. + +Occasionally the namespace scan_work may append the new namespace to the +list before the admin command effects handling is completed. The effects +handling unfreezes namespaces, but if it unfreezes the newly attached +namespace, its request_queue freeze depth will be off and we'll hit the +warning in blk_mq_unfreeze_queue(). + +On the next namespace add, we will fail to freeze that queue due to the +previous bad accounting and deadlock waiting for frozen. + +Fix that by preventing scan work from altering the namespace list while +command effects handling needs to pair freeze with unfreeze. + +Reported-by: Wen Xiong +Tested-by: Wen Xiong +Signed-off-by: Keith Busch +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 8 +++++++- + drivers/nvme/host/nvme.h | 1 + + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 5f9a5ef93969..21d7b646c73d 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1182,6 +1182,7 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, + * effects say only one namespace is affected. + */ + if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { ++ mutex_lock(&ctrl->scan_lock); + nvme_start_freeze(ctrl); + nvme_wait_freeze(ctrl); + } +@@ -1210,8 +1211,10 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) + */ + if (effects & NVME_CMD_EFFECTS_LBCC) + nvme_update_formats(ctrl); +- if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) ++ if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { + nvme_unfreeze(ctrl); ++ mutex_unlock(&ctrl->scan_lock); ++ } + if (effects & NVME_CMD_EFFECTS_CCC) + nvme_init_identify(ctrl); + if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC)) +@@ -3300,6 +3303,7 @@ static void nvme_scan_work(struct work_struct *work) + if (nvme_identify_ctrl(ctrl, &id)) + return; + ++ mutex_lock(&ctrl->scan_lock); + nn = le32_to_cpu(id->nn); + if (ctrl->vs >= NVME_VS(1, 1, 0) && + !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)) { +@@ -3308,6 +3312,7 @@ static void nvme_scan_work(struct work_struct *work) + } + nvme_scan_ns_sequential(ctrl, nn); + out_free_id: ++ mutex_unlock(&ctrl->scan_lock); + kfree(id); + down_write(&ctrl->namespaces_rwsem); + list_sort(NULL, &ctrl->namespaces, ns_cmp); +@@ -3550,6 +3555,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, + + ctrl->state = NVME_CTRL_NEW; + spin_lock_init(&ctrl->lock); ++ mutex_init(&ctrl->scan_lock); + INIT_LIST_HEAD(&ctrl->namespaces); + init_rwsem(&ctrl->namespaces_rwsem); + ctrl->dev = dev; +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 6ffa99a10a60..5274881f9141 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -153,6 +153,7 @@ struct nvme_ctrl { + enum nvme_ctrl_state state; + bool identified; + spinlock_t lock; ++ struct mutex scan_lock; + const struct nvme_ctrl_ops *ops; + struct request_queue *admin_q; + struct request_queue *connect_q; +-- +2.19.1 + diff --git a/queue-4.20/nvme-pci-add-missing-unlock-for-reset-error.patch b/queue-4.20/nvme-pci-add-missing-unlock-for-reset-error.patch new file mode 100644 index 00000000000..74a191739e1 --- /dev/null +++ b/queue-4.20/nvme-pci-add-missing-unlock-for-reset-error.patch @@ -0,0 +1,54 @@ +From f8a7e339f4642bd0c7e4501b57dc0f610ffb97bf Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Mon, 11 Feb 2019 09:23:50 -0700 +Subject: nvme-pci: add missing unlock for reset error + +[ Upstream commit 4726bcf30fad37cc555cd9dcd6c73f2b2668c879 ] + +The reset work holds a mutex to prevent races with removal modifying the +same resources, but was unlocking only on success. Unlock on failure +too. + +Fixes: 5c959d73dba64 ("nvme-pci: fix rapid add remove sequence") +Signed-off-by: Keith Busch +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 439b9f4eb246..5c58e0ffa3ac 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2283,15 +2283,15 @@ static void nvme_reset_work(struct work_struct *work) + mutex_lock(&dev->shutdown_lock); + result = nvme_pci_enable(dev); + if (result) +- goto out; ++ goto out_unlock; + + result = nvme_pci_configure_admin_queue(dev); + if (result) +- goto out; ++ goto out_unlock; + + result = nvme_alloc_admin_tags(dev); + if (result) +- goto out; ++ goto out_unlock; + + /* + * Limit the max command size to prevent iod->sg allocations going +@@ -2374,6 +2374,8 @@ static void nvme_reset_work(struct work_struct *work) + nvme_start_ctrl(&dev->ctrl); + return; + ++ out_unlock: ++ mutex_unlock(&dev->shutdown_lock); + out: + nvme_remove_dead_ctrl(dev, result); + } +-- +2.19.1 + diff --git a/queue-4.20/nvme-pci-fix-rapid-add-remove-sequence.patch b/queue-4.20/nvme-pci-fix-rapid-add-remove-sequence.patch new file mode 100644 index 00000000000..86d8a57c519 --- /dev/null +++ b/queue-4.20/nvme-pci-fix-rapid-add-remove-sequence.patch @@ -0,0 +1,71 @@ +From 759358c6fd1eee7f0a4c4d08775a9ad8f1d76004 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Wed, 23 Jan 2019 18:46:11 -0700 +Subject: nvme-pci: fix rapid add remove sequence + +[ Upstream commit 5c959d73dba6495ec01d04c206ee679d61ccb2b0 ] + +A surprise removal may fail to tear down request queues if it is racing +with the initial asynchronous probe. If that happens, the remove path +won't see the queue resources to tear down, and the controller reset +path may create a new request queue on a removed device, but will not +be able to make forward progress, deadlocking the pci removal. + +Protect setting up non-blocking resources from a shutdown by holding the +same mutex, and transition to the CONNECTING state after these resources +are initialized so the probe path may see the dead controller state +before dispatching new IO. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=202081 +Reported-by: Alex Gagniuc +Signed-off-by: Keith Busch +Tested-by: Alex Gagniuc +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index c0d01048ce4d..439b9f4eb246 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2280,16 +2280,7 @@ static void nvme_reset_work(struct work_struct *work) + if (dev->ctrl.ctrl_config & NVME_CC_ENABLE) + nvme_dev_disable(dev, false); + +- /* +- * Introduce CONNECTING state from nvme-fc/rdma transports to mark the +- * initializing procedure here. +- */ +- if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) { +- dev_warn(dev->ctrl.device, +- "failed to mark controller CONNECTING\n"); +- goto out; +- } +- ++ mutex_lock(&dev->shutdown_lock); + result = nvme_pci_enable(dev); + if (result) + goto out; +@@ -2308,6 +2299,17 @@ static void nvme_reset_work(struct work_struct *work) + */ + dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1; + dev->ctrl.max_segments = NVME_MAX_SEGS; ++ mutex_unlock(&dev->shutdown_lock); ++ ++ /* ++ * Introduce CONNECTING state from nvme-fc/rdma transports to mark the ++ * initializing procedure here. ++ */ ++ if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) { ++ dev_warn(dev->ctrl.device, ++ "failed to mark controller CONNECTING\n"); ++ goto out; ++ } + + result = nvme_init_identify(&dev->ctrl); + if (result) +-- +2.19.1 + diff --git a/queue-4.20/perf-core-fix-perf_proc_update_handler-bug.patch b/queue-4.20/perf-core-fix-perf_proc_update_handler-bug.patch new file mode 100644 index 00000000000..e16e4791348 --- /dev/null +++ b/queue-4.20/perf-core-fix-perf_proc_update_handler-bug.patch @@ -0,0 +1,84 @@ +From e1de252fd42e3444b5a286c23e38a0353541b405 Mon Sep 17 00:00:00 2001 +From: Stephane Eranian +Date: Thu, 10 Jan 2019 17:17:16 -0800 +Subject: perf core: Fix perf_proc_update_handler() bug + +[ Upstream commit 1a51c5da5acc6c188c917ba572eebac5f8793432 ] + +The perf_proc_update_handler() handles /proc/sys/kernel/perf_event_max_sample_rate +syctl variable. When the PMU IRQ handler timing monitoring is disabled, i.e, +when /proc/sys/kernel/perf_cpu_time_max_percent is equal to 0 or 100, +then no modification to sysctl_perf_event_sample_rate is allowed to prevent +possible hang from wrong values. + +The problem is that the test to prevent modification is made after the +sysctl variable is modified in perf_proc_update_handler(). + +You get an error: + + $ echo 10001 >/proc/sys/kernel/perf_event_max_sample_rate + echo: write error: invalid argument + +But the value is still modified causing all sorts of inconsistencies: + + $ cat /proc/sys/kernel/perf_event_max_sample_rate + 10001 + +This patch fixes the problem by moving the parsing of the value after +the test. + +Committer testing: + + # echo 100 > /proc/sys/kernel/perf_cpu_time_max_percent + # echo 10001 > /proc/sys/kernel/perf_event_max_sample_rate + -bash: echo: write error: Invalid argument + # cat /proc/sys/kernel/perf_event_max_sample_rate + 10001 + # + +Signed-off-by: Stephane Eranian +Reviewed-by: Andi Kleen +Reviewed-by: Jiri Olsa +Tested-by: Arnaldo Carvalho de Melo +Cc: Kan Liang +Cc: Peter Zijlstra +Link: http://lkml.kernel.org/r/1547169436-6266-1-git-send-email-eranian@google.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 699bc25d6204..18997730b665 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -436,18 +436,18 @@ int perf_proc_update_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +- +- if (ret || !write) +- return ret; +- ++ int ret; ++ int perf_cpu = sysctl_perf_cpu_time_max_percent; + /* + * If throttling is disabled don't allow the write: + */ +- if (sysctl_perf_cpu_time_max_percent == 100 || +- sysctl_perf_cpu_time_max_percent == 0) ++ if (write && (perf_cpu == 100 || perf_cpu == 0)) + return -EINVAL; + ++ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); ++ if (ret || !write) ++ return ret; ++ + max_samples_per_tick = DIV_ROUND_UP(sysctl_perf_event_sample_rate, HZ); + perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate; + update_perf_cpu_limits(); +-- +2.19.1 + diff --git a/queue-4.20/perf-ordered_events-fix-crash-in-ordered_events__fre.patch b/queue-4.20/perf-ordered_events-fix-crash-in-ordered_events__fre.patch new file mode 100644 index 00000000000..bf040395f16 --- /dev/null +++ b/queue-4.20/perf-ordered_events-fix-crash-in-ordered_events__fre.patch @@ -0,0 +1,57 @@ +From ad30af46b10906b05e29bbe63c987f350cd21d1b Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Thu, 17 Jan 2019 12:30:17 +0100 +Subject: perf ordered_events: Fix crash in ordered_events__free + +[ Upstream commit 99d86c8b88393e29cf07c020585f2c8afbcdd97d ] + +Song Liu reported crash in 'perf record': + + > #0 0x0000000000500055 in ordered_events(float, long double,...)(...) () + > #1 0x0000000000500196 in ordered_events.reinit () + > #2 0x00000000004fe413 in perf_session.process_events () + > #3 0x0000000000440431 in cmd_record () + > #4 0x00000000004a439f in run_builtin () + > #5 0x000000000042b3e5 in main ()" + +This can happen when we get out of buffers during event processing. + +The subsequent ordered_events__free() call assumes oe->buffer != NULL +and crashes. Add a check to prevent that. + +Reported-by: Song Liu +Signed-off-by: Jiri Olsa +Reviewed-by: Song Liu +Tested-by: Song Liu +Cc: Alexander Shishkin +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Stephane Eranian +Link: http://lkml.kernel.org/r/20190117113017.12977-1-jolsa@kernel.org +Fixes: d5ceb62b3654 ("perf ordered_events: Add 'struct ordered_events_buffer' layer") +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/ordered-events.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c +index 1904e7f6ec84..77126a5fa9b6 100644 +--- a/tools/perf/util/ordered-events.c ++++ b/tools/perf/util/ordered-events.c +@@ -359,8 +359,10 @@ void ordered_events__free(struct ordered_events *oe) + * Current buffer might not have all the events allocated + * yet, we need to free only allocated ones ... + */ +- list_del(&oe->buffer->list); +- ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe); ++ if (oe->buffer) { ++ list_del(&oe->buffer->list); ++ ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe); ++ } + + /* ... and continue with the rest */ + list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) { +-- +2.19.1 + diff --git a/queue-4.20/perf-python-remove-fstack-clash-protection-when-buil.patch b/queue-4.20/perf-python-remove-fstack-clash-protection-when-buil.patch new file mode 100644 index 00000000000..21e9d1305a1 --- /dev/null +++ b/queue-4.20/perf-python-remove-fstack-clash-protection-when-buil.patch @@ -0,0 +1,44 @@ +From e62d4ae48094e61354855f20845ac8ad6069e041 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Fri, 18 Jan 2019 11:34:15 -0300 +Subject: perf python: Remove -fstack-clash-protection when building with some + clang versions + +[ Upstream commit 94ec1eb711db69be1414b56b3160b816e86a5c5b ] + +These options are not present in some (all?) clang versions, so when we +build for a distro that has a gcc new enough to have these options and +that the distro python build config settings use them but clang doesn't +support, b00m. + +This is the case with fedora rawhide (now gearing towards f30), so check +if clang has the and remove the missing ones from CFLAGS. + +Cc: Eduardo Habkost +Cc: Thiago Macieira +Cc: Adrian Hunter +Cc: Jiri Olsa +Cc: Namhyung Kim +Link: https://lkml.kernel.org/n/tip-5q50q9w458yawgxf9ez54jbp@git.kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/setup.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py +index 63f758c655d5..64d1f36dee99 100644 +--- a/tools/perf/util/setup.py ++++ b/tools/perf/util/setup.py +@@ -17,6 +17,8 @@ if cc == "clang": + vars[var] = sub("-mcet", "", vars[var]) + if not clang_has_option("-fcf-protection"): + vars[var] = sub("-fcf-protection", "", vars[var]) ++ if not clang_has_option("-fstack-clash-protection"): ++ vars[var] = sub("-fstack-clash-protection", "", vars[var]) + + from distutils.core import setup, Extension + +-- +2.19.1 + diff --git a/queue-4.20/perf-script-fix-crash-when-processing-recorded-stat-.patch b/queue-4.20/perf-script-fix-crash-when-processing-recorded-stat-.patch new file mode 100644 index 00000000000..e3e88b8fdb4 --- /dev/null +++ b/queue-4.20/perf-script-fix-crash-when-processing-recorded-stat-.patch @@ -0,0 +1,101 @@ +From da0e5b7cee1cf8a699a9a6cf863ee97ab65f1fd4 Mon Sep 17 00:00:00 2001 +From: Tony Jones +Date: Sun, 20 Jan 2019 11:14:14 -0800 +Subject: perf script: Fix crash when processing recorded stat data + +[ Upstream commit 8bf8c6da53c2265aea365a1de6038f118f522113 ] + +While updating perf to work with Python3 and Python2 I noticed that the +stat-cpi script was dumping core. + +$ perf stat -e cycles,instructions record -o /tmp/perf.data /bin/false + + Performance counter stats for '/bin/false': + + 802,148 cycles + + 604,622 instructions 802,148 cycles + 604,622 instructions + + 0.001445842 seconds time elapsed + +$ perf script -i /tmp/perf.data -s scripts/python/stat-cpi.py +Segmentation fault (core dumped) +... +... + rblist=rblist@entry=0xb2a200 , + new_entry=new_entry@entry=0x7ffcb755c310) at util/rblist.c:33 + ctx=, type=, create=, + cpu=, evsel=) at util/stat-shadow.c:118 + ctx=, type=, st=) + at util/stat-shadow.c:196 + count=count@entry=727442, cpu=cpu@entry=0, st=0xb2a200 ) + at util/stat-shadow.c:239 + config=config@entry=0xafeb40 , + counter=counter@entry=0x133c6e0) at util/stat.c:372 +... +... + +The issue is that since 1fcd03946b52 perf_stat__update_shadow_stats now calls +update_runtime_stat passing rt_stat rather than calling update_stats but +perf_stat__init_shadow_stats has never been called to initialize rt_stat in +the script path processing recorded stat data. + +Since I can't see any reason why perf_stat__init_shadow_stats() is presently +initialized like it is in builtin-script.c::perf_sample__fprint_metric() +[4bd1bef8bba2f] I'm proposing it instead be initialized once in __cmd_script + +Committer testing: + +After applying the patch: + + # perf script -i /tmp/perf.data -s tools/perf/scripts/python/stat-cpi.py + 0.001970: cpu -1, thread -1 -> cpi 1.709079 (1075684/629394) + # + +No segfault. + +Signed-off-by: Tony Jones +Reviewed-by: Jiri Olsa +Tested-by: Arnaldo Carvalho de Melo +Tested-by: Ravi Bangoria +Cc: Andi Kleen +Cc: Jin Yao +Fixes: 1fcd03946b52 ("perf stat: Update per-thread shadow stats") +Link: http://lkml.kernel.org/r/20190120191414.12925-1-tonyj@suse.de +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-script.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c +index 5c070a600233..d8791e0e5f75 100644 +--- a/tools/perf/builtin-script.c ++++ b/tools/perf/builtin-script.c +@@ -1633,13 +1633,8 @@ static void perf_sample__fprint_metric(struct perf_script *script, + .force_header = false, + }; + struct perf_evsel *ev2; +- static bool init; + u64 val; + +- if (!init) { +- perf_stat__init_shadow_stats(); +- init = true; +- } + if (!evsel->stats) + perf_evlist__alloc_stats(script->session->evlist, false); + if (evsel_script(evsel->leader)->gnum++ == 0) +@@ -2305,6 +2300,8 @@ static int __cmd_script(struct perf_script *script) + + signal(SIGINT, sig_handler); + ++ perf_stat__init_shadow_stats(); ++ + /* override event processing functions */ + if (script->show_task_events) { + script->tool.comm = process_comm_event; +-- +2.19.1 + diff --git a/queue-4.20/perf-script-fix-crash-with-printing-mixed-trace-poin.patch b/queue-4.20/perf-script-fix-crash-with-printing-mixed-trace-poin.patch new file mode 100644 index 00000000000..c440477b9f2 --- /dev/null +++ b/queue-4.20/perf-script-fix-crash-with-printing-mixed-trace-poin.patch @@ -0,0 +1,83 @@ +From 0d8f3697edeaf4d965a7f9ff2260314131817b73 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Thu, 17 Jan 2019 11:48:34 -0800 +Subject: perf script: Fix crash with printing mixed trace point and other + events + +[ Upstream commit 96167167b6e17b25c0e05ecc31119b73baeab094 ] + +'perf script' crashes currently when printing mixed trace points and +other events because the trace format does not handle events without +trace meta data. Add a simple check to avoid that. + + % cat > test.c + main() + { + printf("Hello world\n"); + } + ^D + % gcc -g -o test test.c + % sudo perf probe -x test 'test.c:3' + % perf record -e '{cpu/cpu-cycles,period=10000/,probe_test:main}:S' ./test + % perf script + + +Committer testing: + +Before: + + # perf probe -x /lib64/libc-2.28.so malloc + Added new event: + probe_libc:malloc (on malloc in /usr/lib64/libc-2.28.so) + + You can now use it in all perf tools, such as: + + perf record -e probe_libc:malloc -aR sleep 1 + + # perf probe -l + probe_libc:malloc (on __libc_malloc@malloc/malloc.c in /usr/lib64/libc-2.28.so) + # perf record -e '{cpu/cpu-cycles,period=10000/,probe_libc:*}:S' sleep 1 + [ perf record: Woken up 1 times to write data ] + [ perf record: Captured and wrote 0.023 MB perf.data (40 samples) ] + # perf script + Segmentation fault (core dumped) + ^C + # + +After: + + # perf script | head -6 + sleep 2888 94796.944981: 16198 cpu/cpu-cycles,period=10000/: ffffffff925dc04f get_random_u32+0x1f (/lib/modules/5.0.0-rc2+/build/vmlinux) + sleep 2888 [-01] 94796.944981: probe_libc:malloc: + sleep 2888 94796.944983: 4713 cpu/cpu-cycles,period=10000/: ffffffff922763af change_protection+0xcf (/lib/modules/5.0.0-rc2+/build/vmlinux) + sleep 2888 [-01] 94796.944983: probe_libc:malloc: + sleep 2888 94796.944986: 9934 cpu/cpu-cycles,period=10000/: ffffffff922777e0 move_page_tables+0x0 (/lib/modules/5.0.0-rc2+/build/vmlinux) + sleep 2888 [-01] 94796.944986: probe_libc:malloc: + # + +Signed-off-by: Andi Kleen +Tested-by: Arnaldo Carvalho de Melo +Acked-by: Jiri Olsa +Link: http://lkml.kernel.org/r/20190117194834.21940-1-andi@firstfloor.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-script.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c +index a7b4d3f611c5..5c070a600233 100644 +--- a/tools/perf/builtin-script.c ++++ b/tools/perf/builtin-script.c +@@ -1746,7 +1746,7 @@ static void process_event(struct perf_script *script, + return; + } + +- if (PRINT_FIELD(TRACE)) { ++ if (PRINT_FIELD(TRACE) && sample->raw_data) { + event_format__fprintf(evsel->tp_format, sample->cpu, + sample->raw_data, sample->raw_size, fp); + } +-- +2.19.1 + diff --git a/queue-4.20/perf-symbols-filter-out-hidden-symbols-from-labels.patch b/queue-4.20/perf-symbols-filter-out-hidden-symbols-from-labels.patch new file mode 100644 index 00000000000..7ce5ca91508 --- /dev/null +++ b/queue-4.20/perf-symbols-filter-out-hidden-symbols-from-labels.patch @@ -0,0 +1,94 @@ +From f26d8a8d8aaaa332cf46d0d07bbcd07a0dbfdc4c Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Mon, 28 Jan 2019 14:35:26 +0100 +Subject: perf symbols: Filter out hidden symbols from labels + +[ Upstream commit 59a17706915fe5ea6f711e1f92d4fb706bce07fe ] + +When perf is built with the annobin plugin (RHEL8 build) extra symbols +are added to its binary: + + # nm perf | grep annobin | head -10 + 0000000000241100 t .annobin_annotate.c + 0000000000326490 t .annobin_annotate.c + 0000000000249255 t .annobin_annotate.c_end + 00000000003283a8 t .annobin_annotate.c_end + 00000000001bce18 t .annobin_annotate.c_end.hot + 00000000001bce18 t .annobin_annotate.c_end.hot + 00000000001bc3e2 t .annobin_annotate.c_end.unlikely + 00000000001bc400 t .annobin_annotate.c_end.unlikely + 00000000001bce18 t .annobin_annotate.c.hot + 00000000001bce18 t .annobin_annotate.c.hot + ... + +Those symbols have no use for report or annotation and should be +skipped. Moreover they interfere with the DWARF unwind test on the PPC +arch, where they are mixed with checked symbols and then the test fails: + + # perf test dwarf -v + 59: Test dwarf unwind : + --- start --- + test child forked, pid 8515 + unwind: .annobin_dwarf_unwind.c:ip = 0x10dba40dc (0x2740dc) + ... + got: .annobin_dwarf_unwind.c 0x10dba40dc, expecting test__arch_unwind_sample + unwind: failed with 'no error' + +The annobin symbols are defined as NOTYPE/LOCAL/HIDDEN: + + # readelf -s ./perf | grep annobin | head -1 + 40: 00000000001bce4f 0 NOTYPE LOCAL HIDDEN 13 .annobin_init.c + +They can still pass the check for the label symbol. Adding check for +HIDDEN and INTERNAL (as suggested by Nick below) visibility and filter +out such symbols. + +> Just to be awkward, if you are going to ignore STV_HIDDEN +> symbols then you should probably also ignore STV_INTERNAL ones +> as well... Annobin does not generate them, but you never know, +> one day some other tool might create some. + +Signed-off-by: Jiri Olsa +Cc: Alexander Shishkin +Cc: Masami Hiramatsu +Cc: Michael Petlan +Cc: Namhyung Kim +Cc: Nick Clifton +Cc: Peter Zijlstra +Link: http://lkml.kernel.org/r/20190128133526.GD15461@krava +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol-elf.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c +index 66a84d5846c8..03cb8c6d620a 100644 +--- a/tools/perf/util/symbol-elf.c ++++ b/tools/perf/util/symbol-elf.c +@@ -87,6 +87,11 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym) + return GELF_ST_TYPE(sym->st_info); + } + ++static inline uint8_t elf_sym__visibility(const GElf_Sym *sym) ++{ ++ return GELF_ST_VISIBILITY(sym->st_other); ++} ++ + #ifndef STT_GNU_IFUNC + #define STT_GNU_IFUNC 10 + #endif +@@ -111,7 +116,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym) + return elf_sym__type(sym) == STT_NOTYPE && + sym->st_name != 0 && + sym->st_shndx != SHN_UNDEF && +- sym->st_shndx != SHN_ABS; ++ sym->st_shndx != SHN_ABS && ++ elf_sym__visibility(sym) != STV_HIDDEN && ++ elf_sym__visibility(sym) != STV_INTERNAL; + } + + static bool elf_sym__filter(GElf_Sym *sym) +-- +2.19.1 + diff --git a/queue-4.20/perf-tools-handle-topology-headers-with-no-cpu.patch b/queue-4.20/perf-tools-handle-topology-headers-with-no-cpu.patch new file mode 100644 index 00000000000..f71d0a96359 --- /dev/null +++ b/queue-4.20/perf-tools-handle-topology-headers-with-no-cpu.patch @@ -0,0 +1,67 @@ +From 6036ad1778f9306b2bd1f0579105a389ec65ddc3 Mon Sep 17 00:00:00 2001 +From: Stephane Eranian +Date: Sat, 19 Jan 2019 00:12:39 -0800 +Subject: perf tools: Handle TOPOLOGY headers with no CPU + +[ Upstream commit 1497e804d1a6e2bd9107ddf64b0310449f4673eb ] + +This patch fixes an issue in cpumap.c when used with the TOPOLOGY +header. In some configurations, some NUMA nodes may have no CPU (empty +cpulist). Yet a cpumap map must be created otherwise perf abort with an +error. This patch handles this case by creating a dummy map. + + Before: + + $ perf record -o - -e cycles noploop 2 | perf script -i - + 0x6e8 [0x6c]: failed to process type: 80 + + After: + + $ perf record -o - -e cycles noploop 2 | perf script -i - + noploop for 2 seconds + +Signed-off-by: Stephane Eranian +Acked-by: Jiri Olsa +Cc: Andi Kleen +Cc: Kan Liang +Cc: Peter Zijlstra +Link: http://lkml.kernel.org/r/1547885559-1657-1-git-send-email-eranian@google.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/cpumap.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c +index 1ccbd3342069..383674f448fc 100644 +--- a/tools/perf/util/cpumap.c ++++ b/tools/perf/util/cpumap.c +@@ -134,7 +134,12 @@ struct cpu_map *cpu_map__new(const char *cpu_list) + if (!cpu_list) + return cpu_map__read_all_cpu_map(); + +- if (!isdigit(*cpu_list)) ++ /* ++ * must handle the case of empty cpumap to cover ++ * TOPOLOGY header for NUMA nodes with no CPU ++ * ( e.g., because of CPU hotplug) ++ */ ++ if (!isdigit(*cpu_list) && *cpu_list != '\0') + goto out; + + while (isdigit(*cpu_list)) { +@@ -181,8 +186,10 @@ struct cpu_map *cpu_map__new(const char *cpu_list) + + if (nr_cpus > 0) + cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); +- else ++ else if (*cpu_list != '\0') + cpus = cpu_map__default_new(); ++ else ++ cpus = cpu_map__dummy_new(); + invalid: + free(tmp_cpus); + out: +-- +2.19.1 + diff --git a/queue-4.20/perf-trace-support-multiple-vfs_getname-probes.patch b/queue-4.20/perf-trace-support-multiple-vfs_getname-probes.patch new file mode 100644 index 00000000000..491ce6fc14c --- /dev/null +++ b/queue-4.20/perf-trace-support-multiple-vfs_getname-probes.patch @@ -0,0 +1,101 @@ +From d9ae2a61df34a119912deaedeb72d8e57943001e Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Tue, 29 Jan 2019 15:12:34 +0100 +Subject: perf trace: Support multiple "vfs_getname" probes + +[ Upstream commit 6ab3bc240ade47a0f52bc16d97edd9accbe0024e ] + +With a suitably defined "probe:vfs_getname" probe, 'perf trace' can +"beautify" its output, so syscalls like open() or openat() can print the +"filename" argument instead of just its hex address, like: + + $ perf trace -e open -- touch /dev/null + [...] + 0.590 ( 0.014 ms): touch/18063 open(filename: /dev/null, flags: CREAT|NOCTTY|NONBLOCK|WRONLY, mode: IRUGO|IWUGO) = 3 + [...] + +The output without such beautifier looks like: + + 0.529 ( 0.011 ms): touch/18075 open(filename: 0xc78cf288, flags: CREAT|NOCTTY|NONBLOCK|WRONLY, mode: IRUGO|IWUGO) = 3 + +However, when the vfs_getname probe expands to multiple probes and it is +not the first one that is hit, the beautifier fails, as following: + + 0.326 ( 0.010 ms): touch/18072 open(filename: , flags: CREAT|NOCTTY|NONBLOCK|WRONLY, mode: IRUGO|IWUGO) = 3 + +Fix it by hooking into all the expanded probes (inlines), now, for instance: + + [root@quaco ~]# perf probe -l + probe:vfs_getname (on getname_flags:73@fs/namei.c with pathname) + probe:vfs_getname_1 (on getname_flags:73@fs/namei.c with pathname) + [root@quaco ~]# perf trace -e open* sleep 1 + 0.010 ( 0.005 ms): sleep/5588 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: RDONLY|CLOEXEC) = 3 + 0.029 ( 0.006 ms): sleep/5588 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: RDONLY|CLOEXEC) = 3 + 0.194 ( 0.008 ms): sleep/5588 openat(dfd: CWD, filename: /usr/lib/locale/locale-archive, flags: RDONLY|CLOEXEC) = 3 + [root@quaco ~]# + +Works, further verified with: + + [root@quaco ~]# perf test vfs + 65: Use vfs_getname probe to get syscall args filenames : Ok + 66: Add vfs_getname probe to get syscall args filenames : Ok + 67: Check open filename arg using perf trace + vfs_getname: Ok + [root@quaco ~]# + +Reported-by: Michael Petlan +Tested-by: Michael Petlan +Cc: Adrian Hunter +Cc: Jiri Olsa +Cc: Namhyung Kim +Link: https://lkml.kernel.org/n/tip-mv8kolk17xla1smvmp3qabv1@git.kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-trace.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 835619476370..c108519ddd61 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -2424,19 +2424,30 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); + + static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) + { +- struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname"); ++ bool found = false; ++ struct perf_evsel *evsel, *tmp; ++ struct parse_events_error err = { .idx = 0, }; ++ int ret = parse_events(evlist, "probe:vfs_getname*", &err); + +- if (IS_ERR(evsel)) ++ if (ret) + return false; + +- if (perf_evsel__field(evsel, "pathname") == NULL) { ++ evlist__for_each_entry_safe(evlist, evsel, tmp) { ++ if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname")) ++ continue; ++ ++ if (perf_evsel__field(evsel, "pathname")) { ++ evsel->handler = trace__vfs_getname; ++ found = true; ++ continue; ++ } ++ ++ list_del_init(&evsel->node); ++ evsel->evlist = NULL; + perf_evsel__delete(evsel); +- return false; + } + +- evsel->handler = trace__vfs_getname; +- perf_evlist__add(evlist, evsel); +- return true; ++ return found; + } + + static struct perf_evsel *perf_evsel__new_pgfault(u64 config) +-- +2.19.1 + diff --git a/queue-4.20/pinctrl-mcp23s08-spi-fix-regmap-allocation-for-mcp23.patch b/queue-4.20/pinctrl-mcp23s08-spi-fix-regmap-allocation-for-mcp23.patch new file mode 100644 index 00000000000..e79aadd7274 --- /dev/null +++ b/queue-4.20/pinctrl-mcp23s08-spi-fix-regmap-allocation-for-mcp23.patch @@ -0,0 +1,45 @@ +From fe37ea8138817dc5e944be3a2e3c4dbf5bcfd605 Mon Sep 17 00:00:00 2001 +From: Jason Kridner +Date: Fri, 11 Jan 2019 10:02:13 -0500 +Subject: pinctrl: mcp23s08: spi: Fix regmap allocation for mcp23s18 + +[ Upstream commit f165988b77ef849eb0c1aebd94fe778024f88314 ] + +Fixes issue created by 9b3e4207661e67f04c72af15e29f74cd944f5964. + +It wasn't possible for one_regmap_config to be non-NULL at the point +it was tested for mcp23s18 devices. + +Applied the same pattern of allocating one_regmap_config using +devm_kmemdump() and then initializing the local regmap structure +from that. + +Signed-off-by: Jason Kridner +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-mcp23s08.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c +index b03481ef99a1..98905d4a79ca 100644 +--- a/drivers/pinctrl/pinctrl-mcp23s08.c ++++ b/drivers/pinctrl/pinctrl-mcp23s08.c +@@ -832,8 +832,13 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, + break; + + case MCP_TYPE_S18: ++ one_regmap_config = ++ devm_kmemdup(dev, &mcp23x17_regmap, ++ sizeof(struct regmap_config), GFP_KERNEL); ++ if (!one_regmap_config) ++ return -ENOMEM; + mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp, +- &mcp23x17_regmap); ++ one_regmap_config); + mcp->reg_shift = 1; + mcp->chip.ngpio = 16; + mcp->chip.label = "mcp23s18"; +-- +2.19.1 + diff --git a/queue-4.20/platform-x86-fix-unmet-dependency-warning-for-acpi_c.patch b/queue-4.20/platform-x86-fix-unmet-dependency-warning-for-acpi_c.patch new file mode 100644 index 00000000000..745587e3385 --- /dev/null +++ b/queue-4.20/platform-x86-fix-unmet-dependency-warning-for-acpi_c.patch @@ -0,0 +1,43 @@ +From c1bf40d16c16114b7f19cf93b7202f1836cb843f Mon Sep 17 00:00:00 2001 +From: Sinan Kaya +Date: Thu, 24 Jan 2019 19:31:00 +0000 +Subject: platform/x86: Fix unmet dependency warning for ACPI_CMPC + +[ Upstream commit d58bf90a32a33becec78c3034e781735049fcd25 ] + +Add BACKLIGHT_LCD_SUPPORT for ACPI_CMPC to fix the +warning: unmet direct dependencies detected for BACKLIGHT_CLASS_DEVICE. + +ACPI_CMPC selects BACKLIGHT_CLASS_DEVICE but BACKLIGHT_CLASS_DEVICE +depends on BACKLIGHT_LCD_SUPPORT. + +Copy BACKLIGHT_LCD_SUPPORT dependency into ACPI_CMPC to fix + +WARNING: unmet direct dependencies detected for BACKLIGHT_CLASS_DEVICE + Depends on [n]: HAS_IOMEM [=y] && BACKLIGHT_LCD_SUPPORT [=n] + Selected by [y]: + - ACPI_CMPC [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] && ACPI [=y] && INPUT [=y] && (RFKILL [=n] || RFKILL [=n]=n) + +Signed-off-by: Sinan Kaya +Acked-by: Andy Shevchenko +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 54f6a40c75c6..458f92aac92e 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -901,6 +901,7 @@ config TOSHIBA_WMI + config ACPI_CMPC + tristate "CMPC Laptop Extras" + depends on ACPI && INPUT ++ depends on BACKLIGHT_LCD_SUPPORT + depends on RFKILL || RFKILL=n + select BACKLIGHT_CLASS_DEVICE + help +-- +2.19.1 + diff --git a/queue-4.20/platform-x86-fix-unmet-dependency-warning-for-samsun.patch b/queue-4.20/platform-x86-fix-unmet-dependency-warning-for-samsun.patch new file mode 100644 index 00000000000..a6ecad79d62 --- /dev/null +++ b/queue-4.20/platform-x86-fix-unmet-dependency-warning-for-samsun.patch @@ -0,0 +1,43 @@ +From 35caa8b78a3b2149591bac057a8251161567a927 Mon Sep 17 00:00:00 2001 +From: Sinan Kaya +Date: Thu, 24 Jan 2019 19:31:01 +0000 +Subject: platform/x86: Fix unmet dependency warning for SAMSUNG_Q10 + +[ Upstream commit 0ee4b5f801b73b83a9fb3921d725f2162fd4a2e5 ] + +Add BACKLIGHT_LCD_SUPPORT for SAMSUNG_Q10 to fix the +warning: unmet direct dependencies detected for BACKLIGHT_CLASS_DEVICE. + +SAMSUNG_Q10 selects BACKLIGHT_CLASS_DEVICE but BACKLIGHT_CLASS_DEVICE +depends on BACKLIGHT_LCD_SUPPORT. + +Copy BACKLIGHT_LCD_SUPPORT dependency into SAMSUNG_Q10 to fix: + +WARNING: unmet direct dependencies detected for BACKLIGHT_CLASS_DEVICE + Depends on [n]: HAS_IOMEM [=y] && BACKLIGHT_LCD_SUPPORT [=n] + Selected by [y]: + - SAMSUNG_Q10 [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] && ACPI [=y] + +Signed-off-by: Sinan Kaya +Acked-by: Andy Shevchenko +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 458f92aac92e..0430cad6d84e 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -1125,6 +1125,7 @@ config INTEL_OAKTRAIL + config SAMSUNG_Q10 + tristate "Samsung Q10 Extras" + depends on ACPI ++ depends on BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE + ---help--- + This driver provides support for backlight control on Samsung Q10 +-- +2.19.1 + diff --git a/queue-4.20/proc-fix-proc-net-after-setns-2.patch b/queue-4.20/proc-fix-proc-net-after-setns-2.patch new file mode 100644 index 00000000000..4e8bb941b21 --- /dev/null +++ b/queue-4.20/proc-fix-proc-net-after-setns-2.patch @@ -0,0 +1,289 @@ +From 998797024f3bcf7650b6ec8d04e7fce1f19c9902 Mon Sep 17 00:00:00 2001 +From: Alexey Dobriyan +Date: Fri, 1 Feb 2019 14:20:01 -0800 +Subject: proc: fix /proc/net/* after setns(2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 1fde6f21d90f8ba5da3cb9c54ca991ed72696c43 ] + +/proc entries under /proc/net/* can't be cached into dcache because +setns(2) can change current net namespace. + +[akpm@linux-foundation.org: coding-style fixes] +[akpm@linux-foundation.org: avoid vim miscolorization] +[adobriyan@gmail.com: write test, add dummy ->d_revalidate hook: necessary if /proc/net/* is pinned at setns time] + Link: http://lkml.kernel.org/r/20190108192350.GA12034@avx2 +Link: http://lkml.kernel.org/r/20190107162336.GA9239@avx2 +Fixes: 1da4d377f943fe4194ffb9fb9c26cc58fad4dd24 ("proc: revalidate misc dentries") +Signed-off-by: Alexey Dobriyan +Reported-by: Mateusz Stępień +Reported-by: Ahmad Fatoum +Cc: Al Viro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + fs/proc/generic.c | 4 +- + fs/proc/internal.h | 1 + + fs/proc/proc_net.c | 20 +++ + tools/testing/selftests/proc/.gitignore | 1 + + tools/testing/selftests/proc/Makefile | 1 + + tools/testing/selftests/proc/setns-dcache.c | 129 ++++++++++++++++++++ + 6 files changed, 155 insertions(+), 1 deletion(-) + create mode 100644 tools/testing/selftests/proc/setns-dcache.c + +diff --git a/fs/proc/generic.c b/fs/proc/generic.c +index 8ae109429a88..e39bac94dead 100644 +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -256,7 +256,7 @@ struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry, + inode = proc_get_inode(dir->i_sb, de); + if (!inode) + return ERR_PTR(-ENOMEM); +- d_set_d_op(dentry, &proc_misc_dentry_ops); ++ d_set_d_op(dentry, de->proc_dops); + return d_splice_alias(inode, dentry); + } + read_unlock(&proc_subdir_lock); +@@ -429,6 +429,8 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, + INIT_LIST_HEAD(&ent->pde_openers); + proc_set_user(ent, (*parent)->uid, (*parent)->gid); + ++ ent->proc_dops = &proc_misc_dentry_ops; ++ + out: + return ent; + } +diff --git a/fs/proc/internal.h b/fs/proc/internal.h +index 5185d7f6a51e..95b14196f284 100644 +--- a/fs/proc/internal.h ++++ b/fs/proc/internal.h +@@ -44,6 +44,7 @@ struct proc_dir_entry { + struct completion *pde_unload_completion; + const struct inode_operations *proc_iops; + const struct file_operations *proc_fops; ++ const struct dentry_operations *proc_dops; + union { + const struct seq_operations *seq_ops; + int (*single_show)(struct seq_file *, void *); +diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c +index d5e0fcb3439e..a7b12435519e 100644 +--- a/fs/proc/proc_net.c ++++ b/fs/proc/proc_net.c +@@ -38,6 +38,22 @@ static struct net *get_proc_net(const struct inode *inode) + return maybe_get_net(PDE_NET(PDE(inode))); + } + ++static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) ++{ ++ return 0; ++} ++ ++static const struct dentry_operations proc_net_dentry_ops = { ++ .d_revalidate = proc_net_d_revalidate, ++ .d_delete = always_delete_dentry, ++}; ++ ++static void pde_force_lookup(struct proc_dir_entry *pde) ++{ ++ /* /proc/net/ entries can be changed under us by setns(CLONE_NEWNET) */ ++ pde->proc_dops = &proc_net_dentry_ops; ++} ++ + static int seq_open_net(struct inode *inode, struct file *file) + { + unsigned int state_size = PDE(inode)->state_size; +@@ -90,6 +106,7 @@ struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode, + p = proc_create_reg(name, mode, &parent, data); + if (!p) + return NULL; ++ pde_force_lookup(p); + p->proc_fops = &proc_net_seq_fops; + p->seq_ops = ops; + p->state_size = state_size; +@@ -133,6 +150,7 @@ struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode + p = proc_create_reg(name, mode, &parent, data); + if (!p) + return NULL; ++ pde_force_lookup(p); + p->proc_fops = &proc_net_seq_fops; + p->seq_ops = ops; + p->state_size = state_size; +@@ -181,6 +199,7 @@ struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode, + p = proc_create_reg(name, mode, &parent, data); + if (!p) + return NULL; ++ pde_force_lookup(p); + p->proc_fops = &proc_net_single_fops; + p->single_show = show; + return proc_register(parent, p); +@@ -223,6 +242,7 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo + p = proc_create_reg(name, mode, &parent, data); + if (!p) + return NULL; ++ pde_force_lookup(p); + p->proc_fops = &proc_net_single_fops; + p->single_show = show; + p->write = write; +diff --git a/tools/testing/selftests/proc/.gitignore b/tools/testing/selftests/proc/.gitignore +index 82121a81681f..29bac5ef9a93 100644 +--- a/tools/testing/selftests/proc/.gitignore ++++ b/tools/testing/selftests/proc/.gitignore +@@ -10,4 +10,5 @@ + /proc-uptime-002 + /read + /self ++/setns-dcache + /thread-self +diff --git a/tools/testing/selftests/proc/Makefile b/tools/testing/selftests/proc/Makefile +index 1c12c34cf85d..434d033ee067 100644 +--- a/tools/testing/selftests/proc/Makefile ++++ b/tools/testing/selftests/proc/Makefile +@@ -14,6 +14,7 @@ TEST_GEN_PROGS += proc-uptime-001 + TEST_GEN_PROGS += proc-uptime-002 + TEST_GEN_PROGS += read + TEST_GEN_PROGS += self ++TEST_GEN_PROGS += setns-dcache + TEST_GEN_PROGS += thread-self + + include ../lib.mk +diff --git a/tools/testing/selftests/proc/setns-dcache.c b/tools/testing/selftests/proc/setns-dcache.c +new file mode 100644 +index 000000000000..60ab197a73fc +--- /dev/null ++++ b/tools/testing/selftests/proc/setns-dcache.c +@@ -0,0 +1,129 @@ ++/* ++ * Copyright © 2019 Alexey Dobriyan ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* ++ * Test that setns(CLONE_NEWNET) points to new /proc/net content even ++ * if old one is in dcache. ++ * ++ * FIXME /proc/net/unix is under CONFIG_UNIX which can be disabled. ++ */ ++#undef NDEBUG ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static pid_t pid = -1; ++ ++static void f(void) ++{ ++ if (pid > 0) { ++ kill(pid, SIGTERM); ++ } ++} ++ ++int main(void) ++{ ++ int fd[2]; ++ char _ = 0; ++ int nsfd; ++ ++ atexit(f); ++ ++ /* Check for priviledges and syscall availability straight away. */ ++ if (unshare(CLONE_NEWNET) == -1) { ++ if (errno == ENOSYS || errno == EPERM) { ++ return 4; ++ } ++ return 1; ++ } ++ /* Distinguisher between two otherwise empty net namespaces. */ ++ if (socket(AF_UNIX, SOCK_STREAM, 0) == -1) { ++ return 1; ++ } ++ ++ if (pipe(fd) == -1) { ++ return 1; ++ } ++ ++ pid = fork(); ++ if (pid == -1) { ++ return 1; ++ } ++ ++ if (pid == 0) { ++ if (unshare(CLONE_NEWNET) == -1) { ++ return 1; ++ } ++ ++ if (write(fd[1], &_, 1) != 1) { ++ return 1; ++ } ++ ++ pause(); ++ ++ return 0; ++ } ++ ++ if (read(fd[0], &_, 1) != 1) { ++ return 1; ++ } ++ ++ { ++ char buf[64]; ++ snprintf(buf, sizeof(buf), "/proc/%u/ns/net", pid); ++ nsfd = open(buf, O_RDONLY); ++ if (nsfd == -1) { ++ return 1; ++ } ++ } ++ ++ /* Reliably pin dentry into dcache. */ ++ (void)open("/proc/net/unix", O_RDONLY); ++ ++ if (setns(nsfd, CLONE_NEWNET) == -1) { ++ return 1; ++ } ++ ++ kill(pid, SIGTERM); ++ pid = 0; ++ ++ { ++ char buf[4096]; ++ ssize_t rv; ++ int fd; ++ ++ fd = open("/proc/net/unix", O_RDONLY); ++ if (fd == -1) { ++ return 1; ++ } ++ ++#define S "Num RefCount Protocol Flags Type St Inode Path\n" ++ rv = read(fd, buf, sizeof(buf)); ++ ++ assert(rv == strlen(S)); ++ assert(memcmp(buf, S, strlen(S)) == 0); ++ } ++ ++ return 0; ++} +-- +2.19.1 + diff --git a/queue-4.20/psi-fix-aggregation-idle-shut-off.patch b/queue-4.20/psi-fix-aggregation-idle-shut-off.patch new file mode 100644 index 00000000000..b7c615e16f6 --- /dev/null +++ b/queue-4.20/psi-fix-aggregation-idle-shut-off.patch @@ -0,0 +1,184 @@ +From 772d6c6203333b1d6fea265067b3c65fa19c0a63 Mon Sep 17 00:00:00 2001 +From: Johannes Weiner +Date: Fri, 1 Feb 2019 14:20:42 -0800 +Subject: psi: fix aggregation idle shut-off + +[ Upstream commit 1b69ac6b40ebd85eed73e4dbccde2a36961ab990 ] + +psi has provisions to shut off the periodic aggregation worker when +there is a period of no task activity - and thus no data that needs +aggregating. However, while developing psi monitoring, Suren noticed +that the aggregation clock currently won't stay shut off for good. + +Debugging this revealed a flaw in the idle design: an aggregation run +will see no task activity and decide to go to sleep; shortly thereafter, +the kworker thread that executed the aggregation will go idle and cause +a scheduling change, during which the psi callback will kick the +!pending worker again. This will ping-pong forever, and is equivalent +to having no shut-off logic at all (but with more code!) + +Fix this by exempting aggregation workers from psi's clock waking logic +when the state change is them going to sleep. To do this, tag workers +with the last work function they executed, and if in psi we see a worker +going to sleep after aggregating psi data, we will not reschedule the +aggregation work item. + +What if the worker is also executing other items before or after? + +Any psi state times that were incurred by work items preceding the +aggregation work will have been collected from the per-cpu buckets +during the aggregation itself. If there are work items following the +aggregation work, the worker's last_func tag will be overwritten and the +aggregator will be kept alive to process this genuine new activity. + +If the aggregation work is the last thing the worker does, and we decide +to go idle, the brief period of non-idle time incurred between the +aggregation run and the kworker's dequeue will be stranded in the +per-cpu buckets until the clock is woken by later activity. But that +should not be a problem. The buckets can hold 4s worth of time, and +future activity will wake the clock with a 2s delay, giving us 2s worth +of data we can leave behind when disabling aggregation. If it takes a +worker more than two seconds to go idle after it finishes its last work +item, we likely have bigger problems in the system, and won't notice one +sample that was averaged with a bogus per-CPU weight. + +Link: http://lkml.kernel.org/r/20190116193501.1910-1-hannes@cmpxchg.org +Fixes: eb414681d5a0 ("psi: pressure stall information for CPU, memory, and IO") +Signed-off-by: Johannes Weiner +Reported-by: Suren Baghdasaryan +Acked-by: Tejun Heo +Cc: Peter Zijlstra +Cc: Lai Jiangshan +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + kernel/sched/psi.c | 21 +++++++++++++++++---- + kernel/workqueue.c | 23 +++++++++++++++++++++++ + kernel/workqueue_internal.h | 6 +++++- + 3 files changed, 45 insertions(+), 5 deletions(-) + +diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c +index fe24de3fbc93..c3484785b179 100644 +--- a/kernel/sched/psi.c ++++ b/kernel/sched/psi.c +@@ -124,6 +124,7 @@ + * sampling of the aggregate task states would be. + */ + ++#include "../workqueue_internal.h" + #include + #include + #include +@@ -480,9 +481,6 @@ static void psi_group_change(struct psi_group *group, int cpu, + groupc->tasks[t]++; + + write_seqcount_end(&groupc->seq); +- +- if (!delayed_work_pending(&group->clock_work)) +- schedule_delayed_work(&group->clock_work, PSI_FREQ); + } + + static struct psi_group *iterate_groups(struct task_struct *task, void **iter) +@@ -513,6 +511,7 @@ void psi_task_change(struct task_struct *task, int clear, int set) + { + int cpu = task_cpu(task); + struct psi_group *group; ++ bool wake_clock = true; + void *iter = NULL; + + if (!task->pid) +@@ -530,8 +529,22 @@ void psi_task_change(struct task_struct *task, int clear, int set) + task->psi_flags &= ~clear; + task->psi_flags |= set; + +- while ((group = iterate_groups(task, &iter))) ++ /* ++ * Periodic aggregation shuts off if there is a period of no ++ * task changes, so we wake it back up if necessary. However, ++ * don't do this if the task change is the aggregation worker ++ * itself going to sleep, or we'll ping-pong forever. ++ */ ++ if (unlikely((clear & TSK_RUNNING) && ++ (task->flags & PF_WQ_WORKER) && ++ wq_worker_last_func(task) == psi_update_work)) ++ wake_clock = false; ++ ++ while ((group = iterate_groups(task, &iter))) { + psi_group_change(group, cpu, clear, set); ++ if (wake_clock && !delayed_work_pending(&group->clock_work)) ++ schedule_delayed_work(&group->clock_work, PSI_FREQ); ++ } + } + + void psi_memstall_tick(struct task_struct *task, int cpu) +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 0280deac392e..288b2105bbb1 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -909,6 +909,26 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task) + return to_wakeup ? to_wakeup->task : NULL; + } + ++/** ++ * wq_worker_last_func - retrieve worker's last work function ++ * ++ * Determine the last function a worker executed. This is called from ++ * the scheduler to get a worker's last known identity. ++ * ++ * CONTEXT: ++ * spin_lock_irq(rq->lock) ++ * ++ * Return: ++ * The last work function %current executed as a worker, NULL if it ++ * hasn't executed any work yet. ++ */ ++work_func_t wq_worker_last_func(struct task_struct *task) ++{ ++ struct worker *worker = kthread_data(task); ++ ++ return worker->last_func; ++} ++ + /** + * worker_set_flags - set worker flags and adjust nr_running accordingly + * @worker: self +@@ -2184,6 +2204,9 @@ __acquires(&pool->lock) + if (unlikely(cpu_intensive)) + worker_clr_flags(worker, WORKER_CPU_INTENSIVE); + ++ /* tag the worker for identification in schedule() */ ++ worker->last_func = worker->current_func; ++ + /* we're done with it, release */ + hash_del(&worker->hentry); + worker->current_work = NULL; +diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h +index 66fbb5a9e633..cb68b03ca89a 100644 +--- a/kernel/workqueue_internal.h ++++ b/kernel/workqueue_internal.h +@@ -53,6 +53,9 @@ struct worker { + + /* used only by rescuers to point to the target workqueue */ + struct workqueue_struct *rescue_wq; /* I: the workqueue to rescue */ ++ ++ /* used by the scheduler to determine a worker's last known identity */ ++ work_func_t last_func; + }; + + /** +@@ -67,9 +70,10 @@ static inline struct worker *current_wq_worker(void) + + /* + * Scheduler hooks for concurrency managed workqueue. Only to be used from +- * sched/core.c and workqueue.c. ++ * sched/ and workqueue.c. + */ + void wq_worker_waking_up(struct task_struct *task, int cpu); + struct task_struct *wq_worker_sleeping(struct task_struct *task); ++work_func_t wq_worker_last_func(struct task_struct *task); + + #endif /* _KERNEL_WORKQUEUE_INTERNAL_H */ +-- +2.19.1 + diff --git a/queue-4.20/qed-consider-tx-tcs-while-deriving-the-max-num_queue.patch b/queue-4.20/qed-consider-tx-tcs-while-deriving-the-max-num_queue.patch new file mode 100644 index 00000000000..3234d339a32 --- /dev/null +++ b/queue-4.20/qed-consider-tx-tcs-while-deriving-the-max-num_queue.patch @@ -0,0 +1,44 @@ +From 1fab5a9a96b7e11eff6daa1ad48618573cc762cb Mon Sep 17 00:00:00 2001 +From: Sudarsana Reddy Kalluru +Date: Wed, 6 Feb 2019 14:43:44 -0800 +Subject: qed: Consider TX tcs while deriving the max num_queues for PF. + +[ Upstream commit fb1faab74ddef9ec2d841d54e5d0912a097b3abe ] + +Max supported queues is derived incorrectly in the case of multi-CoS. +Need to consider TCs while calculating num_queues for PF. + +Signed-off-by: Sudarsana Reddy Kalluru +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_l2.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c +index e68ca83ae915..64ac95ca4df2 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c +@@ -2216,7 +2216,7 @@ static int qed_fill_eth_dev_info(struct qed_dev *cdev, + u16 num_queues = 0; + + /* Since the feature controls only queue-zones, +- * make sure we have the contexts [rx, tx, xdp] to ++ * make sure we have the contexts [rx, xdp, tcs] to + * match. + */ + for_each_hwfn(cdev, i) { +@@ -2226,7 +2226,8 @@ static int qed_fill_eth_dev_info(struct qed_dev *cdev, + u16 cids; + + cids = hwfn->pf_params.eth_pf_params.num_cons; +- num_queues += min_t(u16, l2_queues, cids / 3); ++ cids /= (2 + info->num_tc); ++ num_queues += min_t(u16, l2_queues, cids); + } + + /* queues might theoretically be >256, but interrupts' +-- +2.19.1 + diff --git a/queue-4.20/qed-fix-bug-in-tx-promiscuous-mode-settings.patch b/queue-4.20/qed-fix-bug-in-tx-promiscuous-mode-settings.patch new file mode 100644 index 00000000000..e7b8531d255 --- /dev/null +++ b/queue-4.20/qed-fix-bug-in-tx-promiscuous-mode-settings.patch @@ -0,0 +1,55 @@ +From dead03346674367021c72eae3738e87d8f3e09a1 Mon Sep 17 00:00:00 2001 +From: Manish Chopra +Date: Mon, 28 Jan 2019 10:05:04 -0800 +Subject: qed: Fix bug in tx promiscuous mode settings + +[ Upstream commit 9e71a15d8b5bbce25c637f7f8833cd3f45b65646 ] + +When running tx switched traffic between VNICs +created via a bridge(to which VFs are added), +adapter drops the unicast packets in tx flow due to +VNIC's ucast mac being unknown to it. But VF interfaces +being in promiscuous mode should have caused adapter +to accept all the unknown ucast packets. Later, it +was found that driver doesn't really configure tx +promiscuous mode settings to accept all unknown unicast macs. + +This patch fixes tx promiscuous mode settings to accept all +unknown/unmatched unicast macs and works out the scenario. + +Signed-off-by: Manish Chopra +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_l2.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c +index 67c02ea93906..b8baa6fcef8e 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c +@@ -609,6 +609,10 @@ qed_sp_update_accept_mode(struct qed_hwfn *p_hwfn, + (!!(accept_filter & QED_ACCEPT_MCAST_MATCHED) && + !!(accept_filter & QED_ACCEPT_MCAST_UNMATCHED))); + ++ SET_FIELD(state, ETH_VPORT_TX_MODE_UCAST_ACCEPT_ALL, ++ (!!(accept_filter & QED_ACCEPT_UCAST_MATCHED) && ++ !!(accept_filter & QED_ACCEPT_UCAST_UNMATCHED))); ++ + SET_FIELD(state, ETH_VPORT_TX_MODE_BCAST_ACCEPT_ALL, + !!(accept_filter & QED_ACCEPT_BCAST)); + +@@ -2688,7 +2692,8 @@ static int qed_configure_filter_rx_mode(struct qed_dev *cdev, + if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) { + accept_flags.rx_accept_filter |= QED_ACCEPT_UCAST_UNMATCHED | + QED_ACCEPT_MCAST_UNMATCHED; +- accept_flags.tx_accept_filter |= QED_ACCEPT_MCAST_UNMATCHED; ++ accept_flags.tx_accept_filter |= QED_ACCEPT_UCAST_UNMATCHED | ++ QED_ACCEPT_MCAST_UNMATCHED; + } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) { + accept_flags.rx_accept_filter |= QED_ACCEPT_MCAST_UNMATCHED; + accept_flags.tx_accept_filter |= QED_ACCEPT_MCAST_UNMATCHED; +-- +2.19.1 + diff --git a/queue-4.20/qed-fix-eq-full-firmware-assert.patch b/queue-4.20/qed-fix-eq-full-firmware-assert.patch new file mode 100644 index 00000000000..b55f641f8ca --- /dev/null +++ b/queue-4.20/qed-fix-eq-full-firmware-assert.patch @@ -0,0 +1,84 @@ +From f6d74bf1d3a5ebc3689966411ddf2527872a136a Mon Sep 17 00:00:00 2001 +From: Manish Chopra +Date: Wed, 6 Feb 2019 14:43:42 -0800 +Subject: qed: Fix EQ full firmware assert. + +[ Upstream commit 660492bcf4a7561b5fdc13be0ae0b0c0a8c120be ] + +When slowpath messages are sent with high rate, the resulting +events can lead to a FW assert in case they are not handled fast +enough (Event Queue Full assert). Attempt to send queued slowpath +messages only after the newly evacuated entries in the EQ ring +are indicated to FW. + +Signed-off-by: Manish Chopra +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_sp.h | 1 + + drivers/net/ethernet/qlogic/qed/qed_spq.c | 15 +++++++-------- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h +index 3157c0d99441..dae2896e1d8e 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_sp.h ++++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h +@@ -380,6 +380,7 @@ void qed_consq_setup(struct qed_hwfn *p_hwfn); + * @param p_hwfn + */ + void qed_consq_free(struct qed_hwfn *p_hwfn); ++int qed_spq_pend_post(struct qed_hwfn *p_hwfn); + + /** + * @file +diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c +index 0a9c5bb0fa48..a721b9348b6c 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c +@@ -402,6 +402,11 @@ int qed_eq_completion(struct qed_hwfn *p_hwfn, void *cookie) + + qed_eq_prod_update(p_hwfn, qed_chain_get_prod_idx(p_chain)); + ++ /* Attempt to post pending requests */ ++ spin_lock_bh(&p_hwfn->p_spq->lock); ++ rc = qed_spq_pend_post(p_hwfn); ++ spin_unlock_bh(&p_hwfn->p_spq->lock); ++ + return rc; + } + +@@ -744,7 +749,7 @@ static int qed_spq_post_list(struct qed_hwfn *p_hwfn, + return 0; + } + +-static int qed_spq_pend_post(struct qed_hwfn *p_hwfn) ++int qed_spq_pend_post(struct qed_hwfn *p_hwfn) + { + struct qed_spq *p_spq = p_hwfn->p_spq; + struct qed_spq_entry *p_ent = NULL; +@@ -882,7 +887,6 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, + struct qed_spq_entry *p_ent = NULL; + struct qed_spq_entry *tmp; + struct qed_spq_entry *found = NULL; +- int rc; + + if (!p_hwfn) + return -EINVAL; +@@ -940,12 +944,7 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, + */ + qed_spq_return_entry(p_hwfn, found); + +- /* Attempt to post pending requests */ +- spin_lock_bh(&p_spq->lock); +- rc = qed_spq_pend_post(p_hwfn); +- spin_unlock_bh(&p_spq->lock); +- +- return rc; ++ return 0; + } + + int qed_consq_alloc(struct qed_hwfn *p_hwfn) +-- +2.19.1 + diff --git a/queue-4.20/qed-fix-lacp-pdu-drops-for-vfs.patch b/queue-4.20/qed-fix-lacp-pdu-drops-for-vfs.patch new file mode 100644 index 00000000000..996325b057e --- /dev/null +++ b/queue-4.20/qed-fix-lacp-pdu-drops-for-vfs.patch @@ -0,0 +1,94 @@ +From fdcb03cbaecd25dac6af62d445ad337a174ff7ce Mon Sep 17 00:00:00 2001 +From: Manish Chopra +Date: Mon, 28 Jan 2019 10:05:05 -0800 +Subject: qed: Fix LACP pdu drops for VFs + +[ Upstream commit ff9296966e5e00b0d0d00477b2365a178f0f06a3 ] + +VF is always configured to drop control frames +(with reserved mac addresses) but to work LACP +on the VFs, it would require LACP control frames +to be forwarded or transmitted successfully. + +This patch fixes this in such a way that trusted VFs +(marked through ndo_set_vf_trust) would be allowed to +pass the control frames such as LACP pdus. + +Signed-off-by: Manish Chopra +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_l2.c | 5 +++++ + drivers/net/ethernet/qlogic/qed/qed_l2.h | 3 +++ + drivers/net/ethernet/qlogic/qed/qed_sriov.c | 10 ++++++++-- + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c +index b8baa6fcef8e..e68ca83ae915 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c +@@ -748,6 +748,11 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn, + return rc; + } + ++ if (p_params->update_ctl_frame_check) { ++ p_cmn->ctl_frame_mac_check_en = p_params->mac_chk_en; ++ p_cmn->ctl_frame_ethtype_check_en = p_params->ethtype_chk_en; ++ } ++ + /* Update mcast bins for VFs, PF doesn't use this functionality */ + qed_sp_update_mcast_bin(p_hwfn, p_ramrod, p_params); + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.h b/drivers/net/ethernet/qlogic/qed/qed_l2.h +index 8d80f1095d17..7127d5aaac42 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_l2.h ++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.h +@@ -219,6 +219,9 @@ struct qed_sp_vport_update_params { + struct qed_rss_params *rss_params; + struct qed_filter_accept_flags accept_flags; + struct qed_sge_tpa_params *sge_tpa_params; ++ u8 update_ctl_frame_check; ++ u8 mac_chk_en; ++ u8 ethtype_chk_en; + }; + + int qed_sp_vport_update(struct qed_hwfn *p_hwfn, +diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c +index ca6290fa0f30..71a7af134dd8 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c +@@ -1969,7 +1969,9 @@ static void qed_iov_vf_mbx_start_vport(struct qed_hwfn *p_hwfn, + params.vport_id = vf->vport_id; + params.max_buffers_per_cqe = start->max_buffers_per_cqe; + params.mtu = vf->mtu; +- params.check_mac = true; ++ ++ /* Non trusted VFs should enable control frame filtering */ ++ params.check_mac = !vf->p_vf_info.is_trusted_configured; + + rc = qed_sp_eth_vport_start(p_hwfn, ¶ms); + if (rc) { +@@ -5130,6 +5132,9 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn) + params.opaque_fid = vf->opaque_fid; + params.vport_id = vf->vport_id; + ++ params.update_ctl_frame_check = 1; ++ params.mac_chk_en = !vf_info->is_trusted_configured; ++ + if (vf_info->rx_accept_mode & mask) { + flags->update_rx_mode_config = 1; + flags->rx_accept_filter = vf_info->rx_accept_mode; +@@ -5147,7 +5152,8 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn) + } + + if (flags->update_rx_mode_config || +- flags->update_tx_mode_config) ++ flags->update_tx_mode_config || ++ params.update_ctl_frame_check) + qed_sp_vport_update(hwfn, ¶ms, + QED_SPQ_MODE_EBLOCK, NULL); + } +-- +2.19.1 + diff --git a/queue-4.20/qed-fix-stack-out-of-bounds-bug.patch b/queue-4.20/qed-fix-stack-out-of-bounds-bug.patch new file mode 100644 index 00000000000..cf621ec79d9 --- /dev/null +++ b/queue-4.20/qed-fix-stack-out-of-bounds-bug.patch @@ -0,0 +1,109 @@ +From 24d8e70c9ad08a296454806c16f7bd1b0692c9ba Mon Sep 17 00:00:00 2001 +From: Manish Chopra +Date: Mon, 28 Jan 2019 10:05:08 -0800 +Subject: qed: Fix stack out of bounds bug + +[ Upstream commit ffb057f98928aa099b08e419bbe5afc26ec9f448 ] + +KASAN reported following bug in qed_init_qm_get_idx_from_flags +due to inappropriate casting of "pq_flags". Fix the type of "pq_flags". + +[ 196.624707] BUG: KASAN: stack-out-of-bounds in qed_init_qm_get_idx_from_flags+0x1a4/0x1b8 [qed] +[ 196.624712] Read of size 8 at addr ffff809b00bc7360 by task kworker/0:9/1712 +[ 196.624714] +[ 196.624720] CPU: 0 PID: 1712 Comm: kworker/0:9 Not tainted 4.18.0-60.el8.aarch64+debug #1 +[ 196.624723] Hardware name: To be filled by O.E.M. Saber/Saber, BIOS 0ACKL024 09/26/2018 +[ 196.624733] Workqueue: events work_for_cpu_fn +[ 196.624738] Call trace: +[ 196.624742] dump_backtrace+0x0/0x2f8 +[ 196.624745] show_stack+0x24/0x30 +[ 196.624749] dump_stack+0xe0/0x11c +[ 196.624755] print_address_description+0x68/0x260 +[ 196.624759] kasan_report+0x178/0x340 +[ 196.624762] __asan_report_load_n_noabort+0x38/0x48 +[ 196.624786] qed_init_qm_get_idx_from_flags+0x1a4/0x1b8 [qed] +[ 196.624808] qed_init_qm_info+0xec0/0x2200 [qed] +[ 196.624830] qed_resc_alloc+0x284/0x7e8 [qed] +[ 196.624853] qed_slowpath_start+0x6cc/0x1ae8 [qed] +[ 196.624864] __qede_probe.isra.10+0x1cc/0x12c0 [qede] +[ 196.624874] qede_probe+0x78/0xf0 [qede] +[ 196.624879] local_pci_probe+0xc4/0x180 +[ 196.624882] work_for_cpu_fn+0x54/0x98 +[ 196.624885] process_one_work+0x758/0x1900 +[ 196.624888] worker_thread+0x4e0/0xd18 +[ 196.624892] kthread+0x2c8/0x350 +[ 196.624897] ret_from_fork+0x10/0x18 +[ 196.624899] +[ 196.624902] Allocated by task 2: +[ 196.624906] kasan_kmalloc.part.1+0x40/0x108 +[ 196.624909] kasan_kmalloc+0xb4/0xc8 +[ 196.624913] kasan_slab_alloc+0x14/0x20 +[ 196.624916] kmem_cache_alloc_node+0x1dc/0x480 +[ 196.624921] copy_process.isra.1.part.2+0x1d8/0x4a98 +[ 196.624924] _do_fork+0x150/0xfa0 +[ 196.624926] kernel_thread+0x48/0x58 +[ 196.624930] kthreadd+0x3a4/0x5a0 +[ 196.624932] ret_from_fork+0x10/0x18 +[ 196.624934] +[ 196.624937] Freed by task 0: +[ 196.624938] (stack is not available) +[ 196.624940] +[ 196.624943] The buggy address belongs to the object at ffff809b00bc0000 +[ 196.624943] which belongs to the cache thread_stack of size 32768 +[ 196.624946] The buggy address is located 29536 bytes inside of +[ 196.624946] 32768-byte region [ffff809b00bc0000, ffff809b00bc8000) +[ 196.624948] The buggy address belongs to the page: +[ 196.624952] page:ffff7fe026c02e00 count:1 mapcount:0 mapping:ffff809b4001c000 index:0x0 compound_mapcount: 0 +[ 196.624960] flags: 0xfffff8000008100(slab|head) +[ 196.624967] raw: 0fffff8000008100 dead000000000100 dead000000000200 ffff809b4001c000 +[ 196.624970] raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000 +[ 196.624973] page dumped because: kasan: bad access detected +[ 196.624974] +[ 196.624976] Memory state around the buggy address: +[ 196.624980] ffff809b00bc7200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 196.624983] ffff809b00bc7280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 196.624985] >ffff809b00bc7300: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 f2 f2 +[ 196.624988] ^ +[ 196.624990] ffff809b00bc7380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 196.624993] ffff809b00bc7400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 196.624995] ================================================================== + +Signed-off-by: Manish Chopra +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_dev.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c +index 88a8576ca9ce..f81abed29a76 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c +@@ -480,19 +480,19 @@ static void qed_init_qm_pq(struct qed_hwfn *p_hwfn, + + /* get pq index according to PQ_FLAGS */ + static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn, +- u32 pq_flags) ++ unsigned long pq_flags) + { + struct qed_qm_info *qm_info = &p_hwfn->qm_info; + + /* Can't have multiple flags set here */ +- if (bitmap_weight((unsigned long *)&pq_flags, ++ if (bitmap_weight(&pq_flags, + sizeof(pq_flags) * BITS_PER_BYTE) > 1) { +- DP_ERR(p_hwfn, "requested multiple pq flags 0x%x\n", pq_flags); ++ DP_ERR(p_hwfn, "requested multiple pq flags 0x%lx\n", pq_flags); + goto err; + } + + if (!(qed_get_pq_flags(p_hwfn) & pq_flags)) { +- DP_ERR(p_hwfn, "pq flag 0x%x is not set\n", pq_flags); ++ DP_ERR(p_hwfn, "pq flag 0x%lx is not set\n", pq_flags); + goto err; + } + +-- +2.19.1 + diff --git a/queue-4.20/qed-fix-system-crash-in-ll2-xmit.patch b/queue-4.20/qed-fix-system-crash-in-ll2-xmit.patch new file mode 100644 index 00000000000..a636580661b --- /dev/null +++ b/queue-4.20/qed-fix-system-crash-in-ll2-xmit.patch @@ -0,0 +1,84 @@ +From 1086848b88bb2ee7798fd4a75aa021c65fa0df0b Mon Sep 17 00:00:00 2001 +From: Manish Chopra +Date: Mon, 28 Jan 2019 10:05:07 -0800 +Subject: qed: Fix system crash in ll2 xmit + +[ Upstream commit 7c81626a3c37e4ac320b8ad785694ba498f24794 ] + +Cache number of fragments in the skb locally as in case +of linear skb (with zero fragments), tx completion +(or freeing of skb) may happen before driver tries +to get number of frgaments from the skb which could +lead to stale access to an already freed skb. + +Signed-off-by: Manish Chopra +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_ll2.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c +index 9e728ec82c21..25f67c0d5c57 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c +@@ -2441,19 +2441,24 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb, + { + struct qed_ll2_tx_pkt_info pkt; + const skb_frag_t *frag; ++ u8 flags = 0, nr_frags; + int rc = -EINVAL, i; + dma_addr_t mapping; + u16 vlan = 0; +- u8 flags = 0; + + if (unlikely(skb->ip_summed != CHECKSUM_NONE)) { + DP_INFO(cdev, "Cannot transmit a checksummed packet\n"); + return -EINVAL; + } + +- if (1 + skb_shinfo(skb)->nr_frags > CORE_LL2_TX_MAX_BDS_PER_PACKET) { ++ /* Cache number of fragments from SKB since SKB may be freed by ++ * the completion routine after calling qed_ll2_prepare_tx_packet() ++ */ ++ nr_frags = skb_shinfo(skb)->nr_frags; ++ ++ if (1 + nr_frags > CORE_LL2_TX_MAX_BDS_PER_PACKET) { + DP_ERR(cdev, "Cannot transmit a packet with %d fragments\n", +- 1 + skb_shinfo(skb)->nr_frags); ++ 1 + nr_frags); + return -EINVAL; + } + +@@ -2475,7 +2480,7 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb, + } + + memset(&pkt, 0, sizeof(pkt)); +- pkt.num_of_bds = 1 + skb_shinfo(skb)->nr_frags; ++ pkt.num_of_bds = 1 + nr_frags; + pkt.vlan = vlan; + pkt.bd_flags = flags; + pkt.tx_dest = QED_LL2_TX_DEST_NW; +@@ -2486,12 +2491,17 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb, + test_bit(QED_LL2_XMIT_FLAGS_FIP_DISCOVERY, &xmit_flags)) + pkt.remove_stag = true; + ++ /* qed_ll2_prepare_tx_packet() may actually send the packet if ++ * there are no fragments in the skb and subsequently the completion ++ * routine may run and free the SKB, so no dereferencing the SKB ++ * beyond this point unless skb has any fragments. ++ */ + rc = qed_ll2_prepare_tx_packet(&cdev->hwfns[0], cdev->ll2->handle, + &pkt, 1); + if (rc) + goto err; + +- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ for (i = 0; i < nr_frags; i++) { + frag = &skb_shinfo(skb)->frags[i]; + + mapping = skb_frag_dma_map(&cdev->pdev->dev, frag, 0, +-- +2.19.1 + diff --git a/queue-4.20/qed-fix-vf-probe-failure-while-flr.patch b/queue-4.20/qed-fix-vf-probe-failure-while-flr.patch new file mode 100644 index 00000000000..b6af69c8b9e --- /dev/null +++ b/queue-4.20/qed-fix-vf-probe-failure-while-flr.patch @@ -0,0 +1,57 @@ +From 1588c47bdcb6b6fd84d2a13e680d3acae1cd1a00 Mon Sep 17 00:00:00 2001 +From: Manish Chopra +Date: Mon, 28 Jan 2019 10:05:06 -0800 +Subject: qed: Fix VF probe failure while FLR + +[ Upstream commit 327852ec64205bb651be391a069784872098a3b2 ] + +VFs may hit VF-PF channel timeout while probing, as in some +cases it was observed that VF FLR and VF "acquire" message +transaction (i.e first message from VF to PF in VF's probe flow) +could occur simultaneously which could lead VF to fail sending +"acquire" message to PF as VF is marked disabled from HW perspective +due to FLR, which will result into channel timeout and VF probe failure. + +In such cases, try retrying VF "acquire" message so that in later +attempts it could be successful to pass message to PF after the VF +FLR is completed and can be probed successfully. + +Signed-off-by: Manish Chopra +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_vf.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c b/drivers/net/ethernet/qlogic/qed/qed_vf.c +index b6cccf44bf40..5dda547772c1 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_vf.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c +@@ -261,6 +261,7 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) + struct pfvf_acquire_resp_tlv *resp = &p_iov->pf2vf_reply->acquire_resp; + struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info; + struct vf_pf_resc_request *p_resc; ++ u8 retry_cnt = VF_ACQUIRE_THRESH; + bool resources_acquired = false; + struct vfpf_acquire_tlv *req; + int rc = 0, attempts = 0; +@@ -314,6 +315,15 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) + + /* send acquire request */ + rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); ++ ++ /* Re-try acquire in case of vf-pf hw channel timeout */ ++ if (retry_cnt && rc == -EBUSY) { ++ DP_VERBOSE(p_hwfn, QED_MSG_IOV, ++ "VF retrying to acquire due to VPC timeout\n"); ++ retry_cnt--; ++ continue; ++ } ++ + if (rc) + goto exit; + +-- +2.19.1 + diff --git a/queue-4.20/qede-fix-system-crash-on-configuring-channels.patch b/queue-4.20/qede-fix-system-crash-on-configuring-channels.patch new file mode 100644 index 00000000000..32d005c1ffe --- /dev/null +++ b/queue-4.20/qede-fix-system-crash-on-configuring-channels.patch @@ -0,0 +1,95 @@ +From 53d5ef2149e896c1a5507987d2e9c808daca9470 Mon Sep 17 00:00:00 2001 +From: Sudarsana Reddy Kalluru +Date: Wed, 6 Feb 2019 14:43:45 -0800 +Subject: qede: Fix system crash on configuring channels. + +[ Upstream commit 0aa4febb420d91df5b56b1864a2465765da85f4b ] + +Under heavy traffic load, when changing number of channels via +ethtool (ethtool -L) which will cause interface to be reloaded, +it was observed that some packets gets transmitted on old TX +channel/queue id which doesn't really exist after the channel +configuration leads to system crash. + +Add a safeguard in the driver by validating queue id through +ndo_select_queue() which is called before the ndo_start_xmit(). + +Signed-off-by: Sudarsana Reddy Kalluru +Signed-off-by: Ariel Elior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qede/qede.h | 3 +++ + drivers/net/ethernet/qlogic/qede/qede_fp.c | 13 +++++++++++++ + drivers/net/ethernet/qlogic/qede/qede_main.c | 3 +++ + 3 files changed, 19 insertions(+) + +diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h +index de98a974673b..4b875f652ecd 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede.h ++++ b/drivers/net/ethernet/qlogic/qede/qede.h +@@ -489,6 +489,9 @@ struct qede_reload_args { + + /* Datapath functions definition */ + netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev); ++u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev, ++ select_queue_fallback_t fallback); + netdev_features_t qede_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features); +diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c +index 1a78027de071..a96da16f3404 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c +@@ -1695,6 +1695,19 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev) + return NETDEV_TX_OK; + } + ++u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev, ++ select_queue_fallback_t fallback) ++{ ++ struct qede_dev *edev = netdev_priv(dev); ++ int total_txq; ++ ++ total_txq = QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc; ++ ++ return QEDE_TSS_COUNT(edev) ? ++ fallback(dev, skb, NULL) % total_txq : 0; ++} ++ + /* 8B udp header + 8B base tunnel header + 32B option length */ + #define QEDE_MAX_TUN_HDR_LEN 48 + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c +index 46d0f2eaa0c0..f3d9c40c4115 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_main.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c +@@ -631,6 +631,7 @@ static const struct net_device_ops qede_netdev_ops = { + .ndo_open = qede_open, + .ndo_stop = qede_close, + .ndo_start_xmit = qede_start_xmit, ++ .ndo_select_queue = qede_select_queue, + .ndo_set_rx_mode = qede_set_rx_mode, + .ndo_set_mac_address = qede_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, +@@ -666,6 +667,7 @@ static const struct net_device_ops qede_netdev_vf_ops = { + .ndo_open = qede_open, + .ndo_stop = qede_close, + .ndo_start_xmit = qede_start_xmit, ++ .ndo_select_queue = qede_select_queue, + .ndo_set_rx_mode = qede_set_rx_mode, + .ndo_set_mac_address = qede_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, +@@ -684,6 +686,7 @@ static const struct net_device_ops qede_netdev_vf_xdp_ops = { + .ndo_open = qede_open, + .ndo_stop = qede_close, + .ndo_start_xmit = qede_start_xmit, ++ .ndo_select_queue = qede_select_queue, + .ndo_set_rx_mode = qede_set_rx_mode, + .ndo_set_mac_address = qede_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, +-- +2.19.1 + diff --git a/queue-4.20/rdma-umem-add-missing-initialization-of-owning_mm.patch b/queue-4.20/rdma-umem-add-missing-initialization-of-owning_mm.patch new file mode 100644 index 00000000000..5410d57ef46 --- /dev/null +++ b/queue-4.20/rdma-umem-add-missing-initialization-of-owning_mm.patch @@ -0,0 +1,75 @@ +From a0af57c548dc079f9b8c6d192bcafea3176e4655 Mon Sep 17 00:00:00 2001 +From: Artemy Kovalyov +Date: Tue, 22 Jan 2019 09:16:10 +0200 +Subject: RDMA/umem: Add missing initialization of owning_mm + +[ Upstream commit a2093dd35f8cfb28dd7c878ccbd020c1bb20d0d7 ] + +When allocating a umem leaf for implicit ODP MR during page fault the +field owning_mm was not set. + +Initialize and take a reference on this field to avoid kernel panic when +trying to access this field. + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000058 + PGD 800000022dfed067 P4D 800000022dfed067 PUD 22dfcf067 PMD 0 + Oops: 0000 [#1] SMP PTI + CPU: 0 PID: 634 Comm: kworker/u33:0 Not tainted 4.20.0-rc6+ #89 + Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 + Workqueue: mlx5_ib_page_fault mlx5_ib_eqe_pf_action [mlx5_ib] + RIP: 0010:ib_umem_odp_map_dma_pages+0xf3/0x710 [ib_core] + Code: 45 c0 48 21 f3 48 89 75 b0 31 f6 4a 8d 04 33 48 89 45 a8 49 8b 44 24 60 48 8b 78 10 e8 66 16 a8 c5 49 8b 54 24 08 48 89 45 98 <8b> 42 58 85 c0 0f 84 8e 05 00 00 8d 48 01 48 8d 72 58 f0 0f b1 4a + RSP: 0000:ffffb610813a7c20 EFLAGS: 00010202 + RAX: ffff95ace6e8ac80 RBX: 0000000000000000 RCX: 000000000000000c + RDX: 0000000000000000 RSI: 0000000000000850 RDI: ffff95aceaadae80 + RBP: ffffb610813a7ce0 R08: 0000000000000000 R09: 0000000000080c77 + R10: ffff95acfffdbd00 R11: 0000000000000000 R12: ffff95aceaa20a00 + R13: 0000000000001000 R14: 0000000000001000 R15: 000000000000000c + FS: 0000000000000000(0000) GS:ffff95acf7800000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000058 CR3: 000000022c834001 CR4: 00000000001606f0 + Call Trace: + pagefault_single_data_segment+0x1df/0xc60 [mlx5_ib] + mlx5_ib_eqe_pf_action+0x7bc/0xa70 [mlx5_ib] + ? __switch_to+0xe1/0x470 + process_one_work+0x174/0x390 + worker_thread+0x4f/0x3e0 + kthread+0x102/0x140 + ? drain_workqueue+0x130/0x130 + ? kthread_stop+0x110/0x110 + ret_from_fork+0x1f/0x30 + +Fixes: f27a0d50a4bc ("RDMA/umem: Use umem->owning_mm inside ODP") +Signed-off-by: Artemy Kovalyov +Signed-off-by: Moni Shoua +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/umem_odp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c +index 676c1fd1119d..7ef385db52c3 100644 +--- a/drivers/infiniband/core/umem_odp.c ++++ b/drivers/infiniband/core/umem_odp.c +@@ -356,6 +356,8 @@ struct ib_umem_odp *ib_alloc_odp_umem(struct ib_ucontext_per_mm *per_mm, + umem->writable = 1; + umem->is_odp = 1; + odp_data->per_mm = per_mm; ++ umem->owning_mm = per_mm->mm; ++ mmgrab(umem->owning_mm); + + mutex_init(&odp_data->umem_mutex); + init_completion(&odp_data->notifier_completion); +@@ -388,6 +390,7 @@ struct ib_umem_odp *ib_alloc_odp_umem(struct ib_ucontext_per_mm *per_mm, + out_page_list: + vfree(odp_data->page_list); + out_odp_data: ++ mmdrop(umem->owning_mm); + kfree(odp_data); + return ERR_PTR(ret); + } +-- +2.19.1 + diff --git a/queue-4.20/relay-check-return-of-create_buf_file-properly.patch b/queue-4.20/relay-check-return-of-create_buf_file-properly.patch new file mode 100644 index 00000000000..09929de99b9 --- /dev/null +++ b/queue-4.20/relay-check-return-of-create_buf_file-properly.patch @@ -0,0 +1,52 @@ +From 7b4734a85358c604d022c4cb2bbbc4e7bd3f5ec6 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 31 Jan 2019 13:57:58 +0100 +Subject: relay: check return of create_buf_file() properly + +[ Upstream commit 2c1cf00eeacb784781cf1c9896b8af001246d339 ] + +If create_buf_file() returns an error, don't try to reference it later +as a valid dentry pointer. + +This problem was exposed when debugfs started to return errors instead +of just NULL for some calls when they do not succeed properly. + +Also, the check for WARN_ON(dentry) was just wrong :) + +Reported-by: Kees Cook +Reported-and-tested-by: syzbot+16c3a70e1e9b29346c43@syzkaller.appspotmail.com +Reported-by: Tetsuo Handa +Cc: Andrew Morton +Cc: David Rientjes +Fixes: ff9fb72bc077 ("debugfs: return error values, not NULL") +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + kernel/relay.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/relay.c b/kernel/relay.c +index 04f248644e06..9e0f52375487 100644 +--- a/kernel/relay.c ++++ b/kernel/relay.c +@@ -428,6 +428,8 @@ static struct dentry *relay_create_buf_file(struct rchan *chan, + dentry = chan->cb->create_buf_file(tmpname, chan->parent, + S_IRUSR, buf, + &chan->is_global); ++ if (IS_ERR(dentry)) ++ dentry = NULL; + + kfree(tmpname); + +@@ -461,7 +463,7 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu) + dentry = chan->cb->create_buf_file(NULL, NULL, + S_IRUSR, buf, + &chan->is_global); +- if (WARN_ON(dentry)) ++ if (IS_ERR_OR_NULL(dentry)) + goto free_buf; + } + +-- +2.19.1 + diff --git a/queue-4.20/revert-scsi-libfc-add-warn_on-when-deleting-rports.patch b/queue-4.20/revert-scsi-libfc-add-warn_on-when-deleting-rports.patch new file mode 100644 index 00000000000..743f43aab05 --- /dev/null +++ b/queue-4.20/revert-scsi-libfc-add-warn_on-when-deleting-rports.patch @@ -0,0 +1,42 @@ +From f2b6b12d14f6f514fce44cb3148e6edb4d27bb8c Mon Sep 17 00:00:00 2001 +From: Ross Lagerwall +Date: Fri, 1 Feb 2019 14:42:28 +0000 +Subject: Revert "scsi: libfc: Add WARN_ON() when deleting rports" + +[ Upstream commit d8f6382a7d026989029e2e50c515df954488459b ] + +This reverts commit bbc0f8bd88abefb0f27998f40a073634a3a2db89. + +It added a warning whose intent was to check whether the rport was still +linked into the peer list. It doesn't work as intended and gives false +positive warnings for two reasons: + +1) If the rport is never linked into the peer list it will not be +considered empty since the list_head is never initialized. + +2) If the rport is deleted from the peer list using list_del_rcu(), then +the list_head is in an undefined state and it is not considered empty. + +Signed-off-by: Ross Lagerwall +Reviewed-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/libfc/fc_rport.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c +index 1e1c0f1b9e69..8ed2113f5a1e 100644 +--- a/drivers/scsi/libfc/fc_rport.c ++++ b/drivers/scsi/libfc/fc_rport.c +@@ -184,7 +184,6 @@ void fc_rport_destroy(struct kref *kref) + struct fc_rport_priv *rdata; + + rdata = container_of(kref, struct fc_rport_priv, kref); +- WARN_ON(!list_empty(&rdata->peers)); + kfree_rcu(rdata, rcu); + } + EXPORT_SYMBOL(fc_rport_destroy); +-- +2.19.1 + diff --git a/queue-4.20/riscv-adjust-mmap-base-address-at-a-third-of-task-si.patch b/queue-4.20/riscv-adjust-mmap-base-address-at-a-third-of-task-si.patch new file mode 100644 index 00000000000..5c2a7dce5ab --- /dev/null +++ b/queue-4.20/riscv-adjust-mmap-base-address-at-a-third-of-task-si.patch @@ -0,0 +1,36 @@ +From 244a8ebfd1b89be07e1be2c2858836ec51c50ba6 Mon Sep 17 00:00:00 2001 +From: Alexandre Ghiti +Date: Mon, 10 Dec 2018 06:21:46 +0000 +Subject: riscv: Adjust mmap base address at a third of task size + +[ Upstream commit ae662eec8a515ab550524e04c793b5ddf1aae3a1 ] + +This ratio is the most used among all other architectures and make +icache_hygiene libhugetlbfs test pass: this test mmap lots of +hugepages whose addresses, without this patch, reach the end of +the process user address space. + +Signed-off-by: Alexandre Ghiti +Reviewed-by: Christoph Hellwig +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/processor.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h +index 0531f49af5c3..ce70bceb8872 100644 +--- a/arch/riscv/include/asm/processor.h ++++ b/arch/riscv/include/asm/processor.h +@@ -22,7 +22,7 @@ + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +-#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE >> 1) ++#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3) + + #define STACK_TOP TASK_SIZE + #define STACK_TOP_MAX STACK_TOP +-- +2.19.1 + diff --git a/queue-4.20/riscv-fixup-max_low_pfn-with-pfn_down.patch b/queue-4.20/riscv-fixup-max_low_pfn-with-pfn_down.patch new file mode 100644 index 00000000000..10db26e6b90 --- /dev/null +++ b/queue-4.20/riscv-fixup-max_low_pfn-with-pfn_down.patch @@ -0,0 +1,48 @@ +From 534cf4eb298f3f06a40f42c32e80546442bc3819 Mon Sep 17 00:00:00 2001 +From: Guo Ren +Date: Sat, 12 Jan 2019 16:16:27 +0800 +Subject: riscv: fixup max_low_pfn with PFN_DOWN. + +[ Upstream commit 28198c4639b39899a728ac89aea29d2a7a72562f ] + +max_low_pfn should be pfn_size not byte_size. + +Signed-off-by: Guo Ren +Signed-off-by: Mao Han +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/setup.c | 2 +- + arch/riscv/mm/init.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c +index 2c290e6aaa6e..6d652826b5cb 100644 +--- a/arch/riscv/kernel/setup.c ++++ b/arch/riscv/kernel/setup.c +@@ -196,7 +196,7 @@ static void __init setup_bootmem(void) + BUG_ON(mem_size == 0); + + set_max_mapnr(PFN_DOWN(mem_size)); +- max_low_pfn = memblock_end_of_DRAM(); ++ max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); + + #ifdef CONFIG_BLK_DEV_INITRD + setup_initrd(); +diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c +index 1d9bfaff60bc..658ebf645f42 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -28,7 +28,8 @@ static void __init zone_sizes_init(void) + unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, }; + + #ifdef CONFIG_ZONE_DMA32 +- max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn)); ++ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, ++ (unsigned long) PFN_PHYS(max_low_pfn))); + #endif + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + +-- +2.19.1 + diff --git a/queue-4.20/s390-qeth-cancel-close_dev-work-before-removing-a-ca.patch b/queue-4.20/s390-qeth-cancel-close_dev-work-before-removing-a-ca.patch new file mode 100644 index 00000000000..22ebd65ed0b --- /dev/null +++ b/queue-4.20/s390-qeth-cancel-close_dev-work-before-removing-a-ca.patch @@ -0,0 +1,62 @@ +From 7c8acca2e922e5fe81356870b61d1fafa354820f Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Mon, 4 Feb 2019 17:40:08 +0100 +Subject: s390/qeth: cancel close_dev work before removing a card + +[ Upstream commit c2780c1a3fb724560b1d44f7976e0de17bf153c7 ] + +A card's close_dev work is scheduled on a driver-wide workqueue. If the +card is removed and freed while the work is still active, this causes a +use-after-free. +So make sure that the work is completed before freeing the card. + +Fixes: 0f54761d167f ("qeth: Support VEPA mode") +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core.h | 1 + + drivers/s390/net/qeth_l2_main.c | 2 ++ + drivers/s390/net/qeth_l3_main.c | 1 + + 3 files changed, 4 insertions(+) + +diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h +index 99af1a0a3314..8999be74c545 100644 +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include + #include +diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c +index 8d3601891c62..49fa09c67d49 100644 +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -823,6 +823,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) + + if (cgdev->state == CCWGROUP_ONLINE) + qeth_l2_set_offline(cgdev); ++ ++ cancel_work_sync(&card->close_dev_work); + if (qeth_netdev_is_registered(card->dev)) + unregister_netdev(card->dev); + } +diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c +index f08b745c2007..d1bf55b5c8e1 100644 +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -2428,6 +2428,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) + if (cgdev->state == CCWGROUP_ONLINE) + qeth_l3_set_offline(cgdev); + ++ cancel_work_sync(&card->close_dev_work); + if (qeth_netdev_is_registered(card->dev)) + unregister_netdev(card->dev); + qeth_l3_clear_ip_htable(card, 0); +-- +2.19.1 + diff --git a/queue-4.20/s390-qeth-conclude-all-event-processing-before-offli.patch b/queue-4.20/s390-qeth-conclude-all-event-processing-before-offli.patch new file mode 100644 index 00000000000..684b91323a3 --- /dev/null +++ b/queue-4.20/s390-qeth-conclude-all-event-processing-before-offli.patch @@ -0,0 +1,134 @@ +From 7a5550e59f3cbbf40c80c8954545e51640301be0 Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Mon, 4 Feb 2019 17:40:09 +0100 +Subject: s390/qeth: conclude all event processing before offlining a card + +[ Upstream commit c0a2e4d10d9366ada133a8ae4ff2f32397f8b15b ] + +Work for Bridgeport events is currently placed on a driver-wide +workqueue. If the card is removed and freed while any such work is still +active, this causes a use-after-free. +So put the events on a per-card queue, where we can control their +lifetime. As we also don't want stale events to last beyond an +offline & online cycle, flush this queue when setting the card offline. + +Fixes: b4d72c08b358 ("qeth: bridgeport support - basic control") +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core.h | 2 +- + drivers/s390/net/qeth_core_main.c | 10 ++++++++-- + drivers/s390/net/qeth_l2_main.c | 6 ++++-- + drivers/s390/net/qeth_l3_main.c | 2 ++ + 4 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h +index 8999be74c545..8f2af450152f 100644 +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -791,6 +791,7 @@ struct qeth_card { + struct qeth_seqno seqno; + struct qeth_card_options options; + ++ struct workqueue_struct *event_wq; + wait_queue_head_t wait_q; + spinlock_t mclock; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; +@@ -969,7 +970,6 @@ extern const struct attribute_group *qeth_osn_attr_groups[]; + extern const struct attribute_group qeth_device_attr_group; + extern const struct attribute_group qeth_device_blkt_group; + extern const struct device_type qeth_generic_devtype; +-extern struct workqueue_struct *qeth_wq; + + int qeth_card_hw_is_reachable(struct qeth_card *); + const char *qeth_get_cardname_short(struct qeth_card *); +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 89cc172820ca..ebbc3ad504f9 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -76,8 +76,7 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, + static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf); + static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); + +-struct workqueue_struct *qeth_wq; +-EXPORT_SYMBOL_GPL(qeth_wq); ++static struct workqueue_struct *qeth_wq; + + int qeth_card_hw_is_reachable(struct qeth_card *card) + { +@@ -1471,6 +1470,10 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) + CARD_RDEV(card) = gdev->cdev[0]; + CARD_WDEV(card) = gdev->cdev[1]; + CARD_DDEV(card) = gdev->cdev[2]; ++ ++ card->event_wq = alloc_ordered_workqueue("%s", 0, dev_name(&gdev->dev)); ++ if (!card->event_wq) ++ goto out_wq; + if (qeth_setup_channel(&card->read, true)) + goto out_ip; + if (qeth_setup_channel(&card->write, true)) +@@ -1486,6 +1489,8 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) + out_channel: + qeth_clean_channel(&card->read); + out_ip: ++ destroy_workqueue(card->event_wq); ++out_wq: + dev_set_drvdata(&gdev->dev, NULL); + kfree(card); + out: +@@ -5038,6 +5043,7 @@ static void qeth_core_free_card(struct qeth_card *card) + qeth_clean_channel(&card->read); + qeth_clean_channel(&card->write); + qeth_clean_channel(&card->data); ++ destroy_workqueue(card->event_wq); + qeth_free_qdio_buffers(card); + unregister_service_level(&card->qeth_service_level); + dev_set_drvdata(&card->gdev->dev, NULL); +diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c +index 49fa09c67d49..a6c55cbf3d69 100644 +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -391,6 +391,8 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) + qeth_clear_cmd_buffers(&card->read); + qeth_clear_cmd_buffers(&card->write); + } ++ ++ flush_workqueue(card->event_wq); + } + + static int qeth_l2_process_inbound_buffer(struct qeth_card *card, +@@ -1455,7 +1457,7 @@ static void qeth_bridge_state_change(struct qeth_card *card, + data->card = card; + memcpy(&data->qports, qports, + sizeof(struct qeth_sbp_state_change) + extrasize); +- queue_work(qeth_wq, &data->worker); ++ queue_work(card->event_wq, &data->worker); + } + + struct qeth_bridge_host_data { +@@ -1527,7 +1529,7 @@ static void qeth_bridge_host_event(struct qeth_card *card, + data->card = card; + memcpy(&data->hostevs, hostevs, + sizeof(struct qeth_ipacmd_addr_change) + extrasize); +- queue_work(qeth_wq, &data->worker); ++ queue_work(card->event_wq, &data->worker); + } + + /* SETBRIDGEPORT support; sending commands */ +diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c +index d1bf55b5c8e1..29a2408b9282 100644 +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -1436,6 +1436,8 @@ static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) + qeth_clear_cmd_buffers(&card->read); + qeth_clear_cmd_buffers(&card->write); + } ++ ++ flush_workqueue(card->event_wq); + } + + /* +-- +2.19.1 + diff --git a/queue-4.20/s390-qeth-fix-use-after-free-in-error-path.patch b/queue-4.20/s390-qeth-fix-use-after-free-in-error-path.patch new file mode 100644 index 00000000000..cc4bab95fef --- /dev/null +++ b/queue-4.20/s390-qeth-fix-use-after-free-in-error-path.patch @@ -0,0 +1,70 @@ +From 179a25cc6fafcdcbd914cf05180ba353deccf412 Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Mon, 4 Feb 2019 17:40:07 +0100 +Subject: s390/qeth: fix use-after-free in error path + +[ Upstream commit afa0c5904ba16d59b0454f7ee4c807dae350f432 ] + +The error path in qeth_alloc_qdio_buffers() that takes care of +cleaning up the Output Queues is buggy. It first frees the queue, but +then calls qeth_clear_outq_buffers() with that very queue struct. + +Make the call to qeth_clear_outq_buffers() part of the free action +(in the correct order), and while at it fix the naming of the helper. + +Fixes: 0da9581ddb0f ("qeth: exploit asynchronous delivery of storage blocks") +Signed-off-by: Julian Wiedmann +Reviewed-by: Alexandra Winter +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core_main.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 623ddda5d2ba..89cc172820ca 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -2397,11 +2397,12 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx) + return 0; + } + +-static void qeth_free_qdio_out_buf(struct qeth_qdio_out_q *q) ++static void qeth_free_output_queue(struct qeth_qdio_out_q *q) + { + if (!q) + return; + ++ qeth_clear_outq_buffers(q, 1); + qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); + kfree(q); + } +@@ -2475,10 +2476,8 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card) + card->qdio.out_qs[i]->bufs[j] = NULL; + } + out_freeoutq: +- while (i > 0) { +- qeth_free_qdio_out_buf(card->qdio.out_qs[--i]); +- qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); +- } ++ while (i > 0) ++ qeth_free_output_queue(card->qdio.out_qs[--i]); + kfree(card->qdio.out_qs); + card->qdio.out_qs = NULL; + out_freepool: +@@ -2511,10 +2510,8 @@ static void qeth_free_qdio_buffers(struct qeth_card *card) + qeth_free_buffer_pool(card); + /* free outbound qdio_qs */ + if (card->qdio.out_qs) { +- for (i = 0; i < card->qdio.no_out_queues; ++i) { +- qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); +- qeth_free_qdio_out_buf(card->qdio.out_qs[i]); +- } ++ for (i = 0; i < card->qdio.no_out_queues; i++) ++ qeth_free_output_queue(card->qdio.out_qs[i]); + kfree(card->qdio.out_qs); + card->qdio.out_qs = NULL; + } +-- +2.19.1 + diff --git a/queue-4.20/s390-qeth-release-cmd-buffer-in-error-paths.patch b/queue-4.20/s390-qeth-release-cmd-buffer-in-error-paths.patch new file mode 100644 index 00000000000..6def87a7b99 --- /dev/null +++ b/queue-4.20/s390-qeth-release-cmd-buffer-in-error-paths.patch @@ -0,0 +1,66 @@ +From 496d5e9c19a306f489dc2d159a436909ce90b1a6 Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Mon, 4 Feb 2019 17:40:06 +0100 +Subject: s390/qeth: release cmd buffer in error paths + +[ Upstream commit 5065b2dd3e5f9247a6c9d67974bc0472bf561b9d ] + +Whenever we fail before/while starting an IO, make sure to release the +IO buffer. Usually qeth_irq() would do this for us, but if the IO +doesn't even start we obviously won't get an interrupt for it either. + +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 0c9a5250dd93..623ddda5d2ba 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -568,6 +568,7 @@ static int __qeth_issue_next_read(struct qeth_card *card) + QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n", + rc, CARD_DEVID(card)); + atomic_set(&channel->irq_pending, 0); ++ qeth_release_buffer(channel, iob); + card->read_or_write_problem = 1; + qeth_schedule_recovery(card); + wake_up(&card->wait_q); +@@ -1129,6 +1130,8 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, + rc = qeth_get_problem(card, cdev, irb); + if (rc) { + card->read_or_write_problem = 1; ++ if (iob) ++ qeth_release_buffer(iob->channel, iob); + qeth_clear_ipacmd_list(card); + qeth_schedule_recovery(card); + goto out; +@@ -1811,6 +1814,7 @@ static int qeth_idx_activate_get_answer(struct qeth_card *card, + QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc); + QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); + atomic_set(&channel->irq_pending, 0); ++ qeth_release_buffer(channel, iob); + wake_up(&card->wait_q); + return rc; + } +@@ -1880,6 +1884,7 @@ static int qeth_idx_activate_channel(struct qeth_card *card, + rc); + QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + atomic_set(&channel->irq_pending, 0); ++ qeth_release_buffer(channel, iob); + wake_up(&card->wait_q); + return rc; + } +@@ -2060,6 +2065,7 @@ int qeth_send_control_data(struct qeth_card *card, int len, + } + reply = qeth_alloc_reply(card); + if (!reply) { ++ qeth_release_buffer(channel, iob); + return -ENOMEM; + } + reply->callback = reply_cb; +-- +2.19.1 + diff --git a/queue-4.20/scsi-53c700-pass-correct-dev-to-dma_alloc_attrs.patch b/queue-4.20/scsi-53c700-pass-correct-dev-to-dma_alloc_attrs.patch new file mode 100644 index 00000000000..a866ccf43dc --- /dev/null +++ b/queue-4.20/scsi-53c700-pass-correct-dev-to-dma_alloc_attrs.patch @@ -0,0 +1,36 @@ +From d9c00f7365499c1a98faf2df66ad3c9134717a57 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 24 Jan 2019 13:33:27 +0300 +Subject: scsi: 53c700: pass correct "dev" to dma_alloc_attrs() + +[ Upstream commit 8437fcf14deed67e5ad90b5e8abf62fb20f30881 ] + +The "hostdata->dev" pointer is NULL here. We set "hostdata->dev = dev;" +later in the function and we also use "hostdata->dev" when we call +dma_free_attrs() in NCR_700_release(). + +This bug predates git version control. + +Signed-off-by: Dan Carpenter +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/53c700.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c +index 6be77b3aa8a5..ac79f2088b31 100644 +--- a/drivers/scsi/53c700.c ++++ b/drivers/scsi/53c700.c +@@ -295,7 +295,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, + if(tpnt->sdev_attrs == NULL) + tpnt->sdev_attrs = NCR_700_dev_attrs; + +- memory = dma_alloc_attrs(hostdata->dev, TOTAL_MEM_SIZE, &pScript, ++ memory = dma_alloc_attrs(dev, TOTAL_MEM_SIZE, &pScript, + GFP_KERNEL, DMA_ATTR_NON_CONSISTENT); + if(memory == NULL) { + printk(KERN_ERR "53c700: Failed to allocate memory for driver, detaching\n"); +-- +2.19.1 + diff --git a/queue-4.20/scsi-bnx2fc-fix-error-handling-in-probe.patch b/queue-4.20/scsi-bnx2fc-fix-error-handling-in-probe.patch new file mode 100644 index 00000000000..bb9ccd4d180 --- /dev/null +++ b/queue-4.20/scsi-bnx2fc-fix-error-handling-in-probe.patch @@ -0,0 +1,51 @@ +From 5f0c3366dad8f80848ae0653cb683089e9025e3e Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 24 Jan 2019 13:29:40 +0300 +Subject: scsi: bnx2fc: Fix error handling in probe() + +[ Upstream commit b2d3492fc591b1fb46b81d79ca1fc44cac6ae0ae ] + +There are two issues here. First if cmgr->hba is not set early enough then +it leads to a NULL dereference. Second if we don't completely initialize +cmgr->io_bdt_pool[] then we end up dereferencing uninitialized pointers. + +Fixes: 853e2bd2103a ("[SCSI] bnx2fc: Broadcom FCoE offload driver") +Signed-off-by: Dan Carpenter +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/bnx2fc/bnx2fc_io.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c +index 350257c13a5b..bc9f2a2365f4 100644 +--- a/drivers/scsi/bnx2fc/bnx2fc_io.c ++++ b/drivers/scsi/bnx2fc/bnx2fc_io.c +@@ -240,6 +240,7 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) + return NULL; + } + ++ cmgr->hba = hba; + cmgr->free_list = kcalloc(arr_sz, sizeof(*cmgr->free_list), + GFP_KERNEL); + if (!cmgr->free_list) { +@@ -256,7 +257,6 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) + goto mem_err; + } + +- cmgr->hba = hba; + cmgr->cmds = (struct bnx2fc_cmd **)(cmgr + 1); + + for (i = 0; i < arr_sz; i++) { +@@ -295,7 +295,7 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) + + /* Allocate pool of io_bdts - one for each bnx2fc_cmd */ + mem_size = num_ios * sizeof(struct io_bdt *); +- cmgr->io_bdt_pool = kmalloc(mem_size, GFP_KERNEL); ++ cmgr->io_bdt_pool = kzalloc(mem_size, GFP_KERNEL); + if (!cmgr->io_bdt_pool) { + printk(KERN_ERR PFX "failed to alloc io_bdt_pool\n"); + goto mem_err; +-- +2.19.1 + diff --git a/queue-4.20/scsi-libfc-free-skb-when-receiving-invalid-flogi-res.patch b/queue-4.20/scsi-libfc-free-skb-when-receiving-invalid-flogi-res.patch new file mode 100644 index 00000000000..fb325a7dae4 --- /dev/null +++ b/queue-4.20/scsi-libfc-free-skb-when-receiving-invalid-flogi-res.patch @@ -0,0 +1,56 @@ +From 1b1064a888a2860ced5c70d435fc7f542feb01f4 Mon Sep 17 00:00:00 2001 +From: Ming Lu +Date: Thu, 24 Jan 2019 13:25:42 +0800 +Subject: scsi: libfc: free skb when receiving invalid flogi resp + +[ Upstream commit 5d8fc4a9f0eec20b6c07895022a6bea3fb6dfb38 ] + +The issue to be fixed in this commit is when libfc found it received a +invalid FLOGI response from FC switch, it would return without freeing the +fc frame, which is just the skb data. This would cause memory leak if FC +switch keeps sending invalid FLOGI responses. + +This fix is just to make it execute `fc_frame_free(fp)` before returning +from function `fc_lport_flogi_resp`. + +Signed-off-by: Ming Lu +Reviewed-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/libfc/fc_lport.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c +index be83590ed955..ff943f477d6f 100644 +--- a/drivers/scsi/libfc/fc_lport.c ++++ b/drivers/scsi/libfc/fc_lport.c +@@ -1726,14 +1726,14 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, + fc_frame_payload_op(fp) != ELS_LS_ACC) { + FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n"); + fc_lport_error(lport, fp); +- goto err; ++ goto out; + } + + flp = fc_frame_payload_get(fp, sizeof(*flp)); + if (!flp) { + FC_LPORT_DBG(lport, "FLOGI bad response\n"); + fc_lport_error(lport, fp); +- goto err; ++ goto out; + } + + mfs = ntohs(flp->fl_csp.sp_bb_data) & +@@ -1743,7 +1743,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, + FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " + "lport->mfs:%hu\n", mfs, lport->mfs); + fc_lport_error(lport, fp); +- goto err; ++ goto out; + } + + if (mfs <= lport->mfs) { +-- +2.19.1 + diff --git a/queue-4.20/scsi-scsi_debug-fix-write_same-with-virtual_gb-probl.patch b/queue-4.20/scsi-scsi_debug-fix-write_same-with-virtual_gb-probl.patch new file mode 100644 index 00000000000..453fc3eeea7 --- /dev/null +++ b/queue-4.20/scsi-scsi_debug-fix-write_same-with-virtual_gb-probl.patch @@ -0,0 +1,126 @@ +From a1925624dff2f9cbf1551c652b0357ab0af5c918 Mon Sep 17 00:00:00 2001 +From: Douglas Gilbert +Date: Fri, 25 Jan 2019 12:46:09 -0500 +Subject: scsi: scsi_debug: fix write_same with virtual_gb problem + +[ Upstream commit 40d07b523cf434f252b134c86b1f8f2d907ffb0b ] + +The WRITE SAME(10) and (16) implementations didn't take account of the +buffer wrap required when the virtual_gb parameter is greater than 0. + +Fix that and rename the fake_store() function to lba2fake_store() to lessen +confusion with the global fake_storep pointer. Bump version date. + +Signed-off-by: Douglas Gilbert +Reported-by: Bart Van Assche +Tested by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_debug.c | 41 ++++++++++++++++++++------------------- + 1 file changed, 21 insertions(+), 20 deletions(-) + +diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c +index 60bcc6df97a9..65305b3848bc 100644 +--- a/drivers/scsi/scsi_debug.c ++++ b/drivers/scsi/scsi_debug.c +@@ -62,7 +62,7 @@ + + /* make sure inq_product_rev string corresponds to this version */ + #define SDEBUG_VERSION "0188" /* format to fit INQUIRY revision field */ +-static const char *sdebug_version_date = "20180128"; ++static const char *sdebug_version_date = "20190125"; + + #define MY_NAME "scsi_debug" + +@@ -735,7 +735,7 @@ static inline bool scsi_debug_lbp(void) + (sdebug_lbpu || sdebug_lbpws || sdebug_lbpws10); + } + +-static void *fake_store(unsigned long long lba) ++static void *lba2fake_store(unsigned long long lba) + { + lba = do_div(lba, sdebug_store_sectors); + +@@ -2514,8 +2514,8 @@ static int do_device_access(struct scsi_cmnd *scmd, u32 sg_skip, u64 lba, + return ret; + } + +-/* If fake_store(lba,num) compares equal to arr(num), then copy top half of +- * arr into fake_store(lba,num) and return true. If comparison fails then ++/* If lba2fake_store(lba,num) compares equal to arr(num), then copy top half of ++ * arr into lba2fake_store(lba,num) and return true. If comparison fails then + * return false. */ + static bool comp_write_worker(u64 lba, u32 num, const u8 *arr) + { +@@ -2643,7 +2643,7 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, + if (sdt->app_tag == cpu_to_be16(0xffff)) + continue; + +- ret = dif_verify(sdt, fake_store(sector), sector, ei_lba); ++ ret = dif_verify(sdt, lba2fake_store(sector), sector, ei_lba); + if (ret) { + dif_errors++; + return ret; +@@ -3261,10 +3261,12 @@ static int resp_write_scat(struct scsi_cmnd *scp, + static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, + u32 ei_lba, bool unmap, bool ndob) + { ++ int ret; + unsigned long iflags; + unsigned long long i; +- int ret; +- u64 lba_off; ++ u32 lb_size = sdebug_sector_size; ++ u64 block, lbaa; ++ u8 *fs1p; + + ret = check_device_access_params(scp, lba, num); + if (ret) +@@ -3276,31 +3278,30 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, + unmap_region(lba, num); + goto out; + } +- +- lba_off = lba * sdebug_sector_size; ++ lbaa = lba; ++ block = do_div(lbaa, sdebug_store_sectors); + /* if ndob then zero 1 logical block, else fetch 1 logical block */ ++ fs1p = fake_storep + (block * lb_size); + if (ndob) { +- memset(fake_storep + lba_off, 0, sdebug_sector_size); ++ memset(fs1p, 0, lb_size); + ret = 0; + } else +- ret = fetch_to_dev_buffer(scp, fake_storep + lba_off, +- sdebug_sector_size); ++ ret = fetch_to_dev_buffer(scp, fs1p, lb_size); + + if (-1 == ret) { + write_unlock_irqrestore(&atomic_rw, iflags); + return DID_ERROR << 16; +- } else if (sdebug_verbose && !ndob && (ret < sdebug_sector_size)) ++ } else if (sdebug_verbose && !ndob && (ret < lb_size)) + sdev_printk(KERN_INFO, scp->device, + "%s: %s: lb size=%u, IO sent=%d bytes\n", +- my_name, "write same", +- sdebug_sector_size, ret); ++ my_name, "write same", lb_size, ret); + + /* Copy first sector to remaining blocks */ +- for (i = 1 ; i < num ; i++) +- memcpy(fake_storep + ((lba + i) * sdebug_sector_size), +- fake_storep + lba_off, +- sdebug_sector_size); +- ++ for (i = 1 ; i < num ; i++) { ++ lbaa = lba + i; ++ block = do_div(lbaa, sdebug_store_sectors); ++ memmove(fake_storep + (block * lb_size), fs1p, lb_size); ++ } + if (scsi_debug_lbp()) + map_region(lba, num); + out: +-- +2.19.1 + diff --git a/queue-4.20/selftests-cpu-hotplug-fix-case-where-cpus-offline-cp.patch b/queue-4.20/selftests-cpu-hotplug-fix-case-where-cpus-offline-cp.patch new file mode 100644 index 00000000000..6b06c2aec52 --- /dev/null +++ b/queue-4.20/selftests-cpu-hotplug-fix-case-where-cpus-offline-cp.patch @@ -0,0 +1,66 @@ +From d5dc44f6a460d89b7f42c3a9e50723fe8fe4c25f Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Thu, 10 Jan 2019 12:38:02 +0000 +Subject: selftests: cpu-hotplug: fix case where CPUs offline > CPUs present + +[ Upstream commit 2b531b6137834a55857a337ac17510d6436b6fbb ] + +The cpu-hotplug test assumes that we can offline the maximum CPU as +described by /sys/devices/system/cpu/offline. However, in the case +where the number of CPUs exceeds like kernel configuration then +the offline count can be greater than the present count and we end +up trying to test the offlining of a CPU that is not available to +offline. Fix this by testing the maximum present CPU instead. + +Also, the test currently offlines the CPU and does not online it, +so fix this by onlining the CPU after the test. + +Fixes: d89dffa976bc ("fault-injection: add selftests for cpu and memory hotplug") +Signed-off-by: Colin Ian King +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + .../selftests/cpu-hotplug/cpu-on-off-test.sh | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh +index bab13dd025a6..0d26b5e3f966 100755 +--- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh ++++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh +@@ -37,6 +37,10 @@ prerequisite() + exit $ksft_skip + fi + ++ present_cpus=`cat $SYSFS/devices/system/cpu/present` ++ present_max=${present_cpus##*-} ++ echo "present_cpus = $present_cpus present_max = $present_max" ++ + echo -e "\t Cpus in online state: $online_cpus" + + offline_cpus=`cat $SYSFS/devices/system/cpu/offline` +@@ -151,6 +155,8 @@ online_cpus=0 + online_max=0 + offline_cpus=0 + offline_max=0 ++present_cpus=0 ++present_max=0 + + while getopts e:ahp: opt; do + case $opt in +@@ -190,9 +196,10 @@ if [ $allcpus -eq 0 ]; then + online_cpu_expect_success $online_max + + if [[ $offline_cpus -gt 0 ]]; then +- echo -e "\t offline to online to offline: cpu $offline_max" +- online_cpu_expect_success $offline_max +- offline_cpu_expect_success $offline_max ++ echo -e "\t offline to online to offline: cpu $present_max" ++ online_cpu_expect_success $present_max ++ offline_cpu_expect_success $present_max ++ online_cpu $present_max + fi + exit 0 + else +-- +2.19.1 + diff --git a/queue-4.20/selftests-net-use-ldlibs-instead-of-ldflags.patch b/queue-4.20/selftests-net-use-ldlibs-instead-of-ldflags.patch new file mode 100644 index 00000000000..9af0629059f --- /dev/null +++ b/queue-4.20/selftests-net-use-ldlibs-instead-of-ldflags.patch @@ -0,0 +1,80 @@ +From 53449d82eef0501e1c471f0e5f710b57a4e74a66 Mon Sep 17 00:00:00 2001 +From: Fathi Boudra +Date: Wed, 16 Jan 2019 11:43:18 -0600 +Subject: selftests: net: use LDLIBS instead of LDFLAGS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 870f193d48c25a97d61a8e6c04e3c29a2c606850 ] + +reuseport_bpf_numa fails to build due to undefined reference errors: + + aarch64-linaro-linux-gcc + --sysroot=/build/tmp-rpb-glibc/sysroots/hikey -Wall + -Wl,--no-as-needed -O2 -g -I../../../../usr/include/ -Wl,-O1 + -Wl,--hash-style=gnu -Wl,--as-needed -lnuma reuseport_bpf_numa.c + -o + /build/tmp-rpb-glibc/work/hikey-linaro-linux/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/net/reuseport_bpf_numa + /tmp/ccfUuExT.o: In function `send_from_node': + /build/tmp-rpb-glibc/work/hikey-linaro-linux/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/net/reuseport_bpf_numa.c:138: + undefined reference to `numa_run_on_node' + /tmp/ccfUuExT.o: In function `main': + /build/tmp-rpb-glibc/work/hikey-linaro-linux/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/net/reuseport_bpf_numa.c:230: + undefined reference to `numa_available' + /build/tmp-rpb-glibc/work/hikey-linaro-linux/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/net/reuseport_bpf_numa.c:233: + undefined reference to `numa_max_node' + +It's GNU Make and linker specific. + +The default Makefile rule looks like: + +$(CC) $(CFLAGS) $(LDFLAGS) $@ $^ $(LDLIBS) + +When linking is done by gcc itself, no issue, but when it needs to be passed +to proper ld, only LDLIBS follows and then ld cannot know what libs to link +with. + +More detail: +https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html + +LDFLAGS +Extra flags to give to compilers when they are supposed to invoke the linker, +‘ld’, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable +instead. + +LDLIBS +Library flags or names given to compilers when they are supposed to invoke the +linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to +LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS +variable. + +https://lkml.org/lkml/2010/2/10/362 + +tools/perf: libraries must come after objects + +Link order matters, use LDLIBS instead of LDFLAGS to properly link against +libnuma. + +Signed-off-by: Fathi Boudra +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile +index 923570a9708a..68e2295e7589 100644 +--- a/tools/testing/selftests/net/Makefile ++++ b/tools/testing/selftests/net/Makefile +@@ -19,6 +19,6 @@ TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls + KSFT_KHDR_INSTALL := 1 + include ../lib.mk + +-$(OUTPUT)/reuseport_bpf_numa: LDFLAGS += -lnuma ++$(OUTPUT)/reuseport_bpf_numa: LDLIBS += -lnuma + $(OUTPUT)/tcp_mmap: LDFLAGS += -lpthread + $(OUTPUT)/tcp_inq: LDFLAGS += -lpthread +-- +2.19.1 + diff --git a/queue-4.20/selftests-netfilter-add-simple-masq-redirect-test-ca.patch b/queue-4.20/selftests-netfilter-add-simple-masq-redirect-test-ca.patch new file mode 100644 index 00000000000..5a636d978c4 --- /dev/null +++ b/queue-4.20/selftests-netfilter-add-simple-masq-redirect-test-ca.patch @@ -0,0 +1,801 @@ +From 363a05684a6c0f77a3da93afa98472d6a67bff70 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 29 Jan 2019 15:16:23 +0100 +Subject: selftests: netfilter: add simple masq/redirect test cases + +[ Upstream commit 98bfc3414bda335dbd7fec58bde6266f991801d7 ] + +Check basic nat/redirect/masquerade for ipv4 and ipv6. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/netfilter/Makefile | 2 +- + tools/testing/selftests/netfilter/nft_nat.sh | 762 +++++++++++++++++++ + 2 files changed, 763 insertions(+), 1 deletion(-) + create mode 100755 tools/testing/selftests/netfilter/nft_nat.sh + +diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile +index 47ed6cef93fb..c9ff2b47bd1c 100644 +--- a/tools/testing/selftests/netfilter/Makefile ++++ b/tools/testing/selftests/netfilter/Makefile +@@ -1,6 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + # Makefile for netfilter selftests + +-TEST_PROGS := nft_trans_stress.sh ++TEST_PROGS := nft_trans_stress.sh nft_nat.sh + + include ../lib.mk +diff --git a/tools/testing/selftests/netfilter/nft_nat.sh b/tools/testing/selftests/netfilter/nft_nat.sh +new file mode 100755 +index 000000000000..8ec76681605c +--- /dev/null ++++ b/tools/testing/selftests/netfilter/nft_nat.sh +@@ -0,0 +1,762 @@ ++#!/bin/bash ++# ++# This test is for basic NAT functionality: snat, dnat, redirect, masquerade. ++# ++ ++# Kselftest framework requirement - SKIP code is 4. ++ksft_skip=4 ++ret=0 ++ ++nft --version > /dev/null 2>&1 ++if [ $? -ne 0 ];then ++ echo "SKIP: Could not run test without nft tool" ++ exit $ksft_skip ++fi ++ ++ip -Version > /dev/null 2>&1 ++if [ $? -ne 0 ];then ++ echo "SKIP: Could not run test without ip tool" ++ exit $ksft_skip ++fi ++ ++ip netns add ns0 ++ip netns add ns1 ++ip netns add ns2 ++ ++ip link add veth0 netns ns0 type veth peer name eth0 netns ns1 ++ip link add veth1 netns ns0 type veth peer name eth0 netns ns2 ++ ++ip -net ns0 link set lo up ++ip -net ns0 link set veth0 up ++ip -net ns0 addr add 10.0.1.1/24 dev veth0 ++ip -net ns0 addr add dead:1::1/64 dev veth0 ++ ++ip -net ns0 link set veth1 up ++ip -net ns0 addr add 10.0.2.1/24 dev veth1 ++ip -net ns0 addr add dead:2::1/64 dev veth1 ++ ++for i in 1 2; do ++ ip -net ns$i link set lo up ++ ip -net ns$i link set eth0 up ++ ip -net ns$i addr add 10.0.$i.99/24 dev eth0 ++ ip -net ns$i route add default via 10.0.$i.1 ++ ip -net ns$i addr add dead:$i::99/64 dev eth0 ++ ip -net ns$i route add default via dead:$i::1 ++done ++ ++bad_counter() ++{ ++ local ns=$1 ++ local counter=$2 ++ local expect=$3 ++ ++ echo "ERROR: $counter counter in $ns has unexpected value (expected $expect)" 1>&2 ++ ip netns exec $ns nft list counter inet filter $counter 1>&2 ++} ++ ++check_counters() ++{ ++ ns=$1 ++ local lret=0 ++ ++ cnt=$(ip netns exec $ns nft list counter inet filter ns0in | grep -q "packets 1 bytes 84") ++ if [ $? -ne 0 ]; then ++ bad_counter $ns ns0in "packets 1 bytes 84" ++ lret=1 ++ fi ++ cnt=$(ip netns exec $ns nft list counter inet filter ns0out | grep -q "packets 1 bytes 84") ++ if [ $? -ne 0 ]; then ++ bad_counter $ns ns0out "packets 1 bytes 84" ++ lret=1 ++ fi ++ ++ expect="packets 1 bytes 104" ++ cnt=$(ip netns exec $ns nft list counter inet filter ns0in6 | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter $ns ns0in6 "$expect" ++ lret=1 ++ fi ++ cnt=$(ip netns exec $ns nft list counter inet filter ns0out6 | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter $ns ns0out6 "$expect" ++ lret=1 ++ fi ++ ++ return $lret ++} ++ ++check_ns0_counters() ++{ ++ local ns=$1 ++ local lret=0 ++ ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns0in | grep -q "packets 0 bytes 0") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns0in "packets 0 bytes 0" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns0in6 | grep -q "packets 0 bytes 0") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns0in6 "packets 0 bytes 0" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns0out | grep -q "packets 0 bytes 0") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns0out "packets 0 bytes 0" ++ lret=1 ++ fi ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns0out6 | grep -q "packets 0 bytes 0") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns0out6 "packets 0 bytes 0" ++ lret=1 ++ fi ++ ++ for dir in "in" "out" ; do ++ expect="packets 1 bytes 84" ++ cnt=$(ip netns exec ns0 nft list counter inet filter ${ns}${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 $ns$dir "$expect" ++ lret=1 ++ fi ++ ++ expect="packets 1 bytes 104" ++ cnt=$(ip netns exec ns0 nft list counter inet filter ${ns}${dir}6 | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 $ns$dir6 "$expect" ++ lret=1 ++ fi ++ done ++ ++ return $lret ++} ++ ++reset_counters() ++{ ++ for i in 0 1 2;do ++ ip netns exec ns$i nft reset counters inet > /dev/null ++ done ++} ++ ++test_local_dnat6() ++{ ++ local lret=0 ++ip netns exec ns0 nft -f - < /dev/null ++ if [ $? -ne 0 ]; then ++ lret=1 ++ echo "ERROR: ping6 failed" ++ return $lret ++ fi ++ ++ expect="packets 0 bytes 0" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ expect="packets 1 bytes 104" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns2$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # expect 0 count in ns1 ++ expect="packets 0 bytes 0" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # expect 1 packet in ns2 ++ expect="packets 1 bytes 104" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ test $lret -eq 0 && echo "PASS: ipv6 ping to ns1 was NATted to ns2" ++ ip netns exec ns0 nft flush chain ip6 nat output ++ ++ return $lret ++} ++ ++test_local_dnat() ++{ ++ local lret=0 ++ip netns exec ns0 nft -f - < /dev/null ++ if [ $? -ne 0 ]; then ++ lret=1 ++ echo "ERROR: ping failed" ++ return $lret ++ fi ++ ++ expect="packets 0 bytes 0" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns2$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # expect 0 count in ns1 ++ expect="packets 0 bytes 0" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # expect 1 packet in ns2 ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ test $lret -eq 0 && echo "PASS: ping to ns1 was NATted to ns2" ++ ++ ip netns exec ns0 nft flush chain ip nat output ++ ++ reset_counters ++ ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null ++ if [ $? -ne 0 ]; then ++ lret=1 ++ echo "ERROR: ping failed" ++ return $lret ++ fi ++ ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ expect="packets 0 bytes 0" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns2$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # expect 1 count in ns1 ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns0 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # expect 0 packet in ns2 ++ expect="packets 0 bytes 0" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns2$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ test $lret -eq 0 && echo "PASS: ping to ns1 OK after nat output chain flush" ++ ++ return $lret ++} ++ ++ ++test_masquerade6() ++{ ++ local lret=0 ++ ++ ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null ++ ++ ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 via ipv6" ++ return 1 ++ lret=1 ++ fi ++ ++ expect="packets 1 bytes 104" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns2$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ reset_counters ++ ++# add masquerading rule ++ip netns exec ns0 nft -f - < /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerading" ++ lret=1 ++ fi ++ ++ # ns1 should have seen packets from ns0, due to masquerade ++ expect="packets 1 bytes 104" ++ for dir in "in6" "out6" ; do ++ ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # ns1 should not have seen packets from ns2, due to masquerade ++ expect="packets 0 bytes 0" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ ip netns exec ns0 nft flush chain ip6 nat postrouting ++ if [ $? -ne 0 ]; then ++ echo "ERROR: Could not flush ip6 nat postrouting" 1>&2 ++ lret=1 ++ fi ++ ++ test $lret -eq 0 && echo "PASS: IPv6 masquerade for ns2" ++ ++ return $lret ++} ++ ++test_masquerade() ++{ ++ local lret=0 ++ ++ ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null ++ ip netns exec ns0 sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null ++ ++ ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: canot ping ns1 from ns2" ++ lret=1 ++ fi ++ ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns2$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ reset_counters ++ ++# add masquerading rule ++ip netns exec ns0 nft -f - < /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 with active ip masquerading" ++ lret=1 ++ fi ++ ++ # ns1 should have seen packets from ns0, due to masquerade ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns0${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # ns1 should not have seen packets from ns2, due to masquerade ++ expect="packets 0 bytes 0" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ ip netns exec ns0 nft flush chain ip nat postrouting ++ if [ $? -ne 0 ]; then ++ echo "ERROR: Could not flush nat postrouting" 1>&2 ++ lret=1 ++ fi ++ ++ test $lret -eq 0 && echo "PASS: IP masquerade for ns2" ++ ++ return $lret ++} ++ ++test_redirect6() ++{ ++ local lret=0 ++ ++ ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null ++ ++ ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannnot ping ns1 from ns2 via ipv6" ++ lret=1 ++ fi ++ ++ expect="packets 1 bytes 104" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns2$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ reset_counters ++ ++# add redirect rule ++ip netns exec ns0 nft -f - < /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 with active ip6 redirect" ++ lret=1 ++ fi ++ ++ # ns1 should have seen no packets from ns2, due to redirection ++ expect="packets 0 bytes 0" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # ns0 should have seen packets from ns2, due to masquerade ++ expect="packets 1 bytes 104" ++ for dir in "in6" "out6" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ ip netns exec ns0 nft delete table ip6 nat ++ if [ $? -ne 0 ]; then ++ echo "ERROR: Could not delete ip6 nat table" 1>&2 ++ lret=1 ++ fi ++ ++ test $lret -eq 0 && echo "PASS: IPv6 redirection for ns2" ++ ++ return $lret ++} ++ ++test_redirect() ++{ ++ local lret=0 ++ ++ ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null ++ ip netns exec ns0 sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null ++ ++ ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2" ++ lret=1 ++ fi ++ ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns2$dir "$expect" ++ lret=1 ++ fi ++ ++ cnt=$(ip netns exec ns2 nft list counter inet filter ns1${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns2 ns1$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ reset_counters ++ ++# add redirect rule ++ip netns exec ns0 nft -f - < /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 with active ip redirect" ++ lret=1 ++ fi ++ ++ # ns1 should have seen no packets from ns2, due to redirection ++ expect="packets 0 bytes 0" ++ for dir in "in" "out" ; do ++ ++ cnt=$(ip netns exec ns1 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ # ns0 should have seen packets from ns2, due to masquerade ++ expect="packets 1 bytes 84" ++ for dir in "in" "out" ; do ++ cnt=$(ip netns exec ns0 nft list counter inet filter ns2${dir} | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ bad_counter ns1 ns0$dir "$expect" ++ lret=1 ++ fi ++ done ++ ++ ip netns exec ns0 nft delete table ip nat ++ if [ $? -ne 0 ]; then ++ echo "ERROR: Could not delete nat table" 1>&2 ++ lret=1 ++ fi ++ ++ test $lret -eq 0 && echo "PASS: IP redirection for ns2" ++ ++ return $lret ++} ++ ++ ++# ip netns exec ns0 ping -c 1 -q 10.0.$i.99 ++for i in 0 1 2; do ++ip netns exec ns$i nft -f - < /dev/null ++ if [ $? -ne 0 ];then ++ echo "ERROR: Could not reach other namespace(s)" 1>&2 ++ ret=1 ++ fi ++ ++ ip netns exec ns0 ping -c 1 -q dead:$i::99 > /dev/null ++ if [ $? -ne 0 ];then ++ echo "ERROR: Could not reach other namespace(s) via ipv6" 1>&2 ++ ret=1 ++ fi ++ check_counters ns$i ++ if [ $? -ne 0 ]; then ++ ret=1 ++ fi ++ ++ check_ns0_counters ns$i ++ if [ $? -ne 0 ]; then ++ ret=1 ++ fi ++ reset_counters ++done ++ ++if [ $ret -eq 0 ];then ++ echo "PASS: netns routing/connectivity: ns0 can reach ns1 and ns2" ++fi ++ ++reset_counters ++test_local_dnat ++test_local_dnat6 ++ ++reset_counters ++test_masquerade ++test_masquerade6 ++ ++reset_counters ++test_redirect ++test_redirect6 ++ ++for i in 0 1 2; do ip netns del ns$i;done ++ ++exit $ret +-- +2.19.1 + diff --git a/queue-4.20/selftests-netfilter-fix-config-fragment-config_nf_ta.patch b/queue-4.20/selftests-netfilter-fix-config-fragment-config_nf_ta.patch new file mode 100644 index 00000000000..c18442cbdf9 --- /dev/null +++ b/queue-4.20/selftests-netfilter-fix-config-fragment-config_nf_ta.patch @@ -0,0 +1,29 @@ +From abd3053cbecb48e648d61149c5591f3f86431e78 Mon Sep 17 00:00:00 2001 +From: Naresh Kamboju +Date: Tue, 29 Jan 2019 06:28:35 +0000 +Subject: selftests: netfilter: fix config fragment CONFIG_NF_TABLES_INET + +[ Upstream commit 952b72f89ae23b316da8c1021b18d0c388ad6cc4 ] + +In selftests the config fragment for netfilter was added as +NF_TABLES_INET=y and this patch correct it as CONFIG_NF_TABLES_INET=y + +Signed-off-by: Naresh Kamboju +Acked-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/netfilter/config | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/netfilter/config b/tools/testing/selftests/netfilter/config +index 1017313e41a8..59caa8f71cd8 100644 +--- a/tools/testing/selftests/netfilter/config ++++ b/tools/testing/selftests/netfilter/config +@@ -1,2 +1,2 @@ + CONFIG_NET_NS=y +-NF_TABLES_INET=y ++CONFIG_NF_TABLES_INET=y +-- +2.19.1 + diff --git a/queue-4.20/selftests-timers-use-ldlibs-instead-of-ldflags.patch b/queue-4.20/selftests-timers-use-ldlibs-instead-of-ldflags.patch new file mode 100644 index 00000000000..acfb6a214e3 --- /dev/null +++ b/queue-4.20/selftests-timers-use-ldlibs-instead-of-ldflags.patch @@ -0,0 +1,78 @@ +From 6aa0d584a3490d45e36acb2071732cd33afc8e74 Mon Sep 17 00:00:00 2001 +From: Fathi Boudra +Date: Wed, 16 Jan 2019 11:43:20 -0600 +Subject: selftests: timers: use LDLIBS instead of LDFLAGS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 7d4e591bc051d3382c45caaa2530969fb42ed23d ] + +posix_timers fails to build due to undefined reference errors: + + aarch64-linaro-linux-gcc --sysroot=/build/tmp-rpb-glibc/sysroots/hikey + -O2 -pipe -g -feliminate-unused-debug-types -O3 -Wl,-no-as-needed -Wall + -DKTEST -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -lrt -lpthread + posix_timers.c + -o /build/tmp-rpb-glibc/work/hikey-linaro-linux/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/timers/posix_timers + /tmp/cc1FTZzT.o: In function `check_timer_create': + /usr/src/debug/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/timers/posix_timers.c:157: + undefined reference to `timer_create' + /usr/src/debug/kselftests/4.12-r0/linux-4.12-rc7/tools/testing/selftests/timers/posix_timers.c:170: + undefined reference to `timer_settime' + collect2: error: ld returned 1 exit status + +It's GNU Make and linker specific. + +The default Makefile rule looks like: + +$(CC) $(CFLAGS) $(LDFLAGS) $@ $^ $(LDLIBS) + +When linking is done by gcc itself, no issue, but when it needs to be passed +to proper ld, only LDLIBS follows and then ld cannot know what libs to link +with. + +More detail: +https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html + +LDFLAGS +Extra flags to give to compilers when they are supposed to invoke the linker, +‘ld’, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable +instead. + +LDLIBS +Library flags or names given to compilers when they are supposed to invoke the +linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to +LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS +variable. + +https://lkml.org/lkml/2010/2/10/362 + +tools/perf: libraries must come after objects + +Link order matters, use LDLIBS instead of LDFLAGS to properly link against +libpthread. + +Signed-off-by: Denys Dmytriyenko +Signed-off-by: Fathi Boudra +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/timers/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile +index c02683cfb6c9..7656c7ce79d9 100644 +--- a/tools/testing/selftests/timers/Makefile ++++ b/tools/testing/selftests/timers/Makefile +@@ -1,6 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + CFLAGS += -O3 -Wl,-no-as-needed -Wall +-LDFLAGS += -lrt -lpthread -lm ++LDLIBS += -lrt -lpthread -lm + + # these are all "safe" tests that don't modify + # system time or require escalated privileges +-- +2.19.1 + diff --git a/queue-4.20/series b/queue-4.20/series index db14c65e4a7..c08b877b601 100644 --- a/queue-4.20/series +++ b/queue-4.20/series @@ -1 +1,149 @@ media-uvcvideo-fix-type-check-leading-to-overflow.patch +vti4-fix-a-ipip-packet-processing-bug-in-ipcomp-virt.patch +perf-ordered_events-fix-crash-in-ordered_events__fre.patch +netfilter-nft_compat-use-refcnt_t-type-for-nft_xt-re.patch +netfilter-nft_compat-make-lists-per-netns.patch +netfilter-nft_compat-destroy-function-must-not-have-.patch +perf-script-fix-crash-with-printing-mixed-trace-poin.patch +perf-core-fix-perf_proc_update_handler-bug.patch +perf-python-remove-fstack-clash-protection-when-buil.patch +perf-tools-handle-topology-headers-with-no-cpu.patch +perf-script-fix-crash-when-processing-recorded-stat-.patch +ib-hfi1-qib-fix-wc.byte_len-calculation-for-ud_send_.patch +iommu-amd-call-free_iova_fast-with-pfn-in-map_sg.patch +iommu-amd-unmap-all-mapped-pages-in-error-path-of-ma.patch +riscv-fixup-max_low_pfn-with-pfn_down.patch +ipvs-fix-signed-integer-overflow-when-setsockopt-tim.patch +iommu-amd-fix-iommu-page-flush-when-detach-device-fr.patch +clk-ti-fix-error-handling-in-ti_clk_parse_divider_da.patch +clk-qcom-gcc-use-active-only-source-for-cpuss-clocks.patch +xtensa-smp-fix-ccount_timer_shutdown.patch +rdma-umem-add-missing-initialization-of-owning_mm.patch +riscv-adjust-mmap-base-address-at-a-third-of-task-si.patch +ib-ipoib-fix-for-use-after-free-in-ipoib_cm_tx_start.patch +selftests-cpu-hotplug-fix-case-where-cpus-offline-cp.patch +xtensa-smp-fix-secondary-cpu-initialization.patch +xtensa-smp_lx200_defconfig-fix-vectors-clash.patch +xtensa-smp-mark-each-possible-cpu-as-present.patch +iomap-get-put-the-page-in-iomap_page_create-release.patch +iomap-fix-a-use-after-free-in-iomap_dio_rw.patch +xtensa-smp-limit-number-of-possible-cpus-by-nr_cpus.patch +net-altera_tse-fix-msgdma_tx_completion-on-non-zero-.patch +net-hns-fix-for-missing-of_node_put-after-of_parse_p.patch +net-hns-restart-autoneg-need-return-failed-when-auto.patch +net-hns-fix-wrong-read-accesses-via-clause-45-mdio-p.patch +net-stmmac-dwmac-rk-fix-error-handling-in-rk_gmac_po.patch +netfilter-ebtables-compat-un-break-32bit-setsockopt-.patch +gpio-vf610-mask-all-gpio-interrupts.patch +selftests-net-use-ldlibs-instead-of-ldflags.patch +selftests-timers-use-ldlibs-instead-of-ldflags.patch +nfs-fix-null-pointer-dereference-of-dev_name.patch +qed-fix-bug-in-tx-promiscuous-mode-settings.patch +qed-fix-lacp-pdu-drops-for-vfs.patch +qed-fix-vf-probe-failure-while-flr.patch +qed-fix-system-crash-in-ll2-xmit.patch +qed-fix-stack-out-of-bounds-bug.patch +scsi-libfc-free-skb-when-receiving-invalid-flogi-res.patch +scsi-scsi_debug-fix-write_same-with-virtual_gb-probl.patch +scsi-bnx2fc-fix-error-handling-in-probe.patch +scsi-53c700-pass-correct-dev-to-dma_alloc_attrs.patch +platform-x86-fix-unmet-dependency-warning-for-acpi_c.patch +platform-x86-fix-unmet-dependency-warning-for-samsun.patch +x86-cpu-add-atom-tremont-jacobsville.patch +net-macb-apply-rxubr-workaround-only-to-versions-wit.patch +x86-boot-compressed-64-set-efer.lme-1-in-32-bit-tram.patch +cifs-fix-computation-for-max_smb2_hdr_size.patch +x86-microcode-amd-don-t-falsely-trick-the-late-loadi.patch +apparmor-fix-warning-about-unused-function-apparmor_.patch +arm64-kprobe-always-blacklist-the-kvm-world-switch-c.patch +apparmor-fix-aa_label_build-error-handling-for-faile.patch +x86-kexec-don-t-setup-efi-info-if-efi-runtime-is-not.patch +proc-fix-proc-net-after-setns-2.patch +x86_64-increase-stack-size-for-kasan_extra.patch +mm-memory_hotplug-is_mem_section_removable-do-not-pa.patch +mm-memory_hotplug-test_pages_in_a_zone-do-not-pass-t.patch +psi-fix-aggregation-idle-shut-off.patch +lib-test_kmod.c-potential-double-free-in-error-handl.patch +fs-drop_caches.c-avoid-softlockups-in-drop_pagecache.patch +autofs-drop-dentry-reference-only-when-it-is-never-u.patch +autofs-fix-error-return-in-autofs_fill_super.patch +mm-memory_hotplug-fix-off-by-one-in-is_pageblock_rem.patch +arm-omap-dts-n950-n9-fix-onenand-timings.patch +arm-dts-omap4-droid4-fix-typo-in-cpcap-irq-flags.patch +arm-dts-sun8i-h3-add-ethernet0-alias-to-beelink-x2.patch +arm-dts-meson-fix-irq-trigger-type-for-macirq.patch +arm-dts-meson8b-odroidc1-mark-the-sd-card-detection-.patch +arm-dts-meson8b-ec100-mark-the-sd-card-detection-gpi.patch +arm-dts-meson8m2-mxiii-plus-mark-the-sd-card-detecti.patch +signal-make-siginmask-safe-when-passed-a-signal-of-0.patch +arm-dts-imx6sx-correct-backward-compatible-of-gpt.patch +arm64-dts-renesas-r8a7796-enable-dma-for-scif2.patch +arm64-dts-renesas-r8a77965-enable-dma-for-scif2.patch +soc-fsl-qbman-avoid-race-in-clearing-qman-interrupt.patch +pinctrl-mcp23s08-spi-fix-regmap-allocation-for-mcp23.patch +wlcore-sdio-fixup-power-on-off-sequence.patch +bpftool-fix-prog-dump-by-tag.patch +bpftool-fix-percpu-maps-updating.patch +bpf-sock-recvbuff-must-be-limited-by-rmem_max-in-bpf.patch +arm-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch +arm-dts-omap3-gta04-fix-graph_port-warning.patch +arm-dts-n900-fix-mmc1-card-detect-gpio-polarity.patch +arm-dts-am335x-shc.dts-fix-wrong-cd-pin-level.patch +arm64-dts-add-msm8996-compatible-to-gicv3.patch +batman-adv-release-station-info-tidstats.patch +mips-dts-jz4740-correct-interrupt-number-of-dma-core.patch +dts-ci20-fix-bugs-in-ci20-s-device-tree.patch +usb-phy-fix-link-errors.patch +usb-dwc3-exynos-fix-error-handling-of-clk_prepare_en.patch +irqchip-gic-v4-fix-occasional-vlpi-drop.patch +sk_msg-always-cancel-strp-work-before-freeing-the-ps.patch +irqchip-gic-v3-its-gracefully-fail-on-lpi-exhaustion.patch +irqchip-mmp-only-touch-the-pj4-irq-fiq-bits-on-enabl.patch +drm-amdgpu-add-missing-power-attribute-to-apu-check.patch +drm-radeon-check-if-device-is-root-before-getting-pc.patch +drm-amdgpu-transfer-fences-to-dmabuf-importer.patch +net-stmmac-fallback-to-platform-data-clock-in-watchd.patch +net-stmmac-send-tso-packets-always-from-queue-0.patch +net-stmmac-disable-eee-mode-earlier-in-xmit-callback.patch +irqchip-gic-v3-its-fix-itt_entry_size-accessor.patch +relay-check-return-of-create_buf_file-properly.patch +ath10k-correct-bus-type-for-wcn3990.patch +bpf-selftests-fix-handling-of-sparse-cpu-allocations.patch +bpf-run-bpf-programs-with-preemption-disabled.patch +bpf-fix-lockdep-false-positive-in-percpu_freelist.patch +bpf-fix-potential-deadlock-in-bpf_prog_register.patch +bpf-fix-syscall-s-stackmap-lookup-potential-deadlock.patch +drm-amdgpu-implement-doorbell-self-ring-for-nbio-7.4.patch +drm-amdgpu-fix-the-incorrect-external-id-for-raven-s.patch +drm-sun4i-tcon-prepare-and-enable-tcon-channel-0-clo.patch +dmaengine-at_xdmac-fix-wrongfull-report-of-a-channel.patch +vsock-virtio-fix-kernel-panic-after-device-hot-unplu.patch +vsock-virtio-reset-connected-sockets-on-device-remov.patch +dmaengine-dmatest-abort-test-in-case-of-mapping-erro.patch +selftests-netfilter-fix-config-fragment-config_nf_ta.patch +selftests-netfilter-add-simple-masq-redirect-test-ca.patch +netfilter-nf_nat-skip-nat-clash-resolution-for-same-.patch +s390-qeth-release-cmd-buffer-in-error-paths.patch +s390-qeth-fix-use-after-free-in-error-path.patch +s390-qeth-cancel-close_dev-work-before-removing-a-ca.patch +s390-qeth-conclude-all-event-processing-before-offli.patch +perf-symbols-filter-out-hidden-symbols-from-labels.patch +perf-trace-support-multiple-vfs_getname-probes.patch +mips-loongson-introduce-and-use-loongson_llsc_mb.patch +mips-remove-function-size-check-in-get_frame_info.patch +revert-scsi-libfc-add-warn_on-when-deleting-rports.patch +i2c-omap-use-noirq-system-sleep-pm-ops-to-idle-devic.patch +drm-amdgpu-use-spin_lock_irqsave-to-protect-vm_manag.patch +drm-omap-dsi-fix-crash-in-dsi-debug-dumps.patch +drm-omap-dsi-fix-of-platform-depopulate.patch +drm-omap-dsi-hack-fix-dsi-bus-flags.patch +nvme-lock-ns-list-changes-while-handling-command-eff.patch +nvme-pci-fix-rapid-add-remove-sequence.patch +fs-ratelimit-__find_get_block_slow-failure-message.patch +qed-fix-eq-full-firmware-assert.patch +qed-consider-tx-tcs-while-deriving-the-max-num_queue.patch +qede-fix-system-crash-on-configuring-channels.patch +blk-iolatency-fix-io-hang-due-to-negative-inflight-c.patch +nvme-pci-add-missing-unlock-for-reset-error.patch +netfilter-nf_tables-unbind-set-in-rule-from-commit-p.patch +netfilter-nft_compat-don-t-use-refcount_inc-on-newly.patch diff --git a/queue-4.20/signal-make-siginmask-safe-when-passed-a-signal-of-0.patch b/queue-4.20/signal-make-siginmask-safe-when-passed-a-signal-of-0.patch new file mode 100644 index 00000000000..a3571e16ff9 --- /dev/null +++ b/queue-4.20/signal-make-siginmask-safe-when-passed-a-signal-of-0.patch @@ -0,0 +1,98 @@ +From 43b1b1fd7f9be0cb883c841c20180807295abd99 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Sat, 12 Jan 2019 11:48:20 -0600 +Subject: signal: Make siginmask safe when passed a signal of 0 + +[ Upstream commit ee17e5d6201c66492a0e8053190fca2ed2b8457d ] + +Eric Biggers reported: +> The following commit, which went into v4.20, introduced undefined behavior when +> sys_rt_sigqueueinfo() is called with sig=0: +> +> commit 4ce5f9c9e7546915c559ffae594e6d73f918db00 +> Author: Eric W. Biederman +> Date: Tue Sep 25 12:59:31 2018 +0200 +> +> signal: Use a smaller struct siginfo in the kernel +> +> In sig_specific_sicodes(), used from known_siginfo_layout(), the expression +> '1ULL << ((sig)-1)' is undefined as it evaluates to 1ULL << 4294967295. +> +> Reproducer: +> +> #include +> #include +> #include +> +> int main(void) +> { +> siginfo_t si = { .si_code = 1 }; +> syscall(__NR_rt_sigqueueinfo, 0, 0, &si); +> } +> +> UBSAN report for v5.0-rc1: +> +> UBSAN: Undefined behaviour in kernel/signal.c:2946:7 +> shift exponent 4294967295 is too large for 64-bit type 'long unsigned int' +> CPU: 2 PID: 346 Comm: syz_signal Not tainted 5.0.0-rc1 #25 +> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 +> Call Trace: +> __dump_stack lib/dump_stack.c:77 [inline] +> dump_stack+0x70/0xa5 lib/dump_stack.c:113 +> ubsan_epilogue+0xd/0x40 lib/ubsan.c:159 +> __ubsan_handle_shift_out_of_bounds+0x12c/0x170 lib/ubsan.c:425 +> known_siginfo_layout+0xae/0xe0 kernel/signal.c:2946 +> post_copy_siginfo_from_user kernel/signal.c:3009 [inline] +> __copy_siginfo_from_user+0x35/0x60 kernel/signal.c:3035 +> __do_sys_rt_sigqueueinfo kernel/signal.c:3553 [inline] +> __se_sys_rt_sigqueueinfo kernel/signal.c:3549 [inline] +> __x64_sys_rt_sigqueueinfo+0x31/0x70 kernel/signal.c:3549 +> do_syscall_64+0x4c/0x1b0 arch/x86/entry/common.c:290 +> entry_SYSCALL_64_after_hwframe+0x49/0xbe +> RIP: 0033:0x433639 +> Code: c4 18 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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 0f 83 7b 27 00 00 c3 66 2e 0f 1f 84 00 00 00 00 +> RSP: 002b:00007fffcb289fc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000081 +> RAX: ffffffffffffffda RBX: 00000000004002e0 RCX: 0000000000433639 +> RDX: 00007fffcb289fd0 RSI: 0000000000000000 RDI: 0000000000000000 +> RBP: 00000000006b2018 R08: 000000000000004d R09: 0000000000000000 +> R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000401560 +> R13: 00000000004015f0 R14: 0000000000000000 R15: 0000000000000000 + +I have looked at the other callers of siginmask and they all appear to +in locations where sig can not be zero. + +I have looked at the code generation of adding an extra test against +zero and gcc was able with a simple decrement instruction to combine +the two tests together. So the at most adding this test cost a single +cpu cycle. In practice that decrement instruction was already present +as part of the mask comparison, so the only change was when the +instruction was executed. + +So given that it is cheap, and obviously correct to update siginmask +to verify the signal is not zero. Fix this issue there to avoid any +future problems. + +Reported-by: Eric Biggers +Fixes: 4ce5f9c9e754 ("signal: Use a smaller struct siginfo in the kernel") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Sasha Levin +--- + include/linux/signal.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/signal.h b/include/linux/signal.h +index f428e86f4800..b5d99482d3fe 100644 +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -388,7 +388,7 @@ extern bool unhandled_signal(struct task_struct *tsk, int sig); + #endif + + #define siginmask(sig, mask) \ +- ((sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) ++ ((sig) > 0 && (sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) + + #define SIG_KERNEL_ONLY_MASK (\ + rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP)) +-- +2.19.1 + diff --git a/queue-4.20/sk_msg-always-cancel-strp-work-before-freeing-the-ps.patch b/queue-4.20/sk_msg-always-cancel-strp-work-before-freeing-the-ps.patch new file mode 100644 index 00000000000..e7dbb644d8d --- /dev/null +++ b/queue-4.20/sk_msg-always-cancel-strp-work-before-freeing-the-ps.patch @@ -0,0 +1,97 @@ +From d3747ebdfd2fd5e12d8d04ad3f6261503ce52913 Mon Sep 17 00:00:00 2001 +From: Jakub Sitnicki +Date: Mon, 28 Jan 2019 10:13:35 +0100 +Subject: sk_msg: Always cancel strp work before freeing the psock + +[ Upstream commit 1d79895aef18fa05789995d86d523c9b2ee58a02 ] + +Despite having stopped the parser, we still need to deinitialize it +by calling strp_done so that it cancels its work. Otherwise the worker +thread can run after we have freed the parser, and attempt to access +its workqueue resulting in a use-after-free: + +================================================================== +BUG: KASAN: use-after-free in pwq_activate_delayed_work+0x1b/0x1d0 +Read of size 8 at addr ffff888069975240 by task kworker/u2:2/93 + +CPU: 0 PID: 93 Comm: kworker/u2:2 Not tainted 5.0.0-rc2-00335-g28f9d1a3d4fe-dirty #14 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014 +Workqueue: (null) (kstrp) +Call Trace: + print_address_description+0x6e/0x2b0 + ? pwq_activate_delayed_work+0x1b/0x1d0 + kasan_report+0xfd/0x177 + ? pwq_activate_delayed_work+0x1b/0x1d0 + ? pwq_activate_delayed_work+0x1b/0x1d0 + pwq_activate_delayed_work+0x1b/0x1d0 + ? process_one_work+0x4aa/0x660 + pwq_dec_nr_in_flight+0x9b/0x100 + worker_thread+0x82/0x680 + ? process_one_work+0x660/0x660 + kthread+0x1b9/0x1e0 + ? __kthread_create_on_node+0x250/0x250 + ret_from_fork+0x1f/0x30 + +Allocated by task 111: + sk_psock_init+0x3c/0x1b0 + sock_map_link.isra.2+0x103/0x4b0 + sock_map_update_common+0x94/0x270 + sock_map_update_elem+0x145/0x160 + __se_sys_bpf+0x152e/0x1e10 + do_syscall_64+0xb2/0x3e0 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Freed by task 112: + kfree+0x7f/0x140 + process_one_work+0x40b/0x660 + worker_thread+0x82/0x680 + kthread+0x1b9/0x1e0 + ret_from_fork+0x1f/0x30 + +The buggy address belongs to the object at ffff888069975180 + which belongs to the cache kmalloc-512 of size 512 +The buggy address is located 192 bytes inside of + 512-byte region [ffff888069975180, ffff888069975380) +The buggy address belongs to the page: +page:ffffea0001a65d00 count:1 mapcount:0 mapping:ffff88806d401280 index:0x0 compound_mapcount: 0 +flags: 0x4000000000010200(slab|head) +raw: 4000000000010200 dead000000000100 dead000000000200 ffff88806d401280 +raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff888069975100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff888069975180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +>ffff888069975200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff888069975280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff888069975300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +================================================================== + +Reported-by: Marek Majkowski +Signed-off-by: Jakub Sitnicki +Link: https://lore.kernel.org/netdev/CAJPywTLwgXNEZ2dZVoa=udiZmtrWJ0q5SuBW64aYs0Y1khXX3A@mail.gmail.com +Acked-by: Song Liu +Signed-off-by: Daniel Borkmann +Signed-off-by: Sasha Levin +--- + net/core/skmsg.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index 54d854807630..4932861d7b88 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -545,8 +545,7 @@ static void sk_psock_destroy_deferred(struct work_struct *gc) + struct sk_psock *psock = container_of(gc, struct sk_psock, gc); + + /* No sk_callback_lock since already detached. */ +- if (psock->parser.enabled) +- strp_done(&psock->parser.strp); ++ strp_done(&psock->parser.strp); + + cancel_work_sync(&psock->work); + +-- +2.19.1 + diff --git a/queue-4.20/soc-fsl-qbman-avoid-race-in-clearing-qman-interrupt.patch b/queue-4.20/soc-fsl-qbman-avoid-race-in-clearing-qman-interrupt.patch new file mode 100644 index 00000000000..63be64a7f46 --- /dev/null +++ b/queue-4.20/soc-fsl-qbman-avoid-race-in-clearing-qman-interrupt.patch @@ -0,0 +1,51 @@ +From b3d84b1fe56d0333c9046bc58fb5402e36a8c461 Mon Sep 17 00:00:00 2001 +From: Madalin Bucur +Date: Fri, 21 Dec 2018 16:41:42 +0200 +Subject: soc: fsl: qbman: avoid race in clearing QMan interrupt + +[ Upstream commit 89857a8a5c89a406b967ab2be7bd2ccdbe75e73d ] + +By clearing all interrupt sources, not only those that +already occurred, the existing code may acknowledge by +mistake interrupts that occurred after the code checks +for them. + +Signed-off-by: Madalin Bucur +Signed-off-by: Roy Pledge +Signed-off-by: Li Yang +Signed-off-by: Sasha Levin +--- + drivers/soc/fsl/qbman/qman.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c +index 5ce24718c2fd..d8b3ba047c28 100644 +--- a/drivers/soc/fsl/qbman/qman.c ++++ b/drivers/soc/fsl/qbman/qman.c +@@ -1124,18 +1124,19 @@ static void qm_mr_process_task(struct work_struct *work); + static irqreturn_t portal_isr(int irq, void *ptr) + { + struct qman_portal *p = ptr; +- +- u32 clear = QM_DQAVAIL_MASK | p->irq_sources; + u32 is = qm_in(&p->p, QM_REG_ISR) & p->irq_sources; ++ u32 clear = 0; + + if (unlikely(!is)) + return IRQ_NONE; + + /* DQRR-handling if it's interrupt-driven */ +- if (is & QM_PIRQ_DQRI) ++ if (is & QM_PIRQ_DQRI) { + __poll_portal_fast(p, QMAN_POLL_LIMIT); ++ clear = QM_DQAVAIL_MASK | QM_PIRQ_DQRI; ++ } + /* Handling of anything else that's interrupt-driven */ +- clear |= __poll_portal_slow(p, is); ++ clear |= __poll_portal_slow(p, is) & QM_PIRQ_SLOW; + qm_out(&p->p, QM_REG_ISR, clear); + return IRQ_HANDLED; + } +-- +2.19.1 + diff --git a/queue-4.20/usb-dwc3-exynos-fix-error-handling-of-clk_prepare_en.patch b/queue-4.20/usb-dwc3-exynos-fix-error-handling-of-clk_prepare_en.patch new file mode 100644 index 00000000000..a34b6e5f79d --- /dev/null +++ b/queue-4.20/usb-dwc3-exynos-fix-error-handling-of-clk_prepare_en.patch @@ -0,0 +1,47 @@ +From bede2d5f0188036211e72c82bdfa6259816ebf18 Mon Sep 17 00:00:00 2001 +From: Alexey Khoroshilov +Date: Tue, 22 Jan 2019 00:23:50 +0300 +Subject: usb: dwc3: exynos: Fix error handling of clk_prepare_enable + +[ Upstream commit 512e6fb589bc18f9321457632e89b95017447db9 ] + +If clk_prepare_enable() fails in dwc3_exynos_probe() or in +dwc3_exynos_resume(), exynos->clks[0] is left undisabled +because of usage preincrement in while condition. + +Found by Linux Driver Verification project (linuxtesting.org). + +Fixes: 9f2168367a0a ("usb: dwc3: exynos: Rework clock handling and prepare for new variants") +Acked-by: Marek Szyprowski +Signed-off-by: Alexey Khoroshilov +Signed-off-by: Felipe Balbi +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/dwc3-exynos.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c +index cb7fcd7c0ad8..c1e9ea621f41 100644 +--- a/drivers/usb/dwc3/dwc3-exynos.c ++++ b/drivers/usb/dwc3/dwc3-exynos.c +@@ -78,7 +78,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) + for (i = 0; i < exynos->num_clks; i++) { + ret = clk_prepare_enable(exynos->clks[i]); + if (ret) { +- while (--i > 0) ++ while (i-- > 0) + clk_disable_unprepare(exynos->clks[i]); + return ret; + } +@@ -223,7 +223,7 @@ static int dwc3_exynos_resume(struct device *dev) + for (i = 0; i < exynos->num_clks; i++) { + ret = clk_prepare_enable(exynos->clks[i]); + if (ret) { +- while (--i > 0) ++ while (i-- > 0) + clk_disable_unprepare(exynos->clks[i]); + return ret; + } +-- +2.19.1 + diff --git a/queue-4.20/usb-phy-fix-link-errors.patch b/queue-4.20/usb-phy-fix-link-errors.patch new file mode 100644 index 00000000000..526822936fb --- /dev/null +++ b/queue-4.20/usb-phy-fix-link-errors.patch @@ -0,0 +1,58 @@ +From 509e91043c9c87768547441e4f57ad789d763cce Mon Sep 17 00:00:00 2001 +From: Anders Roxell +Date: Tue, 22 Jan 2019 11:36:02 +0100 +Subject: usb: phy: fix link errors + +[ Upstream commit f2105d42597f4d10e431b195d69e96dccaf9b012 ] + +Fix link errors when CONFIG_FSL_USB2_OTG is enabled and USB_OTG_FSM is +set to module then the following link error occurs. + +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o: in function `fsl_otg_ioctl': +drivers/usb/phy/phy-fsl-usb.c:1083: undefined reference to `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.c:1083:(.text+0x574): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o: in function `fsl_otg_start_srp': +drivers/usb/phy/phy-fsl-usb.c:674: undefined reference to `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.c:674:(.text+0x61c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o: in function `fsl_otg_set_host': +drivers/usb/phy/phy-fsl-usb.c:593: undefined reference to `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.c:593:(.text+0x7a4): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o: in function `fsl_otg_start_hnp': +drivers/usb/phy/phy-fsl-usb.c:695: undefined reference to `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.c:695:(.text+0x858): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o: in function `a_wait_enum': +drivers/usb/phy/phy-fsl-usb.c:274: undefined reference to `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.c:274:(.text+0x16f0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `otg_statemachine' +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o:drivers/usb/phy/phy-fsl-usb.c:619: more undefined references to `otg_statemachine' follow +aarch64-linux-gnu-ld: drivers/usb/phy/phy-fsl-usb.o: in function `fsl_otg_set_peripheral': +drivers/usb/phy/phy-fsl-usb.c:619:(.text+0x1fa0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `otg_statemachine' +make[1]: *** [Makefile:1020: vmlinux] Error 1 +make[1]: Target 'Image' not remade because of errors. +make: *** [Makefile:152: sub-make] Error 2 +make: Target 'Image' not remade because of errors. + +Rework so that FSL_USB2_OTG depends on that the USB_OTG_FSM is builtin. + +Signed-off-by: Anders Roxell +Signed-off-by: Felipe Balbi +Signed-off-by: Sasha Levin +--- + drivers/usb/phy/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +index d7312eed6088..91ea3083e7ad 100644 +--- a/drivers/usb/phy/Kconfig ++++ b/drivers/usb/phy/Kconfig +@@ -21,7 +21,7 @@ config AB8500_USB + + config FSL_USB2_OTG + bool "Freescale USB OTG Transceiver Driver" +- depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM ++ depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM=y && PM + depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' + select USB_PHY + help +-- +2.19.1 + diff --git a/queue-4.20/vsock-virtio-fix-kernel-panic-after-device-hot-unplu.patch b/queue-4.20/vsock-virtio-fix-kernel-panic-after-device-hot-unplu.patch new file mode 100644 index 00000000000..3491fcfcbe5 --- /dev/null +++ b/queue-4.20/vsock-virtio-fix-kernel-panic-after-device-hot-unplu.patch @@ -0,0 +1,101 @@ +From 3cdea0efa44f5f59192472a4b62e24168f216a27 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Fri, 1 Feb 2019 12:42:06 +0100 +Subject: vsock/virtio: fix kernel panic after device hot-unplug + +[ Upstream commit 22b5c0b63f32568e130fa2df4ba23efce3eb495b ] + +virtio_vsock_remove() invokes the vsock_core_exit() also if there +are opened sockets for the AF_VSOCK protocol family. In this way +the vsock "transport" pointer is set to NULL, triggering the +kernel panic at the first socket activity. + +This patch move the vsock_core_init()/vsock_core_exit() in the +virtio_vsock respectively in module_init and module_exit functions, +that cannot be invoked until there are open sockets. + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1609699 +Reported-by: Yan Fu +Signed-off-by: Stefano Garzarella +Acked-by: Stefan Hajnoczi +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/vmw_vsock/virtio_transport.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 5d3cce9e8744..9dae54698737 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -75,6 +75,9 @@ static u32 virtio_transport_get_local_cid(void) + { + struct virtio_vsock *vsock = virtio_vsock_get(); + ++ if (!vsock) ++ return VMADDR_CID_ANY; ++ + return vsock->guest_cid; + } + +@@ -584,10 +587,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + + virtio_vsock_update_guest_cid(vsock); + +- ret = vsock_core_init(&virtio_transport.transport); +- if (ret < 0) +- goto out_vqs; +- + vsock->rx_buf_nr = 0; + vsock->rx_buf_max_nr = 0; + atomic_set(&vsock->queued_replies, 0); +@@ -618,8 +617,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + mutex_unlock(&the_virtio_vsock_mutex); + return 0; + +-out_vqs: +- vsock->vdev->config->del_vqs(vsock->vdev); + out: + kfree(vsock); + mutex_unlock(&the_virtio_vsock_mutex); +@@ -669,7 +666,6 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + + mutex_lock(&the_virtio_vsock_mutex); + the_virtio_vsock = NULL; +- vsock_core_exit(); + mutex_unlock(&the_virtio_vsock_mutex); + + vdev->config->del_vqs(vdev); +@@ -702,14 +698,28 @@ static int __init virtio_vsock_init(void) + virtio_vsock_workqueue = alloc_workqueue("virtio_vsock", 0, 0); + if (!virtio_vsock_workqueue) + return -ENOMEM; ++ + ret = register_virtio_driver(&virtio_vsock_driver); + if (ret) +- destroy_workqueue(virtio_vsock_workqueue); ++ goto out_wq; ++ ++ ret = vsock_core_init(&virtio_transport.transport); ++ if (ret) ++ goto out_vdr; ++ ++ return 0; ++ ++out_vdr: ++ unregister_virtio_driver(&virtio_vsock_driver); ++out_wq: ++ destroy_workqueue(virtio_vsock_workqueue); + return ret; ++ + } + + static void __exit virtio_vsock_exit(void) + { ++ vsock_core_exit(); + unregister_virtio_driver(&virtio_vsock_driver); + destroy_workqueue(virtio_vsock_workqueue); + } +-- +2.19.1 + diff --git a/queue-4.20/vsock-virtio-reset-connected-sockets-on-device-remov.patch b/queue-4.20/vsock-virtio-reset-connected-sockets-on-device-remov.patch new file mode 100644 index 00000000000..57561e95a0e --- /dev/null +++ b/queue-4.20/vsock-virtio-reset-connected-sockets-on-device-remov.patch @@ -0,0 +1,35 @@ +From 9e7ed802effd1dab71e84403da511541425959c6 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Fri, 1 Feb 2019 12:42:07 +0100 +Subject: vsock/virtio: reset connected sockets on device removal + +[ Upstream commit 85965487abc540368393a15491e6e7fcd230039d ] + +When the virtio transport device disappear, we should reset all +connected sockets in order to inform the users. + +Signed-off-by: Stefano Garzarella +Reviewed-by: Stefan Hajnoczi +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/vmw_vsock/virtio_transport.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 9dae54698737..15eb5d3d4750 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -634,6 +634,9 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + flush_work(&vsock->event_work); + flush_work(&vsock->send_pkt_work); + ++ /* Reset all connected sockets when the device disappear */ ++ vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ + vdev->config->reset(vdev); + + mutex_lock(&vsock->rx_lock); +-- +2.19.1 + diff --git a/queue-4.20/vti4-fix-a-ipip-packet-processing-bug-in-ipcomp-virt.patch b/queue-4.20/vti4-fix-a-ipip-packet-processing-bug-in-ipcomp-virt.patch new file mode 100644 index 00000000000..f32b38cf2f6 --- /dev/null +++ b/queue-4.20/vti4-fix-a-ipip-packet-processing-bug-in-ipcomp-virt.patch @@ -0,0 +1,119 @@ +From 6c3993b03401dc9a9675e6f22cc6008cb6a5ddfe Mon Sep 17 00:00:00 2001 +From: Su Yanjun +Date: Sun, 6 Jan 2019 21:31:20 -0500 +Subject: vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel + +[ Upstream commit dd9ee3444014e8f28c0eefc9fffc9ac9c5248c12 ] + +Recently we run a network test over ipcomp virtual tunnel.We find that +if a ipv4 packet needs fragment, then the peer can't receive +it. + +We deep into the code and find that when packet need fragment the smaller +fragment will be encapsulated by ipip not ipcomp. So when the ipip packet +goes into xfrm, it's skb->dev is not properly set. The ipv4 reassembly code +always set skb'dev to the last fragment's dev. After ipv4 defrag processing, +when the kernel rp_filter parameter is set, the skb will be drop by -EXDEV +error. + +This patch adds compatible support for the ipip process in ipcomp virtual tunnel. + +Signed-off-by: Su Yanjun +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/ipv4/ip_vti.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c +index d7b43e700023..68a21bf75dd0 100644 +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -74,6 +74,33 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, + return 0; + } + ++static int vti_input_ipip(struct sk_buff *skb, int nexthdr, __be32 spi, ++ int encap_type) ++{ ++ struct ip_tunnel *tunnel; ++ const struct iphdr *iph = ip_hdr(skb); ++ struct net *net = dev_net(skb->dev); ++ struct ip_tunnel_net *itn = net_generic(net, vti_net_id); ++ ++ tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, ++ iph->saddr, iph->daddr, 0); ++ if (tunnel) { ++ if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) ++ goto drop; ++ ++ XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; ++ ++ skb->dev = tunnel->dev; ++ ++ return xfrm_input(skb, nexthdr, spi, encap_type); ++ } ++ ++ return -EINVAL; ++drop: ++ kfree_skb(skb); ++ return 0; ++} ++ + static int vti_rcv(struct sk_buff *skb) + { + XFRM_SPI_SKB_CB(skb)->family = AF_INET; +@@ -82,6 +109,14 @@ static int vti_rcv(struct sk_buff *skb) + return vti_input(skb, ip_hdr(skb)->protocol, 0, 0); + } + ++static int vti_rcv_ipip(struct sk_buff *skb) ++{ ++ XFRM_SPI_SKB_CB(skb)->family = AF_INET; ++ XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); ++ ++ return vti_input_ipip(skb, ip_hdr(skb)->protocol, ip_hdr(skb)->saddr, 0); ++} ++ + static int vti_rcv_cb(struct sk_buff *skb, int err) + { + unsigned short family; +@@ -435,6 +470,12 @@ static struct xfrm4_protocol vti_ipcomp4_protocol __read_mostly = { + .priority = 100, + }; + ++static struct xfrm_tunnel ipip_handler __read_mostly = { ++ .handler = vti_rcv_ipip, ++ .err_handler = vti4_err, ++ .priority = 0, ++}; ++ + static int __net_init vti_init_net(struct net *net) + { + int err; +@@ -603,6 +644,13 @@ static int __init vti_init(void) + if (err < 0) + goto xfrm_proto_comp_failed; + ++ msg = "ipip tunnel"; ++ err = xfrm4_tunnel_register(&ipip_handler, AF_INET); ++ if (err < 0) { ++ pr_info("%s: cant't register tunnel\n",__func__); ++ goto xfrm_tunnel_failed; ++ } ++ + msg = "netlink interface"; + err = rtnl_link_register(&vti_link_ops); + if (err < 0) +@@ -612,6 +660,8 @@ static int __init vti_init(void) + + rtnl_link_failed: + xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP); ++xfrm_tunnel_failed: ++ xfrm4_tunnel_deregister(&ipip_handler, AF_INET); + xfrm_proto_comp_failed: + xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); + xfrm_proto_ah_failed: +-- +2.19.1 + diff --git a/queue-4.20/wlcore-sdio-fixup-power-on-off-sequence.patch b/queue-4.20/wlcore-sdio-fixup-power-on-off-sequence.patch new file mode 100644 index 00000000000..9bb42729d3d --- /dev/null +++ b/queue-4.20/wlcore-sdio-fixup-power-on-off-sequence.patch @@ -0,0 +1,78 @@ +From d43f2bfab95b58acac2d3198c0d3dbd70ef34aee Mon Sep 17 00:00:00 2001 +From: Ulf Hansson +Date: Wed, 16 Jan 2019 12:37:23 +0100 +Subject: wlcore: sdio: Fixup power on/off sequence + +[ Upstream commit 13e62626c578d9889ebbda7c521be5adff9bef8e ] + +During "wlan-up", we are programming the FW into the WiFi-chip. However, +re-programming the FW doesn't work, unless a power cycle of the WiFi-chip +is made in-between the programmings. + +To conform to this requirement and to fix the regression in a simple way, +let's start by allowing that the SDIO card (WiFi-chip) may stay powered on +(runtime resumed) when wl12xx_sdio_power_off() returns. The intent with the +current code is to treat this scenario as an error, but unfortunate this +doesn't work as expected, so let's fix this. + +The other part is to guarantee that a power cycle of the SDIO card has been +completed when wl12xx_sdio_power_on() returns, as to allow the FW +programming to succeed. However, relying solely on runtime PM to deal with +this isn't sufficient. For example, userspace may prevent runtime suspend +via sysfs for the device that represents the SDIO card, leading to that the +mmc core also keeps it powered on. For this reason, let's instead do a +brute force power cycle in wl12xx_sdio_power_on(). + +Fixes: 728a9dc61f13 ("wlcore: sdio: Fix flakey SDIO runtime PM handling") +Signed-off-by: Ulf Hansson +Tested-by: Tony Lindgren +Tested-by: Anders Roxell +Signed-off-by: Ulf Hansson +Signed-off-by: Kalle Valo +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ti/wlcore/sdio.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c +index bd10165d7eec..4d4b07701149 100644 +--- a/drivers/net/wireless/ti/wlcore/sdio.c ++++ b/drivers/net/wireless/ti/wlcore/sdio.c +@@ -164,6 +164,12 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) + } + + sdio_claim_host(func); ++ /* ++ * To guarantee that the SDIO card is power cycled, as required to make ++ * the FW programming to succeed, let's do a brute force HW reset. ++ */ ++ mmc_hw_reset(card->host); ++ + sdio_enable_func(func); + sdio_release_host(func); + +@@ -174,20 +180,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) + { + struct sdio_func *func = dev_to_sdio_func(glue->dev); + struct mmc_card *card = func->card; +- int error; + + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + /* Let runtime PM know the card is powered off */ +- error = pm_runtime_put(&card->dev); +- if (error < 0 && error != -EBUSY) { +- dev_err(&card->dev, "%s failed: %i\n", __func__, error); +- +- return error; +- } +- ++ pm_runtime_put(&card->dev); + return 0; + } + +-- +2.19.1 + diff --git a/queue-4.20/x86-boot-compressed-64-set-efer.lme-1-in-32-bit-tram.patch b/queue-4.20/x86-boot-compressed-64-set-efer.lme-1-in-32-bit-tram.patch new file mode 100644 index 00000000000..3434476e499 --- /dev/null +++ b/queue-4.20/x86-boot-compressed-64-set-efer.lme-1-in-32-bit-tram.patch @@ -0,0 +1,63 @@ +From e9a0b4d1c6e2191daf89936395bff640d313bdbc Mon Sep 17 00:00:00 2001 +From: Wei Huang +Date: Thu, 3 Jan 2019 23:44:11 -0600 +Subject: x86/boot/compressed/64: Set EFER.LME=1 in 32-bit trampoline before + returning to long mode + +[ Upstream commit b677dfae5aa197afc5191755a76a8727ffca538a ] + +In some old AMD KVM implementation, guest's EFER.LME bit is cleared by KVM +when the hypervsior detects that the guest sets CR0.PG to 0. This causes +the guest OS to reboot when it tries to return from 32-bit trampoline code +because the CPU is in incorrect state: CR4.PAE=1, CR0.PG=1, CS.L=1, but +EFER.LME=0. As a precaution, set EFER.LME=1 as part of long mode +activation procedure. This extra step won't cause any harm when Linux is +booted on a bare-metal machine. + +Signed-off-by: Wei Huang +Signed-off-by: Thomas Gleixner +Acked-by: Kirill A. Shutemov +Cc: bp@alien8.de +Cc: hpa@zytor.com +Link: https://lkml.kernel.org/r/20190104054411.12489-1-wei@redhat.com +Signed-off-by: Sasha Levin +--- + arch/x86/boot/compressed/head_64.S | 8 ++++++++ + arch/x86/boot/compressed/pgtable.h | 2 +- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S +index 64037895b085..f105ae8651c9 100644 +--- a/arch/x86/boot/compressed/head_64.S ++++ b/arch/x86/boot/compressed/head_64.S +@@ -600,6 +600,14 @@ ENTRY(trampoline_32bit_src) + leal TRAMPOLINE_32BIT_PGTABLE_OFFSET(%ecx), %eax + movl %eax, %cr3 + 3: ++ /* Set EFER.LME=1 as a precaution in case hypervsior pulls the rug */ ++ pushl %ecx ++ movl $MSR_EFER, %ecx ++ rdmsr ++ btsl $_EFER_LME, %eax ++ wrmsr ++ popl %ecx ++ + /* Enable PAE and LA57 (if required) paging modes */ + movl $X86_CR4_PAE, %eax + cmpl $0, %edx +diff --git a/arch/x86/boot/compressed/pgtable.h b/arch/x86/boot/compressed/pgtable.h +index 91f75638f6e6..6ff7e81b5628 100644 +--- a/arch/x86/boot/compressed/pgtable.h ++++ b/arch/x86/boot/compressed/pgtable.h +@@ -6,7 +6,7 @@ + #define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 + + #define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE +-#define TRAMPOLINE_32BIT_CODE_SIZE 0x60 ++#define TRAMPOLINE_32BIT_CODE_SIZE 0x70 + + #define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE + +-- +2.19.1 + diff --git a/queue-4.20/x86-cpu-add-atom-tremont-jacobsville.patch b/queue-4.20/x86-cpu-add-atom-tremont-jacobsville.patch new file mode 100644 index 00000000000..0eebd5ad96f --- /dev/null +++ b/queue-4.20/x86-cpu-add-atom-tremont-jacobsville.patch @@ -0,0 +1,58 @@ +From 98e4d8cba2c822b5d429085c40145d7feb0201aa Mon Sep 17 00:00:00 2001 +From: Kan Liang +Date: Fri, 25 Jan 2019 11:59:01 -0800 +Subject: x86/cpu: Add Atom Tremont (Jacobsville) + +[ Upstream commit 00ae831dfe4474ef6029558f5eb3ef0332d80043 ] + +Add the Atom Tremont model number to the Intel family list. + +[ Tony: Also update comment at head of file to say "_X" suffix is + also used for microserver parts. ] + +Signed-off-by: Kan Liang +Signed-off-by: Qiuxu Zhuo +Signed-off-by: Tony Luck +Signed-off-by: Borislav Petkov +Cc: Andy Shevchenko +Cc: Aristeu Rozanski +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: linux-edac +Cc: Mauro Carvalho Chehab +Cc: Megha Dey +Cc: Peter Zijlstra +Cc: Qiuxu Zhuo +Cc: Rajneesh Bhardwaj +Cc: Thomas Gleixner +Cc: x86-ml +Link: https://lkml.kernel.org/r/20190125195902.17109-4-tony.luck@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/intel-family.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h +index 0dd6b0f4000e..d9a9993af882 100644 +--- a/arch/x86/include/asm/intel-family.h ++++ b/arch/x86/include/asm/intel-family.h +@@ -6,7 +6,7 @@ + * "Big Core" Processors (Branded as Core, Xeon, etc...) + * + * The "_X" parts are generally the EP and EX Xeons, or the +- * "Extreme" ones, like Broadwell-E. ++ * "Extreme" ones, like Broadwell-E, or Atom microserver. + * + * While adding a new CPUID for a new microarchitecture, add a new + * group to keep logically sorted out in chronological order. Within +@@ -71,6 +71,7 @@ + #define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */ + #define INTEL_FAM6_ATOM_GOLDMONT_X 0x5F /* Denverton */ + #define INTEL_FAM6_ATOM_GOLDMONT_PLUS 0x7A /* Gemini Lake */ ++#define INTEL_FAM6_ATOM_TREMONT_X 0x86 /* Jacobsville */ + + /* Xeon Phi */ + +-- +2.19.1 + diff --git a/queue-4.20/x86-kexec-don-t-setup-efi-info-if-efi-runtime-is-not.patch b/queue-4.20/x86-kexec-don-t-setup-efi-info-if-efi-runtime-is-not.patch new file mode 100644 index 00000000000..4210f14c2dc --- /dev/null +++ b/queue-4.20/x86-kexec-don-t-setup-efi-info-if-efi-runtime-is-not.patch @@ -0,0 +1,70 @@ +From 4f37ccc429288b56eda65476eedd36f3d9ca8c59 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Fri, 18 Jan 2019 19:13:08 +0800 +Subject: x86/kexec: Don't setup EFI info if EFI runtime is not enabled + +[ Upstream commit 2aa958c99c7fd3162b089a1a56a34a0cdb778de1 ] + +Kexec-ing a kernel with "efi=noruntime" on the first kernel's command +line causes the following null pointer dereference: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + #PF error: [normal kernel read fault] + Call Trace: + efi_runtime_map_copy+0x28/0x30 + bzImage64_load+0x688/0x872 + arch_kexec_kernel_image_load+0x6d/0x70 + kimage_file_alloc_init+0x13e/0x220 + __x64_sys_kexec_file_load+0x144/0x290 + do_syscall_64+0x55/0x1a0 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Just skip the EFI info setup if EFI runtime services are not enabled. + + [ bp: Massage commit message. ] + +Suggested-by: Dave Young +Signed-off-by: Kairui Song +Signed-off-by: Borislav Petkov +Acked-by: Dave Young +Cc: AKASHI Takahiro +Cc: Andrew Morton +Cc: Ard Biesheuvel +Cc: bhe@redhat.com +Cc: David Howells +Cc: erik.schmauss@intel.com +Cc: fanc.fnst@cn.fujitsu.com +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: kexec@lists.infradead.org +Cc: lenb@kernel.org +Cc: linux-acpi@vger.kernel.org +Cc: Philipp Rudo +Cc: rafael.j.wysocki@intel.com +Cc: robert.moore@intel.com +Cc: Thomas Gleixner +Cc: x86-ml +Cc: Yannik Sembritzki +Link: https://lkml.kernel.org/r/20190118111310.29589-2-kasong@redhat.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/kexec-bzimage64.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c +index 278cd07228dd..9490a2845f14 100644 +--- a/arch/x86/kernel/kexec-bzimage64.c ++++ b/arch/x86/kernel/kexec-bzimage64.c +@@ -167,6 +167,9 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr, + struct efi_info *current_ei = &boot_params.efi_info; + struct efi_info *ei = ¶ms->efi_info; + ++ if (!efi_enabled(EFI_RUNTIME_SERVICES)) ++ return 0; ++ + if (!current_ei->efi_memmap_size) + return 0; + +-- +2.19.1 + diff --git a/queue-4.20/x86-microcode-amd-don-t-falsely-trick-the-late-loadi.patch b/queue-4.20/x86-microcode-amd-don-t-falsely-trick-the-late-loadi.patch new file mode 100644 index 00000000000..5500c87069a --- /dev/null +++ b/queue-4.20/x86-microcode-amd-don-t-falsely-trick-the-late-loadi.patch @@ -0,0 +1,66 @@ +From fcbb31c82b9840ee3402e14586320f453946cb8d Mon Sep 17 00:00:00 2001 +From: Thomas Lendacky +Date: Thu, 31 Jan 2019 14:33:06 +0000 +Subject: x86/microcode/amd: Don't falsely trick the late loading mechanism + +[ Upstream commit 912139cfbfa6a2bc1da052314d2c29338dae1f6a ] + +The load_microcode_amd() function searches for microcode patches and +attempts to apply a microcode patch if it is of different level than the +currently installed level. + +While the processor won't actually load a level that is less than +what is already installed, the logic wrongly returns UCODE_NEW thus +signaling to its caller reload_store() that a late loading should be +attempted. + +If the file-system contains an older microcode revision than what is +currently running, such a late microcode reload can result in these +misleading messages: + + x86/CPU: CPU features have changed after loading microcode, but might not take effect. + x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update. + +These messages were issued on a system where SME/SEV are not +enabled by the BIOS (MSR C001_0010[23] = 0b) because during boot, +early_detect_mem_encrypt() is called and cleared the SME and SEV +features in this case. + +However, after the wrong late load attempt, get_cpu_cap() is called and +reloads the SME and SEV feature bits, resulting in the messages. + +Update the microcode level check to not attempt microcode loading if the +current level is greater than(!) and not only equal to the current patch +level. + + [ bp: massage commit message. ] + +Fixes: 2613f36ed965 ("x86/microcode: Attempt late loading only when new microcode is present") +Signed-off-by: Tom Lendacky +Signed-off-by: Borislav Petkov +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: Thomas Gleixner +Cc: x86-ml +Link: https://lkml.kernel.org/r/154894518427.9406.8246222496874202773.stgit@tlendack-t1.amdoffice.net +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/microcode/amd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c +index 07b5fc00b188..a4e7e100ed26 100644 +--- a/arch/x86/kernel/cpu/microcode/amd.c ++++ b/arch/x86/kernel/cpu/microcode/amd.c +@@ -707,7 +707,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) + if (!p) { + return ret; + } else { +- if (boot_cpu_data.microcode == p->patch_id) ++ if (boot_cpu_data.microcode >= p->patch_id) + return ret; + + ret = UCODE_NEW; +-- +2.19.1 + diff --git a/queue-4.20/x86_64-increase-stack-size-for-kasan_extra.patch b/queue-4.20/x86_64-increase-stack-size-for-kasan_extra.patch new file mode 100644 index 00000000000..3dfd671ac85 --- /dev/null +++ b/queue-4.20/x86_64-increase-stack-size-for-kasan_extra.patch @@ -0,0 +1,82 @@ +From 951ec57ae48ec08ed2c94ab37ce11bab19d9e734 Mon Sep 17 00:00:00 2001 +From: Qian Cai +Date: Fri, 1 Feb 2019 14:20:20 -0800 +Subject: x86_64: increase stack size for KASAN_EXTRA + +[ Upstream commit a8e911d13540487942d53137c156bd7707f66e5d ] + +If the kernel is configured with KASAN_EXTRA, the stack size is +increasted significantly because this option sets "-fstack-reuse" to +"none" in GCC [1]. As a result, it triggers stack overrun quite often +with 32k stack size compiled using GCC 8. For example, this reproducer + + https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/madvise/madvise06.c + +triggers a "corrupted stack end detected inside scheduler" very reliably +with CONFIG_SCHED_STACK_END_CHECK enabled. + +There are just too many functions that could have a large stack with +KASAN_EXTRA due to large local variables that have been called over and +over again without being able to reuse the stacks. Some noticiable ones +are + + size + 7648 shrink_page_list + 3584 xfs_rmap_convert + 3312 migrate_page_move_mapping + 3312 dev_ethtool + 3200 migrate_misplaced_transhuge_page + 3168 copy_process + +There are other 49 functions are over 2k in size while compiling kernel +with "-Wframe-larger-than=" even with a related minimal config on this +machine. Hence, it is too much work to change Makefiles for each object +to compile without "-fsanitize-address-use-after-scope" individually. + +[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715#c23 + +Although there is a patch in GCC 9 to help the situation, GCC 9 probably +won't be released in a few months and then it probably take another +6-month to 1-year for all major distros to include it as a default. +Hence, the stack usage with KASAN_EXTRA can be revisited again in 2020 +when GCC 9 is everywhere. Until then, this patch will help users avoid +stack overrun. + +This has already been fixed for arm64 for the same reason via +6e8830674ea ("arm64: kasan: Increase stack size for KASAN_EXTRA"). + +Link: http://lkml.kernel.org/r/20190109215209.2903-1-cai@lca.pw +Signed-off-by: Qian Cai +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: Borislav Petkov +Cc: "H. Peter Anvin" +Cc: Andrey Ryabinin +Cc: Alexander Potapenko +Cc: Dmitry Vyukov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/page_64_types.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h +index 8f657286d599..0ce558a8150d 100644 +--- a/arch/x86/include/asm/page_64_types.h ++++ b/arch/x86/include/asm/page_64_types.h +@@ -7,7 +7,11 @@ + #endif + + #ifdef CONFIG_KASAN ++#ifdef CONFIG_KASAN_EXTRA ++#define KASAN_STACK_ORDER 2 ++#else + #define KASAN_STACK_ORDER 1 ++#endif + #else + #define KASAN_STACK_ORDER 0 + #endif +-- +2.19.1 + diff --git a/queue-4.20/xtensa-smp-fix-ccount_timer_shutdown.patch b/queue-4.20/xtensa-smp-fix-ccount_timer_shutdown.patch new file mode 100644 index 00000000000..2a45f05abdf --- /dev/null +++ b/queue-4.20/xtensa-smp-fix-ccount_timer_shutdown.patch @@ -0,0 +1,55 @@ +From f7875a881412670cc8628b764da7dc0da2d0297f Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 29 Jan 2018 09:09:41 -0800 +Subject: xtensa: SMP: fix ccount_timer_shutdown + +[ Upstream commit 4fe8713b873fc881284722ce4ac47995de7cf62c ] + +ccount_timer_shutdown is called from the atomic context in the +secondary_start_kernel, resulting in the following BUG: + +BUG: sleeping function called from invalid context +in_atomic(): 1, irqs_disabled(): 1, pid: 0, name: swapper/1 +Preemption disabled at: + secondary_start_kernel+0xa1/0x130 +Call Trace: + ___might_sleep+0xe7/0xfc + __might_sleep+0x41/0x44 + synchronize_irq+0x24/0x64 + disable_irq+0x11/0x14 + ccount_timer_shutdown+0x12/0x20 + clockevents_switch_state+0x82/0xb4 + clockevents_exchange_device+0x54/0x60 + tick_check_new_device+0x46/0x70 + clockevents_register_device+0x8c/0xc8 + clockevents_config_and_register+0x1d/0x2c + local_timer_setup+0x75/0x7c + secondary_start_kernel+0xb4/0x130 + should_never_return+0x32/0x35 + +Use disable_irq_nosync instead of disable_irq to avoid it. +This is safe because the ccount timer IRQ is per-CPU, and once IRQ is +masked the ISR will not be called. + +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/kernel/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c +index fd524a54d2ab..378186b5eb40 100644 +--- a/arch/xtensa/kernel/time.c ++++ b/arch/xtensa/kernel/time.c +@@ -89,7 +89,7 @@ static int ccount_timer_shutdown(struct clock_event_device *evt) + container_of(evt, struct ccount_timer, evt); + + if (timer->irq_enabled) { +- disable_irq(evt->irq); ++ disable_irq_nosync(evt->irq); + timer->irq_enabled = 0; + } + return 0; +-- +2.19.1 + diff --git a/queue-4.20/xtensa-smp-fix-secondary-cpu-initialization.patch b/queue-4.20/xtensa-smp-fix-secondary-cpu-initialization.patch new file mode 100644 index 00000000000..e2585477085 --- /dev/null +++ b/queue-4.20/xtensa-smp-fix-secondary-cpu-initialization.patch @@ -0,0 +1,128 @@ +From c3dcd76c593c0ef03d5c649c01027bb2f3225d3b Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Fri, 21 Dec 2018 08:26:20 -0800 +Subject: xtensa: SMP: fix secondary CPU initialization + +[ Upstream commit 32a7726c4f4aadfabdb82440d84f88a5a2c8fe13 ] + +- add missing memory barriers to the secondary CPU synchronization spin + loops; add comment to the matching memory barrier in the boot_secondary + and __cpu_die functions; +- use READ_ONCE/WRITE_ONCE to access cpu_start_id/cpu_start_ccount + instead of reading/writing them directly; +- re-initialize cpu_running every time before starting secondary CPU to + flush possible previous CPU startup results. + +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/kernel/head.S | 5 ++++- + arch/xtensa/kernel/smp.c | 34 +++++++++++++++++++++------------- + 2 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S +index 9053a5622d2c..5bd38ea2da38 100644 +--- a/arch/xtensa/kernel/head.S ++++ b/arch/xtensa/kernel/head.S +@@ -280,12 +280,13 @@ should_never_return: + + movi a2, cpu_start_ccount + 1: ++ memw + l32i a3, a2, 0 + beqi a3, 0, 1b + movi a3, 0 + s32i a3, a2, 0 +- memw + 1: ++ memw + l32i a3, a2, 0 + beqi a3, 0, 1b + wsr a3, ccount +@@ -321,11 +322,13 @@ ENTRY(cpu_restart) + rsr a0, prid + neg a2, a0 + movi a3, cpu_start_id ++ memw + s32i a2, a3, 0 + #if XCHAL_DCACHE_IS_WRITEBACK + dhwbi a3, 0 + #endif + 1: ++ memw + l32i a2, a3, 0 + dhi a3, 0 + bne a2, a0, 1b +diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c +index 932d64689bac..c9fc2c4f71b3 100644 +--- a/arch/xtensa/kernel/smp.c ++++ b/arch/xtensa/kernel/smp.c +@@ -195,9 +195,11 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts) + int i; + + #ifdef CONFIG_HOTPLUG_CPU +- cpu_start_id = cpu; +- system_flush_invalidate_dcache_range( +- (unsigned long)&cpu_start_id, sizeof(cpu_start_id)); ++ WRITE_ONCE(cpu_start_id, cpu); ++ /* Pairs with the third memw in the cpu_restart */ ++ mb(); ++ system_flush_invalidate_dcache_range((unsigned long)&cpu_start_id, ++ sizeof(cpu_start_id)); + #endif + smp_call_function_single(0, mx_cpu_start, (void *)cpu, 1); + +@@ -206,18 +208,21 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts) + ccount = get_ccount(); + while (!ccount); + +- cpu_start_ccount = ccount; ++ WRITE_ONCE(cpu_start_ccount, ccount); + +- while (time_before(jiffies, timeout)) { ++ do { ++ /* ++ * Pairs with the first two memws in the ++ * .Lboot_secondary. ++ */ + mb(); +- if (!cpu_start_ccount) +- break; +- } ++ ccount = READ_ONCE(cpu_start_ccount); ++ } while (ccount && time_before(jiffies, timeout)); + +- if (cpu_start_ccount) { ++ if (ccount) { + smp_call_function_single(0, mx_cpu_stop, +- (void *)cpu, 1); +- cpu_start_ccount = 0; ++ (void *)cpu, 1); ++ WRITE_ONCE(cpu_start_ccount, 0); + return -EIO; + } + } +@@ -237,6 +242,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) + pr_debug("%s: Calling wakeup_secondary(cpu:%d, idle:%p, sp: %08lx)\n", + __func__, cpu, idle, start_info.stack); + ++ init_completion(&cpu_running); + ret = boot_secondary(cpu, idle); + if (ret == 0) { + wait_for_completion_timeout(&cpu_running, +@@ -298,8 +304,10 @@ void __cpu_die(unsigned int cpu) + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + while (time_before(jiffies, timeout)) { + system_invalidate_dcache_range((unsigned long)&cpu_start_id, +- sizeof(cpu_start_id)); +- if (cpu_start_id == -cpu) { ++ sizeof(cpu_start_id)); ++ /* Pairs with the second memw in the cpu_restart */ ++ mb(); ++ if (READ_ONCE(cpu_start_id) == -cpu) { + platform_cpu_kill(cpu); + return; + } +-- +2.19.1 + diff --git a/queue-4.20/xtensa-smp-limit-number-of-possible-cpus-by-nr_cpus.patch b/queue-4.20/xtensa-smp-limit-number-of-possible-cpus-by-nr_cpus.patch new file mode 100644 index 00000000000..627e2227e9c --- /dev/null +++ b/queue-4.20/xtensa-smp-limit-number-of-possible-cpus-by-nr_cpus.patch @@ -0,0 +1,49 @@ +From 39ef857731feae640f5b11cb9835a4a825533cfa Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 26 Jan 2019 20:35:18 -0800 +Subject: xtensa: SMP: limit number of possible CPUs by NR_CPUS + +[ Upstream commit 25384ce5f9530def39421597b1457d9462df6455 ] + +This fixes the following warning at boot when the kernel is booted on a +board with more CPU cores than was configured in NR_CPUS: + + smp_init_cpus: Core Count = 8 + smp_init_cpus: Core Id = 0 + ------------[ cut here ]------------ + WARNING: CPU: 0 PID: 0 at include/linux/cpumask.h:121 smp_init_cpus+0x54/0x74 + Modules linked in: + CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc3-00015-g1459333f88a0 #124 + Call Trace: + __warn$part$3+0x6a/0x7c + warn_slowpath_null+0x35/0x3c + smp_init_cpus+0x54/0x74 + setup_arch+0x1c0/0x1d0 + start_kernel+0x44/0x310 + _startup+0x107/0x107 + +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/kernel/smp.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c +index 80be6449c497..be1f280c322c 100644 +--- a/arch/xtensa/kernel/smp.c ++++ b/arch/xtensa/kernel/smp.c +@@ -96,6 +96,11 @@ void __init smp_init_cpus(void) + pr_info("%s: Core Count = %d\n", __func__, ncpus); + pr_info("%s: Core Id = %d\n", __func__, core_id); + ++ if (ncpus > NR_CPUS) { ++ ncpus = NR_CPUS; ++ pr_info("%s: limiting core count by %d\n", __func__, ncpus); ++ } ++ + for (i = 0; i < ncpus; ++i) + set_cpu_possible(i, true); + } +-- +2.19.1 + diff --git a/queue-4.20/xtensa-smp-mark-each-possible-cpu-as-present.patch b/queue-4.20/xtensa-smp-mark-each-possible-cpu-as-present.patch new file mode 100644 index 00000000000..bbda9c00b47 --- /dev/null +++ b/queue-4.20/xtensa-smp-mark-each-possible-cpu-as-present.patch @@ -0,0 +1,32 @@ +From 832766e7489f7f1a47a36be417b2d483d5eec2ba Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 19 Jan 2019 00:26:48 -0800 +Subject: xtensa: SMP: mark each possible CPU as present + +[ Upstream commit 8b1c42cdd7181200dc1fff39dcb6ac1a3fac2c25 ] + +Otherwise it is impossible to enable CPUs after booting with 'maxcpus' +parameter. + +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/kernel/smp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c +index c9fc2c4f71b3..80be6449c497 100644 +--- a/arch/xtensa/kernel/smp.c ++++ b/arch/xtensa/kernel/smp.c +@@ -83,7 +83,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) + { + unsigned i; + +- for (i = 0; i < max_cpus; ++i) ++ for_each_possible_cpu(i) + set_cpu_present(i, true); + } + +-- +2.19.1 + diff --git a/queue-4.20/xtensa-smp_lx200_defconfig-fix-vectors-clash.patch b/queue-4.20/xtensa-smp_lx200_defconfig-fix-vectors-clash.patch new file mode 100644 index 00000000000..84e7a97be0a --- /dev/null +++ b/queue-4.20/xtensa-smp_lx200_defconfig-fix-vectors-clash.patch @@ -0,0 +1,33 @@ +From a11ab26def01fd7d31d63176bfbe67b02eb8f278 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 24 Jan 2019 17:16:11 -0800 +Subject: xtensa: smp_lx200_defconfig: fix vectors clash + +[ Upstream commit 306b38305c0f86de7f17c5b091a95451dcc93d7d ] + +Secondary CPU reset vector overlaps part of the double exception handler +code, resulting in weird crashes and hangups when running user code. +Move exception vectors one page up so that they don't clash with the +secondary CPU reset vector. + +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/configs/smp_lx200_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/xtensa/configs/smp_lx200_defconfig b/arch/xtensa/configs/smp_lx200_defconfig +index 11fed6c06a7c..b5938160fb3d 100644 +--- a/arch/xtensa/configs/smp_lx200_defconfig ++++ b/arch/xtensa/configs/smp_lx200_defconfig +@@ -33,6 +33,7 @@ CONFIG_SMP=y + CONFIG_HOTPLUG_CPU=y + # CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is not set + # CONFIG_PCI is not set ++CONFIG_VECTORS_OFFSET=0x00002000 + CONFIG_XTENSA_PLATFORM_XTFPGA=y + CONFIG_CMDLINE_BOOL=y + CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=96M@0" +-- +2.19.1 +