--- /dev/null
+From 5ae51d67aec95f6f9386aa8dd5db424964895575 Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Mon, 11 Feb 2019 14:59:07 -0800
+Subject: clk: clk-twl6040: Fix imprecise external abort for pdmclk
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 5ae51d67aec95f6f9386aa8dd5db424964895575 upstream.
+
+I noticed that modprobe clk-twl6040 can fail after a cold boot with:
+abe_cm:clk:0010:0: failed to enable
+...
+Unhandled fault: imprecise external abort (0x1406) at 0xbe896b20
+
+WARNING: CPU: 1 PID: 29 at drivers/clk/clk.c:828 clk_core_disable_lock+0x18/0x24
+...
+(clk_core_disable_lock) from [<c0123534>] (_disable_clocks+0x18/0x90)
+(_disable_clocks) from [<c0124040>] (_idle+0x17c/0x244)
+(_idle) from [<c0125ad4>] (omap_hwmod_idle+0x24/0x44)
+(omap_hwmod_idle) from [<c053a038>] (sysc_runtime_suspend+0x48/0x108)
+(sysc_runtime_suspend) from [<c06084c4>] (__rpm_callback+0x144/0x1d8)
+(__rpm_callback) from [<c0608578>] (rpm_callback+0x20/0x80)
+(rpm_callback) from [<c0607034>] (rpm_suspend+0x120/0x694)
+(rpm_suspend) from [<c0607a78>] (__pm_runtime_idle+0x60/0x84)
+(__pm_runtime_idle) from [<c053aaf0>] (sysc_probe+0x874/0xf2c)
+(sysc_probe) from [<c05fecd4>] (platform_drv_probe+0x48/0x98)
+
+After searching around for a similar issue, I came across an earlier fix
+that never got merged upstream in the Android tree for glass-omap-xrr02.
+There is patch "MFD: twl6040-codec: Implement PDMCLK cold temp errata"
+by Misael Lopez Cruz <misael.lopez@ti.com>.
+
+Based on my observations, this fix is also needed when cold booting
+devices, and not just for deeper idle modes. Since we now have a clock
+driver for pdmclk, let's fix the issue in twl6040_pdmclk_prepare().
+
+Cc: Misael Lopez Cruz <misael.lopez@ti.com>
+Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/clk-twl6040.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 51 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/clk-twl6040.c
++++ b/drivers/clk/clk-twl6040.c
+@@ -41,6 +41,43 @@ static int twl6040_pdmclk_is_prepared(st
+ return pdmclk->enabled;
+ }
+
++static int twl6040_pdmclk_reset_one_clock(struct twl6040_pdmclk *pdmclk,
++ unsigned int reg)
++{
++ const u8 reset_mask = TWL6040_HPLLRST; /* Same for HPPLL and LPPLL */
++ int ret;
++
++ ret = twl6040_set_bits(pdmclk->twl6040, reg, reset_mask);
++ if (ret < 0)
++ return ret;
++
++ ret = twl6040_clear_bits(pdmclk->twl6040, reg, reset_mask);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++/*
++ * TWL6040A2 Phoenix Audio IC erratum #6: "PDM Clock Generation Issue At
++ * Cold Temperature". This affects cold boot and deeper idle states it
++ * seems. The workaround consists of resetting HPPLL and LPPLL.
++ */
++static int twl6040_pdmclk_quirk_reset_clocks(struct twl6040_pdmclk *pdmclk)
++{
++ int ret;
++
++ ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_HPPLLCTL);
++ if (ret)
++ return ret;
++
++ ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_LPPLLCTL);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
+ static int twl6040_pdmclk_prepare(struct clk_hw *hw)
+ {
+ struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
+@@ -48,8 +85,20 @@ static int twl6040_pdmclk_prepare(struct
+ int ret;
+
+ ret = twl6040_power(pdmclk->twl6040, 1);
+- if (!ret)
+- pdmclk->enabled = 1;
++ if (ret)
++ return ret;
++
++ ret = twl6040_pdmclk_quirk_reset_clocks(pdmclk);
++ if (ret)
++ goto out_err;
++
++ pdmclk->enabled = 1;
++
++ return 0;
++
++out_err:
++ dev_err(pdmclk->dev, "%s: error %i\n", __func__, ret);
++ twl6040_power(pdmclk->twl6040, 0);
+
+ return ret;
+ }
--- /dev/null
+From 7ca4c922aad2e3c46767a12f80d01c6b25337b59 Mon Sep 17 00:00:00 2001
+From: Paul Cercueil <paul@crapouillou.net>
+Date: Sun, 27 Jan 2019 23:09:21 -0300
+Subject: clk: ingenic: Fix doc of ingenic_cgu_div_info
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+commit 7ca4c922aad2e3c46767a12f80d01c6b25337b59 upstream.
+
+The 'div' field does not represent a number of bits used to divide
+(understand: right-shift) the divider, but a number itself used to
+divide the divider.
+
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Signed-off-by: Maarten ter Huurne <maarten@treewalker.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/ingenic/cgu.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/ingenic/cgu.h
++++ b/drivers/clk/ingenic/cgu.h
+@@ -80,7 +80,7 @@ struct ingenic_cgu_mux_info {
+ * @reg: offset of the divider control register within the CGU
+ * @shift: number of bits to left shift the divide value by (ie. the index of
+ * the lowest bit of the divide value within its control register)
+- * @div: number of bits to divide the divider value by (i.e. if the
++ * @div: number to divide the divider value by (i.e. if the
+ * effective divider value is the value written to the register
+ * multiplied by some constant)
+ * @bits: the size of the divide value in bits
--- /dev/null
+From bc5d922c93491878c44c9216e9d227c7eeb81d7f Mon Sep 17 00:00:00 2001
+From: Paul Cercueil <paul@crapouillou.net>
+Date: Sun, 27 Jan 2019 23:09:20 -0300
+Subject: clk: ingenic: Fix round_rate misbehaving with non-integer dividers
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+commit bc5d922c93491878c44c9216e9d227c7eeb81d7f upstream.
+
+Take a parent rate of 180 MHz, and a requested rate of 4.285715 MHz.
+This results in a theorical divider of 41.999993 which is then rounded
+up to 42. The .round_rate function would then return (180 MHz / 42) as
+the clock, rounded down, so 4.285714 MHz.
+
+Calling clk_set_rate on 4.285714 MHz would round the rate again, and
+give a theorical divider of 42,0000028, now rounded up to 43, and the
+rate returned would be (180 MHz / 43) which is 4.186046 MHz, aka. not
+what we requested.
+
+Fix this by rounding up the divisions.
+
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Tested-by: Maarten ter Huurne <maarten@treewalker.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/ingenic/cgu.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/clk/ingenic/cgu.c
++++ b/drivers/clk/ingenic/cgu.c
+@@ -426,16 +426,16 @@ ingenic_clk_round_rate(struct clk_hw *hw
+ struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+ struct ingenic_cgu *cgu = ingenic_clk->cgu;
+ const struct ingenic_cgu_clk_info *clk_info;
+- long rate = *parent_rate;
++ unsigned int div = 1;
+
+ clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+ if (clk_info->type & CGU_CLK_DIV)
+- rate /= ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
++ div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
+ else if (clk_info->type & CGU_CLK_FIXDIV)
+- rate /= clk_info->fixdiv.div;
++ div = clk_info->fixdiv.div;
+
+- return rate;
++ return DIV_ROUND_UP(*parent_rate, div);
+ }
+
+ static int
+@@ -455,7 +455,7 @@ ingenic_clk_set_rate(struct clk_hw *hw,
+
+ if (clk_info->type & CGU_CLK_DIV) {
+ div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
+- rate = parent_rate / div;
++ rate = DIV_ROUND_UP(parent_rate, div);
+
+ if (rate != req_rate)
+ return -EINVAL;
--- /dev/null
+From 785c9f411eb2d9a6076d3511c631587d5e676bf3 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Thu, 21 Feb 2019 12:45:52 +0100
+Subject: clk: samsung: exynos5: Fix kfree() of const memory on setting driver_override
+
+From: Krzysztof Kozlowski <krzk@kernel.org>
+
+commit 785c9f411eb2d9a6076d3511c631587d5e676bf3 upstream.
+
+Platform driver driver_override field should not be initialized from
+const memory because the core later kfree() it. If driver_override is
+manually set later through sysfs, kfree() of old value leads to:
+
+ $ echo "new_value" > /sys/bus/platform/drivers/.../driver_override
+
+ kernel BUG at ../mm/slub.c:3960!
+ Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
+ ...
+ (kfree) from [<c058e8c0>] (platform_set_driver_override+0x84/0xac)
+ (platform_set_driver_override) from [<c058e908>] (driver_override_store+0x20/0x34)
+ (driver_override_store) from [<c031f778>] (kernfs_fop_write+0x100/0x1dc)
+ (kernfs_fop_write) from [<c0296de8>] (__vfs_write+0x2c/0x17c)
+ (__vfs_write) from [<c02970c4>] (vfs_write+0xa4/0x188)
+ (vfs_write) from [<c02972e8>] (ksys_write+0x4c/0xac)
+ (ksys_write) from [<c0101000>] (ret_fast_syscall+0x0/0x28)
+
+The clk-exynos5-subcmu driver uses override only for the purpose of
+creating meaningful names for children devices (matching names of power
+domains, e.g. DISP, MFC). The driver_override was not developed for
+this purpose so just switch to default names of devices to fix the
+issue.
+
+Fixes: b06a532bf1fa ("clk: samsung: Add Exynos5 sub-CMU clock driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/samsung/clk-exynos5-subcmu.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/clk/samsung/clk-exynos5-subcmu.c
++++ b/drivers/clk/samsung/clk-exynos5-subcmu.c
+@@ -138,12 +138,11 @@ static int __init exynos5_clk_register_s
+ struct platform_device *pdev;
+ int ret;
+
+- pdev = platform_device_alloc(info->pd_name, -1);
++ pdev = platform_device_alloc("exynos5-subcmu", PLATFORM_DEVID_AUTO);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->dev.parent = parent;
+- pdev->driver_override = "exynos5-subcmu";
+ platform_set_drvdata(pdev, (void *)info);
+ of_genpd_add_device(&genpdspec, &pdev->dev);
+ ret = platform_device_add(pdev);
--- /dev/null
+From 5f0b6216ea381b43c0dff88702d6cc5673d63922 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Thu, 21 Feb 2019 12:45:51 +0100
+Subject: clk: samsung: exynos5: Fix possible NULL pointer exception on platform_device_alloc() failure
+
+From: Krzysztof Kozlowski <krzk@kernel.org>
+
+commit 5f0b6216ea381b43c0dff88702d6cc5673d63922 upstream.
+
+During initialization of subdevices if platform_device_alloc() failed,
+returned NULL pointer will be later dereferenced. Add proper error
+paths to exynos5_clk_register_subcmu(). The return value of this
+function is still ignored because at this stage of init there is nothing
+we can do.
+
+Fixes: b06a532bf1fa ("clk: samsung: Add Exynos5 sub-CMU clock driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/samsung/clk-exynos5-subcmu.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/samsung/clk-exynos5-subcmu.c
++++ b/drivers/clk/samsung/clk-exynos5-subcmu.c
+@@ -136,15 +136,21 @@ static int __init exynos5_clk_register_s
+ {
+ struct of_phandle_args genpdspec = { .np = pd_node };
+ struct platform_device *pdev;
++ int ret;
+
+ pdev = platform_device_alloc(info->pd_name, -1);
++ if (!pdev)
++ return -ENOMEM;
++
+ pdev->dev.parent = parent;
+ pdev->driver_override = "exynos5-subcmu";
+ platform_set_drvdata(pdev, (void *)info);
+ of_genpd_add_device(&genpdspec, &pdev->dev);
+- platform_device_add(pdev);
++ ret = platform_device_add(pdev);
++ if (ret)
++ platform_device_put(pdev);
+
+- return 0;
++ return ret;
+ }
+
+ static int __init exynos5_clk_probe(struct platform_device *pdev)
--- /dev/null
+From 521282237b9d78b9bff423ec818becd4c95841c2 Mon Sep 17 00:00:00 2001
+From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Date: Fri, 8 Feb 2019 11:25:23 +0900
+Subject: clk: uniphier: Fix update register for CPU-gear
+
+From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+
+commit 521282237b9d78b9bff423ec818becd4c95841c2 upstream.
+
+Need to set the update bit in UNIPHIER_CLK_CPUGEAR_UPD to update
+the CPU-gear value.
+
+Fixes: d08f1f0d596c ("clk: uniphier: add CPU-gear change (cpufreq) support")
+Cc: linux-stable@vger.kernel.org
+Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Acked-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/uniphier/clk-uniphier-cpugear.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/uniphier/clk-uniphier-cpugear.c
++++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c
+@@ -47,7 +47,7 @@ static int uniphier_clk_cpugear_set_pare
+ return ret;
+
+ ret = regmap_write_bits(gear->regmap,
+- gear->regbase + UNIPHIER_CLK_CPUGEAR_SET,
++ gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
+ UNIPHIER_CLK_CPUGEAR_UPD_BIT,
+ UNIPHIER_CLK_CPUGEAR_UPD_BIT);
+ if (ret)
--- /dev/null
+From 0334906c06967142c8805fbe88acf787f65d3d26 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 20 Feb 2019 16:41:18 +0530
+Subject: cpufreq: kryo: Release OPP tables on module removal
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+commit 0334906c06967142c8805fbe88acf787f65d3d26 upstream.
+
+Commit 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit") made
+it possible to build the kryo cpufreq driver as a module, but it failed
+to release all the resources, i.e. OPP tables, when the module is
+unloaded.
+
+This patch fixes it by releasing the OPP tables, by calling
+dev_pm_opp_put_supported_hw() for them, from the
+qcom_cpufreq_kryo_remove() routine. The array of pointers to the OPP
+tables is also allocated dynamically now in qcom_cpufreq_kryo_probe(),
+as the pointers will be required while releasing the resources.
+
+Compile tested only.
+
+Cc: 4.18+ <stable@vger.kernel.org> # v4.18+
+Fixes: 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit")
+Reviewed-by: Georgi Djakov <georgi.djakov@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/qcom-cpufreq-kryo.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
++++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
+@@ -75,7 +75,7 @@ static enum _msm8996_version qcom_cpufre
+
+ static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
+ {
+- struct opp_table *opp_tables[NR_CPUS] = {0};
++ struct opp_table **opp_tables;
+ enum _msm8996_version msm8996_version;
+ struct nvmem_cell *speedbin_nvmem;
+ struct device_node *np;
+@@ -133,6 +133,10 @@ static int qcom_cpufreq_kryo_probe(struc
+ }
+ kfree(speedbin);
+
++ opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), GFP_KERNEL);
++ if (!opp_tables)
++ return -ENOMEM;
++
+ for_each_possible_cpu(cpu) {
+ cpu_dev = get_cpu_device(cpu);
+ if (NULL == cpu_dev) {
+@@ -151,8 +155,10 @@ static int qcom_cpufreq_kryo_probe(struc
+
+ cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
+ NULL, 0);
+- if (!IS_ERR(cpufreq_dt_pdev))
++ if (!IS_ERR(cpufreq_dt_pdev)) {
++ platform_set_drvdata(pdev, opp_tables);
+ return 0;
++ }
+
+ ret = PTR_ERR(cpufreq_dt_pdev);
+ dev_err(cpu_dev, "Failed to register platform device\n");
+@@ -163,13 +169,23 @@ free_opp:
+ break;
+ dev_pm_opp_put_supported_hw(opp_tables[cpu]);
+ }
++ kfree(opp_tables);
+
+ return ret;
+ }
+
+ static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
+ {
++ struct opp_table **opp_tables = platform_get_drvdata(pdev);
++ unsigned int cpu;
++
+ platform_device_unregister(cpufreq_dt_pdev);
++
++ for_each_possible_cpu(cpu)
++ dev_pm_opp_put_supported_hw(opp_tables[cpu]);
++
++ kfree(opp_tables);
++
+ return 0;
+ }
+
--- /dev/null
+From 9505b98ccddc454008ca7efff90044e3e857c827 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 7 Mar 2019 11:22:41 +0100
+Subject: cpufreq: pxa2xx: remove incorrect __init annotation
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 9505b98ccddc454008ca7efff90044e3e857c827 upstream.
+
+pxa_cpufreq_init_voltages() is marked __init but usually inlined into
+the non-__init pxa_cpufreq_init() function. When building with clang,
+it can stay as a standalone function in a discarded section, and produce
+this warning:
+
+WARNING: vmlinux.o(.text+0x616a00): Section mismatch in reference from the function pxa_cpufreq_init() to the function .init.text:pxa_cpufreq_init_voltages()
+The function pxa_cpufreq_init() references
+the function __init pxa_cpufreq_init_voltages().
+This is often because pxa_cpufreq_init lacks a __init
+annotation or the annotation of pxa_cpufreq_init_voltages is wrong.
+
+Fixes: 50e77fcd790e ("ARM: pxa: remove __init from cpufreq_driver->init()")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
+Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/pxa2xx-cpufreq.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/pxa2xx-cpufreq.c
++++ b/drivers/cpufreq/pxa2xx-cpufreq.c
+@@ -143,7 +143,7 @@ static int pxa_cpufreq_change_voltage(co
+ return ret;
+ }
+
+-static void __init pxa_cpufreq_init_voltages(void)
++static void pxa_cpufreq_init_voltages(void)
+ {
+ vcc_core = regulator_get(NULL, "vcc_core");
+ if (IS_ERR(vcc_core)) {
+@@ -159,7 +159,7 @@ static int pxa_cpufreq_change_voltage(co
+ return 0;
+ }
+
+-static void __init pxa_cpufreq_init_voltages(void) { }
++static void pxa_cpufreq_init_voltages(void) { }
+ #endif
+
+ static void find_freq_tables(struct cpufreq_frequency_table **freq_table,
--- /dev/null
+From 446fae2bb5395f3028d8e3aae1508737e5a72ea1 Mon Sep 17 00:00:00 2001
+From: Yangtao Li <tiny.windzz@gmail.com>
+Date: Mon, 4 Feb 2019 02:48:54 -0500
+Subject: cpufreq: tegra124: add missing of_node_put()
+
+From: Yangtao Li <tiny.windzz@gmail.com>
+
+commit 446fae2bb5395f3028d8e3aae1508737e5a72ea1 upstream.
+
+of_cpu_device_node_get() will increase the refcount of device_node,
+it is necessary to call of_node_put() at the end to release the
+refcount.
+
+Fixes: 9eb15dbbfa1a2 ("cpufreq: Add cpufreq driver for Tegra124")
+Cc: <stable@vger.kernel.org> # 4.4+
+Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/tegra124-cpufreq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/cpufreq/tegra124-cpufreq.c
++++ b/drivers/cpufreq/tegra124-cpufreq.c
+@@ -134,6 +134,8 @@ static int tegra124_cpufreq_probe(struct
+
+ platform_set_drvdata(pdev, priv);
+
++ of_node_put(np);
++
+ return 0;
+
+ out_switch_to_pllx:
--- /dev/null
+From edeb304f659792fb5bab90d7d6f3408b4c7301fb Mon Sep 17 00:00:00 2001
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+Date: Tue, 29 Jan 2019 16:36:18 +0530
+Subject: cxl: Wrap iterations over afu slices inside 'afu_list_lock'
+
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+
+commit edeb304f659792fb5bab90d7d6f3408b4c7301fb upstream.
+
+Within cxl module, iteration over array 'adapter->afu' may be racy
+at few points as it might be simultaneously read during an EEH and its
+contents being set to NULL while driver is being unloaded or unbound
+from the adapter. This might result in a NULL pointer to 'struct afu'
+being de-referenced during an EEH thereby causing a kernel oops.
+
+This patch fixes this by making sure that all access to the array
+'adapter->afu' is wrapped within the context of spin-lock
+'adapter->afu_list_lock'.
+
+Fixes: 9e8df8a21963 ("cxl: EEH support")
+Cc: stable@vger.kernel.org # v4.3+
+Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Acked-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/cxl/guest.c | 2 ++
+ drivers/misc/cxl/pci.c | 39 ++++++++++++++++++++++++++++++---------
+ 2 files changed, 32 insertions(+), 9 deletions(-)
+
+--- a/drivers/misc/cxl/guest.c
++++ b/drivers/misc/cxl/guest.c
+@@ -267,6 +267,7 @@ static int guest_reset(struct cxl *adapt
+ int i, rc;
+
+ pr_devel("Adapter reset request\n");
++ spin_lock(&adapter->afu_list_lock);
+ for (i = 0; i < adapter->slices; i++) {
+ if ((afu = adapter->afu[i])) {
+ pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
+@@ -283,6 +284,7 @@ static int guest_reset(struct cxl *adapt
+ pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
+ }
+ }
++ spin_unlock(&adapter->afu_list_lock);
+ return rc;
+ }
+
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -1805,7 +1805,7 @@ static pci_ers_result_t cxl_vphb_error_d
+ /* There should only be one entry, but go through the list
+ * anyway
+ */
+- if (afu->phb == NULL)
++ if (afu == NULL || afu->phb == NULL)
+ return result;
+
+ list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
+@@ -1832,7 +1832,8 @@ static pci_ers_result_t cxl_pci_error_de
+ {
+ struct cxl *adapter = pci_get_drvdata(pdev);
+ struct cxl_afu *afu;
+- pci_ers_result_t result = PCI_ERS_RESULT_NEED_RESET, afu_result;
++ pci_ers_result_t result = PCI_ERS_RESULT_NEED_RESET;
++ pci_ers_result_t afu_result = PCI_ERS_RESULT_NEED_RESET;
+ int i;
+
+ /* At this point, we could still have an interrupt pending.
+@@ -1843,6 +1844,7 @@ static pci_ers_result_t cxl_pci_error_de
+
+ /* If we're permanently dead, give up. */
+ if (state == pci_channel_io_perm_failure) {
++ spin_lock(&adapter->afu_list_lock);
+ for (i = 0; i < adapter->slices; i++) {
+ afu = adapter->afu[i];
+ /*
+@@ -1851,6 +1853,7 @@ static pci_ers_result_t cxl_pci_error_de
+ */
+ cxl_vphb_error_detected(afu, state);
+ }
++ spin_unlock(&adapter->afu_list_lock);
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+@@ -1932,11 +1935,17 @@ static pci_ers_result_t cxl_pci_error_de
+ * * In slot_reset, free the old resources and allocate new ones.
+ * * In resume, clear the flag to allow things to start.
+ */
++
++ /* Make sure no one else changes the afu list */
++ spin_lock(&adapter->afu_list_lock);
++
+ for (i = 0; i < adapter->slices; i++) {
+ afu = adapter->afu[i];
+
+- afu_result = cxl_vphb_error_detected(afu, state);
++ if (afu == NULL)
++ continue;
+
++ afu_result = cxl_vphb_error_detected(afu, state);
+ cxl_context_detach_all(afu);
+ cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
+ pci_deconfigure_afu(afu);
+@@ -1948,6 +1957,7 @@ static pci_ers_result_t cxl_pci_error_de
+ (result == PCI_ERS_RESULT_NEED_RESET))
+ result = PCI_ERS_RESULT_NONE;
+ }
++ spin_unlock(&adapter->afu_list_lock);
+
+ /* should take the context lock here */
+ if (cxl_adapter_context_lock(adapter) != 0)
+@@ -1980,14 +1990,18 @@ static pci_ers_result_t cxl_pci_slot_res
+ */
+ cxl_adapter_context_unlock(adapter);
+
++ spin_lock(&adapter->afu_list_lock);
+ for (i = 0; i < adapter->slices; i++) {
+ afu = adapter->afu[i];
+
++ if (afu == NULL)
++ continue;
++
+ if (pci_configure_afu(afu, adapter, pdev))
+- goto err;
++ goto err_unlock;
+
+ if (cxl_afu_select_best_mode(afu))
+- goto err;
++ goto err_unlock;
+
+ if (afu->phb == NULL)
+ continue;
+@@ -1999,16 +2013,16 @@ static pci_ers_result_t cxl_pci_slot_res
+ ctx = cxl_get_context(afu_dev);
+
+ if (ctx && cxl_release_context(ctx))
+- goto err;
++ goto err_unlock;
+
+ ctx = cxl_dev_context_init(afu_dev);
+ if (IS_ERR(ctx))
+- goto err;
++ goto err_unlock;
+
+ afu_dev->dev.archdata.cxl_ctx = ctx;
+
+ if (cxl_ops->afu_check_and_enable(afu))
+- goto err;
++ goto err_unlock;
+
+ afu_dev->error_state = pci_channel_io_normal;
+
+@@ -2029,8 +2043,13 @@ static pci_ers_result_t cxl_pci_slot_res
+ result = PCI_ERS_RESULT_DISCONNECT;
+ }
+ }
++
++ spin_unlock(&adapter->afu_list_lock);
+ return result;
+
++err_unlock:
++ spin_unlock(&adapter->afu_list_lock);
++
+ err:
+ /* All the bits that happen in both error_detected and cxl_remove
+ * should be idempotent, so we don't need to worry about leaving a mix
+@@ -2051,10 +2070,11 @@ static void cxl_pci_resume(struct pci_de
+ * This is not the place to be checking if everything came back up
+ * properly, because there's no return value: do that in slot_reset.
+ */
++ spin_lock(&adapter->afu_list_lock);
+ for (i = 0; i < adapter->slices; i++) {
+ afu = adapter->afu[i];
+
+- if (afu->phb == NULL)
++ if (afu == NULL || afu->phb == NULL)
+ continue;
+
+ list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
+@@ -2063,6 +2083,7 @@ static void cxl_pci_resume(struct pci_de
+ afu_dev->driver->err_handler->resume(afu_dev);
+ }
+ }
++ spin_unlock(&adapter->afu_list_lock);
+ }
+
+ static const struct pci_error_handlers cxl_err_handler = {
--- /dev/null
+From 2b6e492467c78183bb629bb0a100ea3509b615a5 Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Wed, 23 Jan 2019 17:44:16 +0300
+Subject: device property: Fix the length used in PROPERTY_ENTRY_STRING()
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit 2b6e492467c78183bb629bb0a100ea3509b615a5 upstream.
+
+With string type property entries we need to use
+sizeof(const char *) instead of the number of characters as
+the length of the entry.
+
+If the string was shorter then sizeof(const char *),
+attempts to read it would have failed with -EOVERFLOW. The
+problem has been hidden because all build-in string
+properties have had a string longer then 8 characters until
+now.
+
+Fixes: a85f42047533 ("device property: helper macros for property entry creation")
+Cc: 4.5+ <stable@vger.kernel.org> # 4.5+
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/property.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/property.h
++++ b/include/linux/property.h
+@@ -258,7 +258,7 @@ struct property_entry {
+ #define PROPERTY_ENTRY_STRING(_name_, _val_) \
+ (struct property_entry) { \
+ .name = _name_, \
+- .length = sizeof(_val_), \
++ .length = sizeof(const char *), \
+ .type = DEV_PROP_STRING, \
+ { .value = { .str = _val_ } }, \
+ }
--- /dev/null
+From 133d624b1cee16906134e92d5befb843b58bcf31 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Thu, 7 Feb 2019 12:59:15 +0100
+Subject: dma: Introduce dma_max_mapping_size()
+
+From: Joerg Roedel <jroedel@suse.de>
+
+commit 133d624b1cee16906134e92d5befb843b58bcf31 upstream.
+
+The function returns the maximum size that can be mapped
+using DMA-API functions. The patch also adds the
+implementation for direct DMA and a new dma_map_ops pointer
+so that other implementations can expose their limit.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/DMA-API.txt | 8 ++++++++
+ include/linux/dma-mapping.h | 8 ++++++++
+ kernel/dma/direct.c | 11 +++++++++++
+ kernel/dma/mapping.c | 14 ++++++++++++++
+ 4 files changed, 41 insertions(+)
+
+--- a/Documentation/DMA-API.txt
++++ b/Documentation/DMA-API.txt
+@@ -195,6 +195,14 @@ Requesting the required mask does not al
+ wish to take advantage of it, you should issue a dma_set_mask()
+ call to set the mask to the value returned.
+
++::
++
++ size_t
++ dma_direct_max_mapping_size(struct device *dev);
++
++Returns the maximum size of a mapping for the device. The size parameter
++of the mapping functions like dma_map_single(), dma_map_page() and
++others should not be larger than the returned value.
+
+ Part Id - Streaming DMA mappings
+ --------------------------------
+--- a/include/linux/dma-mapping.h
++++ b/include/linux/dma-mapping.h
+@@ -130,6 +130,7 @@ struct dma_map_ops {
+ enum dma_data_direction direction);
+ int (*dma_supported)(struct device *dev, u64 mask);
+ u64 (*get_required_mask)(struct device *dev);
++ size_t (*max_mapping_size)(struct device *dev);
+ };
+
+ #define DMA_MAPPING_ERROR (~(dma_addr_t)0)
+@@ -257,6 +258,8 @@ static inline void dma_direct_sync_sg_fo
+ }
+ #endif
+
++size_t dma_direct_max_mapping_size(struct device *dev);
++
+ #ifdef CONFIG_HAS_DMA
+ #include <asm/dma-mapping.h>
+
+@@ -460,6 +463,7 @@ int dma_supported(struct device *dev, u6
+ int dma_set_mask(struct device *dev, u64 mask);
+ int dma_set_coherent_mask(struct device *dev, u64 mask);
+ u64 dma_get_required_mask(struct device *dev);
++size_t dma_max_mapping_size(struct device *dev);
+ #else /* CONFIG_HAS_DMA */
+ static inline dma_addr_t dma_map_page_attrs(struct device *dev,
+ struct page *page, size_t offset, size_t size,
+@@ -561,6 +565,10 @@ static inline u64 dma_get_required_mask(
+ {
+ return 0;
+ }
++static inline size_t dma_max_mapping_size(struct device *dev)
++{
++ return 0;
++}
+ #endif /* CONFIG_HAS_DMA */
+
+ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -380,3 +380,14 @@ int dma_direct_supported(struct device *
+ */
+ return mask >= __phys_to_dma(dev, min_mask);
+ }
++
++size_t dma_direct_max_mapping_size(struct device *dev)
++{
++ size_t size = SIZE_MAX;
++
++ /* If SWIOTLB is active, use its maximum mapping size */
++ if (is_swiotlb_active())
++ size = swiotlb_max_mapping_size(dev);
++
++ return size;
++}
+--- a/kernel/dma/mapping.c
++++ b/kernel/dma/mapping.c
+@@ -357,3 +357,17 @@ void dma_cache_sync(struct device *dev,
+ ops->cache_sync(dev, vaddr, size, dir);
+ }
+ EXPORT_SYMBOL(dma_cache_sync);
++
++size_t dma_max_mapping_size(struct device *dev)
++{
++ const struct dma_map_ops *ops = get_dma_ops(dev);
++ size_t size = SIZE_MAX;
++
++ if (dma_is_direct(ops))
++ size = dma_direct_max_mapping_size(dev);
++ else if (ops && ops->max_mapping_size)
++ size = ops->max_mapping_size(dev);
++
++ return size;
++}
++EXPORT_SYMBOL_GPL(dma_max_mapping_size);
--- /dev/null
+From d9140a0da4a230a03426d175145989667758aa6a Mon Sep 17 00:00:00 2001
+From: Phuong Nguyen <phuong.nguyen.xw@renesas.com>
+Date: Thu, 17 Jan 2019 17:44:17 +0900
+Subject: dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit
+
+From: Phuong Nguyen <phuong.nguyen.xw@renesas.com>
+
+commit d9140a0da4a230a03426d175145989667758aa6a upstream.
+
+This commit fixes the issue that USB-DMAC hangs silently after system
+resumes on R-Car Gen3 hence renesas_usbhs will not work correctly
+when using USB-DMAC for bulk transfer e.g. ethernet or serial
+gadgets.
+
+The issue can be reproduced by these steps:
+ 1. modprobe g_serial
+ 2. Suspend and resume system.
+ 3. connect a usb cable to host side
+ 4. Transfer data from Host to Target
+ 5. cat /dev/ttyGS0 (Target side)
+ 6. echo "test" > /dev/ttyACM0 (Host side)
+
+The 'cat' will not result anything. However, system still can work
+normally.
+
+Currently, USB-DMAC driver does not have system sleep callbacks hence
+this driver relies on the PM core to force runtime suspend/resume to
+suspend and reinitialize USB-DMAC during system resume. After
+the commit 17218e0092f8 ("PM / genpd: Stop/start devices without
+pm_runtime_force_suspend/resume()"), PM core will not force
+runtime suspend/resume anymore so this issue happens.
+
+To solve this, make system suspend resume explicit by using
+pm_runtime_force_{suspend,resume}() as the system sleep callbacks.
+SET_NOIRQ_SYSTEM_SLEEP_PM_OPS() is used to make sure USB-DMAC
+suspended after and initialized before renesas_usbhs."
+
+Signed-off-by: Phuong Nguyen <phuong.nguyen.xw@renesas.com>
+Signed-off-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
+Cc: <stable@vger.kernel.org> # v4.16+
+[shimoda: revise the commit log and add Cc tag]
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/sh/usb-dmac.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/dma/sh/usb-dmac.c
++++ b/drivers/dma/sh/usb-dmac.c
+@@ -694,6 +694,8 @@ static int usb_dmac_runtime_resume(struc
+ #endif /* CONFIG_PM */
+
+ static const struct dev_pm_ops usb_dmac_pm = {
++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
++ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume,
+ NULL)
+ };
--- /dev/null
+From 1c2d14212b15a60300a2d4f6364753e87394c521 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 29 Jan 2019 17:17:24 +0100
+Subject: ext2: Fix underflow in ext2_max_size()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 1c2d14212b15a60300a2d4f6364753e87394c521 upstream.
+
+When ext2 filesystem is created with 64k block size, ext2_max_size()
+will return value less than 0. Also, we cannot write any file in this fs
+since the sb->maxbytes is less than 0. The core of the problem is that
+the size of block index tree for such large block size is more than
+i_blocks can carry. So fix the computation to count with this
+possibility.
+
+File size limits computed with the new function for the full range of
+possible block sizes look like:
+
+bits file_size
+10 17247252480
+11 275415851008
+12 2196873666560
+13 2197948973056
+14 2198486220800
+15 2198754754560
+16 2198888906752
+
+CC: stable@vger.kernel.org
+Reported-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext2/super.c | 41 ++++++++++++++++++++++++++---------------
+ 1 file changed, 26 insertions(+), 15 deletions(-)
+
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -757,7 +757,8 @@ static loff_t ext2_max_size(int bits)
+ {
+ loff_t res = EXT2_NDIR_BLOCKS;
+ int meta_blocks;
+- loff_t upper_limit;
++ unsigned int upper_limit;
++ unsigned int ppb = 1 << (bits-2);
+
+ /* This is calculated to be the largest file size for a
+ * dense, file such that the total number of
+@@ -771,24 +772,34 @@ static loff_t ext2_max_size(int bits)
+ /* total blocks in file system block size */
+ upper_limit >>= (bits - 9);
+
+-
+- /* indirect blocks */
+- meta_blocks = 1;
+- /* double indirect blocks */
+- meta_blocks += 1 + (1LL << (bits-2));
+- /* tripple indirect blocks */
+- meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
+-
+- upper_limit -= meta_blocks;
+- upper_limit <<= bits;
+-
++ /* Compute how many blocks we can address by block tree */
+ res += 1LL << (bits-2);
+ res += 1LL << (2*(bits-2));
+ res += 1LL << (3*(bits-2));
++ /* Does block tree limit file size? */
++ if (res < upper_limit)
++ goto check_lfs;
++
++ res = upper_limit;
++ /* How many metadata blocks are needed for addressing upper_limit? */
++ upper_limit -= EXT2_NDIR_BLOCKS;
++ /* indirect blocks */
++ meta_blocks = 1;
++ upper_limit -= ppb;
++ /* double indirect blocks */
++ if (upper_limit < ppb * ppb) {
++ meta_blocks += 1 + DIV_ROUND_UP(upper_limit, ppb);
++ res -= meta_blocks;
++ goto check_lfs;
++ }
++ meta_blocks += 1 + ppb;
++ upper_limit -= ppb * ppb;
++ /* tripple indirect blocks for the rest */
++ meta_blocks += 1 + DIV_ROUND_UP(upper_limit, ppb) +
++ DIV_ROUND_UP(upper_limit, ppb*ppb);
++ res -= meta_blocks;
++check_lfs:
+ res <<= bits;
+- if (res > upper_limit)
+- res = upper_limit;
+-
+ if (res > MAX_LFS_FILESIZE)
+ res = MAX_LFS_FILESIZE;
+
--- /dev/null
+From abdc644e8cbac2e9b19763680e5a7cf9bab2bee7 Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Mon, 11 Feb 2019 00:35:06 -0500
+Subject: ext4: add mask of ext4 flags to swap
+
+From: yangerkun <yangerkun@huawei.com>
+
+commit abdc644e8cbac2e9b19763680e5a7cf9bab2bee7 upstream.
+
+The reason is that while swapping two inode, we swap the flags too.
+Some flags such as EXT4_JOURNAL_DATA_FL can really confuse the things
+since we're not resetting the address operations structure. The
+simplest way to keep things sane is to restrict the flags that can be
+swapped.
+
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ext4.h | 3 +++
+ fs/ext4/ioctl.c | 6 +++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -426,6 +426,9 @@ struct flex_groups {
+ /* Flags that are appropriate for non-directories/regular files. */
+ #define EXT4_OTHER_FLMASK (EXT4_NODUMP_FL | EXT4_NOATIME_FL)
+
++/* The only flags that should be swapped */
++#define EXT4_FL_SHOULD_SWAP (EXT4_HUGE_FILE_FL | EXT4_EXTENTS_FL)
++
+ /* Mask out flags that are inappropriate for the given type of inode. */
+ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
+ {
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -63,6 +63,7 @@ static void swap_inode_data(struct inode
+ loff_t isize;
+ struct ext4_inode_info *ei1;
+ struct ext4_inode_info *ei2;
++ unsigned long tmp;
+
+ ei1 = EXT4_I(inode1);
+ ei2 = EXT4_I(inode2);
+@@ -72,7 +73,10 @@ static void swap_inode_data(struct inode
+ swap(inode1->i_mtime, inode2->i_mtime);
+
+ memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
+- swap(ei1->i_flags, ei2->i_flags);
++ tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP;
++ ei1->i_flags = (ei2->i_flags & EXT4_FL_SHOULD_SWAP) |
++ (ei1->i_flags & ~EXT4_FL_SHOULD_SWAP);
++ ei2->i_flags = tmp | (ei2->i_flags & ~EXT4_FL_SHOULD_SWAP);
+ swap(ei1->i_disksize, ei2->i_disksize);
+ ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
+ ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);
--- /dev/null
+From a46c68a318b08f819047843abf349aeee5d10ac2 Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Mon, 11 Feb 2019 00:05:24 -0500
+Subject: ext4: cleanup pagecache before swap i_data
+
+From: yangerkun <yangerkun@huawei.com>
+
+commit a46c68a318b08f819047843abf349aeee5d10ac2 upstream.
+
+While do swap, we should make sure there has no new dirty page since we
+should swap i_data between two inode:
+1.We should lock i_mmap_sem with write to avoid new pagecache from mmap
+read/write;
+2.Change filemap_flush to filemap_write_and_wait and move them to the
+space protected by inode lock to avoid new pagecache from buffer read/write.
+
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ioctl.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -121,9 +121,6 @@ static long swap_inode_boot_loader(struc
+ return PTR_ERR(inode_bl);
+ ei_bl = EXT4_I(inode_bl);
+
+- filemap_flush(inode->i_mapping);
+- filemap_flush(inode_bl->i_mapping);
+-
+ /* Protect orig inodes against a truncate and make sure,
+ * that only 1 swap_inode_boot_loader is running. */
+ lock_two_nondirectories(inode, inode_bl);
+@@ -141,6 +138,15 @@ static long swap_inode_boot_loader(struc
+ goto journal_err_out;
+ }
+
++ down_write(&EXT4_I(inode)->i_mmap_sem);
++ err = filemap_write_and_wait(inode->i_mapping);
++ if (err)
++ goto err_out;
++
++ err = filemap_write_and_wait(inode_bl->i_mapping);
++ if (err)
++ goto err_out;
++
+ /* Wait for all existing dio workers */
+ inode_dio_wait(inode);
+ inode_dio_wait(inode_bl);
+@@ -151,7 +157,7 @@ static long swap_inode_boot_loader(struc
+ handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
+ if (IS_ERR(handle)) {
+ err = -EINVAL;
+- goto journal_err_out;
++ goto err_out;
+ }
+
+ /* Protect extent tree against block allocations via delalloc */
+@@ -208,6 +214,8 @@ static long swap_inode_boot_loader(struc
+ ext4_journal_stop(handle);
+ ext4_double_up_write_data_sem(inode, inode_bl);
+
++err_out:
++ up_write(&EXT4_I(inode)->i_mmap_sem);
+ journal_err_out:
+ unlock_two_nondirectories(inode, inode_bl);
+ iput(inode_bl);
--- /dev/null
+From 67a11611e1a5211f6569044fbf8150875764d1d0 Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Mon, 11 Feb 2019 00:02:05 -0500
+Subject: ext4: fix check of inode in swap_inode_boot_loader
+
+From: yangerkun <yangerkun@huawei.com>
+
+commit 67a11611e1a5211f6569044fbf8150875764d1d0 upstream.
+
+Before really do swap between inode and boot inode, something need to
+check to avoid invalid or not permitted operation, like does this inode
+has inline data. But the condition check should be protected by inode
+lock to avoid change while swapping. Also some other condition will not
+change between swapping, but there has no problem to do this under inode
+lock.
+
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ioctl.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -116,15 +116,6 @@ static long swap_inode_boot_loader(struc
+ struct inode *inode_bl;
+ struct ext4_inode_info *ei_bl;
+
+- if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
+- IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
+- ext4_has_inline_data(inode))
+- return -EINVAL;
+-
+- if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
+- !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
+- return -EPERM;
+-
+ inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
+ if (IS_ERR(inode_bl))
+ return PTR_ERR(inode_bl);
+@@ -137,6 +128,19 @@ static long swap_inode_boot_loader(struc
+ * that only 1 swap_inode_boot_loader is running. */
+ lock_two_nondirectories(inode, inode_bl);
+
++ if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
++ IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
++ ext4_has_inline_data(inode)) {
++ err = -EINVAL;
++ goto journal_err_out;
++ }
++
++ if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
++ !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) {
++ err = -EPERM;
++ goto journal_err_out;
++ }
++
+ /* Wait for all existing dio workers */
+ inode_dio_wait(inode);
+ inode_dio_wait(inode_bl);
--- /dev/null
+From f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 11 Feb 2019 13:30:32 -0500
+Subject: ext4: fix crash during online resizing
+
+From: Jan Kara <jack@suse.cz>
+
+commit f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1 upstream.
+
+When computing maximum size of filesystem possible with given number of
+group descriptor blocks, we forget to include s_first_data_block into
+the number of blocks. Thus for filesystems with non-zero
+s_first_data_block it can happen that computed maximum filesystem size
+is actually lower than current filesystem size which confuses the code
+and eventually leads to a BUG_ON in ext4_alloc_group_tables() hitting on
+flex_gd->count == 0. The problem can be reproduced like:
+
+truncate -s 100g /tmp/image
+mkfs.ext4 -b 1024 -E resize=262144 /tmp/image 32768
+mount -t ext4 -o loop /tmp/image /mnt
+resize2fs /dev/loop0 262145
+resize2fs /dev/loop0 300000
+
+Fix the problem by properly including s_first_data_block into the
+computed number of filesystem blocks.
+
+Fixes: 1c6bd7173d66 "ext4: convert file system to meta_bg if needed..."
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1960,7 +1960,8 @@ retry:
+ le16_to_cpu(es->s_reserved_gdt_blocks);
+ n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
+ n_blocks_count = (ext4_fsblk_t)n_group *
+- EXT4_BLOCKS_PER_GROUP(sb);
++ EXT4_BLOCKS_PER_GROUP(sb) +
++ le32_to_cpu(es->s_first_data_block);
+ n_group--; /* set to last group number */
+ }
+
--- /dev/null
+From aa507b5faf38784defe49f5e64605ac3c4425e26 Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Mon, 11 Feb 2019 00:14:02 -0500
+Subject: ext4: update quota information while swapping boot loader inode
+
+From: yangerkun <yangerkun@huawei.com>
+
+commit aa507b5faf38784defe49f5e64605ac3c4425e26 upstream.
+
+While do swap between two inode, they swap i_data without update
+quota information. Also, swap_inode_boot_loader can do "revert"
+somtimes, so update the quota while all operations has been finished.
+
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ioctl.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 43 insertions(+), 13 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -68,8 +68,6 @@ static void swap_inode_data(struct inode
+ ei2 = EXT4_I(inode2);
+
+ swap(inode1->i_version, inode2->i_version);
+- swap(inode1->i_blocks, inode2->i_blocks);
+- swap(inode1->i_bytes, inode2->i_bytes);
+ swap(inode1->i_atime, inode2->i_atime);
+ swap(inode1->i_mtime, inode2->i_mtime);
+
+@@ -115,6 +113,9 @@ static long swap_inode_boot_loader(struc
+ int err;
+ struct inode *inode_bl;
+ struct ext4_inode_info *ei_bl;
++ qsize_t size, size_bl, diff;
++ blkcnt_t blocks;
++ unsigned short bytes;
+
+ inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
+ if (IS_ERR(inode_bl))
+@@ -180,6 +181,13 @@ static long swap_inode_boot_loader(struc
+ memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data));
+ }
+
++ err = dquot_initialize(inode);
++ if (err)
++ goto err_out1;
++
++ size = (qsize_t)(inode->i_blocks) * (1 << 9) + inode->i_bytes;
++ size_bl = (qsize_t)(inode_bl->i_blocks) * (1 << 9) + inode_bl->i_bytes;
++ diff = size - size_bl;
+ swap_inode_data(inode, inode_bl);
+
+ inode->i_ctime = inode_bl->i_ctime = current_time(inode);
+@@ -193,24 +201,46 @@ static long swap_inode_boot_loader(struc
+
+ err = ext4_mark_inode_dirty(handle, inode);
+ if (err < 0) {
++ /* No need to update quota information. */
+ ext4_warning(inode->i_sb,
+ "couldn't mark inode #%lu dirty (err %d)",
+ inode->i_ino, err);
+ /* Revert all changes: */
+ swap_inode_data(inode, inode_bl);
+ ext4_mark_inode_dirty(handle, inode);
+- } else {
+- err = ext4_mark_inode_dirty(handle, inode_bl);
+- if (err < 0) {
+- ext4_warning(inode_bl->i_sb,
+- "couldn't mark inode #%lu dirty (err %d)",
+- inode_bl->i_ino, err);
+- /* Revert all changes: */
+- swap_inode_data(inode, inode_bl);
+- ext4_mark_inode_dirty(handle, inode);
+- ext4_mark_inode_dirty(handle, inode_bl);
+- }
++ goto err_out1;
++ }
++
++ blocks = inode_bl->i_blocks;
++ bytes = inode_bl->i_bytes;
++ inode_bl->i_blocks = inode->i_blocks;
++ inode_bl->i_bytes = inode->i_bytes;
++ err = ext4_mark_inode_dirty(handle, inode_bl);
++ if (err < 0) {
++ /* No need to update quota information. */
++ ext4_warning(inode_bl->i_sb,
++ "couldn't mark inode #%lu dirty (err %d)",
++ inode_bl->i_ino, err);
++ goto revert;
++ }
++
++ /* Bootloader inode should not be counted into quota information. */
++ if (diff > 0)
++ dquot_free_space(inode, diff);
++ else
++ err = dquot_alloc_space(inode, -1 * diff);
++
++ if (err < 0) {
++revert:
++ /* Revert all changes: */
++ inode_bl->i_blocks = blocks;
++ inode_bl->i_bytes = bytes;
++ swap_inode_data(inode, inode_bl);
++ ext4_mark_inode_dirty(handle, inode);
++ ext4_mark_inode_dirty(handle, inode_bl);
+ }
++
++err_out1:
+ ext4_journal_stop(handle);
+ ext4_double_up_write_data_sem(inode, inode_bl);
+
--- /dev/null
+From c378b3aa015931a46c91d6ccc2fe04d97801d060 Mon Sep 17 00:00:00 2001
+From: Mark Walton <mark.walton@serialtek.com>
+Date: Thu, 28 Feb 2019 15:46:36 +0000
+Subject: gpio: pca953x: Fix dereference of irq data in shutdown
+
+From: Mark Walton <mark.walton@serialtek.com>
+
+commit c378b3aa015931a46c91d6ccc2fe04d97801d060 upstream.
+
+If a PCA953x gpio was used as an interrupt and then released,
+the shutdown function was trying to extract the pca953x_chip
+pointer directly from the irq_data, but in reality was getting
+the gpio_chip structure.
+
+The net effect was that the subsequent writes to the data
+structure corrupted data in the gpio_chip structure, which wasn't
+immediately obvious until attempting to use the GPIO again in the
+future, at which point the kernel panics.
+
+This fix correctly extracts the pca953x_chip structure via the
+gpio_chip structure, as is correctly done in the other irq
+functions.
+
+Fixes: 0a70fe00efea ("gpio: pca953x: Clear irq trigger type on irq shutdown")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mark Walton <mark.walton@serialtek.com>
+Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpio-pca953x.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -587,7 +587,8 @@ static int pca953x_irq_set_type(struct i
+
+ static void pca953x_irq_shutdown(struct irq_data *d)
+ {
+- struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct pca953x_chip *chip = gpiochip_get_data(gc);
+ u8 mask = 1 << (d->hwirq % BANK_SZ);
+
+ chip->irq_trig_raise[d->hwirq / BANK_SZ] &= ~mask;
--- /dev/null
+From f4e3f4ae1d9c9330de355f432b69952e8cef650c Mon Sep 17 00:00:00 2001
+From: Sowjanya Komatineni <skomatineni@nvidia.com>
+Date: Tue, 12 Feb 2019 11:06:44 -0800
+Subject: i2c: tegra: fix maximum transfer size
+
+From: Sowjanya Komatineni <skomatineni@nvidia.com>
+
+commit f4e3f4ae1d9c9330de355f432b69952e8cef650c upstream.
+
+Tegra186 and prior supports maximum 4K bytes per packet transfer
+including 12 bytes of packet header.
+
+This patch fixes max write length limit to account packet header
+size for transfers.
+
+Cc: stable@vger.kernel.org # 4.4+
+
+Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
+Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/busses/i2c-tegra.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -837,7 +837,7 @@ static const struct i2c_algorithm tegra_
+ static const struct i2c_adapter_quirks tegra_i2c_quirks = {
+ .flags = I2C_AQ_NO_ZERO_LEN,
+ .max_read_len = 4096,
+- .max_write_len = 4096,
++ .max_write_len = 4096 - 12,
+ };
+
+ static const struct i2c_adapter_quirks tegra194_i2c_quirks = {
--- /dev/null
+From b03ff2a23359d0dd6f0a1516c6a9e9c4760ed230 Mon Sep 17 00:00:00 2001
+From: Sowjanya Komatineni <skomatineni@nvidia.com>
+Date: Tue, 12 Feb 2019 11:06:45 -0800
+Subject: i2c: tegra: update maximum transfer size
+
+From: Sowjanya Komatineni <skomatineni@nvidia.com>
+
+commit b03ff2a23359d0dd6f0a1516c6a9e9c4760ed230 upstream.
+
+Tegra194 supports maximum 64K bytes per packet including 12 bytes of
+packet header irrespective of PIO or DMA mode transfer.
+
+This patch updates Tegra194 max write length to account for packet
+header size for transfers.
+
+Cc: stable@vger.kernel.org # 4.20+
+
+Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
+Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/busses/i2c-tegra.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -118,6 +118,9 @@
+ #define I2C_MST_FIFO_STATUS_TX_MASK 0xff0000
+ #define I2C_MST_FIFO_STATUS_TX_SHIFT 16
+
++/* Packet header size in bytes */
++#define I2C_PACKET_HEADER_SIZE 12
++
+ /*
+ * msg_end_type: The bus control which need to be send at end of transfer.
+ * @MSG_END_STOP: Send stop pulse at end of transfer.
+@@ -836,12 +839,13 @@ static const struct i2c_algorithm tegra_
+ /* payload size is only 12 bit */
+ static const struct i2c_adapter_quirks tegra_i2c_quirks = {
+ .flags = I2C_AQ_NO_ZERO_LEN,
+- .max_read_len = 4096,
+- .max_write_len = 4096 - 12,
++ .max_read_len = SZ_4K,
++ .max_write_len = SZ_4K - I2C_PACKET_HEADER_SIZE,
+ };
+
+ static const struct i2c_adapter_quirks tegra194_i2c_quirks = {
+ .flags = I2C_AQ_NO_ZERO_LEN,
++ .max_write_len = SZ_64K - I2C_PACKET_HEADER_SIZE,
+ };
+
+ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
--- /dev/null
+From bc5add09764c123f58942a37c8335247e683d234 Mon Sep 17 00:00:00 2001
+From: "Michael J. Ruhl" <michael.j.ruhl@intel.com>
+Date: Tue, 26 Feb 2019 08:45:35 -0800
+Subject: IB/hfi1: Close race condition on user context disable and close
+
+From: Michael J. Ruhl <michael.j.ruhl@intel.com>
+
+commit bc5add09764c123f58942a37c8335247e683d234 upstream.
+
+When disabling and removing a receive context, it is possible for an
+asynchronous event (i.e IRQ) to occur. Because of this, there is a race
+between cleaning up the context, and the context being used by the
+asynchronous event.
+
+cpu 0 (context cleanup)
+ rc->ref_count-- (ref_count == 0)
+ hfi1_rcd_free()
+cpu 1 (IRQ (with rcd index))
+ rcd_get_by_index()
+ lock
+ ref_count+++ <-- reference count race (WARNING)
+ return rcd
+ unlock
+cpu 0
+ hfi1_free_ctxtdata() <-- incorrect free location
+ lock
+ remove rcd from array
+ unlock
+ free rcd
+
+This race will cause the following WARNING trace:
+
+WARNING: CPU: 0 PID: 175027 at include/linux/kref.h:52 hfi1_rcd_get_by_index+0x84/0xa0 [hfi1]
+CPU: 0 PID: 175027 Comm: IMB-MPI1 Kdump: loaded Tainted: G OE ------------ 3.10.0-957.el7.x86_64 #1
+Hardware name: Intel Corporation S2600KP/S2600KP, BIOS SE5C610.86B.11.01.0076.C4.111920150602 11/19/2015
+Call Trace:
+ dump_stack+0x19/0x1b
+ __warn+0xd8/0x100
+ warn_slowpath_null+0x1d/0x20
+ hfi1_rcd_get_by_index+0x84/0xa0 [hfi1]
+ is_rcv_urgent_int+0x24/0x90 [hfi1]
+ general_interrupt+0x1b6/0x210 [hfi1]
+ __handle_irq_event_percpu+0x44/0x1c0
+ handle_irq_event_percpu+0x32/0x80
+ handle_irq_event+0x3c/0x60
+ handle_edge_irq+0x7f/0x150
+ handle_irq+0xe4/0x1a0
+ do_IRQ+0x4d/0xf0
+ common_interrupt+0x162/0x162
+
+The race can also lead to a use after free which could be similar to:
+
+general protection fault: 0000 1 SMP
+CPU: 71 PID: 177147 Comm: IMB-MPI1 Kdump: loaded Tainted: G W OE ------------ 3.10.0-957.el7.x86_64 #1
+Hardware name: Intel Corporation S2600KP/S2600KP, BIOS SE5C610.86B.11.01.0076.C4.111920150602 11/19/2015
+task: ffff9962a8098000 ti: ffff99717a508000 task.ti: ffff99717a508000 __kmalloc+0x94/0x230
+Call Trace:
+ ? hfi1_user_sdma_process_request+0x9c8/0x1250 [hfi1]
+ hfi1_user_sdma_process_request+0x9c8/0x1250 [hfi1]
+ hfi1_aio_write+0xba/0x110 [hfi1]
+ do_sync_readv_writev+0x7b/0xd0
+ do_readv_writev+0xce/0x260
+ ? handle_mm_fault+0x39d/0x9b0
+ ? pick_next_task_fair+0x5f/0x1b0
+ ? sched_clock_cpu+0x85/0xc0
+ ? __schedule+0x13a/0x890
+ vfs_writev+0x35/0x60
+ SyS_writev+0x7f/0x110
+ system_call_fastpath+0x22/0x27
+
+Use the appropriate kref API to verify access.
+
+Reorder context cleanup to ensure context removal before cleanup occurs
+correctly.
+
+Cc: stable@vger.kernel.org # v4.14.0+
+Fixes: f683c80ca68e ("IB/hfi1: Resolve kernel panics by reference counting receive contexts")
+Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/hfi1/hfi.h | 2 +-
+ drivers/infiniband/hw/hfi1/init.c | 14 +++++++++-----
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/infiniband/hw/hfi1/hfi.h
++++ b/drivers/infiniband/hw/hfi1/hfi.h
+@@ -1435,7 +1435,7 @@ void hfi1_init_pportdata(struct pci_dev
+ struct hfi1_devdata *dd, u8 hw_pidx, u8 port);
+ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd);
+ int hfi1_rcd_put(struct hfi1_ctxtdata *rcd);
+-void hfi1_rcd_get(struct hfi1_ctxtdata *rcd);
++int hfi1_rcd_get(struct hfi1_ctxtdata *rcd);
+ struct hfi1_ctxtdata *hfi1_rcd_get_by_index_safe(struct hfi1_devdata *dd,
+ u16 ctxt);
+ struct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt);
+--- a/drivers/infiniband/hw/hfi1/init.c
++++ b/drivers/infiniband/hw/hfi1/init.c
+@@ -215,12 +215,12 @@ static void hfi1_rcd_free(struct kref *k
+ struct hfi1_ctxtdata *rcd =
+ container_of(kref, struct hfi1_ctxtdata, kref);
+
+- hfi1_free_ctxtdata(rcd->dd, rcd);
+-
+ spin_lock_irqsave(&rcd->dd->uctxt_lock, flags);
+ rcd->dd->rcd[rcd->ctxt] = NULL;
+ spin_unlock_irqrestore(&rcd->dd->uctxt_lock, flags);
+
++ hfi1_free_ctxtdata(rcd->dd, rcd);
++
+ kfree(rcd);
+ }
+
+@@ -243,10 +243,13 @@ int hfi1_rcd_put(struct hfi1_ctxtdata *r
+ * @rcd: pointer to an initialized rcd data structure
+ *
+ * Use this to get a reference after the init.
++ *
++ * Return : reflect kref_get_unless_zero(), which returns non-zero on
++ * increment, otherwise 0.
+ */
+-void hfi1_rcd_get(struct hfi1_ctxtdata *rcd)
++int hfi1_rcd_get(struct hfi1_ctxtdata *rcd)
+ {
+- kref_get(&rcd->kref);
++ return kref_get_unless_zero(&rcd->kref);
+ }
+
+ /**
+@@ -326,7 +329,8 @@ struct hfi1_ctxtdata *hfi1_rcd_get_by_in
+ spin_lock_irqsave(&dd->uctxt_lock, flags);
+ if (dd->rcd[ctxt]) {
+ rcd = dd->rcd[ctxt];
+- hfi1_rcd_get(rcd);
++ if (!hfi1_rcd_get(rcd))
++ rcd = NULL;
+ }
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
+
--- /dev/null
+From d757c60eca9b22f4d108929a24401e0fdecda0b1 Mon Sep 17 00:00:00 2001
+From: "Michael J. Ruhl" <michael.j.ruhl@intel.com>
+Date: Tue, 26 Feb 2019 08:45:25 -0800
+Subject: IB/rdmavt: Fix concurrency panics in QP post_send and modify to error
+
+From: Michael J. Ruhl <michael.j.ruhl@intel.com>
+
+commit d757c60eca9b22f4d108929a24401e0fdecda0b1 upstream.
+
+The RC/UC code path can go through a software loopback. In this code path
+the receive side QP is manipulated.
+
+If two threads are working on the QP receive side (i.e. post_send, and
+modify_qp to an error state), QP information can be corrupted.
+
+(post_send via loopback)
+ set r_sge
+ loop
+ update r_sge
+(modify_qp)
+ take r_lock
+ update r_sge <---- r_sge is now incorrect
+(post_send)
+ update r_sge <---- crash, etc.
+ ...
+
+This can lead to one of the two following crashes:
+
+ BUG: unable to handle kernel NULL pointer dereference at (null)
+ IP: hfi1_copy_sge+0xf1/0x2e0 [hfi1]
+ PGD 8000001fe6a57067 PUD 1fd9e0c067 PMD 0
+ Call Trace:
+ ruc_loopback+0x49b/0xbc0 [hfi1]
+ hfi1_do_send+0x38e/0x3e0 [hfi1]
+ _hfi1_do_send+0x1e/0x20 [hfi1]
+ process_one_work+0x17f/0x440
+ worker_thread+0x126/0x3c0
+ kthread+0xd1/0xe0
+ ret_from_fork_nospec_begin+0x21/0x21
+
+or:
+
+ BUG: unable to handle kernel NULL pointer dereference at 0000000000000048
+ IP: rvt_clear_mr_refs+0x45/0x370 [rdmavt]
+ PGD 80000006ae5eb067 PUD ef15d0067 PMD 0
+ Call Trace:
+ rvt_error_qp+0xaa/0x240 [rdmavt]
+ rvt_modify_qp+0x47f/0xaa0 [rdmavt]
+ ib_security_modify_qp+0x8f/0x400 [ib_core]
+ ib_modify_qp_with_udata+0x44/0x70 [ib_core]
+ modify_qp.isra.23+0x1eb/0x2b0 [ib_uverbs]
+ ib_uverbs_modify_qp+0xaa/0xf0 [ib_uverbs]
+ ib_uverbs_write+0x272/0x430 [ib_uverbs]
+ vfs_write+0xc0/0x1f0
+ SyS_write+0x7f/0xf0
+ system_call_fastpath+0x1c/0x21
+
+Fix by using the appropriate locking on the receiving QP.
+
+Fixes: 15703461533a ("IB/{hfi1, qib, rdmavt}: Move ruc_loopback to rdmavt")
+Cc: <stable@vger.kernel.org> #v4.9+
+Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/sw/rdmavt/qp.c | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+--- a/drivers/infiniband/sw/rdmavt/qp.c
++++ b/drivers/infiniband/sw/rdmavt/qp.c
+@@ -2785,6 +2785,18 @@ again:
+ }
+ EXPORT_SYMBOL(rvt_copy_sge);
+
++static enum ib_wc_status loopback_qp_drop(struct rvt_ibport *rvp,
++ struct rvt_qp *sqp)
++{
++ rvp->n_pkt_drops++;
++ /*
++ * For RC, the requester would timeout and retry so
++ * shortcut the timeouts and just signal too many retries.
++ */
++ return sqp->ibqp.qp_type == IB_QPT_RC ?
++ IB_WC_RETRY_EXC_ERR : IB_WC_SUCCESS;
++}
++
+ /**
+ * ruc_loopback - handle UC and RC loopback requests
+ * @sqp: the sending QP
+@@ -2857,17 +2869,14 @@ again:
+ }
+ spin_unlock_irqrestore(&sqp->s_lock, flags);
+
+- if (!qp || !(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) ||
++ if (!qp) {
++ send_status = loopback_qp_drop(rvp, sqp);
++ goto serr_no_r_lock;
++ }
++ spin_lock_irqsave(&qp->r_lock, flags);
++ if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) ||
+ qp->ibqp.qp_type != sqp->ibqp.qp_type) {
+- rvp->n_pkt_drops++;
+- /*
+- * For RC, the requester would timeout and retry so
+- * shortcut the timeouts and just signal too many retries.
+- */
+- if (sqp->ibqp.qp_type == IB_QPT_RC)
+- send_status = IB_WC_RETRY_EXC_ERR;
+- else
+- send_status = IB_WC_SUCCESS;
++ send_status = loopback_qp_drop(rvp, sqp);
+ goto serr;
+ }
+
+@@ -3047,6 +3056,7 @@ do_write:
+ wqe->wr.send_flags & IB_SEND_SOLICITED);
+
+ send_comp:
++ spin_unlock_irqrestore(&qp->r_lock, flags);
+ spin_lock_irqsave(&sqp->s_lock, flags);
+ rvp->n_loop_pkts++;
+ flush_send:
+@@ -3073,6 +3083,7 @@ rnr_nak:
+ }
+ if (sqp->s_rnr_retry_cnt < 7)
+ sqp->s_rnr_retry--;
++ spin_unlock_irqrestore(&qp->r_lock, flags);
+ spin_lock_irqsave(&sqp->s_lock, flags);
+ if (!(ib_rvt_state_ops[sqp->state] & RVT_PROCESS_RECV_OK))
+ goto clr_busy;
+@@ -3101,6 +3112,8 @@ err:
+ rvt_rc_error(qp, wc.status);
+
+ serr:
++ spin_unlock_irqrestore(&qp->r_lock, flags);
++serr_no_r_lock:
+ spin_lock_irqsave(&sqp->s_lock, flags);
+ rvt_send_complete(sqp, wqe, send_status);
+ if (sqp->ibqp.qp_type == IB_QPT_RC) {
--- /dev/null
+From 38bbc9f0381550d1d227fc57afa08436e36b32fc Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Date: Tue, 26 Feb 2019 08:45:16 -0800
+Subject: IB/rdmavt: Fix loopback send with invalidate ordering
+
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+
+commit 38bbc9f0381550d1d227fc57afa08436e36b32fc upstream.
+
+The IBTA spec notes:
+
+o9-5.2.1: For any HCA which supports SEND with Invalidate, upon receiving
+an IETH, the Invalidate operation must not take place until after the
+normal transport header validation checks have been successfully
+completed.
+
+The rdmavt loopback code does the validation after the invalidate.
+
+Fix by relocating the operation specific logic for all SEND variants until
+after the validity checks.
+
+Cc: <stable@vger.kernel.org> #v4.20+
+Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/sw/rdmavt/qp.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/infiniband/sw/rdmavt/qp.c
++++ b/drivers/infiniband/sw/rdmavt/qp.c
+@@ -2893,18 +2893,8 @@ again:
+ goto send_comp;
+
+ case IB_WR_SEND_WITH_INV:
+- if (!rvt_invalidate_rkey(qp, wqe->wr.ex.invalidate_rkey)) {
+- wc.wc_flags = IB_WC_WITH_INVALIDATE;
+- wc.ex.invalidate_rkey = wqe->wr.ex.invalidate_rkey;
+- }
+- goto send;
+-
+ case IB_WR_SEND_WITH_IMM:
+- wc.wc_flags = IB_WC_WITH_IMM;
+- wc.ex.imm_data = wqe->wr.ex.imm_data;
+- /* FALLTHROUGH */
+ case IB_WR_SEND:
+-send:
+ ret = rvt_get_rwqe(qp, false);
+ if (ret < 0)
+ goto op_err;
+@@ -2912,6 +2902,22 @@ send:
+ goto rnr_nak;
+ if (wqe->length > qp->r_len)
+ goto inv_err;
++ switch (wqe->wr.opcode) {
++ case IB_WR_SEND_WITH_INV:
++ if (!rvt_invalidate_rkey(qp,
++ wqe->wr.ex.invalidate_rkey)) {
++ wc.wc_flags = IB_WC_WITH_INVALIDATE;
++ wc.ex.invalidate_rkey =
++ wqe->wr.ex.invalidate_rkey;
++ }
++ break;
++ case IB_WR_SEND_WITH_IMM:
++ wc.wc_flags = IB_WC_WITH_IMM;
++ wc.ex.imm_data = wqe->wr.ex.imm_data;
++ break;
++ default:
++ break;
++ }
+ break;
+
+ case IB_WR_RDMA_WRITE_WITH_IMM:
--- /dev/null
+From 9ed3f22223c33347ed963e7c7019cf2956dd4e37 Mon Sep 17 00:00:00 2001
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Date: Thu, 24 Jan 2019 15:11:53 +0200
+Subject: intel_th: Don't reference unassigned outputs
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+commit 9ed3f22223c33347ed963e7c7019cf2956dd4e37 upstream.
+
+When an output port driver is removed, also remove references to it from
+any masters. Failing to do this causes a NULL ptr dereference when
+configuring another output port:
+
+> BUG: unable to handle kernel NULL pointer dereference at 000000000000000d
+> RIP: 0010:master_attr_store+0x9d/0x160 [intel_th_gth]
+> Call Trace:
+> dev_attr_store+0x1b/0x30
+> sysfs_kf_write+0x3c/0x50
+> kernfs_fop_write+0x125/0x1a0
+> __vfs_write+0x3a/0x190
+> ? __vfs_write+0x5/0x190
+> ? _cond_resched+0x1a/0x50
+> ? rcu_all_qs+0x5/0xb0
+> ? __vfs_write+0x5/0x190
+> vfs_write+0xb8/0x1b0
+> ksys_write+0x55/0xc0
+> __x64_sys_write+0x1a/0x20
+> do_syscall_64+0x5a/0x140
+> entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Fixes: b27a6a3f97b9 ("intel_th: Add Global Trace Hub driver")
+CC: stable@vger.kernel.org # v4.4+
+Reported-by: Ammy Yi <ammy.yi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwtracing/intel_th/gth.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/hwtracing/intel_th/gth.c
++++ b/drivers/hwtracing/intel_th/gth.c
+@@ -607,6 +607,7 @@ static void intel_th_gth_unassign(struct
+ {
+ struct gth_device *gth = dev_get_drvdata(&thdev->dev);
+ int port = othdev->output.port;
++ int master;
+
+ if (thdev->host_mode)
+ return;
+@@ -615,6 +616,9 @@ static void intel_th_gth_unassign(struct
+ othdev->output.port = -1;
+ othdev->output.active = false;
+ gth->output[port].output = NULL;
++ for (master = 0; master < TH_CONFIGURABLE_MASTERS; master++)
++ if (gth->master[master] == port)
++ gth->master[master] = -1;
+ spin_unlock(>h->gth_lock);
+ }
+
--- /dev/null
+From 33517881ede742107f416533b8c3e4abc56763da Mon Sep 17 00:00:00 2001
+From: Doug Berger <opendmb@gmail.com>
+Date: Wed, 20 Feb 2019 14:15:28 -0800
+Subject: irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code
+
+From: Doug Berger <opendmb@gmail.com>
+
+commit 33517881ede742107f416533b8c3e4abc56763da upstream.
+
+Using the irq_gc_lock/irq_gc_unlock functions in the suspend and
+resume functions creates the opportunity for a deadlock during
+suspend, resume, and shutdown. Using the irq_gc_lock_irqsave/
+irq_gc_unlock_irqrestore variants prevents this possible deadlock.
+
+Cc: stable@vger.kernel.org
+Fixes: 7f646e92766e2 ("irqchip: brcmstb-l2: Add Broadcom Set Top Box Level-2 interrupt controller")
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+[maz: tidied up $SUBJECT]
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-brcmstb-l2.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/irqchip/irq-brcmstb-l2.c
++++ b/drivers/irqchip/irq-brcmstb-l2.c
+@@ -129,8 +129,9 @@ static void brcmstb_l2_intc_suspend(stru
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ struct brcmstb_l2_intc_data *b = gc->private;
++ unsigned long flags;
+
+- irq_gc_lock(gc);
++ irq_gc_lock_irqsave(gc, flags);
+ /* Save the current mask */
+ b->saved_mask = irq_reg_readl(gc, ct->regs.mask);
+
+@@ -139,7 +140,7 @@ static void brcmstb_l2_intc_suspend(stru
+ irq_reg_writel(gc, ~gc->wake_active, ct->regs.disable);
+ irq_reg_writel(gc, gc->wake_active, ct->regs.enable);
+ }
+- irq_gc_unlock(gc);
++ irq_gc_unlock_irqrestore(gc, flags);
+ }
+
+ static void brcmstb_l2_intc_resume(struct irq_data *d)
+@@ -147,8 +148,9 @@ static void brcmstb_l2_intc_resume(struc
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ struct brcmstb_l2_intc_data *b = gc->private;
++ unsigned long flags;
+
+- irq_gc_lock(gc);
++ irq_gc_lock_irqsave(gc, flags);
+ if (ct->chip.irq_ack) {
+ /* Clear unmasked non-wakeup interrupts */
+ irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active,
+@@ -158,7 +160,7 @@ static void brcmstb_l2_intc_resume(struc
+ /* Restore the saved mask */
+ irq_reg_writel(gc, b->saved_mask, ct->regs.disable);
+ irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable);
+- irq_gc_unlock(gc);
++ irq_gc_unlock_irqrestore(gc, flags);
+ }
+
+ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
--- /dev/null
+From 8d565748b6035eeda18895c213396a4c9fac6a4c Mon Sep 17 00:00:00 2001
+From: Zenghui Yu <yuzenghui@huawei.com>
+Date: Sun, 10 Feb 2019 05:24:10 +0000
+Subject: irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table
+
+From: Zenghui Yu <yuzenghui@huawei.com>
+
+commit 8d565748b6035eeda18895c213396a4c9fac6a4c upstream.
+
+In current logic, its_parse_indirect_baser() will be invoked twice
+when allocating Device tables. Add a *break* to omit the unnecessary
+and annoying (might be ...) invoking.
+
+Fixes: 32bd44dc19de ("irqchip/gic-v3-its: Fix the incorrect parsing of VCPU table size")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-gic-v3-its.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/irqchip/irq-gic-v3-its.c
++++ b/drivers/irqchip/irq-gic-v3-its.c
+@@ -1955,6 +1955,8 @@ static int its_alloc_tables(struct its_n
+ indirect = its_parse_indirect_baser(its, baser,
+ psz, &order,
+ its->device_ids);
++ break;
++
+ case GITS_BASER_TYPE_VCPU:
+ indirect = its_parse_indirect_baser(its, baser,
+ psz, &order,
--- /dev/null
+From 8cf7630b29701d364f8df4a50e4f1f5e752b2778 Mon Sep 17 00:00:00 2001
+From: Zev Weiss <zev@bewilderbeest.net>
+Date: Mon, 11 Mar 2019 23:28:02 -0700
+Subject: kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv
+
+From: Zev Weiss <zev@bewilderbeest.net>
+
+commit 8cf7630b29701d364f8df4a50e4f1f5e752b2778 upstream.
+
+This bug has apparently existed since the introduction of this function
+in the pre-git era (4500e91754d3 in Thomas Gleixner's history.git,
+"[NET]: Add proc_dointvec_userhz_jiffies, use it for proper handling of
+neighbour sysctls.").
+
+As a minimal fix we can simply duplicate the corresponding check in
+do_proc_dointvec_conv().
+
+Link: http://lkml.kernel.org/r/20190207123426.9202-3-zev@bewilderbeest.net
+Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
+Cc: Brendan Higgins <brendanhiggins@google.com>
+Cc: Iurii Zaikin <yzaikin@google.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Luis Chamberlain <mcgrof@kernel.org>
+Cc: <stable@vger.kernel.org> [2.6.2+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sysctl.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -2579,7 +2579,16 @@ static int do_proc_dointvec_minmax_conv(
+ {
+ struct do_proc_dointvec_minmax_conv_param *param = data;
+ if (write) {
+- int val = *negp ? -*lvalp : *lvalp;
++ int val;
++ if (*negp) {
++ if (*lvalp > (unsigned long) INT_MAX + 1)
++ return -EINVAL;
++ val = -*lvalp;
++ } else {
++ if (*lvalp > (unsigned long) INT_MAX)
++ return -EINVAL;
++ val = *lvalp;
++ }
+ if ((param->min && *param->min > val) ||
+ (param->max && *param->max < val))
+ return -EINVAL;
--- /dev/null
+From 607076a904c435f2677fadaadd4af546279db68b Mon Sep 17 00:00:00 2001
+From: Lubomir Rintel <lkundrak@v3.sk>
+Date: Sun, 10 Feb 2019 20:47:49 +0100
+Subject: libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer
+
+From: Lubomir Rintel <lkundrak@v3.sk>
+
+commit 607076a904c435f2677fadaadd4af546279db68b upstream.
+
+It doesn't make sense and the USB core warns on each submit of such
+URB, easily flooding the message buffer with tracebacks.
+
+Analogous issue was fixed in regular libertas driver in commit 6528d8804780
+("libertas: don't set URB_ZERO_PACKET on IN USB transfer").
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
+Reviewed-by: Steve deRosier <derosier@cal-sierra.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c
++++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+@@ -433,8 +433,6 @@ static int __if_usb_submit_rx_urb(struct
+ skb_tail_pointer(skb),
+ MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp);
+
+- cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
+-
+ lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n",
+ cardp->rx_urb);
+ ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC);
--- /dev/null
+From 1d4c41f3d887bcd66e82cb2fda124533dad8808a Mon Sep 17 00:00:00 2001
+From: Loic Poulain <loic.poulain@linaro.org>
+Date: Wed, 30 Jan 2019 11:48:07 -0500
+Subject: media: i2c: ov5640: Fix post-reset delay
+
+From: Loic Poulain <loic.poulain@linaro.org>
+
+commit 1d4c41f3d887bcd66e82cb2fda124533dad8808a upstream.
+
+According to the ov5640 specification (2.7 power up sequence), host can
+access the sensor's registers 20ms after reset. Trying to access them
+before leads to undefined behavior and result in sporadic initialization
+errors.
+
+Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Cc: Adam Ford <aford173@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/i2c/ov5640.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/ov5640.c
++++ b/drivers/media/i2c/ov5640.c
+@@ -1893,7 +1893,7 @@ static void ov5640_reset(struct ov5640_d
+ usleep_range(1000, 2000);
+
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
+- usleep_range(5000, 10000);
++ usleep_range(20000, 25000);
+ }
+
+ static int ov5640_set_power_on(struct ov5640_dev *sensor)
--- /dev/null
+From 46612b751c4941c5c0472ddf04027e877ae5990f Mon Sep 17 00:00:00 2001
+From: zhongjiang <zhongjiang@huawei.com>
+Date: Tue, 5 Mar 2019 15:41:16 -0800
+Subject: mm: hwpoison: fix thp split handing in soft_offline_in_use_page()
+
+From: zhongjiang <zhongjiang@huawei.com>
+
+commit 46612b751c4941c5c0472ddf04027e877ae5990f upstream.
+
+When soft_offline_in_use_page() runs on a thp tail page after pmd is
+split, we trigger the following VM_BUG_ON_PAGE():
+
+ Memory failure: 0x3755ff: non anonymous thp
+ __get_any_page: 0x3755ff: unknown zero refcount page type 2fffff80000000
+ Soft offlining pfn 0x34d805 at process virtual address 0x20fff000
+ page:ffffea000d360140 count:0 mapcount:0 mapping:0000000000000000 index:0x1
+ flags: 0x2fffff80000000()
+ raw: 002fffff80000000 ffffea000d360108 ffffea000d360188 0000000000000000
+ raw: 0000000000000001 0000000000000000 00000000ffffffff 0000000000000000
+ page dumped because: VM_BUG_ON_PAGE(page_ref_count(page) == 0)
+ ------------[ cut here ]------------
+ kernel BUG at ./include/linux/mm.h:519!
+
+soft_offline_in_use_page() passed refcount and page lock from tail page
+to head page, which is not needed because we can pass any subpage to
+split_huge_page().
+
+Naoya had fixed a similar issue in c3901e722b29 ("mm: hwpoison: fix thp
+split handling in memory_failure()"). But he missed fixing soft
+offline.
+
+Link: http://lkml.kernel.org/r/1551452476-24000-1-git-send-email-zhongjiang@huawei.com
+Fixes: 61f5d698cc97 ("mm: re-enable THP")
+Signed-off-by: zhongjiang <zhongjiang@huawei.com>
+Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Kirill A. Shutemov <kirill@shutemov.name>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: <stable@vger.kernel.org> [4.5+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memory-failure.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1825,19 +1825,17 @@ static int soft_offline_in_use_page(stru
+ struct page *hpage = compound_head(page);
+
+ if (!PageHuge(page) && PageTransHuge(hpage)) {
+- lock_page(hpage);
+- if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) {
+- unlock_page(hpage);
+- if (!PageAnon(hpage))
++ lock_page(page);
++ if (!PageAnon(page) || unlikely(split_huge_page(page))) {
++ unlock_page(page);
++ if (!PageAnon(page))
+ pr_info("soft offline: %#lx: non anonymous thp\n", page_to_pfn(page));
+ else
+ pr_info("soft offline: %#lx: thp split failed\n", page_to_pfn(page));
+- put_hwpoison_page(hpage);
++ put_hwpoison_page(page);
+ return -EBUSY;
+ }
+- unlock_page(hpage);
+- get_hwpoison_page(page);
+- put_hwpoison_page(hpage);
++ unlock_page(page);
+ }
+
+ /*
--- /dev/null
+From fc8efd2ddfed3f343c11b693e87140ff358d7ff5 Mon Sep 17 00:00:00 2001
+From: Jan Stancek <jstancek@redhat.com>
+Date: Tue, 5 Mar 2019 15:50:08 -0800
+Subject: mm/memory.c: do_fault: avoid usage of stale vm_area_struct
+
+From: Jan Stancek <jstancek@redhat.com>
+
+commit fc8efd2ddfed3f343c11b693e87140ff358d7ff5 upstream.
+
+LTP testcase mtest06 [1] can trigger a crash on s390x running 5.0.0-rc8.
+This is a stress test, where one thread mmaps/writes/munmaps memory area
+and other thread is trying to read from it:
+
+ CPU: 0 PID: 2611 Comm: mmap1 Not tainted 5.0.0-rc8+ #51
+ Hardware name: IBM 2964 N63 400 (z/VM 6.4.0)
+ Krnl PSW : 0404e00180000000 00000000001ac8d8 (__lock_acquire+0x7/0x7a8)
+ Call Trace:
+ ([<0000000000000000>] (null))
+ [<00000000001adae4>] lock_acquire+0xec/0x258
+ [<000000000080d1ac>] _raw_spin_lock_bh+0x5c/0x98
+ [<000000000012a780>] page_table_free+0x48/0x1a8
+ [<00000000002f6e54>] do_fault+0xdc/0x670
+ [<00000000002fadae>] __handle_mm_fault+0x416/0x5f0
+ [<00000000002fb138>] handle_mm_fault+0x1b0/0x320
+ [<00000000001248cc>] do_dat_exception+0x19c/0x2c8
+ [<000000000080e5ee>] pgm_check_handler+0x19e/0x200
+
+page_table_free() is called with NULL mm parameter, but because "0" is a
+valid address on s390 (see S390_lowcore), it keeps going until it
+eventually crashes in lockdep's lock_acquire. This crash is
+reproducible at least since 4.14.
+
+Problem is that "vmf->vma" used in do_fault() can become stale. Because
+mmap_sem may be released, other threads can come in, call munmap() and
+cause "vma" be returned to kmem cache, and get zeroed/re-initialized and
+re-used:
+
+handle_mm_fault |
+ __handle_mm_fault |
+ do_fault |
+ vma = vmf->vma |
+ do_read_fault |
+ __do_fault |
+ vma->vm_ops->fault(vmf); |
+ mmap_sem is released |
+ |
+ | do_munmap()
+ | remove_vma_list()
+ | remove_vma()
+ | vm_area_free()
+ | # vma is released
+ | ...
+ | # same vma is allocated
+ | # from kmem cache
+ | do_mmap()
+ | vm_area_alloc()
+ | memset(vma, 0, ...)
+ |
+ pte_free(vma->vm_mm, ...); |
+ page_table_free |
+ spin_lock_bh(&mm->context.lock);|
+ <crash> |
+
+Cache mm_struct to avoid using potentially stale "vma".
+
+[1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/mem/mtest06/mmap1.c
+
+Link: http://lkml.kernel.org/r/5b3fdf19e2a5be460a384b936f5b56e13733f1b8.1551595137.git.jstancek@redhat.com
+Signed-off-by: Jan Stancek <jstancek@redhat.com>
+Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
+Reviewed-by: Matthew Wilcox <willy@infradead.org>
+Acked-by: Rafael Aquini <aquini@redhat.com>
+Reviewed-by: Minchan Kim <minchan@kernel.org>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Huang Ying <ying.huang@intel.com>
+Cc: Souptick Joarder <jrdr.linux@gmail.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Mel Gorman <mgorman@techsingularity.net>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memory.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -3517,10 +3517,13 @@ static vm_fault_t do_shared_fault(struct
+ * but allow concurrent faults).
+ * The mmap_sem may have been released depending on flags and our
+ * return value. See filemap_fault() and __lock_page_or_retry().
++ * If mmap_sem is released, vma may become invalid (for example
++ * by other thread calling munmap()).
+ */
+ static vm_fault_t do_fault(struct vm_fault *vmf)
+ {
+ struct vm_area_struct *vma = vmf->vma;
++ struct mm_struct *vm_mm = vma->vm_mm;
+ vm_fault_t ret;
+
+ /*
+@@ -3561,7 +3564,7 @@ static vm_fault_t do_fault(struct vm_fau
+
+ /* preallocated pagetable is unused: free it */
+ if (vmf->prealloc_pte) {
+- pte_free(vma->vm_mm, vmf->prealloc_pte);
++ pte_free(vm_mm, vmf->prealloc_pte);
+ vmf->prealloc_pte = NULL;
+ }
+ return ret;
--- /dev/null
+From 401592d2e095947344e10ec0623adbcd58934dd4 Mon Sep 17 00:00:00 2001
+From: Roman Penyaev <rpenyaev@suse.de>
+Date: Tue, 5 Mar 2019 15:43:20 -0800
+Subject: mm/vmalloc: fix size check for remap_vmalloc_range_partial()
+
+From: Roman Penyaev <rpenyaev@suse.de>
+
+commit 401592d2e095947344e10ec0623adbcd58934dd4 upstream.
+
+When VM_NO_GUARD is not set area->size includes adjacent guard page,
+thus for correct size checking get_vm_area_size() should be used, but
+not area->size.
+
+This fixes possible kernel oops when userspace tries to mmap an area on
+1 page bigger than was allocated by vmalloc_user() call: the size check
+inside remap_vmalloc_range_partial() accounts non-existing guard page
+also, so check successfully passes but vmalloc_to_page() returns NULL
+(guard page does not physically exist).
+
+The following code pattern example should trigger an oops:
+
+ static int oops_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+ void *mem;
+
+ mem = vmalloc_user(4096);
+ BUG_ON(!mem);
+ /* Do not care about mem leak */
+
+ return remap_vmalloc_range(vma, mem, 0);
+ }
+
+And userspace simply mmaps size + PAGE_SIZE:
+
+ mmap(NULL, 8192, PROT_WRITE|PROT_READ, MAP_PRIVATE, fd, 0);
+
+Possible candidates for oops which do not have any explicit size
+checks:
+
+ *** drivers/media/usb/stkwebcam/stk-webcam.c:
+ v4l_stk_mmap[789] ret = remap_vmalloc_range(vma, sbuf->buffer, 0);
+
+Or the following one:
+
+ *** drivers/video/fbdev/core/fbmem.c
+ static int
+ fb_mmap(struct file *file, struct vm_area_struct * vma)
+ ...
+ res = fb->fb_mmap(info, vma);
+
+Where fb_mmap callback calls remap_vmalloc_range() directly without any
+explicit checks:
+
+ *** drivers/video/fbdev/vfb.c
+ static int vfb_mmap(struct fb_info *info,
+ struct vm_area_struct *vma)
+ {
+ return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff);
+ }
+
+Link: http://lkml.kernel.org/r/20190103145954.16942-2-rpenyaev@suse.de
+Signed-off-by: Roman Penyaev <rpenyaev@suse.de>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Cc: Joe Perches <joe@perches.com>
+Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmalloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -2248,7 +2248,7 @@ int remap_vmalloc_range_partial(struct v
+ if (!(area->flags & VM_USERMAP))
+ return -EINVAL;
+
+- if (kaddr + size > area->addr + area->size)
++ if (kaddr + size > area->addr + get_vm_area_size(area))
+ return -EINVAL;
+
+ do {
--- /dev/null
+From f4853e1c321edb48af229ad5ac85076790d34968 Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Date: Fri, 15 Feb 2019 11:42:59 +0100
+Subject: nvmem: core: don't check the return value of notifier chain call
+
+From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+
+commit f4853e1c321edb48af229ad5ac85076790d34968 upstream.
+
+blocking_notifier_call_chain() returns the value returned by the last
+registered callback. A positive return value doesn't indicate an error
+and an nvmem device should correctly register irrespective of any
+notifier callback failures. Drop the retval check.
+
+Fixes: bee1138bea15 ("nvmem: add a notifier chain")
+Cc: stable@vger.kernel.org
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/nvmem/core.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -686,9 +686,7 @@ struct nvmem_device *nvmem_register(cons
+ if (rval)
+ goto err_remove_cells;
+
+- rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
+- if (rval)
+- goto err_remove_cells;
++ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
+
+ return nvmem;
+
--- /dev/null
+From 21698fd57984cd28207d841dbdaa026d6061bceb Mon Sep 17 00:00:00 2001
+From: QiaoChong <qiaochong@loongson.cn>
+Date: Sat, 9 Feb 2019 20:59:07 +0000
+Subject: parport_pc: fix find_superio io compare code, should use equal test.
+
+From: QiaoChong <qiaochong@loongson.cn>
+
+commit 21698fd57984cd28207d841dbdaa026d6061bceb upstream.
+
+In the original code before 181bf1e815a2 the loop was continuing until
+it finds the first matching superios[i].io and p->base.
+But after 181bf1e815a2 the logic changed and the loop now returns the
+pointer to the first mismatched array element which is then used in
+get_superio_dma() and get_superio_irq() and thus returning the wrong
+value.
+Fix the condition so that it now returns the correct pointer.
+
+Fixes: 181bf1e815a2 ("parport_pc: clean up the modified while loops using for")
+Cc: Alan Cox <alan@linux.intel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: QiaoChong <qiaochong@loongson.cn>
+[rewrite the commit message]
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/parport/parport_pc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/parport/parport_pc.c
++++ b/drivers/parport/parport_pc.c
+@@ -1377,7 +1377,7 @@ static struct superio_struct *find_super
+ {
+ int i;
+ for (i = 0; i < NR_SUPERIOS; i++)
+- if (superios[i].io != p->base)
++ if (superios[i].io == p->base)
+ return &superios[i];
+ return NULL;
+ }
--- /dev/null
+From 10ecc818ea7319b5d0d2b4e1aa6a77323e776f76 Mon Sep 17 00:00:00 2001
+From: Bjorn Helgaas <bhelgaas@google.com>
+Date: Fri, 4 Jan 2019 17:59:07 -0600
+Subject: PCI/ASPM: Use LTR if already enabled by platform
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+commit 10ecc818ea7319b5d0d2b4e1aa6a77323e776f76 upstream.
+
+RussianNeuroMancer reported that the Intel 7265 wifi on a Dell Venue 11 Pro
+7140 table stopped working after wakeup from suspend and bisected the
+problem to 9ab105deb60f ("PCI/ASPM: Disable ASPM L1.2 Substate if we don't
+have LTR"). David Ward reported the same problem on a Dell Latitude 7350.
+
+After af8bb9f89838 ("PCI/ACPI: Request LTR control from platform before
+using it"), we don't enable LTR unless the platform has granted LTR control
+to us. In addition, we don't notice if the platform had already enabled
+LTR itself.
+
+After 9ab105deb60f ("PCI/ASPM: Disable ASPM L1.2 Substate if we don't have
+LTR"), we avoid using LTR if we don't think the path to the device has LTR
+enabled.
+
+The combination means that if the platform itself enables LTR but declines
+to give the OS control over LTR, we unnecessarily avoided using ASPM L1.2.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=201469
+Fixes: 9ab105deb60f ("PCI/ASPM: Disable ASPM L1.2 Substate if we don't have LTR")
+Fixes: af8bb9f89838 ("PCI/ACPI: Request LTR control from platform before using it")
+Reported-by: RussianNeuroMancer <russianneuromancer@ya.ru>
+Reported-by: David Ward <david.ward@ll.mit.edu>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+CC: stable@vger.kernel.org # v4.18+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/probe.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -2071,11 +2071,8 @@ static void pci_configure_ltr(struct pci
+ {
+ #ifdef CONFIG_PCIEASPM
+ struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
+- u32 cap;
+ struct pci_dev *bridge;
+-
+- if (!host->native_ltr)
+- return;
++ u32 cap, ctl;
+
+ if (!pci_is_pcie(dev))
+ return;
+@@ -2084,22 +2081,35 @@ static void pci_configure_ltr(struct pci
+ if (!(cap & PCI_EXP_DEVCAP2_LTR))
+ return;
+
+- /*
+- * Software must not enable LTR in an Endpoint unless the Root
+- * Complex and all intermediate Switches indicate support for LTR.
+- * PCIe r3.1, sec 6.18.
+- */
+- if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+- dev->ltr_path = 1;
+- else {
++ pcie_capability_read_dword(dev, PCI_EXP_DEVCTL2, &ctl);
++ if (ctl & PCI_EXP_DEVCTL2_LTR_EN) {
++ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
++ dev->ltr_path = 1;
++ return;
++ }
++
+ bridge = pci_upstream_bridge(dev);
+ if (bridge && bridge->ltr_path)
+ dev->ltr_path = 1;
++
++ return;
+ }
+
+- if (dev->ltr_path)
++ if (!host->native_ltr)
++ return;
++
++ /*
++ * Software must not enable LTR in an Endpoint unless the Root
++ * Complex and all intermediate Switches indicate support for LTR.
++ * PCIe r4.0, sec 6.18.
++ */
++ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
++ ((bridge = pci_upstream_bridge(dev)) &&
++ bridge->ltr_path)) {
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_LTR_EN);
++ dev->ltr_path = 1;
++ }
+ #endif
+ }
+
--- /dev/null
+From 9f08a5d896ce43380314c34ed3f264c8e6075b80 Mon Sep 17 00:00:00 2001
+From: Dongdong Liu <liudongdong3@huawei.com>
+Date: Mon, 11 Feb 2019 15:02:59 +0800
+Subject: PCI/DPC: Fix print AER status in DPC event handling
+
+From: Dongdong Liu <liudongdong3@huawei.com>
+
+commit 9f08a5d896ce43380314c34ed3f264c8e6075b80 upstream.
+
+Previously dpc_handler() called aer_get_device_error_info() without
+initializing info->severity, so aer_get_device_error_info() relied on
+uninitialized data.
+
+Add dpc_get_aer_uncorrect_severity() to read the port's AER status, mask,
+and severity registers and set info->severity.
+
+Also, clear the port's AER fatal error status bits.
+
+Fixes: 8aefa9b0d910 ("PCI/DPC: Print AER status in DPC event handling")
+Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
+[bhelgaas: changelog]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Keith Busch <keith.busch@intel.com>
+Cc: stable@vger.kernel.org # v4.19+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pcie/dpc.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/pcie/dpc.c
++++ b/drivers/pci/pcie/dpc.c
+@@ -202,6 +202,28 @@ static void dpc_process_rp_pio_error(str
+ pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status);
+ }
+
++static int dpc_get_aer_uncorrect_severity(struct pci_dev *dev,
++ struct aer_err_info *info)
++{
++ int pos = dev->aer_cap;
++ u32 status, mask, sev;
++
++ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
++ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask);
++ status &= ~mask;
++ if (!status)
++ return 0;
++
++ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev);
++ status &= sev;
++ if (status)
++ info->severity = AER_FATAL;
++ else
++ info->severity = AER_NONFATAL;
++
++ return 1;
++}
++
+ static irqreturn_t dpc_handler(int irq, void *context)
+ {
+ struct aer_err_info info;
+@@ -229,9 +251,12 @@ static irqreturn_t dpc_handler(int irq,
+ /* show RP PIO error detail information */
+ if (dpc->rp_extensions && reason == 3 && ext_reason == 0)
+ dpc_process_rp_pio_error(dpc);
+- else if (reason == 0 && aer_get_device_error_info(pdev, &info)) {
++ else if (reason == 0 &&
++ dpc_get_aer_uncorrect_severity(pdev, &info) &&
++ aer_get_device_error_info(pdev, &info)) {
+ aer_print_error(pdev, &info);
+ pci_cleanup_aer_uncorrect_error_status(pdev);
++ pci_aer_clear_fatal_status(pdev);
+ }
+
+ /* We configure DPC so it only triggers on ERR_FATAL */
--- /dev/null
+From 3afc8299f39a27b60e1519a28e18878ce878e7dd Mon Sep 17 00:00:00 2001
+From: Lucas Stach <l.stach@pengutronix.de>
+Date: Wed, 27 Feb 2019 17:52:19 +0100
+Subject: PCI: dwc: skip MSI init if MSIs have been explicitly disabled
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+commit 3afc8299f39a27b60e1519a28e18878ce878e7dd upstream.
+
+Since 7c5925afbc58 (PCI: dwc: Move MSI IRQs allocation to IRQ domains
+hierarchical API) the MSI init claims one of the controller IRQs as a
+chained IRQ line for the MSI controller. On some designs, like the i.MX6,
+this line is shared with a PCIe legacy IRQ. When the line is claimed for
+the MSI domain, any device trying to use this legacy IRQs will fail to
+request this IRQ line.
+
+As MSI and legacy IRQs are already mutually exclusive on the DWC core,
+as the core won't forward any legacy IRQs once any MSI has been enabled,
+users wishing to use legacy IRQs already need to explictly disable MSI
+support (usually via the pci=nomsi kernel commandline option). To avoid
+any issues with MSI conflicting with legacy IRQs, just skip all of the
+DWC MSI initalization, including the IRQ line claim, when MSI is disabled.
+
+Fixes: 7c5925afbc58 ("PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API")
+Tested-by: Tim Harvey <tharvey@gateworks.com>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/controller/dwc/pcie-designware-host.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -439,7 +439,7 @@ int dw_pcie_host_init(struct pcie_port *
+ if (ret)
+ pci->num_viewport = 2;
+
+- if (IS_ENABLED(CONFIG_PCI_MSI)) {
++ if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_enabled()) {
+ /*
+ * If a specific SoC driver needs to change the
+ * default number of vectors, it needs to implement
--- /dev/null
+From 59f81c35e0df840f7112cb296dde48df84a67c79 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Date: Wed, 20 Feb 2019 10:48:40 +0100
+Subject: PCI: pci-bridge-emul: Create per-bridge copy of register behavior
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+
+commit 59f81c35e0df840f7112cb296dde48df84a67c79 upstream.
+
+The behavior of the different registers of the PCI-to-PCI bridge is
+currently encoded in two global arrays, shared by all instances of
+PCI-to-PCI bridge emulation.
+
+However, we will need to tweak the behavior on a per-bridge basis, to
+accommodate for different capabilities of the platforms where this
+code is used. In preparation for this, create a per-bridge copy of the
+register behavior arrays, so that they can later be tweaked on a
+per-bridge basis.
+
+Fixes: 1f08673eef123 ("PCI: mvebu: Convert to PCI emulated bridge config space")
+Reported-by: LuÃs Mendes <luis.p.mendes@gmail.com>
+Reported-by: Leigh Brown <leigh@solinno.co.uk>
+Tested-by: Leigh Brown <leigh@solinno.co.uk>
+Tested-by: Luis Mendes <luis.p.mendes@gmail.com>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: stable@vger.kernel.org
+Cc: LuÃs Mendes <luis.p.mendes@gmail.com>
+Cc: Leigh Brown <leigh@solinno.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pci-bridge-emul.c | 80 +++++++++++++++++++++++++++---------------
+ drivers/pci/pci-bridge-emul.h | 8 +++-
+ 2 files changed, 60 insertions(+), 28 deletions(-)
+
+--- a/drivers/pci/pci-bridge-emul.c
++++ b/drivers/pci/pci-bridge-emul.c
+@@ -24,29 +24,6 @@
+ #define PCI_CAP_PCIE_START PCI_BRIDGE_CONF_END
+ #define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2)
+
+-/*
+- * Initialize a pci_bridge_emul structure to represent a fake PCI
+- * bridge configuration space. The caller needs to have initialized
+- * the PCI configuration space with whatever values make sense
+- * (typically at least vendor, device, revision), the ->ops pointer,
+- * and optionally ->data and ->has_pcie.
+- */
+-void pci_bridge_emul_init(struct pci_bridge_emul *bridge)
+-{
+- bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16;
+- bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
+- bridge->conf.cache_line_size = 0x10;
+- bridge->conf.status = PCI_STATUS_CAP_LIST;
+-
+- if (bridge->has_pcie) {
+- bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
+- bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
+- /* Set PCIe v2, root port, slot support */
+- bridge->pcie_conf.cap = PCI_EXP_TYPE_ROOT_PORT << 4 | 2 |
+- PCI_EXP_FLAGS_SLOT;
+- }
+-}
+-
+ struct pci_bridge_reg_behavior {
+ /* Read-only bits */
+ u32 ro;
+@@ -284,6 +261,55 @@ const static struct pci_bridge_reg_behav
+ };
+
+ /*
++ * Initialize a pci_bridge_emul structure to represent a fake PCI
++ * bridge configuration space. The caller needs to have initialized
++ * the PCI configuration space with whatever values make sense
++ * (typically at least vendor, device, revision), the ->ops pointer,
++ * and optionally ->data and ->has_pcie.
++ */
++int pci_bridge_emul_init(struct pci_bridge_emul *bridge)
++{
++ bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16;
++ bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
++ bridge->conf.cache_line_size = 0x10;
++ bridge->conf.status = PCI_STATUS_CAP_LIST;
++ bridge->pci_regs_behavior = kmemdup(pci_regs_behavior,
++ sizeof(pci_regs_behavior),
++ GFP_KERNEL);
++ if (!bridge->pci_regs_behavior)
++ return -ENOMEM;
++
++ if (bridge->has_pcie) {
++ bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
++ bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
++ /* Set PCIe v2, root port, slot support */
++ bridge->pcie_conf.cap = PCI_EXP_TYPE_ROOT_PORT << 4 | 2 |
++ PCI_EXP_FLAGS_SLOT;
++ bridge->pcie_cap_regs_behavior =
++ kmemdup(pcie_cap_regs_behavior,
++ sizeof(pcie_cap_regs_behavior),
++ GFP_KERNEL);
++ if (!bridge->pcie_cap_regs_behavior) {
++ kfree(bridge->pci_regs_behavior);
++ return -ENOMEM;
++ }
++ }
++
++ return 0;
++}
++
++/*
++ * Cleanup a pci_bridge_emul structure that was previously initilized
++ * using pci_bridge_emul_init().
++ */
++void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge)
++{
++ if (bridge->has_pcie)
++ kfree(bridge->pcie_cap_regs_behavior);
++ kfree(bridge->pci_regs_behavior);
++}
++
++/*
+ * Should be called by the PCI controller driver when reading the PCI
+ * configuration space of the fake bridge. It will call back the
+ * ->ops->read_base or ->ops->read_pcie operations.
+@@ -312,11 +338,11 @@ int pci_bridge_emul_conf_read(struct pci
+ reg -= PCI_CAP_PCIE_START;
+ read_op = bridge->ops->read_pcie;
+ cfgspace = (u32 *) &bridge->pcie_conf;
+- behavior = pcie_cap_regs_behavior;
++ behavior = bridge->pcie_cap_regs_behavior;
+ } else {
+ read_op = bridge->ops->read_base;
+ cfgspace = (u32 *) &bridge->conf;
+- behavior = pci_regs_behavior;
++ behavior = bridge->pci_regs_behavior;
+ }
+
+ if (read_op)
+@@ -383,11 +409,11 @@ int pci_bridge_emul_conf_write(struct pc
+ reg -= PCI_CAP_PCIE_START;
+ write_op = bridge->ops->write_pcie;
+ cfgspace = (u32 *) &bridge->pcie_conf;
+- behavior = pcie_cap_regs_behavior;
++ behavior = bridge->pcie_cap_regs_behavior;
+ } else {
+ write_op = bridge->ops->write_base;
+ cfgspace = (u32 *) &bridge->conf;
+- behavior = pci_regs_behavior;
++ behavior = bridge->pci_regs_behavior;
+ }
+
+ /* Keep all bits, except the RW bits */
+--- a/drivers/pci/pci-bridge-emul.h
++++ b/drivers/pci/pci-bridge-emul.h
+@@ -107,15 +107,21 @@ struct pci_bridge_emul_ops {
+ u32 old, u32 new, u32 mask);
+ };
+
++struct pci_bridge_reg_behavior;
++
+ struct pci_bridge_emul {
+ struct pci_bridge_emul_conf conf;
+ struct pci_bridge_emul_pcie_conf pcie_conf;
+ struct pci_bridge_emul_ops *ops;
++ struct pci_bridge_reg_behavior *pci_regs_behavior;
++ struct pci_bridge_reg_behavior *pcie_cap_regs_behavior;
+ void *data;
+ bool has_pcie;
+ };
+
+-void pci_bridge_emul_init(struct pci_bridge_emul *bridge);
++int pci_bridge_emul_init(struct pci_bridge_emul *bridge);
++void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge);
++
+ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
+ int size, u32 *value);
+ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
--- /dev/null
+From 33776d059630e5045ea9ccf756c74de8f9cc86de Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Date: Wed, 20 Feb 2019 10:48:41 +0100
+Subject: PCI: pci-bridge-emul: Extend pci_bridge_emul_init() with flags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+
+commit 33776d059630e5045ea9ccf756c74de8f9cc86de upstream.
+
+Depending on the capabilities of the PCI controller/platform, the
+PCI-to-PCI bridge emulation behavior might need to be different. For
+example, on platforms that use the pci-mvebu code, we currently don't
+support prefetchable memory BARs, so the corresponding fields in the
+PCI-to-PCI bridge configuration space should be read-only.
+
+To implement this, extend pci_bridge_emul_init() to take a "flags"
+argument, with currently one flag supported:
+
+PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR
+
+that will make the prefetchable memory base and limit registers
+read-only.
+
+The pci-mvebu and pci-aardvark drivers are updated accordingly.
+
+Fixes: 1f08673eef123 ("PCI: mvebu: Convert to PCI emulated bridge config space")
+Reported-by: LuÃs Mendes <luis.p.mendes@gmail.com>
+Reported-by: Leigh Brown <leigh@solinno.co.uk>
+Tested-by: Leigh Brown <leigh@solinno.co.uk>
+Tested-by: Luis Mendes <luis.p.mendes@gmail.com>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: stable@vger.kernel.org
+Cc: LuÃs Mendes <luis.p.mendes@gmail.com>
+Cc: Leigh Brown <leigh@solinno.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/controller/pci-aardvark.c | 2 +-
+ drivers/pci/controller/pci-mvebu.c | 2 +-
+ drivers/pci/pci-bridge-emul.c | 8 +++++++-
+ drivers/pci/pci-bridge-emul.h | 7 ++++++-
+ 4 files changed, 15 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -499,7 +499,7 @@ static void advk_sw_pci_bridge_init(stru
+ bridge->data = pcie;
+ bridge->ops = &advk_pci_bridge_emul_ops;
+
+- pci_bridge_emul_init(bridge);
++ pci_bridge_emul_init(bridge, 0);
+
+ }
+
+--- a/drivers/pci/controller/pci-mvebu.c
++++ b/drivers/pci/controller/pci-mvebu.c
+@@ -583,7 +583,7 @@ static void mvebu_pci_bridge_emul_init(s
+ bridge->data = port;
+ bridge->ops = &mvebu_pci_bridge_emul_ops;
+
+- pci_bridge_emul_init(bridge);
++ pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR);
+ }
+
+ static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
+--- a/drivers/pci/pci-bridge-emul.c
++++ b/drivers/pci/pci-bridge-emul.c
+@@ -267,7 +267,8 @@ const static struct pci_bridge_reg_behav
+ * (typically at least vendor, device, revision), the ->ops pointer,
+ * and optionally ->data and ->has_pcie.
+ */
+-int pci_bridge_emul_init(struct pci_bridge_emul *bridge)
++int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
++ unsigned int flags)
+ {
+ bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16;
+ bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
+@@ -295,6 +296,11 @@ int pci_bridge_emul_init(struct pci_brid
+ }
+ }
+
++ if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) {
++ bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0;
++ bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0;
++ }
++
+ return 0;
+ }
+
+--- a/drivers/pci/pci-bridge-emul.h
++++ b/drivers/pci/pci-bridge-emul.h
+@@ -119,7 +119,12 @@ struct pci_bridge_emul {
+ bool has_pcie;
+ };
+
+-int pci_bridge_emul_init(struct pci_bridge_emul *bridge);
++enum {
++ PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0),
++};
++
++int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
++ unsigned int flags);
+ void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge);
+
+ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
--- /dev/null
+From bbe54ea5330d828cc396d451c0e1e5c3f9764c1e Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Thu, 31 Jan 2019 20:07:46 +0300
+Subject: PCI: pciehp: Disable Data Link Layer State Changed event on suspend
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit bbe54ea5330d828cc396d451c0e1e5c3f9764c1e upstream.
+
+Commit 0e157e528604 ("PCI/PME: Implement runtime PM callbacks") tried to
+solve an issue where the hierarchy immediately wakes up when it is
+transitioned into D3cold. However, it turns out to prevent PME
+propagation on some systems that do not support D3cold.
+
+I looked more closely at what might cause the immediate wakeup. It happens
+when the ACPI power resource of the root port is turned off. The AML code
+associated with the _OFF() method of the ACPI power resource starts a PCIe
+L2/L3 Ready transition and waits for it to complete. Right after the L2/L3
+Ready transition is started the root port receives a PME from the
+downstream port.
+
+The simplest hierarchy where this happens looks like this:
+
+ 00:1d.0 PCIe Root Port
+ ^
+ |
+ v
+ 05:00.0 PCIe switch #1 upstream port
+ 06:01.0 PCIe switch #1 downstream hotplug port
+ ^
+ |
+ v
+ 08:00.0 PCIe switch #2 upstream port
+
+It seems that the PCIe link between the two switches, before
+PME_Turn_Off/PME_TO_Ack is complete for the whole hierarchy, goes
+inactive and triggers PME towards the root port bringing it back to D0.
+The L2/L3 Ready sequence is described in PCIe r4.0 spec sections 5.2 and
+5.3.3 but unfortunately they do not state what happens if DLLSCE is
+enabled during the sequence.
+
+Disabling Data Link Layer State Changed event (DLLSCE) seems to prevent
+the issue and still allows the downstream hotplug port to notice when a
+device is plugged/unplugged.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=202593
+Fixes: 0e157e528604 ("PCI/PME: Implement runtime PM callbacks")
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+CC: stable@vger.kernel.org # v4.20+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/hotplug/pciehp_hpc.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -736,12 +736,25 @@ void pcie_clear_hotplug_events(struct co
+
+ void pcie_enable_interrupt(struct controller *ctrl)
+ {
+- pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_HPIE, PCI_EXP_SLTCTL_HPIE);
++ u16 mask;
++
++ mask = PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE;
++ pcie_write_cmd(ctrl, mask, mask);
+ }
+
+ void pcie_disable_interrupt(struct controller *ctrl)
+ {
+- pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_HPIE);
++ u16 mask;
++
++ /*
++ * Mask hot-plug interrupt to prevent it triggering immediately
++ * when the link goes inactive (we still get PME when any of the
++ * enabled events is detected). Same goes with Link Layer State
++ * changed event which generates PME immediately when the link goes
++ * inactive so mask it as well.
++ */
++ mask = PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE;
++ pcie_write_cmd(ctrl, 0, mask);
+ }
+
+ /*
--- /dev/null
+From 02b485e31d98265189b91f3e69c43df2ed50610c Mon Sep 17 00:00:00 2001
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+Date: Fri, 25 Jan 2019 15:26:16 -0800
+Subject: PCI: qcom: Don't deassert reset GPIO during probe
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+commit 02b485e31d98265189b91f3e69c43df2ed50610c upstream.
+
+Acquiring the reset GPIO low means that reset is being deasserted, this
+is followed almost immediately with qcom_pcie_host_init() asserting it,
+initializing it and then finally deasserting it again, for the link to
+come up.
+
+Some PCIe devices requires a minimum time between the initial deassert
+and subsequent reset cycles. In a platform that boots with the reset
+GPIO asserted this requirement is being violated by this deassert/assert
+pulse.
+
+Acquire the reset GPIO high to prevent this situation by matching the
+state to the subsequent asserted state.
+
+Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+[lorenzo.pieralisi@arm.com: updated commit log]
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1228,7 +1228,7 @@ static int qcom_pcie_probe(struct platfo
+
+ pcie->ops = of_device_get_match_data(dev);
+
+- pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
++ pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH);
+ if (IS_ERR(pcie->reset)) {
+ ret = PTR_ERR(pcie->reset);
+ goto err_pm_runtime_put;
btrfs-init-csum_list-before-possible-free.patch
btrfs-fix-corruption-reading-shared-and-compressed-extents-after-hole-punching.patch
btrfs-fix-deadlock-between-clone-dedupe-and-rename.patch
+soc-qcom-rpmh-avoid-accessing-freed-memory-from-batch-api.patch
+libertas_tf-don-t-set-urb_zero_packet-on-in-usb-transfer.patch
+irqchip-gic-v3-its-avoid-parsing-_indirect_-twice-for-device-table.patch
+irqchip-brcmstb-l2-use-_irqsave-locking-variants-in-non-interrupt-code.patch
+x86-kprobes-prohibit-probing-on-optprobe-template-code.patch
+cpufreq-kryo-release-opp-tables-on-module-removal.patch
+cpufreq-tegra124-add-missing-of_node_put.patch
+cpufreq-pxa2xx-remove-incorrect-__init-annotation.patch
+ext4-fix-check-of-inode-in-swap_inode_boot_loader.patch
+ext4-cleanup-pagecache-before-swap-i_data.patch
+mm-hwpoison-fix-thp-split-handing-in-soft_offline_in_use_page.patch
+mm-vmalloc-fix-size-check-for-remap_vmalloc_range_partial.patch
+mm-memory.c-do_fault-avoid-usage-of-stale-vm_area_struct.patch
+kernel-sysctl.c-add-missing-range-check-in-do_proc_dointvec_minmax_conv.patch
+nvmem-core-don-t-check-the-return-value-of-notifier-chain-call.patch
+device-property-fix-the-length-used-in-property_entry_string.patch
+intel_th-don-t-reference-unassigned-outputs.patch
+parport_pc-fix-find_superio-io-compare-code-should-use-equal-test.patch
+i2c-tegra-fix-maximum-transfer-size.patch
+i2c-tegra-update-maximum-transfer-size.patch
+media-i2c-ov5640-fix-post-reset-delay.patch
+gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch
+ext4-update-quota-information-while-swapping-boot-loader-inode.patch
+ext4-add-mask-of-ext4-flags-to-swap.patch
+ext4-fix-crash-during-online-resizing.patch
+dma-introduce-dma_max_mapping_size.patch
+swiotlb-introduce-swiotlb_max_mapping_size.patch
+swiotlb-add-is_swiotlb_active-function.patch
+pci-aspm-use-ltr-if-already-enabled-by-platform.patch
+pci-dpc-fix-print-aer-status-in-dpc-event-handling.patch
+pci-qcom-don-t-deassert-reset-gpio-during-probe.patch
+pci-dwc-skip-msi-init-if-msis-have-been-explicitly-disabled.patch
+pci-pciehp-disable-data-link-layer-state-changed-event-on-suspend.patch
+pci-pci-bridge-emul-create-per-bridge-copy-of-register-behavior.patch
+pci-pci-bridge-emul-extend-pci_bridge_emul_init-with-flags.patch
+ib-hfi1-close-race-condition-on-user-context-disable-and-close.patch
+ib-rdmavt-fix-loopback-send-with-invalidate-ordering.patch
+ib-rdmavt-fix-concurrency-panics-in-qp-post_send-and-modify-to-error.patch
+cxl-wrap-iterations-over-afu-slices-inside-afu_list_lock.patch
+ext2-fix-underflow-in-ext2_max_size.patch
+clk-uniphier-fix-update-register-for-cpu-gear.patch
+clk-clk-twl6040-fix-imprecise-external-abort-for-pdmclk.patch
+clk-samsung-exynos5-fix-possible-null-pointer-exception-on-platform_device_alloc-failure.patch
+clk-samsung-exynos5-fix-kfree-of-const-memory-on-setting-driver_override.patch
+clk-ingenic-fix-round_rate-misbehaving-with-non-integer-dividers.patch
+clk-ingenic-fix-doc-of-ingenic_cgu_div_info.patch
+usb-chipidea-tegra-fix-missed-ci_hdrc_remove_device.patch
+usb-typec-tps6598x-handle-block-writes-separately-with-plain-i2c-adapters.patch
+dmaengine-usb-dmac-make-dmac-system-sleep-callbacks-explicit.patch
--- /dev/null
+From baef1c90aac7e5bf13f0360a3b334825a23d31a1 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <swboyd@chromium.org>
+Date: Tue, 15 Jan 2019 14:54:47 -0800
+Subject: soc: qcom: rpmh: Avoid accessing freed memory from batch API
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+commit baef1c90aac7e5bf13f0360a3b334825a23d31a1 upstream.
+
+Using the batch API from the interconnect driver sometimes leads to a
+KASAN error due to an access to freed memory. This is easier to trigger
+with threadirqs on the kernel commandline.
+
+ BUG: KASAN: use-after-free in rpmh_tx_done+0x114/0x12c
+ Read of size 1 at addr fffffff51414ad84 by task irq/110-apps_rs/57
+
+ CPU: 0 PID: 57 Comm: irq/110-apps_rs Tainted: G W 4.19.10 #72
+ Call trace:
+ dump_backtrace+0x0/0x2f8
+ show_stack+0x20/0x2c
+ __dump_stack+0x20/0x28
+ dump_stack+0xcc/0x10c
+ print_address_description+0x74/0x240
+ kasan_report+0x250/0x26c
+ __asan_report_load1_noabort+0x20/0x2c
+ rpmh_tx_done+0x114/0x12c
+ tcs_tx_done+0x450/0x768
+ irq_forced_thread_fn+0x58/0x9c
+ irq_thread+0x120/0x1dc
+ kthread+0x248/0x260
+ ret_from_fork+0x10/0x18
+
+ Allocated by task 385:
+ kasan_kmalloc+0xac/0x148
+ __kmalloc+0x170/0x1e4
+ rpmh_write_batch+0x174/0x540
+ qcom_icc_set+0x8dc/0x9ac
+ icc_set+0x288/0x2e8
+ a6xx_gmu_stop+0x320/0x3c0
+ a6xx_pm_suspend+0x108/0x124
+ adreno_suspend+0x50/0x60
+ pm_generic_runtime_suspend+0x60/0x78
+ __rpm_callback+0x214/0x32c
+ rpm_callback+0x54/0x184
+ rpm_suspend+0x3f8/0xa90
+ pm_runtime_work+0xb4/0x178
+ process_one_work+0x544/0xbc0
+ worker_thread+0x514/0x7d0
+ kthread+0x248/0x260
+ ret_from_fork+0x10/0x18
+
+ Freed by task 385:
+ __kasan_slab_free+0x12c/0x1e0
+ kasan_slab_free+0x10/0x1c
+ kfree+0x134/0x588
+ rpmh_write_batch+0x49c/0x540
+ qcom_icc_set+0x8dc/0x9ac
+ icc_set+0x288/0x2e8
+ a6xx_gmu_stop+0x320/0x3c0
+ a6xx_pm_suspend+0x108/0x124
+ adreno_suspend+0x50/0x60
+ cr50_spi spi5.0: SPI transfer timed out
+ pm_generic_runtime_suspend+0x60/0x78
+ __rpm_callback+0x214/0x32c
+ rpm_callback+0x54/0x184
+ rpm_suspend+0x3f8/0xa90
+ pm_runtime_work+0xb4/0x178
+ process_one_work+0x544/0xbc0
+ worker_thread+0x514/0x7d0
+ kthread+0x248/0x260
+ ret_from_fork+0x10/0x18
+
+ The buggy address belongs to the object at fffffff51414ac80
+ which belongs to the cache kmalloc-512 of size 512
+ The buggy address is located 260 bytes inside of
+ 512-byte region [fffffff51414ac80, fffffff51414ae80)
+ The buggy address belongs to the page:
+ page:ffffffbfd4505200 count:1 mapcount:0 mapping:fffffff51e00c680 index:0x0 compound_mapcount: 0
+ flags: 0x4000000000008100(slab|head)
+ raw: 4000000000008100 ffffffbfd4529008 ffffffbfd44f9208 fffffff51e00c680
+ raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
+ page dumped because: kasan: bad access detected
+
+ Memory state around the buggy address:
+ fffffff51414ac80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ fffffff51414ad00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ >fffffff51414ad80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ^
+ fffffff51414ae00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ fffffff51414ae80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+
+The batch API sets the same completion for each rpmh message that's sent
+and then loops through all the messages and waits for that single
+completion declared on the stack to be completed before returning from
+the function and freeing the message structures. Unfortunately, some
+messages may still be in process and 'stuck' in the TCS. At some later
+point, the tcs_tx_done() interrupt will run and try to process messages
+that have already been freed at the end of rpmh_write_batch(). This will
+in turn access the 'needs_free' member of the rpmh_request structure and
+cause KASAN to complain. Furthermore, if there's a message that's
+completed in rpmh_tx_done() and freed immediately after the complete()
+call is made we'll be racing with potentially freed memory when
+accessing the 'needs_free' member:
+
+ CPU0 CPU1
+ ---- ----
+ rpmh_tx_done()
+ complete(&compl)
+ wait_for_completion(&compl)
+ kfree(rpm_msg)
+ if (rpm_msg->needs_free)
+ <KASAN warning splat>
+
+Let's fix this by allocating a chunk of completions for each message and
+waiting for all of them to be completed before returning from the batch
+API. Alternatively, we could wait for the last message in the batch, but
+that may be a more complicated change because it looks like
+tcs_tx_done() just iterates through the indices of the queue and
+completes each message instead of tracking the last inserted message and
+completing that first.
+
+Fixes: c8790cb6da58 ("drivers: qcom: rpmh: add support for batch RPMH request")
+Cc: Lina Iyer <ilina@codeaurora.org>
+Cc: "Raju P.L.S.S.S.N" <rplsssn@codeaurora.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Cc: Evan Green <evgreen@chromium.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Lina Iyer <ilina@codeaurora.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Andy Gross <andy.gross@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/soc/qcom/rpmh.c | 34 +++++++++++++++++++++-------------
+ 1 file changed, 21 insertions(+), 13 deletions(-)
+
+--- a/drivers/soc/qcom/rpmh.c
++++ b/drivers/soc/qcom/rpmh.c
+@@ -80,6 +80,7 @@ void rpmh_tx_done(const struct tcs_reque
+ struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
+ msg);
+ struct completion *compl = rpm_msg->completion;
++ bool free = rpm_msg->needs_free;
+
+ rpm_msg->err = r;
+
+@@ -94,7 +95,7 @@ void rpmh_tx_done(const struct tcs_reque
+ complete(compl);
+
+ exit:
+- if (rpm_msg->needs_free)
++ if (free)
+ kfree(rpm_msg);
+ }
+
+@@ -348,11 +349,12 @@ int rpmh_write_batch(const struct device
+ {
+ struct batch_cache_req *req;
+ struct rpmh_request *rpm_msgs;
+- DECLARE_COMPLETION_ONSTACK(compl);
++ struct completion *compls;
+ struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
+ unsigned long time_left;
+ int count = 0;
+- int ret, i, j;
++ int ret, i;
++ void *ptr;
+
+ if (!cmd || !n)
+ return -EINVAL;
+@@ -362,10 +364,15 @@ int rpmh_write_batch(const struct device
+ if (!count)
+ return -EINVAL;
+
+- req = kzalloc(sizeof(*req) + count * sizeof(req->rpm_msgs[0]),
++ ptr = kzalloc(sizeof(*req) +
++ count * (sizeof(req->rpm_msgs[0]) + sizeof(*compls)),
+ GFP_ATOMIC);
+- if (!req)
++ if (!ptr)
+ return -ENOMEM;
++
++ req = ptr;
++ compls = ptr + sizeof(*req) + count * sizeof(*rpm_msgs);
++
+ req->count = count;
+ rpm_msgs = req->rpm_msgs;
+
+@@ -380,25 +387,26 @@ int rpmh_write_batch(const struct device
+ }
+
+ for (i = 0; i < count; i++) {
+- rpm_msgs[i].completion = &compl;
++ struct completion *compl = &compls[i];
++
++ init_completion(compl);
++ rpm_msgs[i].completion = compl;
+ ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg);
+ if (ret) {
+ pr_err("Error(%d) sending RPMH message addr=%#x\n",
+ ret, rpm_msgs[i].msg.cmds[0].addr);
+- for (j = i; j < count; j++)
+- rpmh_tx_done(&rpm_msgs[j].msg, ret);
+ break;
+ }
+ }
+
+ time_left = RPMH_TIMEOUT_MS;
+- for (i = 0; i < count; i++) {
+- time_left = wait_for_completion_timeout(&compl, time_left);
++ while (i--) {
++ time_left = wait_for_completion_timeout(&compls[i], time_left);
+ if (!time_left) {
+ /*
+ * Better hope they never finish because they'll signal
+- * the completion on our stack and that's bad once
+- * we've returned from the function.
++ * the completion that we're going to free once
++ * we've returned from this function.
+ */
+ WARN_ON(1);
+ ret = -ETIMEDOUT;
+@@ -407,7 +415,7 @@ int rpmh_write_batch(const struct device
+ }
+
+ exit:
+- kfree(req);
++ kfree(ptr);
+
+ return ret;
+ }
--- /dev/null
+From 492366f7b4237257ef50ca9c431a6a0d50225aca Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Thu, 7 Feb 2019 12:59:14 +0100
+Subject: swiotlb: Add is_swiotlb_active() function
+
+From: Joerg Roedel <jroedel@suse.de>
+
+commit 492366f7b4237257ef50ca9c431a6a0d50225aca upstream.
+
+This function will be used from dma_direct code to determine
+the maximum segment size of a dma mapping.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/swiotlb.h | 6 ++++++
+ kernel/dma/swiotlb.c | 9 +++++++++
+ 2 files changed, 15 insertions(+)
+
+--- a/include/linux/swiotlb.h
++++ b/include/linux/swiotlb.h
+@@ -77,6 +77,7 @@ bool swiotlb_map(struct device *dev, phy
+ void __init swiotlb_exit(void);
+ unsigned int swiotlb_max_segment(void);
+ size_t swiotlb_max_mapping_size(struct device *dev);
++bool is_swiotlb_active(void);
+ #else
+ #define swiotlb_force SWIOTLB_NO_FORCE
+ static inline bool is_swiotlb_buffer(phys_addr_t paddr)
+@@ -100,6 +101,11 @@ static inline size_t swiotlb_max_mapping
+ {
+ return SIZE_MAX;
+ }
++
++static inline bool is_swiotlb_active(void)
++{
++ return false;
++}
+ #endif /* CONFIG_SWIOTLB */
+
+ extern void swiotlb_print_info(void);
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -667,3 +667,12 @@ size_t swiotlb_max_mapping_size(struct d
+ {
+ return ((size_t)1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE;
+ }
++
++bool is_swiotlb_active(void)
++{
++ /*
++ * When SWIOTLB is initialized, even if io_tlb_start points to physical
++ * address zero, io_tlb_end surely doesn't.
++ */
++ return io_tlb_end != 0;
++}
--- /dev/null
+From abe420bfae528c92bd8cc5ecb62dc95672b1fd6f Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Thu, 7 Feb 2019 12:59:13 +0100
+Subject: swiotlb: Introduce swiotlb_max_mapping_size()
+
+From: Joerg Roedel <jroedel@suse.de>
+
+commit abe420bfae528c92bd8cc5ecb62dc95672b1fd6f upstream.
+
+The function returns the maximum size that can be remapped
+by the SWIOTLB implementation. This function will be later
+exposed to users through the DMA-API.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/swiotlb.h | 5 +++++
+ kernel/dma/swiotlb.c | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+--- a/include/linux/swiotlb.h
++++ b/include/linux/swiotlb.h
+@@ -76,6 +76,7 @@ bool swiotlb_map(struct device *dev, phy
+ size_t size, enum dma_data_direction dir, unsigned long attrs);
+ void __init swiotlb_exit(void);
+ unsigned int swiotlb_max_segment(void);
++size_t swiotlb_max_mapping_size(struct device *dev);
+ #else
+ #define swiotlb_force SWIOTLB_NO_FORCE
+ static inline bool is_swiotlb_buffer(phys_addr_t paddr)
+@@ -95,6 +96,10 @@ static inline unsigned int swiotlb_max_s
+ {
+ return 0;
+ }
++static inline size_t swiotlb_max_mapping_size(struct device *dev)
++{
++ return SIZE_MAX;
++}
+ #endif /* CONFIG_SWIOTLB */
+
+ extern void swiotlb_print_info(void);
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -662,3 +662,8 @@ swiotlb_dma_supported(struct device *hwd
+ {
+ return __phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
+ }
++
++size_t swiotlb_max_mapping_size(struct device *dev)
++{
++ return ((size_t)1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE;
++}
--- /dev/null
+From 563b9372f7ec57e44e8f9a8600c5107d7ffdd166 Mon Sep 17 00:00:00 2001
+From: Dmitry Osipenko <digetx@gmail.com>
+Date: Sun, 24 Feb 2019 18:36:22 +0300
+Subject: usb: chipidea: tegra: Fix missed ci_hdrc_remove_device()
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+commit 563b9372f7ec57e44e8f9a8600c5107d7ffdd166 upstream.
+
+The ChipIdea's platform device need to be unregistered on Tegra's driver
+module removal.
+
+Fixes: dfebb5f43a78827a ("usb: chipidea: Add support for Tegra20/30/114/124")
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Acked-by: Peter Chen <peter.chen@nxp.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/ci_hdrc_tegra.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/chipidea/ci_hdrc_tegra.c
++++ b/drivers/usb/chipidea/ci_hdrc_tegra.c
+@@ -130,6 +130,7 @@ static int tegra_udc_remove(struct platf
+ {
+ struct tegra_udc *udc = platform_get_drvdata(pdev);
+
++ ci_hdrc_remove_device(udc->dev);
+ usb_phy_set_suspend(udc->phy, 1);
+ clk_disable_unprepare(udc->clk);
+
--- /dev/null
+From 8a863a608d47fa5d9dd15cf841817f73f804cf91 Mon Sep 17 00:00:00 2001
+From: Nikolaus Voss <nikolaus.voss@loewensteinmedical.de>
+Date: Wed, 20 Feb 2019 16:11:38 +0100
+Subject: usb: typec: tps6598x: handle block writes separately with plain-I2C adapters
+
+From: Nikolaus Voss <nikolaus.voss@loewensteinmedical.de>
+
+commit 8a863a608d47fa5d9dd15cf841817f73f804cf91 upstream.
+
+Commit 1a2f474d328f handles block _reads_ separately with plain-I2C
+adapters, but the problem described with regmap-i2c not handling
+SMBus block transfers (i.e. read and writes) correctly also exists
+with writes.
+
+As workaround, this patch adds a block write function the same way
+1a2f474d328f adds a block read function.
+
+Fixes: 1a2f474d328f ("usb: typec: tps6598x: handle block reads separately with plain-I2C adapters")
+Fixes: 0a4c005bd171 ("usb: typec: driver for TI TPS6598x USB Power Delivery controllers")
+Signed-off-by: Nikolaus Voss <nikolaus.voss@loewensteinmedical.de>
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/tps6598x.c | 26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/typec/tps6598x.c
++++ b/drivers/usb/typec/tps6598x.c
+@@ -110,6 +110,20 @@ tps6598x_block_read(struct tps6598x *tps
+ return 0;
+ }
+
++static int tps6598x_block_write(struct tps6598x *tps, u8 reg,
++ void *val, size_t len)
++{
++ u8 data[TPS_MAX_LEN + 1];
++
++ if (!tps->i2c_protocol)
++ return regmap_raw_write(tps->regmap, reg, val, len);
++
++ data[0] = len;
++ memcpy(&data[1], val, len);
++
++ return regmap_raw_write(tps->regmap, reg, data, sizeof(data));
++}
++
+ static inline int tps6598x_read16(struct tps6598x *tps, u8 reg, u16 *val)
+ {
+ return tps6598x_block_read(tps, reg, val, sizeof(u16));
+@@ -127,23 +141,23 @@ static inline int tps6598x_read64(struct
+
+ static inline int tps6598x_write16(struct tps6598x *tps, u8 reg, u16 val)
+ {
+- return regmap_raw_write(tps->regmap, reg, &val, sizeof(u16));
++ return tps6598x_block_write(tps, reg, &val, sizeof(u16));
+ }
+
+ static inline int tps6598x_write32(struct tps6598x *tps, u8 reg, u32 val)
+ {
+- return regmap_raw_write(tps->regmap, reg, &val, sizeof(u32));
++ return tps6598x_block_write(tps, reg, &val, sizeof(u32));
+ }
+
+ static inline int tps6598x_write64(struct tps6598x *tps, u8 reg, u64 val)
+ {
+- return regmap_raw_write(tps->regmap, reg, &val, sizeof(u64));
++ return tps6598x_block_write(tps, reg, &val, sizeof(u64));
+ }
+
+ static inline int
+ tps6598x_write_4cc(struct tps6598x *tps, u8 reg, const char *val)
+ {
+- return regmap_raw_write(tps->regmap, reg, &val, sizeof(u32));
++ return tps6598x_block_write(tps, reg, &val, sizeof(u32));
+ }
+
+ static int tps6598x_read_partner_identity(struct tps6598x *tps)
+@@ -229,8 +243,8 @@ static int tps6598x_exec_cmd(struct tps6
+ return -EBUSY;
+
+ if (in_len) {
+- ret = regmap_raw_write(tps->regmap, TPS_REG_DATA1,
+- in_data, in_len);
++ ret = tps6598x_block_write(tps, TPS_REG_DATA1,
++ in_data, in_len);
+ if (ret)
+ return ret;
+ }
--- /dev/null
+From 0192e6535ebe9af68614198ced4fd6d37b778ebf Mon Sep 17 00:00:00 2001
+From: Masami Hiramatsu <mhiramat@kernel.org>
+Date: Wed, 13 Feb 2019 01:11:19 +0900
+Subject: x86/kprobes: Prohibit probing on optprobe template code
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+commit 0192e6535ebe9af68614198ced4fd6d37b778ebf upstream.
+
+Prohibit probing on optprobe template code, since it is not
+a code but a template instruction sequence. If we modify
+this template, copied template must be broken.
+
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrea Righi <righi.andrea@gmail.com>
+Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Fixes: 9326638cbee2 ("kprobes, x86: Use NOKPROBE_SYMBOL() instead of __kprobes annotation")
+Link: http://lkml.kernel.org/r/154998787911.31052.15274376330136234452.stgit@devbox
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/kprobes/opt.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/x86/kernel/kprobes/opt.c
++++ b/arch/x86/kernel/kprobes/opt.c
+@@ -141,6 +141,11 @@ asm (
+
+ void optprobe_template_func(void);
+ STACK_FRAME_NON_STANDARD(optprobe_template_func);
++NOKPROBE_SYMBOL(optprobe_template_func);
++NOKPROBE_SYMBOL(optprobe_template_entry);
++NOKPROBE_SYMBOL(optprobe_template_val);
++NOKPROBE_SYMBOL(optprobe_template_call);
++NOKPROBE_SYMBOL(optprobe_template_end);
+
+ #define TMPL_MOVE_IDX \
+ ((long)optprobe_template_val - (long)optprobe_template_entry)