From: Greg Kroah-Hartman Date: Wed, 20 Mar 2019 20:27:24 +0000 (+0100) Subject: 5.0-stable patches X-Git-Tag: v3.18.137~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aeaf2bba8ae9698281b44e4794e5d58d970f420b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.0-stable patches added patches: clk-clk-twl6040-fix-imprecise-external-abort-for-pdmclk.patch clk-ingenic-fix-doc-of-ingenic_cgu_div_info.patch clk-ingenic-fix-round_rate-misbehaving-with-non-integer-dividers.patch clk-samsung-exynos5-fix-kfree-of-const-memory-on-setting-driver_override.patch clk-samsung-exynos5-fix-possible-null-pointer-exception-on-platform_device_alloc-failure.patch clk-uniphier-fix-update-register-for-cpu-gear.patch cpufreq-kryo-release-opp-tables-on-module-removal.patch cpufreq-pxa2xx-remove-incorrect-__init-annotation.patch cpufreq-tegra124-add-missing-of_node_put.patch cxl-wrap-iterations-over-afu-slices-inside-afu_list_lock.patch device-property-fix-the-length-used-in-property_entry_string.patch dma-introduce-dma_max_mapping_size.patch dmaengine-usb-dmac-make-dmac-system-sleep-callbacks-explicit.patch ext2-fix-underflow-in-ext2_max_size.patch ext4-add-mask-of-ext4-flags-to-swap.patch ext4-cleanup-pagecache-before-swap-i_data.patch ext4-fix-check-of-inode-in-swap_inode_boot_loader.patch ext4-fix-crash-during-online-resizing.patch ext4-update-quota-information-while-swapping-boot-loader-inode.patch gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch i2c-tegra-fix-maximum-transfer-size.patch i2c-tegra-update-maximum-transfer-size.patch ib-hfi1-close-race-condition-on-user-context-disable-and-close.patch ib-rdmavt-fix-concurrency-panics-in-qp-post_send-and-modify-to-error.patch ib-rdmavt-fix-loopback-send-with-invalidate-ordering.patch intel_th-don-t-reference-unassigned-outputs.patch irqchip-brcmstb-l2-use-_irqsave-locking-variants-in-non-interrupt-code.patch irqchip-gic-v3-its-avoid-parsing-_indirect_-twice-for-device-table.patch kernel-sysctl.c-add-missing-range-check-in-do_proc_dointvec_minmax_conv.patch libertas_tf-don-t-set-urb_zero_packet-on-in-usb-transfer.patch media-i2c-ov5640-fix-post-reset-delay.patch mm-hwpoison-fix-thp-split-handing-in-soft_offline_in_use_page.patch mm-memory.c-do_fault-avoid-usage-of-stale-vm_area_struct.patch mm-vmalloc-fix-size-check-for-remap_vmalloc_range_partial.patch nvmem-core-don-t-check-the-return-value-of-notifier-chain-call.patch parport_pc-fix-find_superio-io-compare-code-should-use-equal-test.patch pci-aspm-use-ltr-if-already-enabled-by-platform.patch pci-dpc-fix-print-aer-status-in-dpc-event-handling.patch pci-dwc-skip-msi-init-if-msis-have-been-explicitly-disabled.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 pci-pciehp-disable-data-link-layer-state-changed-event-on-suspend.patch pci-qcom-don-t-deassert-reset-gpio-during-probe.patch soc-qcom-rpmh-avoid-accessing-freed-memory-from-batch-api.patch swiotlb-add-is_swiotlb_active-function.patch swiotlb-introduce-swiotlb_max_mapping_size.patch usb-chipidea-tegra-fix-missed-ci_hdrc_remove_device.patch usb-typec-tps6598x-handle-block-writes-separately-with-plain-i2c-adapters.patch x86-kprobes-prohibit-probing-on-optprobe-template-code.patch --- diff --git a/queue-5.0/clk-clk-twl6040-fix-imprecise-external-abort-for-pdmclk.patch b/queue-5.0/clk-clk-twl6040-fix-imprecise-external-abort-for-pdmclk.patch new file mode 100644 index 00000000000..bde7d50025b --- /dev/null +++ b/queue-5.0/clk-clk-twl6040-fix-imprecise-external-abort-for-pdmclk.patch @@ -0,0 +1,117 @@ +From 5ae51d67aec95f6f9386aa8dd5db424964895575 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Mon, 11 Feb 2019 14:59:07 -0800 +Subject: clk: clk-twl6040: Fix imprecise external abort for pdmclk + +From: Tony Lindgren + +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 [] (_disable_clocks+0x18/0x90) +(_disable_clocks) from [] (_idle+0x17c/0x244) +(_idle) from [] (omap_hwmod_idle+0x24/0x44) +(omap_hwmod_idle) from [] (sysc_runtime_suspend+0x48/0x108) +(sysc_runtime_suspend) from [] (__rpm_callback+0x144/0x1d8) +(__rpm_callback) from [] (rpm_callback+0x20/0x80) +(rpm_callback) from [] (rpm_suspend+0x120/0x694) +(rpm_suspend) from [] (__pm_runtime_idle+0x60/0x84) +(__pm_runtime_idle) from [] (sysc_probe+0x874/0xf2c) +(sysc_probe) from [] (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 . + +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 +Cc: Peter Ujfalusi +Signed-off-by: Tony Lindgren +Acked-by: Peter Ujfalusi +Cc: +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-5.0/clk-ingenic-fix-doc-of-ingenic_cgu_div_info.patch b/queue-5.0/clk-ingenic-fix-doc-of-ingenic_cgu_div_info.patch new file mode 100644 index 00000000000..57af5e0dedb --- /dev/null +++ b/queue-5.0/clk-ingenic-fix-doc-of-ingenic_cgu_div_info.patch @@ -0,0 +1,34 @@ +From 7ca4c922aad2e3c46767a12f80d01c6b25337b59 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sun, 27 Jan 2019 23:09:21 -0300 +Subject: clk: ingenic: Fix doc of ingenic_cgu_div_info + +From: Paul Cercueil + +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 +Signed-off-by: Maarten ter Huurne +Cc: +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-5.0/clk-ingenic-fix-round_rate-misbehaving-with-non-integer-dividers.patch b/queue-5.0/clk-ingenic-fix-round_rate-misbehaving-with-non-integer-dividers.patch new file mode 100644 index 00000000000..4969e9ea8fe --- /dev/null +++ b/queue-5.0/clk-ingenic-fix-round_rate-misbehaving-with-non-integer-dividers.patch @@ -0,0 +1,63 @@ +From bc5d922c93491878c44c9216e9d227c7eeb81d7f Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sun, 27 Jan 2019 23:09:20 -0300 +Subject: clk: ingenic: Fix round_rate misbehaving with non-integer dividers + +From: Paul Cercueil + +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 +Tested-by: Maarten ter Huurne +Cc: +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-5.0/clk-samsung-exynos5-fix-kfree-of-const-memory-on-setting-driver_override.patch b/queue-5.0/clk-samsung-exynos5-fix-kfree-of-const-memory-on-setting-driver_override.patch new file mode 100644 index 00000000000..c31caa6b74a --- /dev/null +++ b/queue-5.0/clk-samsung-exynos5-fix-kfree-of-const-memory-on-setting-driver_override.patch @@ -0,0 +1,59 @@ +From 785c9f411eb2d9a6076d3511c631587d5e676bf3 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +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 + +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 [] (platform_set_driver_override+0x84/0xac) + (platform_set_driver_override) from [] (driver_override_store+0x20/0x34) + (driver_override_store) from [] (kernfs_fop_write+0x100/0x1dc) + (kernfs_fop_write) from [] (__vfs_write+0x2c/0x17c) + (__vfs_write) from [] (vfs_write+0xa4/0x188) + (vfs_write) from [] (ksys_write+0x4c/0xac) + (ksys_write) from [] (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: +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-5.0/clk-samsung-exynos5-fix-possible-null-pointer-exception-on-platform_device_alloc-failure.patch b/queue-5.0/clk-samsung-exynos5-fix-possible-null-pointer-exception-on-platform_device_alloc-failure.patch new file mode 100644 index 00000000000..5c4494daf14 --- /dev/null +++ b/queue-5.0/clk-samsung-exynos5-fix-possible-null-pointer-exception-on-platform_device_alloc-failure.patch @@ -0,0 +1,52 @@ +From 5f0b6216ea381b43c0dff88702d6cc5673d63922 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +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 + +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: +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-5.0/clk-uniphier-fix-update-register-for-cpu-gear.patch b/queue-5.0/clk-uniphier-fix-update-register-for-cpu-gear.patch new file mode 100644 index 00000000000..9a17f4806e3 --- /dev/null +++ b/queue-5.0/clk-uniphier-fix-update-register-for-cpu-gear.patch @@ -0,0 +1,34 @@ +From 521282237b9d78b9bff423ec818becd4c95841c2 Mon Sep 17 00:00:00 2001 +From: Kunihiko Hayashi +Date: Fri, 8 Feb 2019 11:25:23 +0900 +Subject: clk: uniphier: Fix update register for CPU-gear + +From: Kunihiko Hayashi + +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 +Acked-by: Masahiro Yamada +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-5.0/cpufreq-kryo-release-opp-tables-on-module-removal.patch b/queue-5.0/cpufreq-kryo-release-opp-tables-on-module-removal.patch new file mode 100644 index 00000000000..f42e1f44b6c --- /dev/null +++ b/queue-5.0/cpufreq-kryo-release-opp-tables-on-module-removal.patch @@ -0,0 +1,90 @@ +From 0334906c06967142c8805fbe88acf787f65d3d26 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Wed, 20 Feb 2019 16:41:18 +0530 +Subject: cpufreq: kryo: Release OPP tables on module removal + +From: Viresh Kumar + +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+ # v4.18+ +Fixes: 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit") +Reviewed-by: Georgi Djakov +Signed-off-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-5.0/cpufreq-pxa2xx-remove-incorrect-__init-annotation.patch b/queue-5.0/cpufreq-pxa2xx-remove-incorrect-__init-annotation.patch new file mode 100644 index 00000000000..003134a6568 --- /dev/null +++ b/queue-5.0/cpufreq-pxa2xx-remove-incorrect-__init-annotation.patch @@ -0,0 +1,53 @@ +From 9505b98ccddc454008ca7efff90044e3e857c827 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 7 Mar 2019 11:22:41 +0100 +Subject: cpufreq: pxa2xx: remove incorrect __init annotation + +From: Arnd Bergmann + +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 +Acked-by: Viresh Kumar +Reviewed-by: Nathan Chancellor +Acked-by: Robert Jarzmik +Cc: All applicable +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-5.0/cpufreq-tegra124-add-missing-of_node_put.patch b/queue-5.0/cpufreq-tegra124-add-missing-of_node_put.patch new file mode 100644 index 00000000000..27cb92fc6ee --- /dev/null +++ b/queue-5.0/cpufreq-tegra124-add-missing-of_node_put.patch @@ -0,0 +1,35 @@ +From 446fae2bb5395f3028d8e3aae1508737e5a72ea1 Mon Sep 17 00:00:00 2001 +From: Yangtao Li +Date: Mon, 4 Feb 2019 02:48:54 -0500 +Subject: cpufreq: tegra124: add missing of_node_put() + +From: Yangtao Li + +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: # 4.4+ +Signed-off-by: Yangtao Li +Acked-by: Thierry Reding +Signed-off-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman + +--- + 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: diff --git a/queue-5.0/cxl-wrap-iterations-over-afu-slices-inside-afu_list_lock.patch b/queue-5.0/cxl-wrap-iterations-over-afu-slices-inside-afu_list_lock.patch new file mode 100644 index 00000000000..94482efcd9d --- /dev/null +++ b/queue-5.0/cxl-wrap-iterations-over-afu-slices-inside-afu_list_lock.patch @@ -0,0 +1,191 @@ +From edeb304f659792fb5bab90d7d6f3408b4c7301fb Mon Sep 17 00:00:00 2001 +From: Vaibhav Jain +Date: Tue, 29 Jan 2019 16:36:18 +0530 +Subject: cxl: Wrap iterations over afu slices inside 'afu_list_lock' + +From: Vaibhav Jain + +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 +Acked-by: Frederic Barrat +Acked-by: Christophe Lombard +Signed-off-by: Vaibhav Jain +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 = { diff --git a/queue-5.0/device-property-fix-the-length-used-in-property_entry_string.patch b/queue-5.0/device-property-fix-the-length-used-in-property_entry_string.patch new file mode 100644 index 00000000000..80edd4e9088 --- /dev/null +++ b/queue-5.0/device-property-fix-the-length-used-in-property_entry_string.patch @@ -0,0 +1,41 @@ +From 2b6e492467c78183bb629bb0a100ea3509b615a5 Mon Sep 17 00:00:00 2001 +From: Heikki Krogerus +Date: Wed, 23 Jan 2019 17:44:16 +0300 +Subject: device property: Fix the length used in PROPERTY_ENTRY_STRING() + +From: Heikki Krogerus + +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+ # 4.5+ +Signed-off-by: Heikki Krogerus +Reviewed-by: Andy Shevchenko +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + 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_ } }, \ + } diff --git a/queue-5.0/dma-introduce-dma_max_mapping_size.patch b/queue-5.0/dma-introduce-dma_max_mapping_size.patch new file mode 100644 index 00000000000..7904f638786 --- /dev/null +++ b/queue-5.0/dma-introduce-dma_max_mapping_size.patch @@ -0,0 +1,120 @@ +From 133d624b1cee16906134e92d5befb843b58bcf31 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Thu, 7 Feb 2019 12:59:15 +0100 +Subject: dma: Introduce dma_max_mapping_size() + +From: Joerg Roedel + +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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Joerg Roedel +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + +@@ -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); diff --git a/queue-5.0/dmaengine-usb-dmac-make-dmac-system-sleep-callbacks-explicit.patch b/queue-5.0/dmaengine-usb-dmac-make-dmac-system-sleep-callbacks-explicit.patch new file mode 100644 index 00000000000..dcbf03adde7 --- /dev/null +++ b/queue-5.0/dmaengine-usb-dmac-make-dmac-system-sleep-callbacks-explicit.patch @@ -0,0 +1,60 @@ +From d9140a0da4a230a03426d175145989667758aa6a Mon Sep 17 00:00:00 2001 +From: Phuong Nguyen +Date: Thu, 17 Jan 2019 17:44:17 +0900 +Subject: dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit + +From: Phuong Nguyen + +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 +Signed-off-by: Hiroyuki Yokoyama +Cc: # v4.16+ +[shimoda: revise the commit log and add Cc tag] +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + 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) + }; diff --git a/queue-5.0/ext2-fix-underflow-in-ext2_max_size.patch b/queue-5.0/ext2-fix-underflow-in-ext2_max_size.patch new file mode 100644 index 00000000000..a15e2e9c518 --- /dev/null +++ b/queue-5.0/ext2-fix-underflow-in-ext2_max_size.patch @@ -0,0 +1,98 @@ +From 1c2d14212b15a60300a2d4f6364753e87394c521 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 29 Jan 2019 17:17:24 +0100 +Subject: ext2: Fix underflow in ext2_max_size() + +From: Jan Kara + +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 +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-5.0/ext4-add-mask-of-ext4-flags-to-swap.patch b/queue-5.0/ext4-add-mask-of-ext4-flags-to-swap.patch new file mode 100644 index 00000000000..00189e8f0bc --- /dev/null +++ b/queue-5.0/ext4-add-mask-of-ext4-flags-to-swap.patch @@ -0,0 +1,59 @@ +From abdc644e8cbac2e9b19763680e5a7cf9bab2bee7 Mon Sep 17 00:00:00 2001 +From: yangerkun +Date: Mon, 11 Feb 2019 00:35:06 -0500 +Subject: ext4: add mask of ext4 flags to swap + +From: yangerkun + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-5.0/ext4-cleanup-pagecache-before-swap-i_data.patch b/queue-5.0/ext4-cleanup-pagecache-before-swap-i_data.patch new file mode 100644 index 00000000000..8492c7e2bb0 --- /dev/null +++ b/queue-5.0/ext4-cleanup-pagecache-before-swap-i_data.patch @@ -0,0 +1,71 @@ +From a46c68a318b08f819047843abf349aeee5d10ac2 Mon Sep 17 00:00:00 2001 +From: yangerkun +Date: Mon, 11 Feb 2019 00:05:24 -0500 +Subject: ext4: cleanup pagecache before swap i_data + +From: yangerkun + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-5.0/ext4-fix-check-of-inode-in-swap_inode_boot_loader.patch b/queue-5.0/ext4-fix-check-of-inode-in-swap_inode_boot_loader.patch new file mode 100644 index 00000000000..497d915415f --- /dev/null +++ b/queue-5.0/ext4-fix-check-of-inode-in-swap_inode_boot_loader.patch @@ -0,0 +1,63 @@ +From 67a11611e1a5211f6569044fbf8150875764d1d0 Mon Sep 17 00:00:00 2001 +From: yangerkun +Date: Mon, 11 Feb 2019 00:02:05 -0500 +Subject: ext4: fix check of inode in swap_inode_boot_loader + +From: yangerkun + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-5.0/ext4-fix-crash-during-online-resizing.patch b/queue-5.0/ext4-fix-crash-during-online-resizing.patch new file mode 100644 index 00000000000..685715add23 --- /dev/null +++ b/queue-5.0/ext4-fix-crash-during-online-resizing.patch @@ -0,0 +1,48 @@ +From f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 11 Feb 2019 13:30:32 -0500 +Subject: ext4: fix crash during online resizing + +From: Jan Kara + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ + } + diff --git a/queue-5.0/ext4-update-quota-information-while-swapping-boot-loader-inode.patch b/queue-5.0/ext4-update-quota-information-while-swapping-boot-loader-inode.patch new file mode 100644 index 00000000000..6d3c98c3791 --- /dev/null +++ b/queue-5.0/ext4-update-quota-information-while-swapping-boot-loader-inode.patch @@ -0,0 +1,115 @@ +From aa507b5faf38784defe49f5e64605ac3c4425e26 Mon Sep 17 00:00:00 2001 +From: yangerkun +Date: Mon, 11 Feb 2019 00:14:02 -0500 +Subject: ext4: update quota information while swapping boot loader inode + +From: yangerkun + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-5.0/gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch b/queue-5.0/gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch new file mode 100644 index 00000000000..dc81c61aa9e --- /dev/null +++ b/queue-5.0/gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch @@ -0,0 +1,46 @@ +From c378b3aa015931a46c91d6ccc2fe04d97801d060 Mon Sep 17 00:00:00 2001 +From: Mark Walton +Date: Thu, 28 Feb 2019 15:46:36 +0000 +Subject: gpio: pca953x: Fix dereference of irq data in shutdown + +From: Mark Walton + +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 +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-5.0/i2c-tegra-fix-maximum-transfer-size.patch b/queue-5.0/i2c-tegra-fix-maximum-transfer-size.patch new file mode 100644 index 00000000000..34af73cc599 --- /dev/null +++ b/queue-5.0/i2c-tegra-fix-maximum-transfer-size.patch @@ -0,0 +1,37 @@ +From f4e3f4ae1d9c9330de355f432b69952e8cef650c Mon Sep 17 00:00:00 2001 +From: Sowjanya Komatineni +Date: Tue, 12 Feb 2019 11:06:44 -0800 +Subject: i2c: tegra: fix maximum transfer size + +From: Sowjanya Komatineni + +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 +Signed-off-by: Sowjanya Komatineni +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 = { diff --git a/queue-5.0/i2c-tegra-update-maximum-transfer-size.patch b/queue-5.0/i2c-tegra-update-maximum-transfer-size.patch new file mode 100644 index 00000000000..bd0e95519c1 --- /dev/null +++ b/queue-5.0/i2c-tegra-update-maximum-transfer-size.patch @@ -0,0 +1,54 @@ +From b03ff2a23359d0dd6f0a1516c6a9e9c4760ed230 Mon Sep 17 00:00:00 2001 +From: Sowjanya Komatineni +Date: Tue, 12 Feb 2019 11:06:45 -0800 +Subject: i2c: tegra: update maximum transfer size + +From: Sowjanya Komatineni + +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 +Signed-off-by: Sowjanya Komatineni +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 = { diff --git a/queue-5.0/ib-hfi1-close-race-condition-on-user-context-disable-and-close.patch b/queue-5.0/ib-hfi1-close-race-condition-on-user-context-disable-and-close.patch new file mode 100644 index 00000000000..0aa39af9cc6 --- /dev/null +++ b/queue-5.0/ib-hfi1-close-race-condition-on-user-context-disable-and-close.patch @@ -0,0 +1,142 @@ +From bc5add09764c123f58942a37c8335247e683d234 Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" +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 + +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 +Signed-off-by: Michael J. Ruhl +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-5.0/ib-rdmavt-fix-concurrency-panics-in-qp-post_send-and-modify-to-error.patch b/queue-5.0/ib-rdmavt-fix-concurrency-panics-in-qp-post_send-and-modify-to-error.patch new file mode 100644 index 00000000000..200c0ffca0e --- /dev/null +++ b/queue-5.0/ib-rdmavt-fix-concurrency-panics-in-qp-post_send-and-modify-to-error.patch @@ -0,0 +1,142 @@ +From d757c60eca9b22f4d108929a24401e0fdecda0b1 Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" +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 + +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: #v4.9+ +Reviewed-by: Mike Marciniszyn +Signed-off-by: Michael J. Ruhl +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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) { diff --git a/queue-5.0/ib-rdmavt-fix-loopback-send-with-invalidate-ordering.patch b/queue-5.0/ib-rdmavt-fix-loopback-send-with-invalidate-ordering.patch new file mode 100644 index 00000000000..477366b8557 --- /dev/null +++ b/queue-5.0/ib-rdmavt-fix-loopback-send-with-invalidate-ordering.patch @@ -0,0 +1,76 @@ +From 38bbc9f0381550d1d227fc57afa08436e36b32fc Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 26 Feb 2019 08:45:16 -0800 +Subject: IB/rdmavt: Fix loopback send with invalidate ordering + +From: Mike Marciniszyn + +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: #v4.20+ +Reviewed-by: Michael J. Ruhl +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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: diff --git a/queue-5.0/intel_th-don-t-reference-unassigned-outputs.patch b/queue-5.0/intel_th-don-t-reference-unassigned-outputs.patch new file mode 100644 index 00000000000..c4da70ca18f --- /dev/null +++ b/queue-5.0/intel_th-don-t-reference-unassigned-outputs.patch @@ -0,0 +1,60 @@ +From 9ed3f22223c33347ed963e7c7019cf2956dd4e37 Mon Sep 17 00:00:00 2001 +From: Alexander Shishkin +Date: Thu, 24 Jan 2019 15:11:53 +0200 +Subject: intel_th: Don't reference unassigned outputs + +From: Alexander Shishkin + +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 +Fixes: b27a6a3f97b9 ("intel_th: Add Global Trace Hub driver") +CC: stable@vger.kernel.org # v4.4+ +Reported-by: Ammy Yi +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + diff --git a/queue-5.0/irqchip-brcmstb-l2-use-_irqsave-locking-variants-in-non-interrupt-code.patch b/queue-5.0/irqchip-brcmstb-l2-use-_irqsave-locking-variants-in-non-interrupt-code.patch new file mode 100644 index 00000000000..d656ce4105c --- /dev/null +++ b/queue-5.0/irqchip-brcmstb-l2-use-_irqsave-locking-variants-in-non-interrupt-code.patch @@ -0,0 +1,68 @@ +From 33517881ede742107f416533b8c3e4abc56763da Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Wed, 20 Feb 2019 14:15:28 -0800 +Subject: irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code + +From: Doug Berger + +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 +Signed-off-by: Florian Fainelli +[maz: tidied up $SUBJECT] +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-5.0/irqchip-gic-v3-its-avoid-parsing-_indirect_-twice-for-device-table.patch b/queue-5.0/irqchip-gic-v3-its-avoid-parsing-_indirect_-twice-for-device-table.patch new file mode 100644 index 00000000000..762ffd64bfa --- /dev/null +++ b/queue-5.0/irqchip-gic-v3-its-avoid-parsing-_indirect_-twice-for-device-table.patch @@ -0,0 +1,34 @@ +From 8d565748b6035eeda18895c213396a4c9fac6a4c Mon Sep 17 00:00:00 2001 +From: Zenghui Yu +Date: Sun, 10 Feb 2019 05:24:10 +0000 +Subject: irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table + +From: Zenghui Yu + +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 +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-5.0/kernel-sysctl.c-add-missing-range-check-in-do_proc_dointvec_minmax_conv.patch b/queue-5.0/kernel-sysctl.c-add-missing-range-check-in-do_proc_dointvec_minmax_conv.patch new file mode 100644 index 00000000000..0c05be79d6a --- /dev/null +++ b/queue-5.0/kernel-sysctl.c-add-missing-range-check-in-do_proc_dointvec_minmax_conv.patch @@ -0,0 +1,52 @@ +From 8cf7630b29701d364f8df4a50e4f1f5e752b2778 Mon Sep 17 00:00:00 2001 +From: Zev Weiss +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 + +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 +Cc: Brendan Higgins +Cc: Iurii Zaikin +Cc: Kees Cook +Cc: Luis Chamberlain +Cc: [2.6.2+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-5.0/libertas_tf-don-t-set-urb_zero_packet-on-in-usb-transfer.patch b/queue-5.0/libertas_tf-don-t-set-urb_zero_packet-on-in-usb-transfer.patch new file mode 100644 index 00000000000..cbe71d9cc57 --- /dev/null +++ b/queue-5.0/libertas_tf-don-t-set-urb_zero_packet-on-in-usb-transfer.patch @@ -0,0 +1,36 @@ +From 607076a904c435f2677fadaadd4af546279db68b Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +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 + +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 +Reviewed-by: Steve deRosier +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-5.0/media-i2c-ov5640-fix-post-reset-delay.patch b/queue-5.0/media-i2c-ov5640-fix-post-reset-delay.patch new file mode 100644 index 00000000000..a5ad03c6421 --- /dev/null +++ b/queue-5.0/media-i2c-ov5640-fix-post-reset-delay.patch @@ -0,0 +1,35 @@ +From 1d4c41f3d887bcd66e82cb2fda124533dad8808a Mon Sep 17 00:00:00 2001 +From: Loic Poulain +Date: Wed, 30 Jan 2019 11:48:07 -0500 +Subject: media: i2c: ov5640: Fix post-reset delay + +From: Loic Poulain + +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 +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Cc: Adam Ford +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-5.0/mm-hwpoison-fix-thp-split-handing-in-soft_offline_in_use_page.patch b/queue-5.0/mm-hwpoison-fix-thp-split-handing-in-soft_offline_in_use_page.patch new file mode 100644 index 00000000000..27d07850ef8 --- /dev/null +++ b/queue-5.0/mm-hwpoison-fix-thp-split-handing-in-soft_offline_in_use_page.patch @@ -0,0 +1,76 @@ +From 46612b751c4941c5c0472ddf04027e877ae5990f Mon Sep 17 00:00:00 2001 +From: zhongjiang +Date: Tue, 5 Mar 2019 15:41:16 -0800 +Subject: mm: hwpoison: fix thp split handing in soft_offline_in_use_page() + +From: zhongjiang + +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 +Acked-by: Naoya Horiguchi +Cc: Michal Hocko +Cc: Hugh Dickins +Cc: Kirill A. Shutemov +Cc: Andrea Arcangeli +Cc: [4.5+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + + /* diff --git a/queue-5.0/mm-memory.c-do_fault-avoid-usage-of-stale-vm_area_struct.patch b/queue-5.0/mm-memory.c-do_fault-avoid-usage-of-stale-vm_area_struct.patch new file mode 100644 index 00000000000..1e1770072d3 --- /dev/null +++ b/queue-5.0/mm-memory.c-do_fault-avoid-usage-of-stale-vm_area_struct.patch @@ -0,0 +1,118 @@ +From fc8efd2ddfed3f343c11b693e87140ff358d7ff5 Mon Sep 17 00:00:00 2001 +From: Jan Stancek +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 + +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);| + | + +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 +Reviewed-by: Andrea Arcangeli +Reviewed-by: Matthew Wilcox +Acked-by: Rafael Aquini +Reviewed-by: Minchan Kim +Acked-by: Kirill A. Shutemov +Cc: Rik van Riel +Cc: Michal Hocko +Cc: Huang Ying +Cc: Souptick Joarder +Cc: Jerome Glisse +Cc: Aneesh Kumar K.V +Cc: David Hildenbrand +Cc: Andrea Arcangeli +Cc: David Rientjes +Cc: Mel Gorman +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-5.0/mm-vmalloc-fix-size-check-for-remap_vmalloc_range_partial.patch b/queue-5.0/mm-vmalloc-fix-size-check-for-remap_vmalloc_range_partial.patch new file mode 100644 index 00000000000..4a1a439a310 --- /dev/null +++ b/queue-5.0/mm-vmalloc-fix-size-check-for-remap_vmalloc_range_partial.patch @@ -0,0 +1,86 @@ +From 401592d2e095947344e10ec0623adbcd58934dd4 Mon Sep 17 00:00:00 2001 +From: Roman Penyaev +Date: Tue, 5 Mar 2019 15:43:20 -0800 +Subject: mm/vmalloc: fix size check for remap_vmalloc_range_partial() + +From: Roman Penyaev + +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 +Acked-by: Michal Hocko +Cc: Andrey Ryabinin +Cc: Joe Perches +Cc: "Luis R. Rodriguez" +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 { diff --git a/queue-5.0/nvmem-core-don-t-check-the-return-value-of-notifier-chain-call.patch b/queue-5.0/nvmem-core-don-t-check-the-return-value-of-notifier-chain-call.patch new file mode 100644 index 00000000000..7025aea6538 --- /dev/null +++ b/queue-5.0/nvmem-core-don-t-check-the-return-value-of-notifier-chain-call.patch @@ -0,0 +1,37 @@ +From f4853e1c321edb48af229ad5ac85076790d34968 Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +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 + +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 +Acked-by: Srinivas Kandagatla +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-5.0/parport_pc-fix-find_superio-io-compare-code-should-use-equal-test.patch b/queue-5.0/parport_pc-fix-find_superio-io-compare-code-should-use-equal-test.patch new file mode 100644 index 00000000000..0deff712d87 --- /dev/null +++ b/queue-5.0/parport_pc-fix-find_superio-io-compare-code-should-use-equal-test.patch @@ -0,0 +1,40 @@ +From 21698fd57984cd28207d841dbdaa026d6061bceb Mon Sep 17 00:00:00 2001 +From: QiaoChong +Date: Sat, 9 Feb 2019 20:59:07 +0000 +Subject: parport_pc: fix find_superio io compare code, should use equal test. + +From: QiaoChong + +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 +Cc: stable@vger.kernel.org +Signed-off-by: QiaoChong +[rewrite the commit message] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-5.0/pci-aspm-use-ltr-if-already-enabled-by-platform.patch b/queue-5.0/pci-aspm-use-ltr-if-already-enabled-by-platform.patch new file mode 100644 index 00000000000..49996dc271a --- /dev/null +++ b/queue-5.0/pci-aspm-use-ltr-if-already-enabled-by-platform.patch @@ -0,0 +1,99 @@ +From 10ecc818ea7319b5d0d2b4e1aa6a77323e776f76 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Fri, 4 Jan 2019 17:59:07 -0600 +Subject: PCI/ASPM: Use LTR if already enabled by platform + +From: Bjorn Helgaas + +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 +Reported-by: David Ward +Signed-off-by: Bjorn Helgaas +CC: stable@vger.kernel.org # v4.18+ +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + } + diff --git a/queue-5.0/pci-dpc-fix-print-aer-status-in-dpc-event-handling.patch b/queue-5.0/pci-dpc-fix-print-aer-status-in-dpc-event-handling.patch new file mode 100644 index 00000000000..569e8f9fe20 --- /dev/null +++ b/queue-5.0/pci-dpc-fix-print-aer-status-in-dpc-event-handling.patch @@ -0,0 +1,75 @@ +From 9f08a5d896ce43380314c34ed3f264c8e6075b80 Mon Sep 17 00:00:00 2001 +From: Dongdong Liu +Date: Mon, 11 Feb 2019 15:02:59 +0800 +Subject: PCI/DPC: Fix print AER status in DPC event handling + +From: Dongdong Liu + +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 +[bhelgaas: changelog] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Keith Busch +Cc: stable@vger.kernel.org # v4.19+ +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-5.0/pci-dwc-skip-msi-init-if-msis-have-been-explicitly-disabled.patch b/queue-5.0/pci-dwc-skip-msi-init-if-msis-have-been-explicitly-disabled.patch new file mode 100644 index 00000000000..79183777ae7 --- /dev/null +++ b/queue-5.0/pci-dwc-skip-msi-init-if-msis-have-been-explicitly-disabled.patch @@ -0,0 +1,46 @@ +From 3afc8299f39a27b60e1519a28e18878ce878e7dd Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Wed, 27 Feb 2019 17:52:19 +0100 +Subject: PCI: dwc: skip MSI init if MSIs have been explicitly disabled + +From: Lucas Stach + +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 +Signed-off-by: Lucas Stach +Signed-off-by: Lorenzo Pieralisi +Acked-by: Gustavo Pimentel +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-5.0/pci-pci-bridge-emul-create-per-bridge-copy-of-register-behavior.patch b/queue-5.0/pci-pci-bridge-emul-create-per-bridge-copy-of-register-behavior.patch new file mode 100644 index 00000000000..13aea9815c8 --- /dev/null +++ b/queue-5.0/pci-pci-bridge-emul-create-per-bridge-copy-of-register-behavior.patch @@ -0,0 +1,180 @@ +From 59f81c35e0df840f7112cb296dde48df84a67c79 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +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 + +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 +Reported-by: Leigh Brown +Tested-by: Leigh Brown +Tested-by: Luis Mendes +Signed-off-by: Thomas Petazzoni +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org +Cc: Luís Mendes +Cc: Leigh Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-5.0/pci-pci-bridge-emul-extend-pci_bridge_emul_init-with-flags.patch b/queue-5.0/pci-pci-bridge-emul-extend-pci_bridge_emul_init-with-flags.patch new file mode 100644 index 00000000000..a3882191cfc --- /dev/null +++ b/queue-5.0/pci-pci-bridge-emul-extend-pci_bridge_emul_init-with-flags.patch @@ -0,0 +1,109 @@ +From 33776d059630e5045ea9ccf756c74de8f9cc86de Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +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 + +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 +Reported-by: Leigh Brown +Tested-by: Leigh Brown +Tested-by: Luis Mendes +Signed-off-by: Thomas Petazzoni +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org +Cc: Luís Mendes +Cc: Leigh Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-5.0/pci-pciehp-disable-data-link-layer-state-changed-event-on-suspend.patch b/queue-5.0/pci-pciehp-disable-data-link-layer-state-changed-event-on-suspend.patch new file mode 100644 index 00000000000..af61ae88135 --- /dev/null +++ b/queue-5.0/pci-pciehp-disable-data-link-layer-state-changed-event-on-suspend.patch @@ -0,0 +1,87 @@ +From bbe54ea5330d828cc396d451c0e1e5c3f9764c1e Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Thu, 31 Jan 2019 20:07:46 +0300 +Subject: PCI: pciehp: Disable Data Link Layer State Changed event on suspend + +From: Mika Westerberg + +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 +Signed-off-by: Bjorn Helgaas +Reviewed-by: Rafael J. Wysocki +CC: stable@vger.kernel.org # v4.20+ +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + + /* diff --git a/queue-5.0/pci-qcom-don-t-deassert-reset-gpio-during-probe.patch b/queue-5.0/pci-qcom-don-t-deassert-reset-gpio-during-probe.patch new file mode 100644 index 00000000000..e41bf7cbbd5 --- /dev/null +++ b/queue-5.0/pci-qcom-don-t-deassert-reset-gpio-during-probe.patch @@ -0,0 +1,45 @@ +From 02b485e31d98265189b91f3e69c43df2ed50610c Mon Sep 17 00:00:00 2001 +From: Bjorn Andersson +Date: Fri, 25 Jan 2019 15:26:16 -0800 +Subject: PCI: qcom: Don't deassert reset GPIO during probe + +From: Bjorn Andersson + +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 +[lorenzo.pieralisi@arm.com: updated commit log] +Signed-off-by: Lorenzo Pieralisi +Acked-by: Stanimir Varbanov +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-5.0/series b/queue-5.0/series index 77310acb6c7..9c9ad5566be 100644 --- a/queue-5.0/series +++ b/queue-5.0/series @@ -96,3 +96,52 @@ btrfs-ensure-that-a-dup-or-raid1-block-group-has-exactly-two-stripes.patch 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 diff --git a/queue-5.0/soc-qcom-rpmh-avoid-accessing-freed-memory-from-batch-api.patch b/queue-5.0/soc-qcom-rpmh-avoid-accessing-freed-memory-from-batch-api.patch new file mode 100644 index 00000000000..fe2393505a5 --- /dev/null +++ b/queue-5.0/soc-qcom-rpmh-avoid-accessing-freed-memory-from-batch-api.patch @@ -0,0 +1,233 @@ +From baef1c90aac7e5bf13f0360a3b334825a23d31a1 Mon Sep 17 00:00:00 2001 +From: Stephen Boyd +Date: Tue, 15 Jan 2019 14:54:47 -0800 +Subject: soc: qcom: rpmh: Avoid accessing freed memory from batch API + +From: Stephen Boyd + +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) + + +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 +Cc: "Raju P.L.S.S.S.N" +Cc: Matthias Kaehlcke +Cc: Evan Green +Cc: stable@vger.kernel.org +Reviewed-by: Lina Iyer +Reviewed-by: Evan Green +Signed-off-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Signed-off-by: Andy Gross +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-5.0/swiotlb-add-is_swiotlb_active-function.patch b/queue-5.0/swiotlb-add-is_swiotlb_active-function.patch new file mode 100644 index 00000000000..a1d7ab4f14c --- /dev/null +++ b/queue-5.0/swiotlb-add-is_swiotlb_active-function.patch @@ -0,0 +1,61 @@ +From 492366f7b4237257ef50ca9c431a6a0d50225aca Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Thu, 7 Feb 2019 12:59:14 +0100 +Subject: swiotlb: Add is_swiotlb_active() function + +From: Joerg Roedel + +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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Joerg Roedel +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + 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; ++} diff --git a/queue-5.0/swiotlb-introduce-swiotlb_max_mapping_size.patch b/queue-5.0/swiotlb-introduce-swiotlb_max_mapping_size.patch new file mode 100644 index 00000000000..b0c170776c4 --- /dev/null +++ b/queue-5.0/swiotlb-introduce-swiotlb_max_mapping_size.patch @@ -0,0 +1,57 @@ +From abe420bfae528c92bd8cc5ecb62dc95672b1fd6f Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Thu, 7 Feb 2019 12:59:13 +0100 +Subject: swiotlb: Introduce swiotlb_max_mapping_size() + +From: Joerg Roedel + +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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Joerg Roedel +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + 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; ++} diff --git a/queue-5.0/usb-chipidea-tegra-fix-missed-ci_hdrc_remove_device.patch b/queue-5.0/usb-chipidea-tegra-fix-missed-ci_hdrc_remove_device.patch new file mode 100644 index 00000000000..c323bfd9f5d --- /dev/null +++ b/queue-5.0/usb-chipidea-tegra-fix-missed-ci_hdrc_remove_device.patch @@ -0,0 +1,32 @@ +From 563b9372f7ec57e44e8f9a8600c5107d7ffdd166 Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Sun, 24 Feb 2019 18:36:22 +0300 +Subject: usb: chipidea: tegra: Fix missed ci_hdrc_remove_device() + +From: Dmitry Osipenko + +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 +Acked-by: Peter Chen +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-5.0/usb-typec-tps6598x-handle-block-writes-separately-with-plain-i2c-adapters.patch b/queue-5.0/usb-typec-tps6598x-handle-block-writes-separately-with-plain-i2c-adapters.patch new file mode 100644 index 00000000000..a514eaf230f --- /dev/null +++ b/queue-5.0/usb-typec-tps6598x-handle-block-writes-separately-with-plain-i2c-adapters.patch @@ -0,0 +1,91 @@ +From 8a863a608d47fa5d9dd15cf841817f73f804cf91 Mon Sep 17 00:00:00 2001 +From: Nikolaus Voss +Date: Wed, 20 Feb 2019 16:11:38 +0100 +Subject: usb: typec: tps6598x: handle block writes separately with plain-I2C adapters + +From: Nikolaus Voss + +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 +Cc: stable +Reviewed-by: Guenter Roeck +Acked-by: Heikki Krogerus +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-5.0/x86-kprobes-prohibit-probing-on-optprobe-template-code.patch b/queue-5.0/x86-kprobes-prohibit-probing-on-optprobe-template-code.patch new file mode 100644 index 00000000000..ec27d850193 --- /dev/null +++ b/queue-5.0/x86-kprobes-prohibit-probing-on-optprobe-template-code.patch @@ -0,0 +1,47 @@ +From 0192e6535ebe9af68614198ced4fd6d37b778ebf Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Wed, 13 Feb 2019 01:11:19 +0900 +Subject: x86/kprobes: Prohibit probing on optprobe template code + +From: Masami Hiramatsu + +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 +Cc: Alexander Shishkin +Cc: Andrea Righi +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Mathieu Desnoyers +Cc: Peter Zijlstra +Cc: Steven Rostedt +Cc: Thomas Gleixner +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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)