--- /dev/null
+From 11a163f2c7d6a9f27ce144cd7e367a81c851621a Mon Sep 17 00:00:00 2001
+From: Paul Cercueil <paul@crapouillou.net>
+Date: Sat, 12 Dec 2020 13:57:33 +0000
+Subject: clk: ingenic: Fix divider calculation with div tables
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+commit 11a163f2c7d6a9f27ce144cd7e367a81c851621a upstream.
+
+The previous code assumed that a higher hardware value always resulted
+in a bigger divider, which is correct for the regular clocks, but is
+an invalid assumption when a divider table is provided for the clock.
+
+Perfect example of this is the PLL0_HALF clock, which applies a /2
+divider with the hardware value 0, and a /1 divider otherwise.
+
+Fixes: a9fa2893fcc6 ("clk: ingenic: Add support for divider tables")
+Cc: <stable@vger.kernel.org> # 5.2
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Link: https://lore.kernel.org/r/20201212135733.38050-1-paul@crapouillou.net
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/ingenic/cgu.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/clk/ingenic/cgu.c
++++ b/drivers/clk/ingenic/cgu.c
+@@ -392,15 +392,21 @@ static unsigned int
+ ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info,
+ unsigned int div)
+ {
+- unsigned int i;
++ unsigned int i, best_i = 0, best = (unsigned int)-1;
+
+ for (i = 0; i < (1 << clk_info->div.bits)
+ && clk_info->div.div_table[i]; i++) {
+- if (clk_info->div.div_table[i] >= div)
+- return i;
++ if (clk_info->div.div_table[i] >= div &&
++ clk_info->div.div_table[i] < best) {
++ best = clk_info->div.div_table[i];
++ best_i = i;
++
++ if (div == best)
++ break;
++ }
+ }
+
+- return i - 1;
++ return best_i;
+ }
+
+ static unsigned
--- /dev/null
+From 6f37689cf6b38fff96de52e7f0d3e78f22803ba0 Mon Sep 17 00:00:00 2001
+From: Terry Zhou <bjzhou@marvell.com>
+Date: Fri, 6 Nov 2020 11:00:39 +0100
+Subject: clk: mvebu: a3700: fix the XTAL MODE pin to MPP1_9
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Terry Zhou <bjzhou@marvell.com>
+
+commit 6f37689cf6b38fff96de52e7f0d3e78f22803ba0 upstream.
+
+There is an error in the current code that the XTAL MODE
+pin was set to NB MPP1_31 which should be NB MPP1_9.
+The latch register of NB MPP1_9 has different offset of 0x8.
+
+Signed-off-by: Terry Zhou <bjzhou@marvell.com>
+[pali: Fix pin name in commit message]
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: 7ea8250406a6 ("clk: mvebu: Add the xtal clock for Armada 3700 SoC")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20201106100039.11385-1-pali@kernel.org
+Reviewed-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/mvebu/armada-37xx-xtal.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-xtal.c
++++ b/drivers/clk/mvebu/armada-37xx-xtal.c
+@@ -13,8 +13,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+
+-#define NB_GPIO1_LATCH 0xC
+-#define XTAL_MODE BIT(31)
++#define NB_GPIO1_LATCH 0x8
++#define XTAL_MODE BIT(9)
+
+ static int armada_3700_xtal_clock_probe(struct platform_device *pdev)
+ {
--- /dev/null
+From 6160aca443148416994c022a35c77daeba948ea6 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicoleotsuka@gmail.com>
+Date: Wed, 28 Oct 2020 17:48:20 -0700
+Subject: clk: tegra: Do not return 0 on failure
+
+From: Nicolin Chen <nicoleotsuka@gmail.com>
+
+commit 6160aca443148416994c022a35c77daeba948ea6 upstream.
+
+Return values from read_dt_param() will be either TRUE (1) or
+FALSE (0), while dfll_fetch_pwm_params() returns 0 on success
+or an ERR code on failure.
+
+So this patch fixes the bug of returning 0 on failure.
+
+Fixes: 36541f0499fe ("clk: tegra: dfll: support PWM regulator control")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/tegra/clk-dfll.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/tegra/clk-dfll.c
++++ b/drivers/clk/tegra/clk-dfll.c
+@@ -1856,13 +1856,13 @@ static int dfll_fetch_pwm_params(struct
+ &td->reg_init_uV);
+ if (!ret) {
+ dev_err(td->dev, "couldn't get initialized voltage\n");
+- return ret;
++ return -EINVAL;
+ }
+
+ ret = read_dt_param(td, "nvidia,pwm-period-nanoseconds", &pwm_period);
+ if (!ret) {
+ dev_err(td->dev, "couldn't get PWM period\n");
+- return ret;
++ return -EINVAL;
+ }
+ td->pwm_rate = (NSEC_PER_SEC / pwm_period) * (MAX_DFLL_VOLTAGES - 1);
+
--- /dev/null
+From 3418bd7cfce0bd8ef1ccedc4655f9f86f6c3b0ca Mon Sep 17 00:00:00 2001
+From: William Breathitt Gray <vilhelm.gray@gmail.com>
+Date: Sat, 14 Nov 2020 18:28:05 -0500
+Subject: counter: microchip-tcb-capture: Fix CMR value check
+
+From: William Breathitt Gray <vilhelm.gray@gmail.com>
+
+commit 3418bd7cfce0bd8ef1ccedc4655f9f86f6c3b0ca upstream.
+
+The ATMEL_TC_ETRGEDG_* defines are not masks but rather possible values
+for CMR. This patch fixes the action_get() callback to properly check
+for these values rather than mask them.
+
+Fixes: 106b104137fd ("counter: Add microchip TCB capture counter")
+Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Acked-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20201114232805.253108-1-vilhelm.gray@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/counter/microchip-tcb-capture.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/counter/microchip-tcb-capture.c
++++ b/drivers/counter/microchip-tcb-capture.c
+@@ -183,16 +183,20 @@ static int mchp_tc_count_action_get(stru
+
+ regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
+
+- *action = MCHP_TC_SYNAPSE_ACTION_NONE;
+-
+- if (cmr & ATMEL_TC_ETRGEDG_NONE)
++ switch (cmr & ATMEL_TC_ETRGEDG) {
++ default:
+ *action = MCHP_TC_SYNAPSE_ACTION_NONE;
+- else if (cmr & ATMEL_TC_ETRGEDG_RISING)
++ break;
++ case ATMEL_TC_ETRGEDG_RISING:
+ *action = MCHP_TC_SYNAPSE_ACTION_RISING_EDGE;
+- else if (cmr & ATMEL_TC_ETRGEDG_FALLING)
++ break;
++ case ATMEL_TC_ETRGEDG_FALLING:
+ *action = MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE;
+- else if (cmr & ATMEL_TC_ETRGEDG_BOTH)
++ break;
++ case ATMEL_TC_ETRGEDG_BOTH:
+ *action = MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE;
++ break;
++ }
+
+ return 0;
+ }
--- /dev/null
+From 1aa574312518ef1d60d2dc62d58f7021db3b163a Mon Sep 17 00:00:00 2001
+From: Wang Hai <wanghai38@huawei.com>
+Date: Tue, 1 Dec 2020 21:59:29 +0800
+Subject: device-dax/core: Fix memory leak when rmmod dax.ko
+
+From: Wang Hai <wanghai38@huawei.com>
+
+commit 1aa574312518ef1d60d2dc62d58f7021db3b163a upstream.
+
+When I repeatedly modprobe and rmmod dax.ko, kmemleak report a
+memory leak as follows:
+
+unreferenced object 0xffff9a5588c05088 (size 8):
+ comm "modprobe", pid 261, jiffies 4294693644 (age 42.063s)
+...
+ backtrace:
+ [<00000000e007ced0>] kstrdup+0x35/0x70
+ [<000000002ae73897>] kstrdup_const+0x3d/0x50
+ [<000000002b00c9c3>] kvasprintf_const+0xbc/0xf0
+ [<000000008023282f>] kobject_set_name_vargs+0x3b/0xd0
+ [<00000000d2cbaa4e>] kobject_set_name+0x62/0x90
+ [<00000000202e7a22>] bus_register+0x7f/0x2b0
+ [<000000000b77792c>] 0xffffffffc02840f7
+ [<000000002d5be5ac>] 0xffffffffc02840b4
+ [<00000000dcafb7cd>] do_one_initcall+0x58/0x240
+ [<00000000049fe480>] do_init_module+0x56/0x1e2
+ [<0000000022671491>] load_module+0x2517/0x2840
+ [<000000001a2201cb>] __do_sys_finit_module+0x9c/0xe0
+ [<000000003eb304e7>] do_syscall_64+0x33/0x40
+ [<0000000051c5fd06>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+When rmmod dax is executed, dax_bus_exit() is missing. This patch
+can fix this bug.
+
+Fixes: 9567da0b408a ("device-dax: Introduce bus + driver model")
+Cc: <stable@vger.kernel.org>
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Link: https://lore.kernel.org/r/20201201135929.66530-1-wanghai38@huawei.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dax/super.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/dax/super.c
++++ b/drivers/dax/super.c
+@@ -752,6 +752,7 @@ err_chrdev:
+
+ static void __exit dax_core_exit(void)
+ {
++ dax_bus_exit();
+ unregister_chrdev_region(dax_devt, MINORMASK+1);
+ ida_destroy(&dax_minor_ida);
+ dax_fs_exit();
--- /dev/null
+From bf8975837dac156c33a4d15d46602700998cb6dd Mon Sep 17 00:00:00 2001
+From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Date: Tue, 24 Nov 2020 12:57:07 +0100
+Subject: dma-buf/dma-resv: Respect num_fences when initializing the shared fence list.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+
+commit bf8975837dac156c33a4d15d46602700998cb6dd upstream.
+
+We hardcode the maximum number of shared fences to 4, instead of
+respecting num_fences. Use a minimum of 4, but more if num_fences
+is higher.
+
+This seems to have been an oversight when first implementing the
+api.
+
+Fixes: 04a5faa8cbe5 ("reservation: update api and add some helpers")
+Cc: <stable@vger.kernel.org> # v3.17+
+Reported-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20201124115707.406917-1-maarten.lankhorst@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma-buf/dma-resv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/dma-buf/dma-resv.c
++++ b/drivers/dma-buf/dma-resv.c
+@@ -200,7 +200,7 @@ int dma_resv_reserve_shared(struct dma_r
+ max = max(old->shared_count + num_fences,
+ old->shared_max * 2);
+ } else {
+- max = 4;
++ max = max(4ul, roundup_pow_of_two(num_fences));
+ }
+
+ new = dma_resv_list_alloc(max);
--- /dev/null
+From 66482f640755b31cb94371ff6cef17400cda6db5 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 8 Dec 2020 20:03:26 +0100
+Subject: driver: core: Fix list corruption after device_del()
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 66482f640755b31cb94371ff6cef17400cda6db5 upstream.
+
+The device_links_purge() function (called from device_del()) tries to
+remove the links.needs_suppliers list entry, but it's using
+list_del(), hence it doesn't initialize after the removal. This is OK
+for normal cases where device_del() is called via device_destroy().
+However, it's not guaranteed that the device object will be really
+deleted soon after device_del(). In a minor case like HD-audio codec
+reconfiguration that re-initializes the device after device_del(), it
+may lead to a crash by the corrupted list entry.
+
+As a simple fix, replace list_del() with list_del_init() in order to
+make the list intact after the device_del() call.
+
+Fixes: e2ae9bcc4aaa ("driver core: Add support for linking devices during device addition")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/20201208190326.27531-1-tiwai@suse.de
+Cc: Saravana Kannan <saravanak@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -1386,7 +1386,7 @@ static void device_links_purge(struct de
+ return;
+
+ mutex_lock(&wfs_lock);
+- list_del(&dev->links.needs_suppliers);
++ list_del_init(&dev->links.needs_suppliers);
+ mutex_unlock(&wfs_lock);
+
+ /*
--- /dev/null
+From a135a1b4c4db1f3b8cbed9676a40ede39feb3362 Mon Sep 17 00:00:00 2001
+From: Stylon Wang <stylon.wang@amd.com>
+Date: Tue, 10 Nov 2020 15:40:06 +0800
+Subject: drm/amd/display: Fix memory leaks in S3 resume
+
+From: Stylon Wang <stylon.wang@amd.com>
+
+commit a135a1b4c4db1f3b8cbed9676a40ede39feb3362 upstream.
+
+EDID parsing in S3 resume pushes new display modes
+to probed_modes list but doesn't consolidate to actual
+mode list. This creates a race condition when
+amdgpu_dm_connector_ddc_get_modes() re-initializes the
+list head without walking the list and results in memory leak.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=209987
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Stylon Wang <stylon.wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2278,7 +2278,8 @@ void amdgpu_dm_update_connector_after_de
+
+ drm_connector_update_edid_property(connector,
+ aconnector->edid);
+- drm_add_edid_modes(connector, aconnector->edid);
++ aconnector->num_modes = drm_add_edid_modes(connector, aconnector->edid);
++ drm_connector_list_update(connector);
+
+ if (aconnector->dc_link->aux_mode)
+ drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
--- /dev/null
+From be7b9b327e79cd2db07b659af599867b629b2f66 Mon Sep 17 00:00:00 2001
+From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
+Date: Sat, 21 Dec 2019 19:05:37 +0100
+Subject: drm/amd/display: Honor the offset for plane 0.
+
+From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
+
+commit be7b9b327e79cd2db07b659af599867b629b2f66 upstream.
+
+With modifiers I'd like to support non-dedicated buffers for
+images.
+
+Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Cc: stable@vger.kernel.org # 5.1.0
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -3746,6 +3746,7 @@ fill_plane_dcc_attributes(struct amdgpu_
+ struct dc *dc = adev->dm.dc;
+ struct dc_dcc_surface_param input;
+ struct dc_surface_dcc_cap output;
++ uint64_t plane_address = afb->address + afb->base.offsets[0];
+ uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
+ uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
+ uint64_t dcc_address;
+@@ -3789,7 +3790,7 @@ fill_plane_dcc_attributes(struct amdgpu_
+ AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
+ dcc->independent_64b_blks = i64b;
+
+- dcc_address = get_dcc_address(afb->address, info);
++ dcc_address = get_dcc_address(plane_address, info);
+ address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+ address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+
+@@ -3820,6 +3821,8 @@ fill_plane_buffer_attributes(struct amdg
+ address->tmz_surface = tmz_surface;
+
+ if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
++ uint64_t addr = afb->address + fb->offsets[0];
++
+ plane_size->surface_size.x = 0;
+ plane_size->surface_size.y = 0;
+ plane_size->surface_size.width = fb->width;
+@@ -3828,9 +3831,10 @@ fill_plane_buffer_attributes(struct amdg
+ fb->pitches[0] / fb->format->cpp[0];
+
+ address->type = PLN_ADDR_TYPE_GRAPHICS;
+- address->grph.addr.low_part = lower_32_bits(afb->address);
+- address->grph.addr.high_part = upper_32_bits(afb->address);
++ address->grph.addr.low_part = lower_32_bits(addr);
++ address->grph.addr.high_part = upper_32_bits(addr);
+ } else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
++ uint64_t luma_addr = afb->address + fb->offsets[0];
+ uint64_t chroma_addr = afb->address + fb->offsets[1];
+
+ plane_size->surface_size.x = 0;
+@@ -3851,9 +3855,9 @@ fill_plane_buffer_attributes(struct amdg
+
+ address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
+ address->video_progressive.luma_addr.low_part =
+- lower_32_bits(afb->address);
++ lower_32_bits(luma_addr);
+ address->video_progressive.luma_addr.high_part =
+- upper_32_bits(afb->address);
++ upper_32_bits(luma_addr);
+ address->video_progressive.chroma_addr.low_part =
+ lower_32_bits(chroma_addr);
+ address->video_progressive.chroma_addr.high_part =
--- /dev/null
+From 05211e7fbbf042dd7f51155ebe64eb2ecacb25cb Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 17 Dec 2020 12:11:36 -0500
+Subject: drm/amdgpu: only set DP subconnector type on DP and eDP connectors
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 05211e7fbbf042dd7f51155ebe64eb2ecacb25cb upstream.
+
+Fixes a crash in drm_object_property_set_value() because the property
+is not set for internal DP ports that connect to a bridge chips
+(e.g., DP to VGA or DP to LVDS).
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=210739
+Fixes: 65bf2cf95d3ade ("drm/amdgpu: utilize subconnector property for DP through atombios")
+Tested-By: Kris Karas <bugs-a17@moonlit-rail.com>
+Cc: Oleg Vasilev <oleg.vasilev@intel.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 5.10.x
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -1414,10 +1414,12 @@ out:
+ pm_runtime_put_autosuspend(connector->dev->dev);
+ }
+
+- drm_dp_set_subconnector_property(&amdgpu_connector->base,
+- ret,
+- amdgpu_dig_connector->dpcd,
+- amdgpu_dig_connector->downstream_ports);
++ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
++ connector->connector_type == DRM_MODE_CONNECTOR_eDP)
++ drm_dp_set_subconnector_property(&amdgpu_connector->base,
++ ret,
++ amdgpu_dig_connector->dpcd,
++ amdgpu_dig_connector->downstream_ports);
+ return ret;
+ }
+
--- /dev/null
+From 73b62cdb93b68d7e2c1d373c6a411bc00c53e702 Mon Sep 17 00:00:00 2001
+From: Zwane Mwaikambo <zwane@yosper.io>
+Date: Mon, 12 Oct 2020 22:59:14 -0700
+Subject: drm/dp_aux_dev: check aux_dev before use in drm_dp_aux_dev_get_by_minor()
+
+From: Zwane Mwaikambo <zwane@yosper.io>
+
+commit 73b62cdb93b68d7e2c1d373c6a411bc00c53e702 upstream.
+
+I observed this when unplugging a DP monitor whilst a computer is asleep
+and then waking it up. This left DP chardev nodes still being present on
+the filesystem and accessing these device nodes caused an oops because
+drm_dp_aux_dev_get_by_minor() assumes a device exists if it is opened.
+This can also be reproduced by creating a device node with mknod(1) and
+issuing an open(2)
+
+[166164.933198] BUG: kernel NULL pointer dereference, address: 0000000000000018
+[166164.933202] #PF: supervisor read access in kernel mode
+[166164.933204] #PF: error_code(0x0000) - not-present page
+[166164.933205] PGD 0 P4D 0
+[166164.933208] Oops: 0000 [#1] PREEMPT SMP NOPTI
+[166164.933211] CPU: 4 PID: 99071 Comm: fwupd Tainted: G W
+5.8.0-rc6+ #1
+[166164.933213] Hardware name: LENOVO 20RD002VUS/20RD002VUS, BIOS R16ET25W
+(1.11 ) 04/21/2020
+[166164.933232] RIP: 0010:drm_dp_aux_dev_get_by_minor+0x29/0x70
+[drm_kms_helper]
+[166164.933234] Code: 00 0f 1f 44 00 00 55 48 89 e5 41 54 41 89 fc 48 c7
+c7 60 01 a4 c0 e8 26 ab 30 d7 44 89 e6 48 c7 c7 80 01 a4 c0 e8 47 94 d6 d6
+<8b> 50 18 49 89 c4 48 8d 78 18 85 d2 74 33 8d 4a 01 89 d0 f0 0f b1
+[166164.933236] RSP: 0018:ffffb7d7c41cbbf0 EFLAGS: 00010246
+[166164.933237] RAX: 0000000000000000 RBX: ffff8a90001fe900 RCX: 0000000000000000
+[166164.933238] RDX: 0000000000000000 RSI: 0000000000000003 RDI: ffffffffc0a40180
+[166164.933239] RBP: ffffb7d7c41cbbf8 R08: 0000000000000000 R09: ffff8a93e157d6d0
+[166164.933240] R10: 0000000000000000 R11: ffffffffc0a40188 R12: 0000000000000003
+[166164.933241] R13: ffff8a9402200e80 R14: ffff8a90001fe900 R15: 0000000000000000
+[166164.933244] FS: 00007f7fb041eb00(0000) GS:ffff8a9411500000(0000)
+knlGS:0000000000000000
+[166164.933245] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[166164.933246] CR2: 0000000000000018 CR3: 00000000352c2003 CR4: 00000000003606e0
+[166164.933247] Call Trace:
+[166164.933264] auxdev_open+0x1b/0x40 [drm_kms_helper]
+[166164.933278] chrdev_open+0xa7/0x1c0
+[166164.933282] ? cdev_put.part.0+0x20/0x20
+[166164.933287] do_dentry_open+0x161/0x3c0
+[166164.933291] vfs_open+0x2d/0x30
+[166164.933297] path_openat+0xb27/0x10e0
+[166164.933306] ? atime_needs_update+0x73/0xd0
+[166164.933309] do_filp_open+0x91/0x100
+[166164.933313] ? __alloc_fd+0xb2/0x150
+[166164.933316] do_sys_openat2+0x210/0x2d0
+[166164.933318] do_sys_open+0x46/0x80
+[166164.933320] __x64_sys_openat+0x20/0x30
+[166164.933328] do_syscall_64+0x52/0xc0
+[166164.933336] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+(gdb) disassemble drm_dp_aux_dev_get_by_minor+0x29
+Dump of assembler code for function drm_dp_aux_dev_get_by_minor:
+ 0x0000000000017b10 <+0>: callq 0x17b15 <drm_dp_aux_dev_get_by_minor+5>
+ 0x0000000000017b15 <+5>: push %rbp
+ 0x0000000000017b16 <+6>: mov %rsp,%rbp
+ 0x0000000000017b19 <+9>: push %r12
+ 0x0000000000017b1b <+11>: mov %edi,%r12d
+ 0x0000000000017b1e <+14>: mov $0x0,%rdi
+ 0x0000000000017b25 <+21>: callq 0x17b2a <drm_dp_aux_dev_get_by_minor+26>
+ 0x0000000000017b2a <+26>: mov %r12d,%esi
+ 0x0000000000017b2d <+29>: mov $0x0,%rdi
+ 0x0000000000017b34 <+36>: callq 0x17b39 <drm_dp_aux_dev_get_by_minor+41>
+ 0x0000000000017b39 <+41>: mov 0x18(%rax),%edx <=========
+ 0x0000000000017b3c <+44>: mov %rax,%r12
+ 0x0000000000017b3f <+47>: lea 0x18(%rax),%rdi
+ 0x0000000000017b43 <+51>: test %edx,%edx
+ 0x0000000000017b45 <+53>: je 0x17b7a <drm_dp_aux_dev_get_by_minor+106>
+ 0x0000000000017b47 <+55>: lea 0x1(%rdx),%ecx
+ 0x0000000000017b4a <+58>: mov %edx,%eax
+ 0x0000000000017b4c <+60>: lock cmpxchg %ecx,(%rdi)
+ 0x0000000000017b50 <+64>: jne 0x17b76 <drm_dp_aux_dev_get_by_minor+102>
+ 0x0000000000017b52 <+66>: test %edx,%edx
+ 0x0000000000017b54 <+68>: js 0x17b6d <drm_dp_aux_dev_get_by_minor+93>
+ 0x0000000000017b56 <+70>: test %ecx,%ecx
+ 0x0000000000017b58 <+72>: js 0x17b6d <drm_dp_aux_dev_get_by_minor+93>
+ 0x0000000000017b5a <+74>: mov $0x0,%rdi
+ 0x0000000000017b61 <+81>: callq 0x17b66 <drm_dp_aux_dev_get_by_minor+86>
+ 0x0000000000017b66 <+86>: mov %r12,%rax
+ 0x0000000000017b69 <+89>: pop %r12
+ 0x0000000000017b6b <+91>: pop %rbp
+ 0x0000000000017b6c <+92>: retq
+ 0x0000000000017b6d <+93>: xor %esi,%esi
+ 0x0000000000017b6f <+95>: callq 0x17b74 <drm_dp_aux_dev_get_by_minor+100>
+ 0x0000000000017b74 <+100>: jmp 0x17b5a <drm_dp_aux_dev_get_by_minor+74>
+ 0x0000000000017b76 <+102>: mov %eax,%edx
+ 0x0000000000017b78 <+104>: jmp 0x17b43 <drm_dp_aux_dev_get_by_minor+51>
+ 0x0000000000017b7a <+106>: xor %r12d,%r12d
+ 0x0000000000017b7d <+109>: jmp 0x17b5a <drm_dp_aux_dev_get_by_minor+74>
+End of assembler dump.
+
+(gdb) list *drm_dp_aux_dev_get_by_minor+0x29
+0x17b39 is in drm_dp_aux_dev_get_by_minor (drivers/gpu/drm/drm_dp_aux_dev.c:65).
+60 static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
+61 {
+62 struct drm_dp_aux_dev *aux_dev = NULL;
+63
+64 mutex_lock(&aux_idr_mutex);
+65 aux_dev = idr_find(&aux_idr, index);
+66 if (!kref_get_unless_zero(&aux_dev->refcount))
+67 aux_dev = NULL;
+68 mutex_unlock(&aux_idr_mutex);
+69
+(gdb) p/x &((struct drm_dp_aux_dev *)(0x0))->refcount
+$8 = 0x18
+
+Looking at the caller, checks on the minor are pushed down to
+drm_dp_aux_dev_get_by_minor()
+
+static int auxdev_open(struct inode *inode, struct file *file)
+{
+ unsigned int minor = iminor(inode);
+ struct drm_dp_aux_dev *aux_dev;
+
+ aux_dev = drm_dp_aux_dev_get_by_minor(minor); <====
+ if (!aux_dev)
+ return -ENODEV;
+
+ file->private_data = aux_dev;
+ return 0;
+}
+
+Fixes: e94cb37b34eb ("drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers.")
+Cc: <stable@vger.kernel.org> # v4.6+
+Signed-off-by: Zwane Mwaikambo <zwane@yosper.io>
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+[added Cc to stable]
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/alpine.DEB.2.21.2010122231070.38717@montezuma.home
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_dp_aux_dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_dp_aux_dev.c
++++ b/drivers/gpu/drm/drm_dp_aux_dev.c
+@@ -63,7 +63,7 @@ static struct drm_dp_aux_dev *drm_dp_aux
+
+ mutex_lock(&aux_idr_mutex);
+ aux_dev = idr_find(&aux_idr, index);
+- if (!kref_get_unless_zero(&aux_dev->refcount))
++ if (aux_dev && !kref_get_unless_zero(&aux_dev->refcount))
+ aux_dev = NULL;
+ mutex_unlock(&aux_idr_mutex);
+
--- /dev/null
+From 0e53656ad8abc99e0a80c3de611e593ebbf55829 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Wed, 16 Dec 2020 09:29:51 +0000
+Subject: drm/i915: Fix mismatch between misplaced vma check and vma insert
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 0e53656ad8abc99e0a80c3de611e593ebbf55829 upstream.
+
+When inserting a VMA, we restrict the placement to the low 4G unless the
+caller opts into using the full range. This was done to allow usersapce
+the opportunity to transition slowly from a 32b address space, and to
+avoid breaking inherent 32b assumptions of some commands.
+
+However, for insert we limited ourselves to 4G-4K, but on verification
+we allowed the full 4G. This causes some attempts to bind a new buffer
+to sporadically fail with -ENOSPC, but at other times be bound
+successfully.
+
+commit 48ea1e32c39d ("drm/i915/gen9: Set PIN_ZONE_4G end to 4GB - 1
+page") suggests that there is a genuine problem with stateless addressing
+that cannot utilize the last page in 4G and so we purposefully excluded
+it. This means that the quick pin pass may cause us to utilize a buggy
+placement.
+
+Reported-by: CQ Tang <cq.tang@intel.com>
+Testcase: igt/gem_exec_params/larger-than-life-batch
+Fixes: 48ea1e32c39d ("drm/i915/gen9: Set PIN_ZONE_4G end to 4GB - 1 page")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: CQ Tang <cq.tang@intel.com>
+Reviewed-by: CQ Tang <cq.tang@intel.com>
+Reviewed-by: Matthew Auld <matthew.auld@intel.com>
+Cc: <stable@vger.kernel.org> # v4.5+
+Link: https://patchwork.freedesktop.org/patch/msgid/20201216092951.7124-1-chris@chris-wilson.co.uk
+(cherry picked from commit 5f22cc0b134ab702d7f64b714e26018f7288ffee)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -382,7 +382,7 @@ eb_vma_misplaced(const struct drm_i915_g
+ return true;
+
+ if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) &&
+- (vma->node.start + vma->node.size - 1) >> 32)
++ (vma->node.start + vma->node.size + 4095) >> 32)
+ return true;
+
+ if (flags & __EXEC_OBJECT_NEEDS_MAP &&
--- /dev/null
+From 1a11a88cfd9a97e13be8bc880c4795f9844fbbec Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@collabora.com>
+Date: Fri, 2 Oct 2020 14:25:06 +0200
+Subject: drm/panfrost: Fix job timeout handling
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+commit 1a11a88cfd9a97e13be8bc880c4795f9844fbbec upstream.
+
+If more than two jobs end up timeout-ing concurrently, only one of them
+(the one attached to the scheduler acquiring the lock) is fully handled.
+The other one remains in a dangling state where it's no longer part of
+the scheduling queue, but still blocks something in scheduler, leading
+to repetitive timeouts when new jobs are queued.
+
+Let's make sure all bad jobs are properly handled by the thread
+acquiring the lock.
+
+v3:
+- Add Steven's R-b
+- Don't take the sched_lock when stopping the schedulers
+
+v2:
+- Fix the subject prefix
+- Stop the scheduler before returning from panfrost_job_timedout()
+- Call cancel_delayed_work_sync() after drm_sched_stop() to make sure
+ no timeout handlers are in flight when we reset the GPU (Steven Price)
+- Make sure we release the reset lock before restarting the
+ schedulers (Steven Price)
+
+Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20201002122506.1374183-1-boris.brezillon@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/panfrost/panfrost_job.c | 62 +++++++++++++++++++++++++++-----
+ 1 file changed, 53 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/panfrost/panfrost_job.c
++++ b/drivers/gpu/drm/panfrost/panfrost_job.c
+@@ -25,7 +25,8 @@
+
+ struct panfrost_queue_state {
+ struct drm_gpu_scheduler sched;
+-
++ bool stopped;
++ struct mutex lock;
+ u64 fence_context;
+ u64 emit_seqno;
+ };
+@@ -369,6 +370,24 @@ void panfrost_job_enable_interrupts(stru
+ job_write(pfdev, JOB_INT_MASK, irq_mask);
+ }
+
++static bool panfrost_scheduler_stop(struct panfrost_queue_state *queue,
++ struct drm_sched_job *bad)
++{
++ bool stopped = false;
++
++ mutex_lock(&queue->lock);
++ if (!queue->stopped) {
++ drm_sched_stop(&queue->sched, bad);
++ if (bad)
++ drm_sched_increase_karma(bad);
++ queue->stopped = true;
++ stopped = true;
++ }
++ mutex_unlock(&queue->lock);
++
++ return stopped;
++}
++
+ static void panfrost_job_timedout(struct drm_sched_job *sched_job)
+ {
+ struct panfrost_job *job = to_panfrost_job(sched_job);
+@@ -392,19 +411,39 @@ static void panfrost_job_timedout(struct
+ job_read(pfdev, JS_TAIL_LO(js)),
+ sched_job);
+
++ /* Scheduler is already stopped, nothing to do. */
++ if (!panfrost_scheduler_stop(&pfdev->js->queue[js], sched_job))
++ return;
++
+ if (!mutex_trylock(&pfdev->reset_lock))
+ return;
+
+ for (i = 0; i < NUM_JOB_SLOTS; i++) {
+ struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched;
+
+- drm_sched_stop(sched, sched_job);
+- if (js != i)
+- /* Ensure any timeouts on other slots have finished */
++ /*
++ * If the queue is still active, make sure we wait for any
++ * pending timeouts.
++ */
++ if (!pfdev->js->queue[i].stopped)
++ cancel_delayed_work_sync(&sched->work_tdr);
++
++ /*
++ * If the scheduler was not already stopped, there's a tiny
++ * chance a timeout has expired just before we stopped it, and
++ * drm_sched_stop() does not flush pending works. Let's flush
++ * them now so the timeout handler doesn't get called in the
++ * middle of a reset.
++ */
++ if (panfrost_scheduler_stop(&pfdev->js->queue[i], NULL))
+ cancel_delayed_work_sync(&sched->work_tdr);
+- }
+
+- drm_sched_increase_karma(sched_job);
++ /*
++ * Now that we cancelled the pending timeouts, we can safely
++ * reset the stopped state.
++ */
++ pfdev->js->queue[i].stopped = false;
++ }
+
+ spin_lock_irqsave(&pfdev->js->job_lock, flags);
+ for (i = 0; i < NUM_JOB_SLOTS; i++) {
+@@ -421,11 +460,11 @@ static void panfrost_job_timedout(struct
+ for (i = 0; i < NUM_JOB_SLOTS; i++)
+ drm_sched_resubmit_jobs(&pfdev->js->queue[i].sched);
+
++ mutex_unlock(&pfdev->reset_lock);
++
+ /* restart scheduler after GPU is usable again */
+ for (i = 0; i < NUM_JOB_SLOTS; i++)
+ drm_sched_start(&pfdev->js->queue[i].sched, true);
+-
+- mutex_unlock(&pfdev->reset_lock);
+ }
+
+ static const struct drm_sched_backend_ops panfrost_sched_ops = {
+@@ -558,6 +597,7 @@ int panfrost_job_open(struct panfrost_fi
+ int ret, i;
+
+ for (i = 0; i < NUM_JOB_SLOTS; i++) {
++ mutex_init(&js->queue[i].lock);
+ sched = &js->queue[i].sched;
+ ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i],
+ DRM_SCHED_PRIORITY_NORMAL, &sched,
+@@ -570,10 +610,14 @@ int panfrost_job_open(struct panfrost_fi
+
+ void panfrost_job_close(struct panfrost_file_priv *panfrost_priv)
+ {
++ struct panfrost_device *pfdev = panfrost_priv->pfdev;
++ struct panfrost_job_slot *js = pfdev->js;
+ int i;
+
+- for (i = 0; i < NUM_JOB_SLOTS; i++)
++ for (i = 0; i < NUM_JOB_SLOTS; i++) {
+ drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]);
++ mutex_destroy(&js->queue[i].lock);
++ }
+ }
+
+ int panfrost_job_is_idle(struct panfrost_device *pfdev)
--- /dev/null
+From 5bc5cc2819c2c0adb644919e3e790b504ea47e0a Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@collabora.com>
+Date: Thu, 5 Nov 2020 16:17:04 +0100
+Subject: drm/panfrost: Move the GPU reset bits outside the timeout handler
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+commit 5bc5cc2819c2c0adb644919e3e790b504ea47e0a upstream.
+
+We've fixed many races in panfrost_job_timedout() but some remain.
+Instead of trying to fix it again, let's simplify the logic and move
+the reset bits to a separate work scheduled when one of the queue
+reports a timeout.
+
+v5:
+- Simplify panfrost_scheduler_stop() (Steven Price)
+- Always restart the queue in panfrost_scheduler_start() even if
+ the status is corrupted (Steven Price)
+
+v4:
+- Rework the logic to prevent a race between drm_sched_start()
+ (reset work) and drm_sched_job_timedout() (timeout work)
+- Drop Steven's R-b
+- Add dma_fence annotation to the panfrost_reset() function (Daniel Vetter)
+
+v3:
+- Replace the atomic_cmpxchg() by an atomic_xchg() (Robin Murphy)
+- Add Steven's R-b
+
+v2:
+- Use atomic_cmpxchg() to conditionally schedule the reset work
+ (Steven Price)
+
+Fixes: 1a11a88cfd9a ("drm/panfrost: Fix job timeout handling")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20201105151704.2010667-1-boris.brezillon@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/panfrost/panfrost_device.c | 1
+ drivers/gpu/drm/panfrost/panfrost_device.h | 6
+ drivers/gpu/drm/panfrost/panfrost_job.c | 187 +++++++++++++++++++----------
+ 3 files changed, 130 insertions(+), 64 deletions(-)
+
+--- a/drivers/gpu/drm/panfrost/panfrost_device.c
++++ b/drivers/gpu/drm/panfrost/panfrost_device.c
+@@ -206,7 +206,6 @@ int panfrost_device_init(struct panfrost
+ struct resource *res;
+
+ mutex_init(&pfdev->sched_lock);
+- mutex_init(&pfdev->reset_lock);
+ INIT_LIST_HEAD(&pfdev->scheduled_jobs);
+ INIT_LIST_HEAD(&pfdev->as_lru_list);
+
+--- a/drivers/gpu/drm/panfrost/panfrost_device.h
++++ b/drivers/gpu/drm/panfrost/panfrost_device.h
+@@ -105,7 +105,11 @@ struct panfrost_device {
+ struct panfrost_perfcnt *perfcnt;
+
+ struct mutex sched_lock;
+- struct mutex reset_lock;
++
++ struct {
++ struct work_struct work;
++ atomic_t pending;
++ } reset;
+
+ struct mutex shrinker_lock;
+ struct list_head shrinker_list;
+--- a/drivers/gpu/drm/panfrost/panfrost_job.c
++++ b/drivers/gpu/drm/panfrost/panfrost_job.c
+@@ -20,12 +20,21 @@
+ #include "panfrost_gpu.h"
+ #include "panfrost_mmu.h"
+
++#define JOB_TIMEOUT_MS 500
++
+ #define job_write(dev, reg, data) writel(data, dev->iomem + (reg))
+ #define job_read(dev, reg) readl(dev->iomem + (reg))
+
++enum panfrost_queue_status {
++ PANFROST_QUEUE_STATUS_ACTIVE,
++ PANFROST_QUEUE_STATUS_STOPPED,
++ PANFROST_QUEUE_STATUS_STARTING,
++ PANFROST_QUEUE_STATUS_FAULT_PENDING,
++};
++
+ struct panfrost_queue_state {
+ struct drm_gpu_scheduler sched;
+- bool stopped;
++ atomic_t status;
+ struct mutex lock;
+ u64 fence_context;
+ u64 emit_seqno;
+@@ -373,28 +382,61 @@ void panfrost_job_enable_interrupts(stru
+ static bool panfrost_scheduler_stop(struct panfrost_queue_state *queue,
+ struct drm_sched_job *bad)
+ {
++ enum panfrost_queue_status old_status;
+ bool stopped = false;
+
+ mutex_lock(&queue->lock);
+- if (!queue->stopped) {
+- drm_sched_stop(&queue->sched, bad);
+- if (bad)
+- drm_sched_increase_karma(bad);
+- queue->stopped = true;
+- stopped = true;
+- }
++ old_status = atomic_xchg(&queue->status,
++ PANFROST_QUEUE_STATUS_STOPPED);
++ if (old_status == PANFROST_QUEUE_STATUS_STOPPED)
++ goto out;
++
++ WARN_ON(old_status != PANFROST_QUEUE_STATUS_ACTIVE);
++ drm_sched_stop(&queue->sched, bad);
++ if (bad)
++ drm_sched_increase_karma(bad);
++
++ stopped = true;
++
++ /*
++ * Set the timeout to max so the timer doesn't get started
++ * when we return from the timeout handler (restored in
++ * panfrost_scheduler_start()).
++ */
++ queue->sched.timeout = MAX_SCHEDULE_TIMEOUT;
++
++out:
+ mutex_unlock(&queue->lock);
+
+ return stopped;
+ }
+
++static void panfrost_scheduler_start(struct panfrost_queue_state *queue)
++{
++ enum panfrost_queue_status old_status;
++
++ mutex_lock(&queue->lock);
++ old_status = atomic_xchg(&queue->status,
++ PANFROST_QUEUE_STATUS_STARTING);
++ WARN_ON(old_status != PANFROST_QUEUE_STATUS_STOPPED);
++
++ /* Restore the original timeout before starting the scheduler. */
++ queue->sched.timeout = msecs_to_jiffies(JOB_TIMEOUT_MS);
++ drm_sched_resubmit_jobs(&queue->sched);
++ drm_sched_start(&queue->sched, true);
++ old_status = atomic_xchg(&queue->status,
++ PANFROST_QUEUE_STATUS_ACTIVE);
++ if (old_status == PANFROST_QUEUE_STATUS_FAULT_PENDING)
++ drm_sched_fault(&queue->sched);
++
++ mutex_unlock(&queue->lock);
++}
++
+ static void panfrost_job_timedout(struct drm_sched_job *sched_job)
+ {
+ struct panfrost_job *job = to_panfrost_job(sched_job);
+ struct panfrost_device *pfdev = job->pfdev;
+ int js = panfrost_job_get_slot(job);
+- unsigned long flags;
+- int i;
+
+ /*
+ * If the GPU managed to complete this jobs fence, the timeout is
+@@ -415,56 +457,9 @@ static void panfrost_job_timedout(struct
+ if (!panfrost_scheduler_stop(&pfdev->js->queue[js], sched_job))
+ return;
+
+- if (!mutex_trylock(&pfdev->reset_lock))
+- return;
+-
+- for (i = 0; i < NUM_JOB_SLOTS; i++) {
+- struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched;
+-
+- /*
+- * If the queue is still active, make sure we wait for any
+- * pending timeouts.
+- */
+- if (!pfdev->js->queue[i].stopped)
+- cancel_delayed_work_sync(&sched->work_tdr);
+-
+- /*
+- * If the scheduler was not already stopped, there's a tiny
+- * chance a timeout has expired just before we stopped it, and
+- * drm_sched_stop() does not flush pending works. Let's flush
+- * them now so the timeout handler doesn't get called in the
+- * middle of a reset.
+- */
+- if (panfrost_scheduler_stop(&pfdev->js->queue[i], NULL))
+- cancel_delayed_work_sync(&sched->work_tdr);
+-
+- /*
+- * Now that we cancelled the pending timeouts, we can safely
+- * reset the stopped state.
+- */
+- pfdev->js->queue[i].stopped = false;
+- }
+-
+- spin_lock_irqsave(&pfdev->js->job_lock, flags);
+- for (i = 0; i < NUM_JOB_SLOTS; i++) {
+- if (pfdev->jobs[i]) {
+- pm_runtime_put_noidle(pfdev->dev);
+- panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
+- pfdev->jobs[i] = NULL;
+- }
+- }
+- spin_unlock_irqrestore(&pfdev->js->job_lock, flags);
+-
+- panfrost_device_reset(pfdev);
+-
+- for (i = 0; i < NUM_JOB_SLOTS; i++)
+- drm_sched_resubmit_jobs(&pfdev->js->queue[i].sched);
+-
+- mutex_unlock(&pfdev->reset_lock);
+-
+- /* restart scheduler after GPU is usable again */
+- for (i = 0; i < NUM_JOB_SLOTS; i++)
+- drm_sched_start(&pfdev->js->queue[i].sched, true);
++ /* Schedule a reset if there's no reset in progress. */
++ if (!atomic_xchg(&pfdev->reset.pending, 1))
++ schedule_work(&pfdev->reset.work);
+ }
+
+ static const struct drm_sched_backend_ops panfrost_sched_ops = {
+@@ -496,6 +491,8 @@ static irqreturn_t panfrost_job_irq_hand
+ job_write(pfdev, JOB_INT_CLEAR, mask);
+
+ if (status & JOB_INT_MASK_ERR(j)) {
++ enum panfrost_queue_status old_status;
++
+ job_write(pfdev, JS_COMMAND_NEXT(j), JS_COMMAND_NOP);
+
+ dev_err(pfdev->dev, "js fault, js=%d, status=%s, head=0x%x, tail=0x%x",
+@@ -504,7 +501,18 @@ static irqreturn_t panfrost_job_irq_hand
+ job_read(pfdev, JS_HEAD_LO(j)),
+ job_read(pfdev, JS_TAIL_LO(j)));
+
+- drm_sched_fault(&pfdev->js->queue[j].sched);
++ /*
++ * When the queue is being restarted we don't report
++ * faults directly to avoid races between the timeout
++ * and reset handlers. panfrost_scheduler_start() will
++ * call drm_sched_fault() after the queue has been
++ * started if status == FAULT_PENDING.
++ */
++ old_status = atomic_cmpxchg(&pfdev->js->queue[j].status,
++ PANFROST_QUEUE_STATUS_STARTING,
++ PANFROST_QUEUE_STATUS_FAULT_PENDING);
++ if (old_status == PANFROST_QUEUE_STATUS_ACTIVE)
++ drm_sched_fault(&pfdev->js->queue[j].sched);
+ }
+
+ if (status & JOB_INT_MASK_DONE(j)) {
+@@ -531,11 +539,66 @@ static irqreturn_t panfrost_job_irq_hand
+ return IRQ_HANDLED;
+ }
+
++static void panfrost_reset(struct work_struct *work)
++{
++ struct panfrost_device *pfdev = container_of(work,
++ struct panfrost_device,
++ reset.work);
++ unsigned long flags;
++ unsigned int i;
++ bool cookie;
++
++ cookie = dma_fence_begin_signalling();
++ for (i = 0; i < NUM_JOB_SLOTS; i++) {
++ /*
++ * We want pending timeouts to be handled before we attempt
++ * to stop the scheduler. If we don't do that and the timeout
++ * handler is in flight, it might have removed the bad job
++ * from the list, and we'll lose this job if the reset handler
++ * enters the critical section in panfrost_scheduler_stop()
++ * before the timeout handler.
++ *
++ * Timeout is set to MAX_SCHEDULE_TIMEOUT - 1 because we need
++ * something big enough to make sure the timer will not expire
++ * before we manage to stop the scheduler, but we can't use
++ * MAX_SCHEDULE_TIMEOUT because drm_sched_get_cleanup_job()
++ * considers that as 'timer is not running' and will dequeue
++ * the job without making sure the timeout handler is not
++ * running.
++ */
++ pfdev->js->queue[i].sched.timeout = MAX_SCHEDULE_TIMEOUT - 1;
++ cancel_delayed_work_sync(&pfdev->js->queue[i].sched.work_tdr);
++ panfrost_scheduler_stop(&pfdev->js->queue[i], NULL);
++ }
++
++ /* All timers have been stopped, we can safely reset the pending state. */
++ atomic_set(&pfdev->reset.pending, 0);
++
++ spin_lock_irqsave(&pfdev->js->job_lock, flags);
++ for (i = 0; i < NUM_JOB_SLOTS; i++) {
++ if (pfdev->jobs[i]) {
++ pm_runtime_put_noidle(pfdev->dev);
++ panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
++ pfdev->jobs[i] = NULL;
++ }
++ }
++ spin_unlock_irqrestore(&pfdev->js->job_lock, flags);
++
++ panfrost_device_reset(pfdev);
++
++ for (i = 0; i < NUM_JOB_SLOTS; i++)
++ panfrost_scheduler_start(&pfdev->js->queue[i]);
++
++ dma_fence_end_signalling(cookie);
++}
++
+ int panfrost_job_init(struct panfrost_device *pfdev)
+ {
+ struct panfrost_job_slot *js;
+ int ret, j, irq;
+
++ INIT_WORK(&pfdev->reset.work, panfrost_reset);
++
+ pfdev->js = js = devm_kzalloc(pfdev->dev, sizeof(*js), GFP_KERNEL);
+ if (!js)
+ return -ENOMEM;
+@@ -558,7 +621,7 @@ int panfrost_job_init(struct panfrost_de
+
+ ret = drm_sched_init(&js->queue[j].sched,
+ &panfrost_sched_ops,
+- 1, 0, msecs_to_jiffies(500),
++ 1, 0, msecs_to_jiffies(JOB_TIMEOUT_MS),
+ "pan_js");
+ if (ret) {
+ dev_err(pfdev->dev, "Failed to create scheduler: %d.", ret);
--- /dev/null
+From 0fb6ee8d0b5e90b72f870f76debc8bd31a742014 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Tue, 24 Nov 2020 14:38:07 +0200
+Subject: iio: ad_sigma_delta: Don't put SPI transfer buffer on the stack
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit 0fb6ee8d0b5e90b72f870f76debc8bd31a742014 upstream.
+
+Use a heap allocated memory for the SPI transfer buffer. Using stack memory
+can corrupt stack memory when using DMA on some systems.
+
+This change moves the buffer from the stack of the trigger handler call to
+the heap of the buffer of the state struct. The size increases takes into
+account the alignment for the timestamp, which is 8 bytes.
+
+The 'data' buffer is split into 'tx_buf' and 'rx_buf', to make a clearer
+separation of which part of the buffer should be used for TX & RX.
+
+Fixes: af3008485ea03 ("iio:adc: Add common code for ADI Sigma Delta devices")
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Link: https://lore.kernel.org/r/20201124123807.19717-1-alexandru.ardelean@analog.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ad_sigma_delta.c | 18 ++++++++----------
+ include/linux/iio/adc/ad_sigma_delta.h | 6 +++++-
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+--- a/drivers/iio/adc/ad_sigma_delta.c
++++ b/drivers/iio/adc/ad_sigma_delta.c
+@@ -57,7 +57,7 @@ EXPORT_SYMBOL_GPL(ad_sd_set_comm);
+ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
+ unsigned int size, unsigned int val)
+ {
+- uint8_t *data = sigma_delta->data;
++ uint8_t *data = sigma_delta->tx_buf;
+ struct spi_transfer t = {
+ .tx_buf = data,
+ .len = size + 1,
+@@ -99,7 +99,7 @@ EXPORT_SYMBOL_GPL(ad_sd_write_reg);
+ static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
+ unsigned int reg, unsigned int size, uint8_t *val)
+ {
+- uint8_t *data = sigma_delta->data;
++ uint8_t *data = sigma_delta->tx_buf;
+ int ret;
+ struct spi_transfer t[] = {
+ {
+@@ -146,22 +146,22 @@ int ad_sd_read_reg(struct ad_sigma_delta
+ {
+ int ret;
+
+- ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data);
++ ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->rx_buf);
+ if (ret < 0)
+ goto out;
+
+ switch (size) {
+ case 4:
+- *val = get_unaligned_be32(sigma_delta->data);
++ *val = get_unaligned_be32(sigma_delta->rx_buf);
+ break;
+ case 3:
+- *val = get_unaligned_be24(&sigma_delta->data[0]);
++ *val = get_unaligned_be24(sigma_delta->rx_buf);
+ break;
+ case 2:
+- *val = get_unaligned_be16(sigma_delta->data);
++ *val = get_unaligned_be16(sigma_delta->rx_buf);
+ break;
+ case 1:
+- *val = sigma_delta->data[0];
++ *val = sigma_delta->rx_buf[0];
+ break;
+ default:
+ ret = -EINVAL;
+@@ -395,11 +395,9 @@ static irqreturn_t ad_sd_trigger_handler
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
++ uint8_t *data = sigma_delta->rx_buf;
+ unsigned int reg_size;
+ unsigned int data_reg;
+- uint8_t data[16];
+-
+- memset(data, 0x00, 16);
+
+ reg_size = indio_dev->channels[0].scan_type.realbits +
+ indio_dev->channels[0].scan_type.shift;
+--- a/include/linux/iio/adc/ad_sigma_delta.h
++++ b/include/linux/iio/adc/ad_sigma_delta.h
+@@ -79,8 +79,12 @@ struct ad_sigma_delta {
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
++ * 'tx_buf' is up to 32 bits.
++ * 'rx_buf' is up to 32 bits per sample + 64 bit timestamp,
++ * rounded to 16 bytes to take into account padding.
+ */
+- uint8_t data[4] ____cacheline_aligned;
++ uint8_t tx_buf[4] ____cacheline_aligned;
++ uint8_t rx_buf[16] __aligned(8);
+ };
+
+ static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd,
--- /dev/null
+From 560c6b914c6ec7d9d9a69fddbb5bf3bf71433e8b Mon Sep 17 00:00:00 2001
+From: Qinglang Miao <miaoqinglang@huawei.com>
+Date: Tue, 3 Nov 2020 20:07:43 +0800
+Subject: iio: adc: rockchip_saradc: fix missing clk_disable_unprepare() on error in rockchip_saradc_resume
+
+From: Qinglang Miao <miaoqinglang@huawei.com>
+
+commit 560c6b914c6ec7d9d9a69fddbb5bf3bf71433e8b upstream.
+
+Fix the missing clk_disable_unprepare() of info->pclk
+before return from rockchip_saradc_resume in the error
+handling case when fails to prepare and enable info->clk.
+
+Suggested-by: Robin Murphy <robin.murphy@arm.com>
+Fixes: 44d6f2ef94f9 ("iio: adc: add driver for Rockchip saradc")
+Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20201103120743.110662-1-miaoqinglang@huawei.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/rockchip_saradc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/rockchip_saradc.c
++++ b/drivers/iio/adc/rockchip_saradc.c
+@@ -462,7 +462,7 @@ static int rockchip_saradc_resume(struct
+
+ ret = clk_prepare_enable(info->clk);
+ if (ret)
+- return ret;
++ clk_disable_unprepare(info->pclk);
+
+ return ret;
+ }
--- /dev/null
+From 1e405bc2512f80a903ddd6ba8740cee885238d7f Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:42 +0100
+Subject: iio:adc:ti-ads124s08: Fix alignment and data leak issues.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 1e405bc2512f80a903ddd6ba8740cee885238d7f upstream.
+
+One of a class of bugs pointed out by Lars in a recent review.
+iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned
+to the size of the timestamp (8 bytes). This is not guaranteed in
+this driver which uses an array of smaller elements on the stack.
+As Lars also noted this anti pattern can involve a leak of data to
+userspace and that indeed can happen here. We close both issues by
+moving to a suitable structure in the iio_priv() data with alignment
+explicitly requested. This data is allocated with kzalloc() so no
+data can leak apart from previous readings.
+
+In this driver the timestamp can end up in various different locations
+depending on what other channels are enabled. As a result, we don't
+use a structure to specify it's position as that would be misleading.
+
+Fixes: e717f8c6dfec ("iio: adc: Add the TI ads124s08 ADC code")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Dan Murphy <dmurphy@ti.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-9-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ti-ads124s08.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/adc/ti-ads124s08.c
++++ b/drivers/iio/adc/ti-ads124s08.c
+@@ -99,6 +99,14 @@ struct ads124s_private {
+ struct gpio_desc *reset_gpio;
+ struct spi_device *spi;
+ struct mutex lock;
++ /*
++ * Used to correctly align data.
++ * Ensure timestamp is naturally aligned.
++ * Note that the full buffer length may not be needed if not
++ * all channels are enabled, as long as the alignment of the
++ * timestamp is maintained.
++ */
++ u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)] __aligned(8);
+ u8 data[5] ____cacheline_aligned;
+ };
+
+@@ -269,7 +277,6 @@ static irqreturn_t ads124s_trigger_handl
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ads124s_private *priv = iio_priv(indio_dev);
+- u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)];
+ int scan_index, j = 0;
+ int ret;
+
+@@ -284,7 +291,7 @@ static irqreturn_t ads124s_trigger_handl
+ if (ret)
+ dev_err(&priv->spi->dev, "Start ADC conversions failed\n");
+
+- buffer[j] = ads124s_read(indio_dev, scan_index);
++ priv->buffer[j] = ads124s_read(indio_dev, scan_index);
+ ret = ads124s_write_cmd(indio_dev, ADS124S08_STOP_CONV);
+ if (ret)
+ dev_err(&priv->spi->dev, "Stop ADC conversions failed\n");
+@@ -292,7 +299,7 @@ static irqreturn_t ads124s_trigger_handl
+ j++;
+ }
+
+- iio_push_to_buffers_with_timestamp(indio_dev, buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer,
+ pf->timestamp);
+
+ iio_trigger_notify_done(indio_dev->trig);
--- /dev/null
+From b0bd27f02d768e3a861c4e6c27f8e369720e6c25 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:41 +0100
+Subject: iio:adc:ti-ads124s08: Fix buffer being too long.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit b0bd27f02d768e3a861c4e6c27f8e369720e6c25 upstream.
+
+The buffer is expressed as a u32 array, yet the extra space for
+the s64 timestamp was expressed as sizeof(s64)/sizeof(u16).
+This will result in 2 extra u32 elements.
+Fix by dividing by sizeof(u32).
+
+Fixes: e717f8c6dfec ("iio: adc: Add the TI ads124s08 ADC code")
+Signed-off-by: Jonathan Cameron<Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Dan Murphy <dmurphy@ti.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-8-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ti-ads124s08.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/ti-ads124s08.c
++++ b/drivers/iio/adc/ti-ads124s08.c
+@@ -269,7 +269,7 @@ static irqreturn_t ads124s_trigger_handl
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ads124s_private *priv = iio_priv(indio_dev);
+- u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u16)];
++ u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)];
+ int scan_index, j = 0;
+ int ret;
+
--- /dev/null
+From 19ef7b70ca9487773c29b449adf0c70f540a0aab Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nuno=20S=C3=A1?= <nuno.sa@analog.com>
+Date: Thu, 12 Nov 2020 15:43:22 +0100
+Subject: iio: buffer: Fix demux update
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nuno Sá <nuno.sa@analog.com>
+
+commit 19ef7b70ca9487773c29b449adf0c70f540a0aab upstream.
+
+When updating the buffer demux, we will skip a scan element from the
+device in the case `in_ind != out_ind` and we enter the while loop.
+in_ind should only be refreshed with `find_next_bit()` in the end of the
+loop.
+
+Note, to cause problems we need a situation where we are skippig over
+an element (channel not enabled) that happens to not have the same size
+as the next element. Whilst this is a possible situation we haven't
+actually identified any cases in mainline where it happens as most drivers
+have consistent channel storage sizes with the exception of the timestamp
+which is the last element and hence never skipped over.
+
+Fixes: 5ada4ea9be16 ("staging:iio: add demux optionally to path from device to buffer")
+Signed-off-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20201112144323.28887-1-nuno.sa@analog.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/industrialio-buffer.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/industrialio-buffer.c
++++ b/drivers/iio/industrialio-buffer.c
+@@ -865,12 +865,12 @@ static int iio_buffer_update_demux(struc
+ indio_dev->masklength,
+ in_ind + 1);
+ while (in_ind != out_ind) {
+- in_ind = find_next_bit(indio_dev->active_scan_mask,
+- indio_dev->masklength,
+- in_ind + 1);
+ length = iio_storage_bytes_for_si(indio_dev, in_ind);
+ /* Make sure we are aligned */
+ in_loc = roundup(in_loc, length) + length;
++ in_ind = find_next_bit(indio_dev->active_scan_mask,
++ indio_dev->masklength,
++ in_ind + 1);
+ }
+ length = iio_storage_bytes_for_si(indio_dev, in_ind);
+ out_loc = roundup(out_loc, length);
--- /dev/null
+From 7b6b51234df6cd8b04fe736b0b89c25612d896b8 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:39 +0100
+Subject: iio:imu:bmi160: Fix alignment and data leak issues
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 7b6b51234df6cd8b04fe736b0b89c25612d896b8 upstream.
+
+One of a class of bugs pointed out by Lars in a recent review.
+iio_push_to_buffers_with_timestamp assumes the buffer used is aligned
+to the size of the timestamp (8 bytes). This is not guaranteed in
+this driver which uses an array of smaller elements on the stack.
+As Lars also noted this anti pattern can involve a leak of data to
+userspace and that indeed can happen here. We close both issues by
+moving to a suitable array in the iio_priv() data with alignment
+explicitly requested. This data is allocated with kzalloc() so no
+data can leak apart from previous readings.
+
+In this driver, depending on which channels are enabled, the timestamp
+can be in a number of locations. Hence we cannot use a structure
+to specify the data layout without it being misleading.
+
+Fixes: 77c4ad2d6a9b ("iio: imu: Add initial support for Bosch BMI160")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Daniel Baluta <daniel.baluta@gmail.com>
+Cc: Daniel Baluta <daniel.baluta@oss.nxp.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-6-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/imu/bmi160/bmi160.h | 7 +++++++
+ drivers/iio/imu/bmi160/bmi160_core.c | 6 ++----
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/imu/bmi160/bmi160.h
++++ b/drivers/iio/imu/bmi160/bmi160.h
+@@ -10,6 +10,13 @@ struct bmi160_data {
+ struct iio_trigger *trig;
+ struct regulator_bulk_data supplies[2];
+ struct iio_mount_matrix orientation;
++ /*
++ * Ensure natural alignment for timestamp if present.
++ * Max length needed: 2 * 3 channels + 4 bytes padding + 8 byte ts.
++ * If fewer channels are enabled, less space may be needed, as
++ * long as the timestamp is still aligned to 8 bytes.
++ */
++ __le16 buf[12] __aligned(8);
+ };
+
+ extern const struct regmap_config bmi160_regmap_config;
+--- a/drivers/iio/imu/bmi160/bmi160_core.c
++++ b/drivers/iio/imu/bmi160/bmi160_core.c
+@@ -427,8 +427,6 @@ static irqreturn_t bmi160_trigger_handle
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct bmi160_data *data = iio_priv(indio_dev);
+- __le16 buf[12];
+- /* 2 sens x 3 axis x __le16 + 2 x __le16 pad + 4 x __le16 tstamp */
+ int i, ret, j = 0, base = BMI160_REG_DATA_MAGN_XOUT_L;
+ __le16 sample;
+
+@@ -438,10 +436,10 @@ static irqreturn_t bmi160_trigger_handle
+ &sample, sizeof(sample));
+ if (ret)
+ goto done;
+- buf[j++] = sample;
++ data->buf[j++] = sample;
+ }
+
+- iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
++ iio_push_to_buffers_with_timestamp(indio_dev, data->buf, pf->timestamp);
+ done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
--- /dev/null
+From dc7de42d6b50a07b37feeba4c6b5136290fcee81 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:38 +0100
+Subject: iio:imu:bmi160: Fix too large a buffer.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit dc7de42d6b50a07b37feeba4c6b5136290fcee81 upstream.
+
+The comment implies this device has 3 sensor types, but it only
+has an accelerometer and a gyroscope (both 3D). As such the
+buffer does not need to be as long as stated.
+
+Note I've separated this from the following patch which fixes
+the alignment for passing to iio_push_to_buffers_with_timestamp()
+as they are different issues even if they affect the same line
+of code.
+
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Daniel Baluta <daniel.baluta@oss.nxp.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-5-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/imu/bmi160/bmi160_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/imu/bmi160/bmi160_core.c
++++ b/drivers/iio/imu/bmi160/bmi160_core.c
+@@ -427,8 +427,8 @@ static irqreturn_t bmi160_trigger_handle
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct bmi160_data *data = iio_priv(indio_dev);
+- __le16 buf[16];
+- /* 3 sens x 3 axis x __le16 + 3 x __le16 pad + 4 x __le16 tstamp */
++ __le16 buf[12];
++ /* 2 sens x 3 axis x __le16 + 2 x __le16 pad + 4 x __le16 tstamp */
+ int i, ret, j = 0, base = BMI160_REG_DATA_MAGN_XOUT_L;
+ __le16 sample;
+
--- /dev/null
+From 3f9bce7a22a3f8ac9d885c9d75bc45569f24ac8b Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sat, 14 Nov 2020 19:39:05 +0100
+Subject: iio: imu: st_lsm6dsx: fix edge-trigger interrupts
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+commit 3f9bce7a22a3f8ac9d885c9d75bc45569f24ac8b upstream.
+
+If we are using edge IRQs, new samples can arrive while processing
+current interrupt since there are no hw guarantees the irq line
+stays "low" long enough to properly detect the new interrupt.
+In this case the new sample will be missed.
+Polling FIFO status register in st_lsm6dsx_handler_thread routine
+allow us to read new samples even if the interrupt arrives while
+processing previous data and the timeslot where the line is "low"
+is too short to be properly detected.
+
+Fixes: 89ca88a7cdf2 ("iio: imu: st_lsm6dsx: support active-low interrupts")
+Fixes: 290a6ce11d93 ("iio: imu: add support to lsm6dsx driver")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/5e93cda7dc1e665f5685c53ad8e9ea71dbae782d.1605378871.git.lorenzo@kernel.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -2255,19 +2255,35 @@ st_lsm6dsx_report_motion_event(struct st
+ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
+ {
+ struct st_lsm6dsx_hw *hw = private;
++ int fifo_len = 0, len;
+ bool event;
+- int count;
+
+ event = st_lsm6dsx_report_motion_event(hw);
+
+ if (!hw->settings->fifo_ops.read_fifo)
+ return event ? IRQ_HANDLED : IRQ_NONE;
+
+- mutex_lock(&hw->fifo_lock);
+- count = hw->settings->fifo_ops.read_fifo(hw);
+- mutex_unlock(&hw->fifo_lock);
++ /*
++ * If we are using edge IRQs, new samples can arrive while
++ * processing current interrupt since there are no hw
++ * guarantees the irq line stays "low" long enough to properly
++ * detect the new interrupt. In this case the new sample will
++ * be missed.
++ * Polling FIFO status register allow us to read new
++ * samples even if the interrupt arrives while processing
++ * previous data and the timeslot where the line is "low" is
++ * too short to be properly detected.
++ */
++ do {
++ mutex_lock(&hw->fifo_lock);
++ len = hw->settings->fifo_ops.read_fifo(hw);
++ mutex_unlock(&hw->fifo_lock);
+
+- return count || event ? IRQ_HANDLED : IRQ_NONE;
++ if (len > 0)
++ fifo_len += len;
++ } while (len > 0);
++
++ return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
+ }
+
+ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
--- /dev/null
+From a61817216bcc755eabbcb1cf281d84ccad267ed1 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:35 +0100
+Subject: iio:light:rpr0521: Fix timestamp alignment and prevent data leak.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit a61817216bcc755eabbcb1cf281d84ccad267ed1 upstream.
+
+One of a class of bugs pointed out by Lars in a recent review.
+iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned
+to the size of the timestamp (8 bytes). This is not guaranteed in
+this driver which uses an array of smaller elements on the stack.
+As Lars also noted this anti pattern can involve a leak of data to
+userspace and that indeed can happen here. We close both issues by
+moving to a suitable structure in the iio_priv().
+This data is allocated with kzalloc() so no data can leak apart
+from previous readings and in this case the status byte from the device.
+
+The forced alignment of ts is not necessary in this case but it
+potentially makes the code less fragile.
+
+>From personal communications with Mikko:
+
+We could probably split the reading of the int register, but it
+would mean a significant performance cost of 20 i2c clock cycles.
+
+Fixes: e12ffd241c00 ("iio: light: rpr0521 triggered buffer")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Mikko Koivunen <mikko.koivunen@fi.rohmeurope.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-2-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/light/rpr0521.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/light/rpr0521.c
++++ b/drivers/iio/light/rpr0521.c
+@@ -194,6 +194,17 @@ struct rpr0521_data {
+ bool pxs_need_dis;
+
+ struct regmap *regmap;
++
++ /*
++ * Ensure correct naturally aligned timestamp.
++ * Note that the read will put garbage data into
++ * the padding but this should not be a problem
++ */
++ struct {
++ __le16 channels[3];
++ u8 garbage;
++ s64 ts __aligned(8);
++ } scan;
+ };
+
+ static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
+@@ -449,8 +460,6 @@ static irqreturn_t rpr0521_trigger_consu
+ struct rpr0521_data *data = iio_priv(indio_dev);
+ int err;
+
+- u8 buffer[16]; /* 3 16-bit channels + padding + ts */
+-
+ /* Use irq timestamp when reasonable. */
+ if (iio_trigger_using_own(indio_dev) && data->irq_timestamp) {
+ pf->timestamp = data->irq_timestamp;
+@@ -461,11 +470,11 @@ static irqreturn_t rpr0521_trigger_consu
+ pf->timestamp = iio_get_time_ns(indio_dev);
+
+ err = regmap_bulk_read(data->regmap, RPR0521_REG_PXS_DATA,
+- &buffer,
++ data->scan.channels,
+ (3 * 2) + 1); /* 3 * 16-bit + (discarded) int clear reg. */
+ if (!err)
+ iio_push_to_buffers_with_timestamp(indio_dev,
+- buffer, pf->timestamp);
++ &data->scan, pf->timestamp);
+ else
+ dev_err(&data->client->dev,
+ "Trigger consumer can't read from sensor.\n");
--- /dev/null
+From d837a996f57c29a985177bc03b0e599082047f27 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:36 +0100
+Subject: iio:light:st_uvis25: Fix timestamp alignment and prevent data leak.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit d837a996f57c29a985177bc03b0e599082047f27 upstream.
+
+One of a class of bugs pointed out by Lars in a recent review.
+iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned
+to the size of the timestamp (8 bytes). This is not guaranteed in
+this driver which uses an array of smaller elements on the stack.
+As Lars also noted this anti pattern can involve a leak of data to
+userspace and that indeed can happen here. We close both issues by
+moving to a suitable structure in the iio_priv()
+
+This data is allocated with kzalloc() so no data can leak apart
+from previous readings.
+
+A local unsigned int variable is used for the regmap call so it
+is clear there is no potential issue with writing into the padding
+of the structure.
+
+Fixes: 3025c8688c1e ("iio: light: add support for UVIS25 sensor")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-3-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/light/st_uvis25.h | 5 +++++
+ drivers/iio/light/st_uvis25_core.c | 8 +++++---
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/light/st_uvis25.h
++++ b/drivers/iio/light/st_uvis25.h
+@@ -27,6 +27,11 @@ struct st_uvis25_hw {
+ struct iio_trigger *trig;
+ bool enabled;
+ int irq;
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u8 chan;
++ s64 ts __aligned(8);
++ } scan;
+ };
+
+ extern const struct dev_pm_ops st_uvis25_pm_ops;
+--- a/drivers/iio/light/st_uvis25_core.c
++++ b/drivers/iio/light/st_uvis25_core.c
+@@ -232,17 +232,19 @@ static const struct iio_buffer_setup_ops
+
+ static irqreturn_t st_uvis25_buffer_handler_thread(int irq, void *p)
+ {
+- u8 buffer[ALIGN(sizeof(u8), sizeof(s64)) + sizeof(s64)];
+ struct iio_poll_func *pf = p;
+ struct iio_dev *iio_dev = pf->indio_dev;
+ struct st_uvis25_hw *hw = iio_priv(iio_dev);
++ unsigned int val;
+ int err;
+
+- err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, (int *)buffer);
++ err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, &val);
+ if (err < 0)
+ goto out;
+
+- iio_push_to_buffers_with_timestamp(iio_dev, buffer,
++ hw->scan.chan = val;
++
++ iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
+ iio_get_time_ns(iio_dev));
+
+ out:
--- /dev/null
+From 89deb1334252ea4a8491d47654811e28b0790364 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:37 +0100
+Subject: iio:magnetometer:mag3110: Fix alignment and data leak issues.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 89deb1334252ea4a8491d47654811e28b0790364 upstream.
+
+One of a class of bugs pointed out by Lars in a recent review.
+iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned
+to the size of the timestamp (8 bytes). This is not guaranteed in
+this driver which uses an array of smaller elements on the stack.
+As Lars also noted this anti pattern can involve a leak of data to
+userspace and that indeed can happen here. We close both issues by
+moving to a suitable structure in the iio_priv() data.
+This data is allocated with kzalloc() so no data can leak apart from
+previous readings.
+
+The explicit alignment of ts is not necessary in this case but
+does make the code slightly less fragile so I have included it.
+
+Fixes: 39631b5f9584 ("iio: Add Freescale mag3110 magnetometer driver")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-4-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/magnetometer/mag3110.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/magnetometer/mag3110.c
++++ b/drivers/iio/magnetometer/mag3110.c
+@@ -56,6 +56,12 @@ struct mag3110_data {
+ int sleep_val;
+ struct regulator *vdd_reg;
+ struct regulator *vddio_reg;
++ /* Ensure natural alignment of timestamp */
++ struct {
++ __be16 channels[3];
++ u8 temperature;
++ s64 ts __aligned(8);
++ } scan;
+ };
+
+ static int mag3110_request(struct mag3110_data *data)
+@@ -387,10 +393,9 @@ static irqreturn_t mag3110_trigger_handl
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct mag3110_data *data = iio_priv(indio_dev);
+- u8 buffer[16]; /* 3 16-bit channels + 1 byte temp + padding + ts */
+ int ret;
+
+- ret = mag3110_read(data, (__be16 *) buffer);
++ ret = mag3110_read(data, data->scan.channels);
+ if (ret < 0)
+ goto done;
+
+@@ -399,10 +404,10 @@ static irqreturn_t mag3110_trigger_handl
+ MAG3110_DIE_TEMP);
+ if (ret < 0)
+ goto done;
+- buffer[6] = ret;
++ data->scan.temperature = ret;
+ }
+
+- iio_push_to_buffers_with_timestamp(indio_dev, buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ iio_get_time_ns(indio_dev));
+
+ done:
--- /dev/null
+From 198cf32f0503d2ad60d320b95ef6fb8243db857f Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:40 +0100
+Subject: iio:pressure:mpl3115: Force alignment of buffer
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 198cf32f0503d2ad60d320b95ef6fb8243db857f upstream.
+
+Whilst this is another case of the issue Lars reported with
+an array of elements of smaller than 8 bytes being passed
+to iio_push_to_buffers_with_timestamp(), the solution here is
+a bit different from the other cases and relies on __aligned
+working on the stack (true since 4.6?)
+
+This one is unusual. We have to do an explicit memset() each time
+as we are reading 3 bytes into a potential 4 byte channel which
+may sometimes be a 2 byte channel depending on what is enabled.
+As such, moving the buffer to the heap in the iio_priv structure
+doesn't save us much. We can't use a nice explicit structure
+on the stack either as the data channels have different storage
+sizes and are all separately controlled.
+
+Fixes: cc26ad455f57 ("iio: Add Freescale MPL3115A2 pressure / temperature sensor driver")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Peter Meerwald <pmeerw@pmeerw.net>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-7-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/pressure/mpl3115.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/pressure/mpl3115.c
++++ b/drivers/iio/pressure/mpl3115.c
+@@ -144,7 +144,14 @@ static irqreturn_t mpl3115_trigger_handl
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct mpl3115_data *data = iio_priv(indio_dev);
+- u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */
++ /*
++ * 32-bit channel + 16-bit channel + padding + ts
++ * Note that it is possible for only one of the first 2
++ * channels to be enabled. If that happens, the first element
++ * of the buffer may be either 16 or 32-bits. As such we cannot
++ * use a simple structure definition to express this data layout.
++ */
++ u8 buffer[16] __aligned(8);
+ int ret, pos = 0;
+
+ mutex_lock(&data->lock);
--- /dev/null
+From c61b3e4839007668360ed8b87d7da96d2e59fc6c Mon Sep 17 00:00:00 2001
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+Date: Fri, 13 Nov 2020 14:58:46 -0600
+Subject: jfs: Fix array index bounds check in dbAdjTree
+
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+
+commit c61b3e4839007668360ed8b87d7da96d2e59fc6c upstream.
+
+Bounds checking tools can flag a bug in dbAdjTree() for an array index
+out of bounds in dmt_stree. Since dmt_stree can refer to the stree in
+both structures dmaptree and dmapctl, use the larger array to eliminate
+the false positive.
+
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Reported-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jfs/jfs_dmap.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/jfs/jfs_dmap.h
++++ b/fs/jfs/jfs_dmap.h
+@@ -183,7 +183,7 @@ typedef union dmtree {
+ #define dmt_leafidx t1.leafidx
+ #define dmt_height t1.height
+ #define dmt_budmin t1.budmin
+-#define dmt_stree t1.stree
++#define dmt_stree t2.stree
+
+ /*
+ * on-disk aggregate disk allocation map descriptor.
--- /dev/null
+From 2dd2a1740ee19cd2636d247276cf27bfa434b0e2 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Fri, 20 Nov 2020 08:50:07 -0800
+Subject: libnvdimm/namespace: Fix reaping of invalidated block-window-namespace labels
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 2dd2a1740ee19cd2636d247276cf27bfa434b0e2 upstream.
+
+A recent change to ndctl to attempt to reconfigure namespaces in place
+uncovered a label accounting problem in block-window-type namespaces.
+The ndctl "create.sh" test is able to trigger this signature:
+
+ WARNING: CPU: 34 PID: 9167 at drivers/nvdimm/label.c:1100 __blk_label_update+0x9a3/0xbc0 [libnvdimm]
+ [..]
+ RIP: 0010:__blk_label_update+0x9a3/0xbc0 [libnvdimm]
+ [..]
+ Call Trace:
+ uuid_store+0x21b/0x2f0 [libnvdimm]
+ kernfs_fop_write+0xcf/0x1c0
+ vfs_write+0xcc/0x380
+ ksys_write+0x68/0xe0
+
+When allocated capacity for a namespace is renamed (new UUID) the labels
+with the old UUID need to be deleted. The ndctl behavior to always
+destroy namespaces on reconfiguration hid this problem.
+
+The immediate impact of this bug is limited since block-window-type
+namespaces only seem to exist in the specification and not in any
+shipping products. However, the label handling code is being reused for
+other technologies like CXL region labels, so there is a benefit to
+making sure both vertical labels sets (block-window) and horizontal
+label sets (pmem) have a functional reference implementation in
+libnvdimm.
+
+Fixes: c4703ce11c23 ("libnvdimm/namespace: Fix label tracking error")
+Cc: <stable@vger.kernel.org>
+Cc: Vishal Verma <vishal.l.verma@intel.com>
+Cc: Dave Jiang <dave.jiang@intel.com>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/nvdimm/label.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/nvdimm/label.c
++++ b/drivers/nvdimm/label.c
+@@ -980,6 +980,15 @@ static int __blk_label_update(struct nd_
+ }
+ }
+
++ /* release slots associated with any invalidated UUIDs */
++ mutex_lock(&nd_mapping->lock);
++ list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list)
++ if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags)) {
++ reap_victim(nd_mapping, label_ent);
++ list_move(&label_ent->list, &list);
++ }
++ mutex_unlock(&nd_mapping->lock);
++
+ /*
+ * Find the resource associated with the first label in the set
+ * per the v1.2 namespace specification.
--- /dev/null
+From a8da01f79c89755fad55ed0ea96e8d2103242a72 Mon Sep 17 00:00:00 2001
+From: Zhao Heming <heming.zhao@suse.com>
+Date: Thu, 19 Nov 2020 19:41:33 +0800
+Subject: md/cluster: block reshape with remote resync job
+
+From: Zhao Heming <heming.zhao@suse.com>
+
+commit a8da01f79c89755fad55ed0ea96e8d2103242a72 upstream.
+
+Reshape request should be blocked with ongoing resync job. In cluster
+env, a node can start resync job even if the resync cmd isn't executed
+on it, e.g., user executes "mdadm --grow" on node A, sometimes node B
+will start resync job. However, current update_raid_disks() only check
+local recovery status, which is incomplete. As a result, we see user will
+execute "mdadm --grow" successfully on local, while the remote node deny
+to do reshape job when it doing resync job. The inconsistent handling
+cause array enter unexpected status. If user doesn't observe this issue
+and continue executing mdadm cmd, the array doesn't work at last.
+
+Fix this issue by blocking reshape request. When node executes "--grow"
+and detects ongoing resync, it should stop and report error to user.
+
+The following script reproduces the issue with ~100% probability.
+(two nodes share 3 iSCSI luns: sdg/sdh/sdi. Each lun size is 1GB)
+```
+ # on node1, node2 is the remote node.
+ssh root@node2 "mdadm -S --scan"
+mdadm -S --scan
+for i in {g,h,i};do dd if=/dev/zero of=/dev/sd$i oflag=direct bs=1M \
+count=20; done
+
+mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sdg /dev/sdh
+ssh root@node2 "mdadm -A /dev/md0 /dev/sdg /dev/sdh"
+
+sleep 5
+
+mdadm --manage --add /dev/md0 /dev/sdi
+mdadm --wait /dev/md0
+mdadm --grow --raid-devices=3 /dev/md0
+
+mdadm /dev/md0 --fail /dev/sdg
+mdadm /dev/md0 --remove /dev/sdg
+mdadm --grow --raid-devices=2 /dev/md0
+```
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhao Heming <heming.zhao@suse.com>
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/md.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -7278,6 +7278,7 @@ static int update_raid_disks(struct mdde
+ return -EINVAL;
+ if (mddev->sync_thread ||
+ test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
++ test_bit(MD_RESYNCING_REMOTE, &mddev->recovery) ||
+ mddev->reshape_position != MaxSector)
+ return -EBUSY;
+
+@@ -9645,8 +9646,11 @@ static void check_sb_changes(struct mdde
+ }
+ }
+
+- if (mddev->raid_disks != le32_to_cpu(sb->raid_disks))
+- update_raid_disks(mddev, le32_to_cpu(sb->raid_disks));
++ if (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) {
++ ret = update_raid_disks(mddev, le32_to_cpu(sb->raid_disks));
++ if (ret)
++ pr_warn("md: updating array disks failed. %d\n", ret);
++ }
+
+ /*
+ * Since mddev->delta_disks has already updated in update_raid_disks,
--- /dev/null
+From bca5b0658020be90b6b504ca514fd80110204f71 Mon Sep 17 00:00:00 2001
+From: Zhao Heming <heming.zhao@suse.com>
+Date: Thu, 19 Nov 2020 19:41:34 +0800
+Subject: md/cluster: fix deadlock when node is doing resync job
+
+From: Zhao Heming <heming.zhao@suse.com>
+
+commit bca5b0658020be90b6b504ca514fd80110204f71 upstream.
+
+md-cluster uses MD_CLUSTER_SEND_LOCK to make node can exclusively send msg.
+During sending msg, node can concurrently receive msg from another node.
+When node does resync job, grab token_lockres:EX may trigger a deadlock:
+```
+nodeA nodeB
+-------------------- --------------------
+a.
+send METADATA_UPDATED
+held token_lockres:EX
+ b.
+ md_do_sync
+ resync_info_update
+ send RESYNCING
+ + set MD_CLUSTER_SEND_LOCK
+ + wait for holding token_lockres:EX
+
+ c.
+ mdadm /dev/md0 --remove /dev/sdg
+ + held reconfig_mutex
+ + send REMOVE
+ + wait_event(MD_CLUSTER_SEND_LOCK)
+
+ d.
+ recv_daemon //METADATA_UPDATED from A
+ process_metadata_update
+ + (mddev_trylock(mddev) ||
+ MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD)
+ //this time, both return false forever
+```
+Explaination:
+a. A send METADATA_UPDATED
+ This will block another node to send msg
+
+b. B does sync jobs, which will send RESYNCING at intervals.
+ This will be block for holding token_lockres:EX lock.
+
+c. B do "mdadm --remove", which will send REMOVE.
+ This will be blocked by step <b>: MD_CLUSTER_SEND_LOCK is 1.
+
+d. B recv METADATA_UPDATED msg, which send from A in step <a>.
+ This will be blocked by step <c>: holding mddev lock, it makes
+ wait_event can't hold mddev lock. (btw,
+ MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD keep ZERO in this scenario.)
+
+There is a similar deadlock in commit 0ba959774e93
+("md-cluster: use sync way to handle METADATA_UPDATED msg")
+In that commit, step c is "update sb". This patch step c is
+"mdadm --remove".
+
+For fixing this issue, we can refer the solution of function:
+metadata_update_start. Which does the same grab lock_token action.
+lock_comm can use the same steps to avoid deadlock. By moving
+MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD from lock_token to lock_comm.
+It enlarge a little bit window of MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
+but it is safe & can break deadlock.
+
+Repro steps (I only triggered 3 times with hundreds tests):
+
+two nodes share 3 iSCSI luns: sdg/sdh/sdi. Each lun size is 1GB.
+```
+ssh root@node2 "mdadm -S --scan"
+mdadm -S --scan
+for i in {g,h,i};do dd if=/dev/zero of=/dev/sd$i oflag=direct bs=1M \
+count=20; done
+
+mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sdg /dev/sdh \
+ --bitmap-chunk=1M
+ssh root@node2 "mdadm -A /dev/md0 /dev/sdg /dev/sdh"
+
+sleep 5
+
+mkfs.xfs /dev/md0
+mdadm --manage --add /dev/md0 /dev/sdi
+mdadm --wait /dev/md0
+mdadm --grow --raid-devices=3 /dev/md0
+
+mdadm /dev/md0 --fail /dev/sdg
+mdadm /dev/md0 --remove /dev/sdg
+mdadm --grow --raid-devices=2 /dev/md0
+```
+
+test script will hung when executing "mdadm --remove".
+
+```
+ # dump stacks by "echo t > /proc/sysrq-trigger"
+md0_cluster_rec D 0 5329 2 0x80004000
+Call Trace:
+ __schedule+0x1f6/0x560
+ ? _cond_resched+0x2d/0x40
+ ? schedule+0x4a/0xb0
+ ? process_metadata_update.isra.0+0xdb/0x140 [md_cluster]
+ ? wait_woken+0x80/0x80
+ ? process_recvd_msg+0x113/0x1d0 [md_cluster]
+ ? recv_daemon+0x9e/0x120 [md_cluster]
+ ? md_thread+0x94/0x160 [md_mod]
+ ? wait_woken+0x80/0x80
+ ? md_congested+0x30/0x30 [md_mod]
+ ? kthread+0x115/0x140
+ ? __kthread_bind_mask+0x60/0x60
+ ? ret_from_fork+0x1f/0x40
+
+mdadm D 0 5423 1 0x00004004
+Call Trace:
+ __schedule+0x1f6/0x560
+ ? __schedule+0x1fe/0x560
+ ? schedule+0x4a/0xb0
+ ? lock_comm.isra.0+0x7b/0xb0 [md_cluster]
+ ? wait_woken+0x80/0x80
+ ? remove_disk+0x4f/0x90 [md_cluster]
+ ? hot_remove_disk+0xb1/0x1b0 [md_mod]
+ ? md_ioctl+0x50c/0xba0 [md_mod]
+ ? wait_woken+0x80/0x80
+ ? blkdev_ioctl+0xa2/0x2a0
+ ? block_ioctl+0x39/0x40
+ ? ksys_ioctl+0x82/0xc0
+ ? __x64_sys_ioctl+0x16/0x20
+ ? do_syscall_64+0x5f/0x150
+ ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+md0_resync D 0 5425 2 0x80004000
+Call Trace:
+ __schedule+0x1f6/0x560
+ ? schedule+0x4a/0xb0
+ ? dlm_lock_sync+0xa1/0xd0 [md_cluster]
+ ? wait_woken+0x80/0x80
+ ? lock_token+0x2d/0x90 [md_cluster]
+ ? resync_info_update+0x95/0x100 [md_cluster]
+ ? raid1_sync_request+0x7d3/0xa40 [raid1]
+ ? md_do_sync.cold+0x737/0xc8f [md_mod]
+ ? md_thread+0x94/0x160 [md_mod]
+ ? md_congested+0x30/0x30 [md_mod]
+ ? kthread+0x115/0x140
+ ? __kthread_bind_mask+0x60/0x60
+ ? ret_from_fork+0x1f/0x40
+```
+
+At last, thanks for Xiao's solution.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhao Heming <heming.zhao@suse.com>
+Suggested-by: Xiao Ni <xni@redhat.com>
+Reviewed-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/md-cluster.c | 67 +++++++++++++++++++++++++++---------------------
+ drivers/md/md.c | 6 ++--
+ 2 files changed, 42 insertions(+), 31 deletions(-)
+
+--- a/drivers/md/md-cluster.c
++++ b/drivers/md/md-cluster.c
+@@ -664,9 +664,27 @@ out:
+ * Takes the lock on the TOKEN lock resource so no other
+ * node can communicate while the operation is underway.
+ */
+-static int lock_token(struct md_cluster_info *cinfo, bool mddev_locked)
++static int lock_token(struct md_cluster_info *cinfo)
+ {
+- int error, set_bit = 0;
++ int error;
++
++ error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX);
++ if (error) {
++ pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n",
++ __func__, __LINE__, error);
++ } else {
++ /* Lock the receive sequence */
++ mutex_lock(&cinfo->recv_mutex);
++ }
++ return error;
++}
++
++/* lock_comm()
++ * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel.
++ */
++static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked)
++{
++ int rv, set_bit = 0;
+ struct mddev *mddev = cinfo->mddev;
+
+ /*
+@@ -677,34 +695,19 @@ static int lock_token(struct md_cluster_
+ */
+ if (mddev_locked && !test_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
+ &cinfo->state)) {
+- error = test_and_set_bit_lock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
++ rv = test_and_set_bit_lock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
+ &cinfo->state);
+- WARN_ON_ONCE(error);
++ WARN_ON_ONCE(rv);
+ md_wakeup_thread(mddev->thread);
+ set_bit = 1;
+ }
+- error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX);
+- if (set_bit)
+- clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
+
+- if (error)
+- pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n",
+- __func__, __LINE__, error);
+-
+- /* Lock the receive sequence */
+- mutex_lock(&cinfo->recv_mutex);
+- return error;
+-}
+-
+-/* lock_comm()
+- * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel.
+- */
+-static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked)
+-{
+ wait_event(cinfo->wait,
+ !test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state));
+-
+- return lock_token(cinfo, mddev_locked);
++ rv = lock_token(cinfo);
++ if (set_bit)
++ clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
++ return rv;
+ }
+
+ static void unlock_comm(struct md_cluster_info *cinfo)
+@@ -784,9 +787,11 @@ static int sendmsg(struct md_cluster_inf
+ {
+ int ret;
+
+- lock_comm(cinfo, mddev_locked);
+- ret = __sendmsg(cinfo, cmsg);
+- unlock_comm(cinfo);
++ ret = lock_comm(cinfo, mddev_locked);
++ if (!ret) {
++ ret = __sendmsg(cinfo, cmsg);
++ unlock_comm(cinfo);
++ }
+ return ret;
+ }
+
+@@ -1061,7 +1066,7 @@ static int metadata_update_start(struct
+ return 0;
+ }
+
+- ret = lock_token(cinfo, 1);
++ ret = lock_token(cinfo);
+ clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
+ return ret;
+ }
+@@ -1255,7 +1260,10 @@ static void update_size(struct mddev *md
+ int raid_slot = -1;
+
+ md_update_sb(mddev, 1);
+- lock_comm(cinfo, 1);
++ if (lock_comm(cinfo, 1)) {
++ pr_err("%s: lock_comm failed\n", __func__);
++ return;
++ }
+
+ memset(&cmsg, 0, sizeof(cmsg));
+ cmsg.type = cpu_to_le32(METADATA_UPDATED);
+@@ -1407,7 +1415,8 @@ static int add_new_disk(struct mddev *md
+ cmsg.type = cpu_to_le32(NEWDISK);
+ memcpy(cmsg.uuid, uuid, 16);
+ cmsg.raid_slot = cpu_to_le32(rdev->desc_nr);
+- lock_comm(cinfo, 1);
++ if (lock_comm(cinfo, 1))
++ return -EAGAIN;
+ ret = __sendmsg(cinfo, &cmsg);
+ if (ret) {
+ unlock_comm(cinfo);
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -6948,8 +6948,10 @@ static int hot_remove_disk(struct mddev
+ goto busy;
+
+ kick_rdev:
+- if (mddev_is_clustered(mddev))
+- md_cluster_ops->remove_disk(mddev, rdev);
++ if (mddev_is_clustered(mddev)) {
++ if (md_cluster_ops->remove_disk(mddev, rdev))
++ goto busy;
++ }
+
+ md_kick_rdev_from_array(rdev);
+ set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
--- /dev/null
+From 96999c797ec1ef41259f00b4ddf9cf33b342cb78 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 3 Aug 2020 17:36:07 +0300
+Subject: memory: jz4780_nemc: Fix an error pointer vs NULL check in probe()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 96999c797ec1ef41259f00b4ddf9cf33b342cb78 upstream.
+
+The devm_ioremap() function returns NULL on error, it doesn't return
+error pointers. This bug could lead to an Oops during probe.
+
+Fixes: f046e4a3f0b9 ("memory: jz4780_nemc: Only request IO memory the driver will use")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Paul Cercueil <paul@crapouillou.net>
+Link: https://lore.kernel.org/r/20200803143607.GC346925@mwanda
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/memory/jz4780-nemc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/memory/jz4780-nemc.c
++++ b/drivers/memory/jz4780-nemc.c
+@@ -306,9 +306,9 @@ static int jz4780_nemc_probe(struct plat
+ }
+
+ nemc->base = devm_ioremap(dev, res->start, NEMC_REG_LEN);
+- if (IS_ERR(nemc->base)) {
++ if (!nemc->base) {
+ dev_err(dev, "failed to get I/O memory\n");
+- return PTR_ERR(nemc->base);
++ return -ENOMEM;
+ }
+
+ writel(0, nemc->base + NEMC_NFCSR);
--- /dev/null
+From 4e6b86b409f9fc63fedb39d6e3a0202c4b0244ce Mon Sep 17 00:00:00 2001
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Date: Thu, 26 Nov 2020 19:11:44 +0000
+Subject: memory: renesas-rpc-if: Fix a node reference leak in rpcif_probe()
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+commit 4e6b86b409f9fc63fedb39d6e3a0202c4b0244ce upstream.
+
+Release the node reference by calling of_node_put(flash) in the probe.
+
+Fixes: ca7d8b980b67f ("memory: add Renesas RPC-IF driver")
+Reported-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Sergei Shtylyov <sergei.shtylyov@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Pavel Machek (CIP) <pavel@denx.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20201126191146.8753-4-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/memory/renesas-rpc-if.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -560,9 +560,11 @@ static int rpcif_probe(struct platform_d
+ } else if (of_device_is_compatible(flash, "cfi-flash")) {
+ name = "rpc-if-hyperflash";
+ } else {
++ of_node_put(flash);
+ dev_warn(&pdev->dev, "unknown flash type\n");
+ return -ENODEV;
+ }
++ of_node_put(flash);
+
+ vdev = platform_device_alloc(name, pdev->id);
+ if (!vdev)
--- /dev/null
+From 61a6d854b9555b420fbfae62ef26baa8b9493b32 Mon Sep 17 00:00:00 2001
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Date: Thu, 26 Nov 2020 19:11:43 +0000
+Subject: memory: renesas-rpc-if: Fix unbalanced pm_runtime_enable in rpcif_{enable,disable}_rpm
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+commit 61a6d854b9555b420fbfae62ef26baa8b9493b32 upstream.
+
+rpcif_enable_rpm calls pm_runtime_enable, so rpcif_disable_rpm needs to
+call pm_runtime_disable and not pm_runtime_put_sync.
+
+Fixes: ca7d8b980b67f ("memory: add Renesas RPC-IF driver")
+Reported-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Sergei Shtylyov <sergei.shtylyov@gmail.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20201126191146.8753-3-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/memory/renesas-rpc-if.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -212,7 +212,7 @@ EXPORT_SYMBOL(rpcif_enable_rpm);
+
+ void rpcif_disable_rpm(struct rpcif *rpc)
+ {
+- pm_runtime_put_sync(rpc->dev);
++ pm_runtime_disable(rpc->dev);
+ }
+ EXPORT_SYMBOL(rpcif_disable_rpm);
+
--- /dev/null
+From a0453f4ed066cae651b3119ed11f52d31dae1eca Mon Sep 17 00:00:00 2001
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Date: Thu, 26 Nov 2020 19:11:42 +0000
+Subject: memory: renesas-rpc-if: Return correct value to the caller of rpcif_manual_xfer()
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+commit a0453f4ed066cae651b3119ed11f52d31dae1eca upstream.
+
+In the error path of rpcif_manual_xfer() the value of ret is overwritten
+by value returned by reset_control_reset() function and thus returning
+incorrect value to the caller.
+
+This patch makes sure the correct value is returned to the caller of
+rpcif_manual_xfer() by dropping the overwrite of ret in error path.
+Also now we ignore the value returned by reset_control_reset() in the
+error path and instead print a error message when it fails.
+
+Fixes: ca7d8b980b67f ("memory: add Renesas RPC-IF driver")
+Reported-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Sergei Shtylyov <sergei.shtylyov@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Pavel Machek (CIP) <pavel@denx.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20201126191146.8753-2-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/memory/renesas-rpc-if.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -508,7 +508,8 @@ exit:
+ return ret;
+
+ err_out:
+- ret = reset_control_reset(rpc->rstc);
++ if (reset_control_reset(rpc->rstc))
++ dev_err(rpc->dev, "Failed to reset HW\n");
+ rpcif_hw_init(rpc, rpc->bus_size == 2);
+ goto exit;
+ }
--- /dev/null
+From ed89b89330b521f20682ead6bf93e1014b21a200 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 10 Oct 2020 15:20:18 +0200
+Subject: mt76: add back the SUPPORTS_REORDERING_BUFFER flag
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit ed89b89330b521f20682ead6bf93e1014b21a200 upstream.
+
+It was accidentally dropped while adding multiple wiphy support
+Fixes fast-rx support and avoids handling reordering in both mac80211
+and the driver
+
+Cc: stable@vger.kernel.org
+Fixes: c89d36254155 ("mt76: add function for allocating an extra wiphy")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/mediatek/mt76/mac80211.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -305,6 +305,7 @@ mt76_phy_init(struct mt76_dev *dev, stru
+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
+ ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
+ ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
++ ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
+
+ if (!(dev->drv->drv_flags & MT_DRV_AMSDU_OFFLOAD)) {
+ ieee80211_hw_set(hw, TX_AMSDU);
--- /dev/null
+From 1ca71415f075353974524e96ed175306d8a937a8 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Sun, 6 Dec 2020 21:22:20 +0100
+Subject: mtd: core: Fix refcounting for unpartitioned MTDs
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 1ca71415f075353974524e96ed175306d8a937a8 upstream.
+
+Apply changes to usecount also to the master partition.
+Otherwise we have no refcounting at all if an MTD has no partitions.
+
+Cc: stable@vger.kernel.org
+Fixes: 46b5889cc2c5 ("mtd: implement proper partition handling")
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201206202220.27290-1-richard@nod.at
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/mtdcore.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -993,6 +993,8 @@ int __get_mtd_device(struct mtd_info *mt
+ }
+ }
+
++ master->usecount++;
++
+ while (mtd->parent) {
+ mtd->usecount++;
+ mtd = mtd->parent;
+@@ -1059,6 +1061,8 @@ void __put_mtd_device(struct mtd_info *m
+ mtd = mtd->parent;
+ }
+
++ master->usecount--;
++
+ if (master->_put_device)
+ master->_put_device(master);
+
--- /dev/null
+From 639a82434f16a6df0ce0e7c8595976f1293940fd Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 24 Nov 2020 07:25:06 +0100
+Subject: mtd: parser: cmdline: Fix parsing of part-names with colons
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 639a82434f16a6df0ce0e7c8595976f1293940fd upstream.
+
+Some devices (especially QCA ones) are already using hardcoded partition
+names with colons in it. The OpenMesh A62 for example provides following
+mtd relevant information via cmdline:
+
+ root=31:11 mtdparts=spi0.0:256k(0:SBL1),128k(0:MIBIB),384k(0:QSEE),64k(0:CDT),64k(0:DDRPARAMS),64k(0:APPSBLENV),512k(0:APPSBL),64k(0:ART),64k(custom),64k(0:KEYS),0x002b0000(kernel),0x00c80000(rootfs),15552k(inactive) rootfsname=rootfs rootwait
+
+The change to split only on the last colon between mtd-id and partitions
+will cause newpart to see following string for the first partition:
+
+ KEYS),0x002b0000(kernel),0x00c80000(rootfs),15552k(inactive)
+
+Such a partition list cannot be parsed and thus the device fails to boot.
+
+Avoid this behavior by making sure that the start of the first part-name
+("(") will also be the last byte the mtd-id split algorithm is using for
+its colon search.
+
+Fixes: eb13fa022741 ("mtd: parser: cmdline: Support MTD names containing one or more colons")
+Cc: stable@vger.kernel.org
+Cc: Ron Minnich <rminnich@google.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201124062506.185392-1-sven@narfation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/parsers/cmdlinepart.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/parsers/cmdlinepart.c
++++ b/drivers/mtd/parsers/cmdlinepart.c
+@@ -226,7 +226,7 @@ static int mtdpart_setup_real(char *s)
+ struct cmdline_mtd_partition *this_mtd;
+ struct mtd_partition *parts;
+ int mtd_id_len, num_parts;
+- char *p, *mtd_id, *semicol;
++ char *p, *mtd_id, *semicol, *open_parenth;
+
+ /*
+ * Replace the first ';' by a NULL char so strrchr can work
+@@ -236,6 +236,14 @@ static int mtdpart_setup_real(char *s)
+ if (semicol)
+ *semicol = '\0';
+
++ /*
++ * make sure that part-names with ":" will not be handled as
++ * part of the mtd-id with an ":"
++ */
++ open_parenth = strchr(s, '(');
++ if (open_parenth)
++ *open_parenth = '\0';
++
+ mtd_id = s;
+
+ /*
+@@ -245,6 +253,10 @@ static int mtdpart_setup_real(char *s)
+ */
+ p = strrchr(s, ':');
+
++ /* Restore the '(' now. */
++ if (open_parenth)
++ *open_parenth = '(';
++
+ /* Restore the ';' now. */
+ if (semicol)
+ *semicol = ';';
--- /dev/null
+From c13d845e9a69580424d40b7b101c37d4f71bcd63 Mon Sep 17 00:00:00 2001
+From: Sergei Antonov <saproj@gmail.com>
+Date: Wed, 28 Oct 2020 12:49:40 +0300
+Subject: mtd: rawnand: meson: fix meson_nfc_dma_buffer_release() arguments
+
+From: Sergei Antonov <saproj@gmail.com>
+
+commit c13d845e9a69580424d40b7b101c37d4f71bcd63 upstream.
+
+Arguments 'infolen' and 'datalen' to meson_nfc_dma_buffer_release() were mixed up.
+
+Fixes: 8fae856c53500 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sergei Antonov <saproj@gmail.com>
+Acked-by: Liang Yang <liang.yang@amlogic.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201028094940.11765-1-saproj@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/raw/meson_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -510,7 +510,7 @@ static int meson_nfc_dma_buffer_setup(st
+ }
+
+ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
+- int infolen, int datalen,
++ int datalen, int infolen,
+ enum dma_data_direction dir)
+ {
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
--- /dev/null
+From bc3686021122de953858a5be4cbf6e3f1d821e79 Mon Sep 17 00:00:00 2001
+From: Praveenkumar I <ipkumar@codeaurora.org>
+Date: Fri, 9 Oct 2020 13:37:52 +0530
+Subject: mtd: rawnand: qcom: Fix DMA sync on FLASH_STATUS register read
+
+From: Praveenkumar I <ipkumar@codeaurora.org>
+
+commit bc3686021122de953858a5be4cbf6e3f1d821e79 upstream.
+
+After each codeword NAND_FLASH_STATUS is read for possible operational
+failures. But there is no DMA sync for CPU operation before reading it
+and this leads to incorrect or older copy of DMA buffer in reg_read_buf.
+
+This patch adds the DMA sync on reg_read_buf for CPU before reading it.
+
+Fixes: 5bc36b2bf6e2 ("mtd: rawnand: qcom: check for operation errors in case of raw read")
+Cc: stable@vger.kernel.org
+Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/1602230872-25616-1-git-send-email-ipkumar@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/raw/qcom_nandc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mtd/nand/raw/qcom_nandc.c
++++ b/drivers/mtd/nand/raw/qcom_nandc.c
+@@ -1570,6 +1570,8 @@ static int check_flash_errors(struct qco
+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
+ int i;
+
++ nandc_read_buffer_sync(nandc, true);
++
+ for (i = 0; i < cw_cnt; i++) {
+ u32 flash = le32_to_cpu(nandc->reg_read_buf[i]);
+
--- /dev/null
+From 868cbe2a6dcee451bd8f87cbbb2a73cf463b57e5 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+Date: Thu, 1 Oct 2020 12:20:13 +0200
+Subject: mtd: spinand: Fix OOB read
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+commit 868cbe2a6dcee451bd8f87cbbb2a73cf463b57e5 upstream.
+
+So far OOB have never been used in SPI-NAND, add the missing memcpy to
+make it work properly.
+
+Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201001102014.20100-6-miquel.raynal@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/spi/core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -318,6 +318,10 @@ static int spinand_write_to_cache_op(str
+ buf += ret;
+ }
+
++ if (req->ooblen)
++ memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs,
++ req->ooblen);
++
+ return 0;
+ }
+
--- /dev/null
+From 2e896d89510f23927ec393bee1e0570db3d5a6c6 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <damien.lemoal@wdc.com>
+Date: Fri, 20 Nov 2020 10:55:12 +0900
+Subject: null_blk: Fail zone append to conventional zones
+
+From: Damien Le Moal <damien.lemoal@wdc.com>
+
+commit 2e896d89510f23927ec393bee1e0570db3d5a6c6 upstream.
+
+Conventional zones do not have a write pointer and so cannot accept zone
+append writes. Make sure to fail any zone append write command issued to
+a conventional zone.
+
+Reported-by: Naohiro Aota <naohiro.aota@wdc.com>
+Fixes: e0489ed5daeb ("null_blk: Support REQ_OP_ZONE_APPEND")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/null_blk_zoned.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/block/null_blk_zoned.c
++++ b/drivers/block/null_blk_zoned.c
+@@ -339,8 +339,11 @@ static blk_status_t null_zone_write(stru
+
+ trace_nullb_zone_op(cmd, zno, zone->cond);
+
+- if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
++ if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) {
++ if (append)
++ return BLK_STS_IOERR;
+ return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
++ }
+
+ null_lock_zone(dev, zno);
+
--- /dev/null
+From 0ebcdd702f49aeb0ad2e2d894f8c124a0acc6e23 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <damien.lemoal@wdc.com>
+Date: Fri, 20 Nov 2020 10:55:11 +0900
+Subject: null_blk: Fix zone size initialization
+
+From: Damien Le Moal <damien.lemoal@wdc.com>
+
+commit 0ebcdd702f49aeb0ad2e2d894f8c124a0acc6e23 upstream.
+
+For a null_blk device with zoned mode enabled is currently initialized
+with a number of zones equal to the device capacity divided by the zone
+size, without considering if the device capacity is a multiple of the
+zone size. If the zone size is not a divisor of the capacity, the zones
+end up not covering the entire capacity, potentially resulting is out
+of bounds accesses to the zone array.
+
+Fix this by adding one last smaller zone with a size equal to the
+remainder of the disk capacity divided by the zone size if the capacity
+is not a multiple of the zone size. For such smaller last zone, the zone
+capacity is also checked so that it does not exceed the smaller zone
+size.
+
+Reported-by: Naohiro Aota <naohiro.aota@wdc.com>
+Fixes: ca4b2a011948 ("null_blk: add zone support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/null_blk_zoned.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+--- a/drivers/block/null_blk_zoned.c
++++ b/drivers/block/null_blk_zoned.c
+@@ -6,8 +6,7 @@
+ #define CREATE_TRACE_POINTS
+ #include "null_blk_trace.h"
+
+-/* zone_size in MBs to sectors. */
+-#define ZONE_SIZE_SHIFT 11
++#define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT)
+
+ static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect)
+ {
+@@ -16,7 +15,7 @@ static inline unsigned int null_zone_no(
+
+ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
+ {
+- sector_t dev_size = (sector_t)dev->size * 1024 * 1024;
++ sector_t dev_capacity_sects, zone_capacity_sects;
+ sector_t sector = 0;
+ unsigned int i;
+
+@@ -38,9 +37,13 @@ int null_init_zoned_dev(struct nullb_dev
+ return -EINVAL;
+ }
+
+- dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT;
+- dev->nr_zones = dev_size >>
+- (SECTOR_SHIFT + ilog2(dev->zone_size_sects));
++ zone_capacity_sects = MB_TO_SECTS(dev->zone_capacity);
++ dev_capacity_sects = MB_TO_SECTS(dev->size);
++ dev->zone_size_sects = MB_TO_SECTS(dev->zone_size);
++ dev->nr_zones = dev_capacity_sects >> ilog2(dev->zone_size_sects);
++ if (dev_capacity_sects & (dev->zone_size_sects - 1))
++ dev->nr_zones++;
++
+ dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct blk_zone),
+ GFP_KERNEL | __GFP_ZERO);
+ if (!dev->zones)
+@@ -101,8 +104,12 @@ int null_init_zoned_dev(struct nullb_dev
+ struct blk_zone *zone = &dev->zones[i];
+
+ zone->start = zone->wp = sector;
+- zone->len = dev->zone_size_sects;
+- zone->capacity = dev->zone_capacity << ZONE_SIZE_SHIFT;
++ if (zone->start + dev->zone_size_sects > dev_capacity_sects)
++ zone->len = dev_capacity_sects - zone->start;
++ else
++ zone->len = dev->zone_size_sects;
++ zone->capacity =
++ min_t(sector_t, zone->len, zone_capacity_sects);
+ zone->type = BLK_ZONE_TYPE_SEQWRITE_REQ;
+ zone->cond = BLK_ZONE_COND_EMPTY;
+
--- /dev/null
+From 5812b32e01c6d86ba7a84110702b46d8a8531fe9 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 23 Nov 2020 11:23:12 +0100
+Subject: of: fix linker-section match-table corruption
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5812b32e01c6d86ba7a84110702b46d8a8531fe9 upstream.
+
+Specify type alignment when declaring linker-section match-table entries
+to prevent gcc from increasing alignment and corrupting the various
+tables with padding (e.g. timers, irqchips, clocks, reserved memory).
+
+This is specifically needed on x86 where gcc (typically) aligns larger
+objects like struct of_device_id with static extent on 32-byte
+boundaries which at best prevents matching on anything but the first
+entry. Specifying alignment when declaring variables suppresses this
+optimisation.
+
+Here's a 64-bit example where all entries are corrupt as 16 bytes of
+padding has been inserted before the first entry:
+
+ ffffffff8266b4b0 D __clk_of_table
+ ffffffff8266b4c0 d __of_table_fixed_factor_clk
+ ffffffff8266b5a0 d __of_table_fixed_clk
+ ffffffff8266b680 d __clk_of_table_sentinel
+
+And here's a 32-bit example where the 8-byte-aligned table happens to be
+placed on a 32-byte boundary so that all but the first entry are corrupt
+due to the 28 bytes of padding inserted between entries:
+
+ 812b3ec0 D __irqchip_of_table
+ 812b3ec0 d __of_table_irqchip1
+ 812b3fa0 d __of_table_irqchip2
+ 812b4080 d __of_table_irqchip3
+ 812b4160 d irqchip_of_match_end
+
+Verified on x86 using gcc-9.3 and gcc-4.9 (which uses 64-byte
+alignment), and on arm using gcc-7.2.
+
+Note that there are no in-tree users of these tables on x86 currently
+(even if they are included in the image).
+
+Fixes: 54196ccbe0ba ("of: consolidate linker section OF match table declarations")
+Fixes: f6e916b82022 ("irqchip: add basic infrastructure")
+Cc: stable <stable@vger.kernel.org> # 3.9
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20201123102319.8090-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/of.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -1300,6 +1300,7 @@ static inline int of_get_available_child
+ #define _OF_DECLARE(table, name, compat, fn, fn_type) \
+ static const struct of_device_id __of_table_##name \
+ __used __section("__" #table "_of_table") \
++ __aligned(__alignof__(struct of_device_id)) \
+ = { .compatible = compat, \
+ .data = (fn == (fn_type)NULL) ? fn : fn }
+ #else
--- /dev/null
+From 398840f8bb935d33c64df4ec4fed77a7d24c267d Mon Sep 17 00:00:00 2001
+From: Aleksa Sarai <cyphar@cyphar.com>
+Date: Wed, 28 Oct 2020 10:50:43 +1100
+Subject: openat2: reject RESOLVE_BENEATH|RESOLVE_IN_ROOT
+
+From: Aleksa Sarai <cyphar@cyphar.com>
+
+commit 398840f8bb935d33c64df4ec4fed77a7d24c267d upstream.
+
+This was an oversight in the original implementation, as it makes no
+sense to specify both scoping flags to the same openat2(2) invocation
+(before this patch, the result of such an invocation was equivalent to
+RESOLVE_IN_ROOT being ignored).
+
+This is a userspace-visible ABI change, but the only user of openat2(2)
+at the moment is LXC which doesn't specify both flags and so no
+userspace programs will break as a result.
+
+Fixes: fddb5d430ad9 ("open: introduce openat2(2) syscall")
+Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
+Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
+Cc: <stable@vger.kernel.org> # v5.6+
+Link: https://lore.kernel.org/r/20201027235044.5240-2-cyphar@cyphar.com
+Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/open.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -1010,6 +1010,10 @@ inline int build_open_flags(const struct
+ if (how->resolve & ~VALID_RESOLVE_FLAGS)
+ return -EINVAL;
+
++ /* Scoping flags are mutually exclusive. */
++ if ((how->resolve & RESOLVE_BENEATH) && (how->resolve & RESOLVE_IN_ROOT))
++ return -EINVAL;
++
+ /* Deal with the mode. */
+ if (WILL_CREATE(flags)) {
+ if (how->mode & ~S_IALLUGO)
--- /dev/null
+From 4684709bf81a2d98152ed6b610e3d5c403f9bced Mon Sep 17 00:00:00 2001
+From: Jubin Zhong <zhongjubin@huawei.com>
+Date: Wed, 2 Dec 2020 10:33:42 +0800
+Subject: PCI: Fix pci_slot_release() NULL pointer dereference
+
+From: Jubin Zhong <zhongjubin@huawei.com>
+
+commit 4684709bf81a2d98152ed6b610e3d5c403f9bced upstream.
+
+If kobject_init_and_add() fails, pci_slot_release() is called to delete
+slot->list from parent->slots. But slot->list hasn't been initialized
+yet, so we dereference a NULL pointer:
+
+ Unable to handle kernel NULL pointer dereference at virtual address
+00000000
+ ...
+ CPU: 10 PID: 1 Comm: swapper/0 Not tainted 4.4.240 #197
+ task: ffffeb398a45ef10 task.stack: ffffeb398a470000
+ PC is at __list_del_entry_valid+0x5c/0xb0
+ LR is at pci_slot_release+0x84/0xe4
+ ...
+ __list_del_entry_valid+0x5c/0xb0
+ pci_slot_release+0x84/0xe4
+ kobject_put+0x184/0x1c4
+ pci_create_slot+0x17c/0x1b4
+ __pci_hp_initialize+0x68/0xa4
+ pciehp_probe+0x1a4/0x2fc
+ pcie_port_probe_service+0x58/0x84
+ driver_probe_device+0x320/0x470
+
+Initialize slot->list before calling kobject_init_and_add() to avoid this.
+
+Fixes: 8a94644b440e ("PCI: Fix pci_create_slot() reference count leak")
+Link: https://lore.kernel.org/r/1606876422-117457-1-git-send-email-zhongjubin@huawei.com
+Signed-off-by: Jubin Zhong <zhongjubin@huawei.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org # v5.9+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/slot.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/slot.c
++++ b/drivers/pci/slot.c
+@@ -272,6 +272,9 @@ placeholder:
+ goto err;
+ }
+
++ INIT_LIST_HEAD(&slot->list);
++ list_add(&slot->list, &parent->slots);
++
+ err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
+ "%s", slot_name);
+ if (err) {
+@@ -279,9 +282,6 @@ placeholder:
+ goto err;
+ }
+
+- INIT_LIST_HEAD(&slot->list);
+- list_add(&slot->list, &parent->slots);
+-
+ down_read(&pci_bus_sem);
+ list_for_each_entry(dev, &parent->devices, bus_list)
+ if (PCI_SLOT(dev->devfn) == slot_nr)
--- /dev/null
+From a1158e36f876f6269978a4176e3a1d48d27fe7a1 Mon Sep 17 00:00:00 2001
+From: Yangtao Li <frank@allwinnertech.com>
+Date: Tue, 10 Nov 2020 14:24:40 +0800
+Subject: pinctrl: sunxi: Always call chained_irq_{enter, exit} in sunxi_pinctrl_irq_handler
+
+From: Yangtao Li <frank@allwinnertech.com>
+
+commit a1158e36f876f6269978a4176e3a1d48d27fe7a1 upstream.
+
+It is found on many allwinner soc that there is a low probability that
+the interrupt status cannot be read in sunxi_pinctrl_irq_handler. This
+will cause the interrupt status of a gpio bank to always be active on
+gic, preventing gic from responding to other spi interrupts correctly.
+
+So we should call the chained_irq_* each time enter sunxi_pinctrl_irq_handler().
+
+Signed-off-by: Yangtao Li <frank@allwinnertech.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/85263ce8b058e80cea25c6ad6383eb256ce96cc8.1604988979.git.frank@allwinnertech.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -1142,20 +1142,22 @@ static void sunxi_pinctrl_irq_handler(st
+ if (bank == pctl->desc->irq_banks)
+ return;
+
++ chained_irq_enter(chip, desc);
++
+ reg = sunxi_irq_status_reg_from_bank(pctl->desc, bank);
+ val = readl(pctl->membase + reg);
+
+ if (val) {
+ int irqoffset;
+
+- chained_irq_enter(chip, desc);
+ for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
+ int pin_irq = irq_find_mapping(pctl->domain,
+ bank * IRQ_PER_BANK + irqoffset);
+ generic_handle_irq(pin_irq);
+ }
+- chained_irq_exit(chip, desc);
+ }
++
++ chained_irq_exit(chip, desc);
+ }
+
+ static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
--- /dev/null
+From fe6000990394639ed374cb76c313be3640714f47 Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Tue, 1 Dec 2020 14:57:27 +0100
+Subject: platform/x86: intel-vbtn: Allow switch events on Acer Switch Alpha 12
+
+From: Carlos Garnacho <carlosg@gnome.org>
+
+commit fe6000990394639ed374cb76c313be3640714f47 upstream.
+
+This 2-in-1 model (Product name: Switch SA5-271) features a SW_TABLET_MODE
+that works as it would be expected, both when detaching the keyboard and
+when folding it behind the tablet body.
+
+It used to work until the introduction of the allow list at
+commit 8169bd3e6e193 ("platform/x86: intel-vbtn: Switch to an allow-list
+for SW_TABLET_MODE reporting"). Add this model to it, so that the Virtual
+Buttons device announces the EV_SW features again.
+
+Fixes: 8169bd3e6e193 ("platform/x86: intel-vbtn: Switch to an allow-list for SW_TABLET_MODE reporting")
+Cc: stable@vger.kernel.org
+Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
+Link: https://lore.kernel.org/r/20201201135727.212917-1-carlosg@gnome.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/intel-vbtn.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/platform/x86/intel-vbtn.c
++++ b/drivers/platform/x86/intel-vbtn.c
+@@ -216,6 +216,12 @@ static const struct dmi_system_id dmi_sw
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"),
+ },
+ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"),
++ },
++ },
+ {} /* Array terminator */
+ };
+
--- /dev/null
+From 291de1d102fafef0798cdad9666cd4f8da7da7cc Mon Sep 17 00:00:00 2001
+From: DingHua Ma <dinghua.ma.sz@gmail.com>
+Date: Tue, 1 Dec 2020 08:10:00 +0800
+Subject: regulator: axp20x: Fix DLDO2 voltage control register mask for AXP22x
+
+From: DingHua Ma <dinghua.ma.sz@gmail.com>
+
+commit 291de1d102fafef0798cdad9666cd4f8da7da7cc upstream.
+
+When I use the axp20x chip to power my SDIO device on the 5.4 kernel,
+the output voltage of DLDO2 is wrong. After comparing the register
+manual and source code of the chip, I found that the mask bit of the
+driver register of the port was wrong. I fixed this error by modifying
+the mask register of the source code. This error seems to be a copy
+error of the macro when writing the code. Now the voltage output of
+the DLDO2 port of axp20x is correct. My development environment is
+Allwinner A40I of arm architecture, and the kernel version is 5.4.
+
+Signed-off-by: DingHua Ma <dinghua.ma.sz@gmail.com>
+Reviewed-by: Chen-Yu Tsai <wens@csie.org>
+Cc: <stable@vger.kernel.org>
+Fixes: db4a555f7c4c ("regulator: axp20x: use defines for masks")
+Link: https://lore.kernel.org/r/20201201001000.22302-1-dinghua.ma.sz@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/regulator/axp20x-regulator.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/regulator/axp20x-regulator.c
++++ b/drivers/regulator/axp20x-regulator.c
+@@ -594,7 +594,7 @@ static const struct regulator_desc axp22
+ AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK,
+ AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK),
+ AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
+- AXP22X_DLDO2_V_OUT, AXP22X_PWR_OUT_DLDO2_MASK,
++ AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT_MASK,
+ AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK),
+ AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
+ AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK,
--- /dev/null
+From 138a6428ba9023ae29e103e87a223575fbc3d2b7 Mon Sep 17 00:00:00 2001
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+Date: Sat, 21 Nov 2020 21:41:32 -0800
+Subject: remoteproc: sysmon: Ensure remote notification ordering
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+commit 138a6428ba9023ae29e103e87a223575fbc3d2b7 upstream.
+
+The reliance on the remoteproc's state for determining when to send
+sysmon notifications to a remote processor is racy with regard to
+concurrent remoteproc operations.
+
+Further more the advertisement of the state of other remote processor to
+a newly started remote processor might not only send the wrong state,
+but might result in a stream of state changes that are out of order.
+
+Address this by introducing state tracking within the sysmon instances
+themselves and extend the locking to ensure that the notifications are
+consistent with this state.
+
+Fixes: 1f36ab3f6e3b ("remoteproc: sysmon: Inform current rproc about all active rprocs")
+Fixes: 1877f54f75ad ("remoteproc: sysmon: Add notifications for events")
+Fixes: 1fb82ee806d1 ("remoteproc: qcom: Introduce sysmon")
+Cc: stable@vger.kernel.org
+Reviewed-by: Rishabh Bhatnagar <rishabhb@codeaurora.org>
+Link: https://lore.kernel.org/r/20201122054135.802935-2-bjorn.andersson@linaro.org
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/remoteproc/qcom_sysmon.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+--- a/drivers/remoteproc/qcom_sysmon.c
++++ b/drivers/remoteproc/qcom_sysmon.c
+@@ -22,6 +22,9 @@ struct qcom_sysmon {
+ struct rproc_subdev subdev;
+ struct rproc *rproc;
+
++ int state;
++ struct mutex state_lock;
++
+ struct list_head node;
+
+ const char *name;
+@@ -448,7 +451,10 @@ static int sysmon_prepare(struct rproc_s
+ .ssr_event = SSCTL_SSR_EVENT_BEFORE_POWERUP
+ };
+
++ mutex_lock(&sysmon->state_lock);
++ sysmon->state = SSCTL_SSR_EVENT_BEFORE_POWERUP;
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
++ mutex_unlock(&sysmon->state_lock);
+
+ return 0;
+ }
+@@ -472,20 +478,25 @@ static int sysmon_start(struct rproc_sub
+ .ssr_event = SSCTL_SSR_EVENT_AFTER_POWERUP
+ };
+
++ mutex_lock(&sysmon->state_lock);
++ sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP;
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
++ mutex_unlock(&sysmon->state_lock);
+
+ mutex_lock(&sysmon_lock);
+ list_for_each_entry(target, &sysmon_list, node) {
+- if (target == sysmon ||
+- target->rproc->state != RPROC_RUNNING)
++ if (target == sysmon)
+ continue;
+
++ mutex_lock(&target->state_lock);
+ event.subsys_name = target->name;
++ event.ssr_event = target->state;
+
+ if (sysmon->ssctl_version == 2)
+ ssctl_send_event(sysmon, &event);
+ else if (sysmon->ept)
+ sysmon_send_event(sysmon, &event);
++ mutex_unlock(&target->state_lock);
+ }
+ mutex_unlock(&sysmon_lock);
+
+@@ -500,7 +511,10 @@ static void sysmon_stop(struct rproc_sub
+ .ssr_event = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN
+ };
+
++ mutex_lock(&sysmon->state_lock);
++ sysmon->state = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN;
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
++ mutex_unlock(&sysmon->state_lock);
+
+ /* Don't request graceful shutdown if we've crashed */
+ if (crashed)
+@@ -521,7 +535,10 @@ static void sysmon_unprepare(struct rpro
+ .ssr_event = SSCTL_SSR_EVENT_AFTER_SHUTDOWN
+ };
+
++ mutex_lock(&sysmon->state_lock);
++ sysmon->state = SSCTL_SSR_EVENT_AFTER_SHUTDOWN;
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
++ mutex_unlock(&sysmon->state_lock);
+ }
+
+ /**
+@@ -534,11 +551,10 @@ static int sysmon_notify(struct notifier
+ void *data)
+ {
+ struct qcom_sysmon *sysmon = container_of(nb, struct qcom_sysmon, nb);
+- struct rproc *rproc = sysmon->rproc;
+ struct sysmon_event *sysmon_event = data;
+
+ /* Skip non-running rprocs and the originating instance */
+- if (rproc->state != RPROC_RUNNING ||
++ if (sysmon->state != SSCTL_SSR_EVENT_AFTER_POWERUP ||
+ !strcmp(sysmon_event->subsys_name, sysmon->name)) {
+ dev_dbg(sysmon->dev, "not notifying %s\n", sysmon->name);
+ return NOTIFY_DONE;
+@@ -591,6 +607,7 @@ struct qcom_sysmon *qcom_add_sysmon_subd
+ init_completion(&sysmon->ind_comp);
+ init_completion(&sysmon->shutdown_comp);
+ mutex_init(&sysmon->lock);
++ mutex_init(&sysmon->state_lock);
+
+ sysmon->shutdown_irq = of_irq_get_byname(sysmon->dev->of_node,
+ "shutdown-ack");
--- /dev/null
+From adab66b71abfe206a020f11e561f4df41f0b2aba Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Mon, 14 Dec 2020 12:33:51 -0500
+Subject: Revert: "ring-buffer: Remove HAVE_64BIT_ALIGNED_ACCESS"
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit adab66b71abfe206a020f11e561f4df41f0b2aba upstream.
+
+It was believed that metag was the only architecture that required the ring
+buffer to keep 8 byte words aligned on 8 byte architectures, and with its
+removal, it was assumed that the ring buffer code did not need to handle
+this case. It appears that sparc64 also requires this.
+
+The following was reported on a sparc64 boot up:
+
+ kernel: futex hash table entries: 65536 (order: 9, 4194304 bytes, linear)
+ kernel: Running postponed tracer tests:
+ kernel: Testing tracer function:
+ kernel: Kernel unaligned access at TPC[552a20] trace_function+0x40/0x140
+ kernel: Kernel unaligned access at TPC[552a24] trace_function+0x44/0x140
+ kernel: Kernel unaligned access at TPC[552a20] trace_function+0x40/0x140
+ kernel: Kernel unaligned access at TPC[552a24] trace_function+0x44/0x140
+ kernel: Kernel unaligned access at TPC[552a20] trace_function+0x40/0x140
+ kernel: PASSED
+
+Need to put back the 64BIT aligned code for the ring buffer.
+
+Link: https://lore.kernel.org/r/CADxRZqzXQRYgKc=y-KV=S_yHL+Y8Ay2mh5ezeZUnpRvg+syWKw@mail.gmail.com
+
+Cc: stable@vger.kernel.org
+Fixes: 86b3de60a0b6 ("ring-buffer: Remove HAVE_64BIT_ALIGNED_ACCESS")
+Reported-by: Anatoly Pugachev <matorola@gmail.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/Kconfig | 16 ++++++++++++++++
+ kernel/trace/ring_buffer.c | 17 +++++++++++++----
+ 2 files changed, 29 insertions(+), 4 deletions(-)
+
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -143,6 +143,22 @@ config UPROBES
+ managed by the kernel and kept transparent to the probed
+ application. )
+
++config HAVE_64BIT_ALIGNED_ACCESS
++ def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS
++ help
++ Some architectures require 64 bit accesses to be 64 bit
++ aligned, which also requires structs containing 64 bit values
++ to be 64 bit aligned too. This includes some 32 bit
++ architectures which can do 64 bit accesses, as well as 64 bit
++ architectures without unaligned access.
++
++ This symbol should be selected by an architecture if 64 bit
++ accesses are required to be 64 bit aligned in this way even
++ though it is not a 64 bit architecture.
++
++ See Documentation/unaligned-memory-access.txt for more
++ information on the topic of unaligned memory accesses.
++
+ config HAVE_EFFICIENT_UNALIGNED_ACCESS
+ bool
+ help
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -129,7 +129,16 @@ int ring_buffer_print_entry_header(struc
+ #define RB_ALIGNMENT 4U
+ #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
+ #define RB_EVNT_MIN_SIZE 8U /* two 32bit words */
+-#define RB_ALIGN_DATA __aligned(RB_ALIGNMENT)
++
++#ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS
++# define RB_FORCE_8BYTE_ALIGNMENT 0
++# define RB_ARCH_ALIGNMENT RB_ALIGNMENT
++#else
++# define RB_FORCE_8BYTE_ALIGNMENT 1
++# define RB_ARCH_ALIGNMENT 8U
++#endif
++
++#define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT)
+
+ /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */
+ #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX
+@@ -2719,7 +2728,7 @@ rb_update_event(struct ring_buffer_per_c
+
+ event->time_delta = delta;
+ length -= RB_EVNT_HDR_SIZE;
+- if (length > RB_MAX_SMALL_DATA) {
++ if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) {
+ event->type_len = 0;
+ event->array[0] = length;
+ } else
+@@ -2734,11 +2743,11 @@ static unsigned rb_calculate_event_lengt
+ if (!length)
+ length++;
+
+- if (length > RB_MAX_SMALL_DATA)
++ if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT)
+ length += sizeof(event.array[0]);
+
+ length += RB_EVNT_HDR_SIZE;
+- length = ALIGN(length, RB_ALIGNMENT);
++ length = ALIGN(length, RB_ARCH_ALIGNMENT);
+
+ /*
+ * In case the time delta is larger than the 27 bits for it
--- /dev/null
+From 00c33482bb6110bce8110daa351f9b3baf4df7dc Mon Sep 17 00:00:00 2001
+From: Nikita Shubin <nikita.shubin@maquefel.me>
+Date: Tue, 1 Dec 2020 12:55:07 +0300
+Subject: rtc: ep93xx: Fix NULL pointer dereference in ep93xx_rtc_read_time
+
+From: Nikita Shubin <nikita.shubin@maquefel.me>
+
+commit 00c33482bb6110bce8110daa351f9b3baf4df7dc upstream.
+
+Mismatch in probe platform_set_drvdata set's and method's that call
+dev_get_platdata will result in "Unable to handle kernel NULL pointer
+dereference", let's use according method for getting driver data after
+platform_set_drvdata.
+
+8<--- cut here ---
+Unable to handle kernel NULL pointer dereference at virtual address 00000000
+pgd = (ptrval)
+[00000000] *pgd=00000000
+Internal error: Oops: 5 [#1] ARM
+Modules linked in:
+CPU: 0 PID: 1 Comm: swapper Not tainted 5.9.10-00003-g723e101e0037-dirty #4
+Hardware name: Technologic Systems TS-72xx SBC
+PC is at ep93xx_rtc_read_time+0xc/0x2c
+LR is at __rtc_read_time+0x4c/0x8c
+[...]
+[<c02b01c8>] (ep93xx_rtc_read_time) from [<c02ac38c>] (__rtc_read_time+0x4c/0x8c)
+[<c02ac38c>] (__rtc_read_time) from [<c02ac3f8>] (rtc_read_time+0x2c/0x4c)
+[<c02ac3f8>] (rtc_read_time) from [<c02acc54>] (__rtc_read_alarm+0x28/0x358)
+[<c02acc54>] (__rtc_read_alarm) from [<c02abd80>] (__rtc_register_device+0x124/0x2ec)
+[<c02abd80>] (__rtc_register_device) from [<c02b028c>] (ep93xx_rtc_probe+0xa4/0xac)
+[<c02b028c>] (ep93xx_rtc_probe) from [<c026424c>] (platform_drv_probe+0x24/0x5c)
+[<c026424c>] (platform_drv_probe) from [<c0262918>] (really_probe+0x218/0x374)
+[<c0262918>] (really_probe) from [<c0262da0>] (device_driver_attach+0x44/0x60)
+[<c0262da0>] (device_driver_attach) from [<c0262e70>] (__driver_attach+0xb4/0xc0)
+[<c0262e70>] (__driver_attach) from [<c0260d44>] (bus_for_each_dev+0x68/0xac)
+[<c0260d44>] (bus_for_each_dev) from [<c026223c>] (driver_attach+0x18/0x24)
+[<c026223c>] (driver_attach) from [<c0261dd8>] (bus_add_driver+0x150/0x1b4)
+[<c0261dd8>] (bus_add_driver) from [<c026342c>] (driver_register+0xb0/0xf4)
+[<c026342c>] (driver_register) from [<c0264210>] (__platform_driver_register+0x30/0x48)
+[<c0264210>] (__platform_driver_register) from [<c04cb9ac>] (ep93xx_rtc_driver_init+0x10/0x1c)
+[<c04cb9ac>] (ep93xx_rtc_driver_init) from [<c000973c>] (do_one_initcall+0x7c/0x1c0)
+[<c000973c>] (do_one_initcall) from [<c04b9ecc>] (kernel_init_freeable+0x168/0x1ac)
+[<c04b9ecc>] (kernel_init_freeable) from [<c03b2228>] (kernel_init+0x8/0xf4)
+[<c03b2228>] (kernel_init) from [<c00082c0>] (ret_from_fork+0x14/0x34)
+Exception stack(0xc441dfb0 to 0xc441dff8)
+dfa0: 00000000 00000000 00000000 00000000
+dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
+Code: e12fff1e e92d4010 e590303c e1a02001 (e5933000)
+---[ end trace c914d6030eaa95c8 ]---
+
+Fixes: b809d192eb98 ("rtc: ep93xx: stop setting platform_data")
+Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20201201095507.10317-1-nikita.shubin@maquefel.me
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-ep93xx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/rtc/rtc-ep93xx.c
++++ b/drivers/rtc/rtc-ep93xx.c
+@@ -33,7 +33,7 @@ struct ep93xx_rtc {
+ static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
+ unsigned short *delete)
+ {
+- struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
++ struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
+ unsigned long comp;
+
+ comp = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP);
+@@ -51,7 +51,7 @@ static int ep93xx_rtc_get_swcomp(struct
+
+ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
+ {
+- struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
++ struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
+ unsigned long time;
+
+ time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
+@@ -62,7 +62,7 @@ static int ep93xx_rtc_read_time(struct d
+
+ static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm)
+ {
+- struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
++ struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
+ unsigned long secs = rtc_tm_to_time64(tm);
+
+ writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD);
--- /dev/null
+From 62e3a931db60daf94fdb3159d685a5bc6ad4d0cf Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@broadcom.com>
+Date: Tue, 20 Oct 2020 13:27:11 -0700
+Subject: scsi: lpfc: Fix invalid sleeping context in lpfc_sli4_nvmet_alloc()
+
+From: James Smart <james.smart@broadcom.com>
+
+commit 62e3a931db60daf94fdb3159d685a5bc6ad4d0cf upstream.
+
+The following calltrace was seen:
+
+BUG: sleeping function called from invalid context at mm/slab.h:494
+...
+Call Trace:
+ dump_stack+0x9a/0xf0
+ ___might_sleep.cold.63+0x13d/0x178
+ slab_pre_alloc_hook+0x6a/0x90
+ kmem_cache_alloc_trace+0x3a/0x2d0
+ lpfc_sli4_nvmet_alloc+0x4c/0x280 [lpfc]
+ lpfc_post_rq_buffer+0x2e7/0xa60 [lpfc]
+ lpfc_sli4_hba_setup+0x6b4c/0xa4b0 [lpfc]
+ lpfc_pci_probe_one_s4.isra.15+0x14f8/0x2280 [lpfc]
+ lpfc_pci_probe_one+0x260/0x2880 [lpfc]
+ local_pci_probe+0xd4/0x180
+ work_for_cpu_fn+0x51/0xa0
+ process_one_work+0x8f0/0x17b0
+ worker_thread+0x536/0xb50
+ kthread+0x30c/0x3d0
+ ret_from_fork+0x3a/0x50
+
+A prior patch introduced a spin_lock_irqsave(hbalock) in the
+lpfc_post_rq_buffer() routine. Call trace is seen as the hbalock is held
+with interrupts disabled during a GFP_KERNEL allocation in
+lpfc_sli4_nvmet_alloc().
+
+Fix by reordering locking so that hbalock not held when calling
+sli4_nvmet_alloc() (aka rqb_buf_list()).
+
+Link: https://lore.kernel.org/r/20201020202719.54726-2-james.smart@broadcom.com
+Fixes: 411de511c694 ("scsi: lpfc: Fix RQ empty firmware trap")
+Cc: <stable@vger.kernel.org> # v4.17+
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/lpfc/lpfc_mem.c | 4 +---
+ drivers/scsi/lpfc/lpfc_sli.c | 10 ++++++++--
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -588,8 +588,6 @@ lpfc_sli4_rb_free(struct lpfc_hba *phba,
+ * Description: Allocates a DMA-mapped receive buffer from the lpfc_hrb_pool PCI
+ * pool along a non-DMA-mapped container for it.
+ *
+- * Notes: Not interrupt-safe. Must be called with no locks held.
+- *
+ * Returns:
+ * pointer to HBQ on success
+ * NULL on failure
+@@ -599,7 +597,7 @@ lpfc_sli4_nvmet_alloc(struct lpfc_hba *p
+ {
+ struct rqb_dmabuf *dma_buf;
+
+- dma_buf = kzalloc(sizeof(struct rqb_dmabuf), GFP_KERNEL);
++ dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL);
+ if (!dma_buf)
+ return NULL;
+
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -7248,12 +7248,16 @@ lpfc_post_rq_buffer(struct lpfc_hba *phb
+ struct rqb_dmabuf *rqb_buffer;
+ LIST_HEAD(rqb_buf_list);
+
+- spin_lock_irqsave(&phba->hbalock, flags);
+ rqbp = hrq->rqbp;
+ for (i = 0; i < count; i++) {
++ spin_lock_irqsave(&phba->hbalock, flags);
+ /* IF RQ is already full, don't bother */
+- if (rqbp->buffer_count + i >= rqbp->entry_count - 1)
++ if (rqbp->buffer_count + i >= rqbp->entry_count - 1) {
++ spin_unlock_irqrestore(&phba->hbalock, flags);
+ break;
++ }
++ spin_unlock_irqrestore(&phba->hbalock, flags);
++
+ rqb_buffer = rqbp->rqb_alloc_buffer(phba);
+ if (!rqb_buffer)
+ break;
+@@ -7262,6 +7266,8 @@ lpfc_post_rq_buffer(struct lpfc_hba *phb
+ rqb_buffer->idx = idx;
+ list_add_tail(&rqb_buffer->hbuf.list, &rqb_buf_list);
+ }
++
++ spin_lock_irqsave(&phba->hbalock, flags);
+ while (!list_empty(&rqb_buf_list)) {
+ list_remove_head(&rqb_buf_list, rqb_buffer, struct rqb_dmabuf,
+ hbuf.list);
--- /dev/null
+From e7dab164a9aa457f89d4528452bdfc3e15ac98b6 Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@broadcom.com>
+Date: Tue, 20 Oct 2020 13:27:12 -0700
+Subject: scsi: lpfc: Fix scheduling call while in softirq context in lpfc_unreg_rpi
+
+From: James Smart <james.smart@broadcom.com>
+
+commit e7dab164a9aa457f89d4528452bdfc3e15ac98b6 upstream.
+
+The following call trace was seen during HBA reset testing:
+
+BUG: scheduling while atomic: swapper/2/0/0x10000100
+...
+Call Trace:
+dump_stack+0x19/0x1b
+__schedule_bug+0x64/0x72
+__schedule+0x782/0x840
+__cond_resched+0x26/0x30
+_cond_resched+0x3a/0x50
+mempool_alloc+0xa0/0x170
+lpfc_unreg_rpi+0x151/0x630 [lpfc]
+lpfc_sli_abts_recover_port+0x171/0x190 [lpfc]
+lpfc_sli4_abts_err_handler+0xb2/0x1f0 [lpfc]
+lpfc_sli4_io_xri_aborted+0x256/0x300 [lpfc]
+lpfc_sli4_sp_handle_abort_xri_wcqe.isra.51+0xa3/0x190 [lpfc]
+lpfc_sli4_fp_handle_cqe+0x89/0x4d0 [lpfc]
+__lpfc_sli4_process_cq+0xdb/0x2e0 [lpfc]
+__lpfc_sli4_hba_process_cq+0x41/0x100 [lpfc]
+lpfc_cq_poll_hdler+0x1a/0x30 [lpfc]
+irq_poll_softirq+0xc7/0x100
+__do_softirq+0xf5/0x280
+call_softirq+0x1c/0x30
+do_softirq+0x65/0xa0
+irq_exit+0x105/0x110
+do_IRQ+0x56/0xf0
+common_interrupt+0x16a/0x16a
+
+With the conversion to blk_io_poll for better interrupt latency in normal
+cases, it introduced this code path, executed when I/O aborts or logouts
+are seen, which attempts to allocate memory for a mailbox command to be
+issued. The allocation is GFP_KERNEL, thus it could attempt to sleep.
+
+Fix by creating a work element that performs the event handling for the
+remote port. This will have the mailbox commands and other items performed
+in the work element, not the irq. A much better method as the "irq" routine
+does not stall while performing all this deep handling code.
+
+Ensure that allocation failures are handled and send LOGO on failure.
+
+Additionally, enlarge the mailbox memory pool to reduce the possibility of
+additional allocation in this path.
+
+Link: https://lore.kernel.org/r/20201020202719.54726-3-james.smart@broadcom.com
+Fixes: 317aeb83c92b ("scsi: lpfc: Add blk_io_poll support for latency improvment")
+Cc: <stable@vger.kernel.org> # v5.9+
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/lpfc/lpfc.h | 2 -
+ drivers/scsi/lpfc/lpfc_disc.h | 2 +
+ drivers/scsi/lpfc/lpfc_hbadisc.c | 35 +++++++++++++++++++++
+ drivers/scsi/lpfc/lpfc_init.c | 46 ++++++++++++++++------------
+ drivers/scsi/lpfc/lpfc_mem.c | 5 +--
+ drivers/scsi/lpfc/lpfc_nvme.c | 18 +++++++---
+ drivers/scsi/lpfc/lpfc_sli.c | 64 +++++++++++++++++++++++++++++++--------
+ drivers/scsi/lpfc/lpfc_sli4.h | 6 +--
+ 8 files changed, 136 insertions(+), 42 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -753,7 +753,7 @@ struct lpfc_hba {
+ #define HBA_SP_QUEUE_EVT 0x8 /* Slow-path qevt posted to worker thread*/
+ #define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
+ #define HBA_PERSISTENT_TOPO 0x20 /* Persistent topology support in hba */
+-#define ELS_XRI_ABORT_EVENT 0x40
++#define ELS_XRI_ABORT_EVENT 0x40 /* ELS_XRI abort event was queued */
+ #define ASYNC_EVENT 0x80
+ #define LINK_DISABLED 0x100 /* Link disabled by user */
+ #define FCF_TS_INPROG 0x200 /* FCF table scan in progress */
+--- a/drivers/scsi/lpfc/lpfc_disc.h
++++ b/drivers/scsi/lpfc/lpfc_disc.h
+@@ -41,6 +41,7 @@ enum lpfc_work_type {
+ LPFC_EVT_DEV_LOSS,
+ LPFC_EVT_FASTPATH_MGMT_EVT,
+ LPFC_EVT_RESET_HBA,
++ LPFC_EVT_RECOVER_PORT
+ };
+
+ /* structure used to queue event to the discovery tasklet */
+@@ -128,6 +129,7 @@ struct lpfc_nodelist {
+ struct lpfc_vport *vport;
+ struct lpfc_work_evt els_retry_evt;
+ struct lpfc_work_evt dev_loss_evt;
++ struct lpfc_work_evt recovery_evt;
+ struct kref kref;
+ atomic_t cmd_pending;
+ uint32_t cmd_qdepth;
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -552,6 +552,15 @@ lpfc_work_list_done(struct lpfc_hba *phb
+ fcf_inuse,
+ nlp_did);
+ break;
++ case LPFC_EVT_RECOVER_PORT:
++ ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
++ lpfc_sli_abts_recover_port(ndlp->vport, ndlp);
++ free_evt = 0;
++ /* decrement the node reference count held for
++ * this queued work
++ */
++ lpfc_nlp_put(ndlp);
++ break;
+ case LPFC_EVT_ONLINE:
+ if (phba->link_state < LPFC_LINK_DOWN)
+ *(int *) (evtp->evt_arg1) = lpfc_online(phba);
+@@ -4515,6 +4524,8 @@ lpfc_initialize_node(struct lpfc_vport *
+ INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
+ INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
+ timer_setup(&ndlp->nlp_delayfunc, lpfc_els_retry_delay, 0);
++ INIT_LIST_HEAD(&ndlp->recovery_evt.evt_listp);
++
+ ndlp->nlp_DID = did;
+ ndlp->vport = vport;
+ ndlp->phba = vport->phba;
+@@ -5011,6 +5022,29 @@ lpfc_unreg_rpi(struct lpfc_vport *vport,
+ mempool_free(mbox, phba->mbox_mem_pool);
+ acc_plogi = 1;
+ }
++ } else {
++ lpfc_printf_vlog(vport, KERN_INFO,
++ LOG_NODE | LOG_DISCOVERY,
++ "1444 Failed to allocate mempool "
++ "unreg_rpi UNREG x%x, "
++ "DID x%x, flag x%x, "
++ "ndlp x%px\n",
++ ndlp->nlp_rpi, ndlp->nlp_DID,
++ ndlp->nlp_flag, ndlp);
++
++ /* Because mempool_alloc failed, we
++ * will issue a LOGO here and keep the rpi alive if
++ * not unloading.
++ */
++ if (!(vport->load_flag & FC_UNLOADING)) {
++ ndlp->nlp_flag &= ~NLP_UNREG_INP;
++ lpfc_issue_els_logo(vport, ndlp, 0);
++ ndlp->nlp_prev_state = ndlp->nlp_state;
++ lpfc_nlp_set_state(vport, ndlp,
++ NLP_STE_NPR_NODE);
++ }
++
++ return 1;
+ }
+ lpfc_no_rpi(phba, ndlp);
+ out:
+@@ -5214,6 +5248,7 @@ lpfc_cleanup_node(struct lpfc_vport *vpo
+
+ list_del_init(&ndlp->els_retry_evt.evt_listp);
+ list_del_init(&ndlp->dev_loss_evt.evt_listp);
++ list_del_init(&ndlp->recovery_evt.evt_listp);
+ lpfc_cleanup_vports_rrqs(vport, ndlp);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ ndlp->nlp_flag |= NLP_RELEASE_RPI;
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -5958,18 +5958,21 @@ lpfc_sli4_async_grp5_evt(struct lpfc_hba
+ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
+ {
+ struct lpfc_cq_event *cq_event;
++ unsigned long iflags;
+
+ /* First, declare the async event has been handled */
+- spin_lock_irq(&phba->hbalock);
++ spin_lock_irqsave(&phba->hbalock, iflags);
+ phba->hba_flag &= ~ASYNC_EVENT;
+- spin_unlock_irq(&phba->hbalock);
++ spin_unlock_irqrestore(&phba->hbalock, iflags);
++
+ /* Now, handle all the async events */
++ spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
+ while (!list_empty(&phba->sli4_hba.sp_asynce_work_queue)) {
+- /* Get the first event from the head of the event queue */
+- spin_lock_irq(&phba->hbalock);
+ list_remove_head(&phba->sli4_hba.sp_asynce_work_queue,
+ cq_event, struct lpfc_cq_event, list);
+- spin_unlock_irq(&phba->hbalock);
++ spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock,
++ iflags);
++
+ /* Process the asynchronous event */
+ switch (bf_get(lpfc_trailer_code, &cq_event->cqe.mcqe_cmpl)) {
+ case LPFC_TRAILER_CODE_LINK:
+@@ -6001,9 +6004,12 @@ void lpfc_sli4_async_event_proc(struct l
+ &cq_event->cqe.mcqe_cmpl));
+ break;
+ }
++
+ /* Free the completion event processed to the free pool */
+ lpfc_sli4_cq_event_release(phba, cq_event);
++ spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
+ }
++ spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags);
+ }
+
+ /**
+@@ -6630,6 +6636,8 @@ lpfc_sli4_driver_resource_setup(struct l
+ /* This abort list used by worker thread */
+ spin_lock_init(&phba->sli4_hba.sgl_list_lock);
+ spin_lock_init(&phba->sli4_hba.nvmet_io_wait_lock);
++ spin_lock_init(&phba->sli4_hba.asynce_list_lock);
++ spin_lock_init(&phba->sli4_hba.els_xri_abrt_list_lock);
+
+ /*
+ * Initialize driver internal slow-path work queues
+@@ -6641,8 +6649,6 @@ lpfc_sli4_driver_resource_setup(struct l
+ INIT_LIST_HEAD(&phba->sli4_hba.sp_queue_event);
+ /* Asynchronous event CQ Event work queue list */
+ INIT_LIST_HEAD(&phba->sli4_hba.sp_asynce_work_queue);
+- /* Fast-path XRI aborted CQ Event work queue list */
+- INIT_LIST_HEAD(&phba->sli4_hba.sp_fcp_xri_aborted_work_queue);
+ /* Slow-path XRI aborted CQ Event work queue list */
+ INIT_LIST_HEAD(&phba->sli4_hba.sp_els_xri_aborted_work_queue);
+ /* Receive queue CQ Event work queue list */
+@@ -10174,26 +10180,28 @@ lpfc_sli4_cq_event_release(struct lpfc_h
+ static void
+ lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba)
+ {
+- LIST_HEAD(cqelist);
+- struct lpfc_cq_event *cqe;
++ LIST_HEAD(cq_event_list);
++ struct lpfc_cq_event *cq_event;
+ unsigned long iflags;
+
+ /* Retrieve all the pending WCQEs from pending WCQE lists */
+- spin_lock_irqsave(&phba->hbalock, iflags);
+- /* Pending FCP XRI abort events */
+- list_splice_init(&phba->sli4_hba.sp_fcp_xri_aborted_work_queue,
+- &cqelist);
++
+ /* Pending ELS XRI abort events */
++ spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, iflags);
+ list_splice_init(&phba->sli4_hba.sp_els_xri_aborted_work_queue,
+- &cqelist);
++ &cq_event_list);
++ spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, iflags);
++
+ /* Pending asynnc events */
++ spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
+ list_splice_init(&phba->sli4_hba.sp_asynce_work_queue,
+- &cqelist);
+- spin_unlock_irqrestore(&phba->hbalock, iflags);
++ &cq_event_list);
++ spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags);
+
+- while (!list_empty(&cqelist)) {
+- list_remove_head(&cqelist, cqe, struct lpfc_cq_event, list);
+- lpfc_sli4_cq_event_release(phba, cqe);
++ while (!list_empty(&cq_event_list)) {
++ list_remove_head(&cq_event_list, cq_event,
++ struct lpfc_cq_event, list);
++ lpfc_sli4_cq_event_release(phba, cq_event);
+ }
+ }
+
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -46,6 +46,7 @@
+ #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */
+ #define LPFC_DEVICE_DATA_POOL_SIZE 64 /* max elements in device data pool */
+ #define LPFC_RRQ_POOL_SIZE 256 /* max elements in non-DMA pool */
++#define LPFC_MBX_POOL_SIZE 256 /* max elements in MBX non-DMA pool */
+
+ int
+ lpfc_mem_alloc_active_rrq_pool_s4(struct lpfc_hba *phba) {
+@@ -111,8 +112,8 @@ lpfc_mem_alloc(struct lpfc_hba *phba, in
+ pool->current_count++;
+ }
+
+- phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
+- sizeof(LPFC_MBOXQ_t));
++ phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MBX_POOL_SIZE,
++ sizeof(LPFC_MBOXQ_t));
+ if (!phba->mbox_mem_pool)
+ goto fail_free_mbuf_pool;
+
+--- a/drivers/scsi/lpfc/lpfc_nvme.c
++++ b/drivers/scsi/lpfc/lpfc_nvme.c
+@@ -2280,6 +2280,8 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_v
+ int ret, i, pending = 0;
+ struct lpfc_sli_ring *pring;
+ struct lpfc_hba *phba = vport->phba;
++ struct lpfc_sli4_hdw_queue *qp;
++ int abts_scsi, abts_nvme;
+
+ /* Host transport has to clean up and confirm requiring an indefinite
+ * wait. Print a message if a 10 second wait expires and renew the
+@@ -2290,17 +2292,23 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_v
+ ret = wait_for_completion_timeout(lport_unreg_cmp, wait_tmo);
+ if (unlikely(!ret)) {
+ pending = 0;
++ abts_scsi = 0;
++ abts_nvme = 0;
+ for (i = 0; i < phba->cfg_hdw_queue; i++) {
+- pring = phba->sli4_hba.hdwq[i].io_wq->pring;
++ qp = &phba->sli4_hba.hdwq[i];
++ pring = qp->io_wq->pring;
+ if (!pring)
+ continue;
+- if (pring->txcmplq_cnt)
+- pending += pring->txcmplq_cnt;
++ pending += pring->txcmplq_cnt;
++ abts_scsi += qp->abts_scsi_io_bufs;
++ abts_nvme += qp->abts_nvme_io_bufs;
+ }
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
+ "6176 Lport x%px Localport x%px wait "
+- "timed out. Pending %d. Renewing.\n",
+- lport, vport->localport, pending);
++ "timed out. Pending %d [%d:%d]. "
++ "Renewing.\n",
++ lport, vport->localport, pending,
++ abts_scsi, abts_nvme);
+ continue;
+ }
+ break;
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -10370,6 +10370,32 @@ lpfc_extra_ring_setup( struct lpfc_hba *
+ return 0;
+ }
+
++static void
++lpfc_sli_post_recovery_event(struct lpfc_hba *phba,
++ struct lpfc_nodelist *ndlp)
++{
++ unsigned long iflags;
++ struct lpfc_work_evt *evtp = &ndlp->recovery_evt;
++
++ spin_lock_irqsave(&phba->hbalock, iflags);
++ if (!list_empty(&evtp->evt_listp)) {
++ spin_unlock_irqrestore(&phba->hbalock, iflags);
++ return;
++ }
++
++ /* Incrementing the reference count until the queued work is done. */
++ evtp->evt_arg1 = lpfc_nlp_get(ndlp);
++ if (!evtp->evt_arg1) {
++ spin_unlock_irqrestore(&phba->hbalock, iflags);
++ return;
++ }
++ evtp->evt = LPFC_EVT_RECOVER_PORT;
++ list_add_tail(&evtp->evt_listp, &phba->work_list);
++ spin_unlock_irqrestore(&phba->hbalock, iflags);
++
++ lpfc_worker_wake_up(phba);
++}
++
+ /* lpfc_sli_abts_err_handler - handle a failed ABTS request from an SLI3 port.
+ * @phba: Pointer to HBA context object.
+ * @iocbq: Pointer to iocb object.
+@@ -10460,7 +10486,7 @@ lpfc_sli4_abts_err_handler(struct lpfc_h
+ ext_status = axri->parameter & IOERR_PARAM_MASK;
+ if ((bf_get(lpfc_wcqe_xa_status, axri) == IOSTAT_LOCAL_REJECT) &&
+ ((ext_status == IOERR_SEQUENCE_TIMEOUT) || (ext_status == 0)))
+- lpfc_sli_abts_recover_port(vport, ndlp);
++ lpfc_sli_post_recovery_event(phba, ndlp);
+ }
+
+ /**
+@@ -13068,23 +13094,30 @@ lpfc_sli_intr_handler(int irq, void *dev
+ void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba)
+ {
+ struct lpfc_cq_event *cq_event;
++ unsigned long iflags;
+
+ /* First, declare the els xri abort event has been handled */
+- spin_lock_irq(&phba->hbalock);
++ spin_lock_irqsave(&phba->hbalock, iflags);
+ phba->hba_flag &= ~ELS_XRI_ABORT_EVENT;
+- spin_unlock_irq(&phba->hbalock);
++ spin_unlock_irqrestore(&phba->hbalock, iflags);
++
+ /* Now, handle all the els xri abort events */
++ spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, iflags);
+ while (!list_empty(&phba->sli4_hba.sp_els_xri_aborted_work_queue)) {
+ /* Get the first event from the head of the event queue */
+- spin_lock_irq(&phba->hbalock);
+ list_remove_head(&phba->sli4_hba.sp_els_xri_aborted_work_queue,
+ cq_event, struct lpfc_cq_event, list);
+- spin_unlock_irq(&phba->hbalock);
++ spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock,
++ iflags);
+ /* Notify aborted XRI for ELS work queue */
+ lpfc_sli4_els_xri_aborted(phba, &cq_event->cqe.wcqe_axri);
++
+ /* Free the event processed back to the free pool */
+ lpfc_sli4_cq_event_release(phba, cq_event);
++ spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock,
++ iflags);
+ }
++ spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, iflags);
+ }
+
+ /**
+@@ -13295,9 +13328,13 @@ lpfc_sli4_sp_handle_async_event(struct l
+ cq_event = lpfc_cq_event_setup(phba, mcqe, sizeof(struct lpfc_mcqe));
+ if (!cq_event)
+ return false;
+- spin_lock_irqsave(&phba->hbalock, iflags);
++
++ spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
+ list_add_tail(&cq_event->list, &phba->sli4_hba.sp_asynce_work_queue);
++ spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags);
++
+ /* Set the async event flag */
++ spin_lock_irqsave(&phba->hbalock, iflags);
+ phba->hba_flag |= ASYNC_EVENT;
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+
+@@ -13572,17 +13609,20 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struc
+ break;
+ case LPFC_NVME_LS: /* NVME LS uses ELS resources */
+ case LPFC_ELS:
+- cq_event = lpfc_cq_event_setup(
+- phba, wcqe, sizeof(struct sli4_wcqe_xri_aborted));
+- if (!cq_event)
+- return false;
++ cq_event = lpfc_cq_event_setup(phba, wcqe, sizeof(*wcqe));
++ if (!cq_event) {
++ workposted = false;
++ break;
++ }
+ cq_event->hdwq = cq->hdwq;
+- spin_lock_irqsave(&phba->hbalock, iflags);
++ spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock,
++ iflags);
+ list_add_tail(&cq_event->list,
+ &phba->sli4_hba.sp_els_xri_aborted_work_queue);
+ /* Set the els xri abort event flag */
+ phba->hba_flag |= ELS_XRI_ABORT_EVENT;
+- spin_unlock_irqrestore(&phba->hbalock, iflags);
++ spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock,
++ iflags);
+ workposted = true;
+ break;
+ default:
+--- a/drivers/scsi/lpfc/lpfc_sli4.h
++++ b/drivers/scsi/lpfc/lpfc_sli4.h
+@@ -920,8 +920,9 @@ struct lpfc_sli4_hba {
+ struct list_head sp_queue_event;
+ struct list_head sp_cqe_event_pool;
+ struct list_head sp_asynce_work_queue;
+- struct list_head sp_fcp_xri_aborted_work_queue;
++ spinlock_t asynce_list_lock; /* protect sp_asynce_work_queue list */
+ struct list_head sp_els_xri_aborted_work_queue;
++ spinlock_t els_xri_abrt_list_lock; /* protect els_xri_aborted list */
+ struct list_head sp_unsol_work_queue;
+ struct lpfc_sli4_link link_state;
+ struct lpfc_sli4_lnk_info lnk_info;
+@@ -1103,8 +1104,7 @@ void lpfc_sli4_async_event_proc(struct l
+ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *);
+ int lpfc_sli4_resume_rpi(struct lpfc_nodelist *,
+ void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *);
+-void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *);
+-void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *);
++void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba);
+ void lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba,
+ struct sli4_wcqe_xri_aborted *axri,
+ struct lpfc_io_buf *lpfc_ncmd);
--- /dev/null
+From e5785d3ec32f5f44dd88cd7b398e496742630469 Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@broadcom.com>
+Date: Tue, 20 Oct 2020 13:27:13 -0700
+Subject: scsi: lpfc: Re-fix use after free in lpfc_rq_buf_free()
+
+From: James Smart <james.smart@broadcom.com>
+
+commit e5785d3ec32f5f44dd88cd7b398e496742630469 upstream.
+
+Commit 9816ef6ecbc1 ("scsi: lpfc: Use after free in lpfc_rq_buf_free()")
+was made to correct a use after free condition in lpfc_rq_buf_free().
+Unfortunately, a subsequent patch cut on a tree without the fix
+inadvertently reverted the fix.
+
+Put the fix back: Move the freeing of the rqb_entry to after the print
+function that references it.
+
+Link: https://lore.kernel.org/r/20201020202719.54726-4-james.smart@broadcom.com
+Fixes: 411de511c694 ("scsi: lpfc: Fix RQ empty firmware trap")
+Cc: <stable@vger.kernel.org> # v4.17+
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/lpfc/lpfc_mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -721,7 +721,6 @@ lpfc_rq_buf_free(struct lpfc_hba *phba,
+ drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys);
+ rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe);
+ if (rc < 0) {
+- (rqbp->rqb_free_buffer)(phba, rqb_entry);
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "6409 Cannot post to HRQ %d: %x %x %x "
+ "DRQ %x %x\n",
+@@ -731,6 +730,7 @@ lpfc_rq_buf_free(struct lpfc_hba *phba,
+ rqb_entry->hrq->entry_count,
+ rqb_entry->drq->host_index,
+ rqb_entry->drq->hba_index);
++ (rqbp->rqb_free_buffer)(phba, rqb_entry);
+ } else {
+ list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list);
+ rqbp->buffer_count++;
--- /dev/null
+From 8de309e7299a00b3045fb274f82b326f356404f0 Mon Sep 17 00:00:00 2001
+From: Arun Easi <aeasi@marvell.com>
+Date: Wed, 2 Dec 2020 05:23:04 -0800
+Subject: scsi: qla2xxx: Fix crash during driver load on big endian machines
+
+From: Arun Easi <aeasi@marvell.com>
+
+commit 8de309e7299a00b3045fb274f82b326f356404f0 upstream.
+
+Crash stack:
+ [576544.715489] Unable to handle kernel paging request for data at address 0xd00000000f970000
+ [576544.715497] Faulting instruction address: 0xd00000000f880f64
+ [576544.715503] Oops: Kernel access of bad area, sig: 11 [#1]
+ [576544.715506] SMP NR_CPUS=2048 NUMA pSeries
+ :
+ [576544.715703] NIP [d00000000f880f64] .qla27xx_fwdt_template_valid+0x94/0x100 [qla2xxx]
+ [576544.715722] LR [d00000000f7952dc] .qla24xx_load_risc_flash+0x2fc/0x590 [qla2xxx]
+ [576544.715726] Call Trace:
+ [576544.715731] [c0000004d0ffb000] [c0000006fe02c350] 0xc0000006fe02c350 (unreliable)
+ [576544.715750] [c0000004d0ffb080] [d00000000f7952dc] .qla24xx_load_risc_flash+0x2fc/0x590 [qla2xxx]
+ [576544.715770] [c0000004d0ffb170] [d00000000f7aa034] .qla81xx_load_risc+0x84/0x1a0 [qla2xxx]
+ [576544.715789] [c0000004d0ffb210] [d00000000f79f7c8] .qla2x00_setup_chip+0xc8/0x910 [qla2xxx]
+ [576544.715808] [c0000004d0ffb300] [d00000000f7a631c] .qla2x00_initialize_adapter+0x4dc/0xb00 [qla2xxx]
+ [576544.715826] [c0000004d0ffb3e0] [d00000000f78ce28] .qla2x00_probe_one+0xf08/0x2200 [qla2xxx]
+
+Link: https://lore.kernel.org/r/20201202132312.19966-8-njavali@marvell.com
+Fixes: f73cb695d3ec ("[SCSI] qla2xxx: Add support for ISP2071.")
+Cc: stable@vger.kernel.org
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Arun Easi <aeasi@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_tmpl.c | 9 +++++----
+ drivers/scsi/qla2xxx/qla_tmpl.h | 2 +-
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_tmpl.c
++++ b/drivers/scsi/qla2xxx/qla_tmpl.c
+@@ -928,7 +928,8 @@ qla27xx_template_checksum(void *p, ulong
+ static inline int
+ qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp)
+ {
+- return qla27xx_template_checksum(tmp, tmp->template_size) == 0;
++ return qla27xx_template_checksum(tmp,
++ le32_to_cpu(tmp->template_size)) == 0;
+ }
+
+ static inline int
+@@ -944,7 +945,7 @@ qla27xx_execute_fwdt_template(struct scs
+ ulong len = 0;
+
+ if (qla27xx_fwdt_template_valid(tmp)) {
+- len = tmp->template_size;
++ len = le32_to_cpu(tmp->template_size);
+ tmp = memcpy(buf, tmp, len);
+ ql27xx_edit_template(vha, tmp);
+ qla27xx_walk_template(vha, tmp, buf, &len);
+@@ -960,7 +961,7 @@ qla27xx_fwdt_calculate_dump_size(struct
+ ulong len = 0;
+
+ if (qla27xx_fwdt_template_valid(tmp)) {
+- len = tmp->template_size;
++ len = le32_to_cpu(tmp->template_size);
+ qla27xx_walk_template(vha, tmp, NULL, &len);
+ }
+
+@@ -972,7 +973,7 @@ qla27xx_fwdt_template_size(void *p)
+ {
+ struct qla27xx_fwdt_template *tmp = p;
+
+- return tmp->template_size;
++ return le32_to_cpu(tmp->template_size);
+ }
+
+ int
+--- a/drivers/scsi/qla2xxx/qla_tmpl.h
++++ b/drivers/scsi/qla2xxx/qla_tmpl.h
+@@ -12,7 +12,7 @@
+ struct __packed qla27xx_fwdt_template {
+ __le32 template_type;
+ __le32 entry_offset;
+- uint32_t template_size;
++ __le32 template_size;
+ uint32_t count; /* borrow field for running/residual count */
+
+ __le32 entry_count;
fsnotify-generalize-handle_inode_event.patch
inotify-convert-to-handle_inode_event-interface.patch
fsnotify-fix-events-reported-to-watching-parent-and-child.patch
+jfs-fix-array-index-bounds-check-in-dbadjtree.patch
+drm-panfrost-fix-job-timeout-handling.patch
+drm-panfrost-move-the-gpu-reset-bits-outside-the-timeout-handler.patch
+drm-amd-display-honor-the-offset-for-plane-0.patch
+drm-amdgpu-only-set-dp-subconnector-type-on-dp-and-edp-connectors.patch
+drm-amd-display-fix-memory-leaks-in-s3-resume.patch
+drm-dp_aux_dev-check-aux_dev-before-use-in-drm_dp_aux_dev_get_by_minor.patch
+drm-i915-fix-mismatch-between-misplaced-vma-check-and-vma-insert.patch
+iio-ad_sigma_delta-don-t-put-spi-transfer-buffer-on-the-stack.patch
+spi-pxa2xx-fix-use-after-free-on-unbind.patch
+spi-spi-sh-fix-use-after-free-on-unbind.patch
+spi-atmel-quadspi-fix-use-after-free-on-unbind.patch
+spi-spi-mtk-nor-don-t-leak-spi-master-in-probe-error-path.patch
+spi-ar934x-don-t-leak-spi-master-in-probe-error-path.patch
+spi-davinci-fix-use-after-free-on-unbind.patch
+spi-fsl-fix-use-of-spisel_boot-signal-on-mpc8309.patch
+spi-gpio-don-t-leak-spi-master-in-probe-error-path.patch
+spi-mxic-don-t-leak-spi-master-in-probe-error-path.patch
+spi-npcm-fiu-disable-clock-in-probe-error-path.patch
+spi-pic32-don-t-leak-dma-channels-in-probe-error-path.patch
+spi-rb4xx-don-t-leak-spi-master-in-probe-error-path.patch
+spi-rpc-if-fix-use-after-free-on-unbind.patch
+spi-sc18is602-don-t-leak-spi-master-in-probe-error-path.patch
+spi-spi-geni-qcom-fix-use-after-free-on-unbind.patch
+spi-spi-qcom-qspi-fix-use-after-free-on-unbind.patch
+spi-st-ssc4-fix-unbalanced-pm_runtime_disable-in-probe-error-path.patch
+spi-synquacer-disable-clock-in-probe-error-path.patch
+spi-mt7621-disable-clock-in-probe-error-path.patch
+spi-mt7621-don-t-leak-spi-master-in-probe-error-path.patch
+spi-atmel-quadspi-disable-clock-in-probe-error-path.patch
+spi-atmel-quadspi-fix-ahb-memory-accesses.patch
+soc-qcom-smp2p-safely-acquire-spinlock-without-irqs.patch
+mtd-spinand-fix-oob-read.patch
+mtd-parser-cmdline-fix-parsing-of-part-names-with-colons.patch
+mtd-core-fix-refcounting-for-unpartitioned-mtds.patch
+mtd-rawnand-qcom-fix-dma-sync-on-flash_status-register-read.patch
+mtd-rawnand-meson-fix-meson_nfc_dma_buffer_release-arguments.patch
+scsi-qla2xxx-fix-crash-during-driver-load-on-big-endian-machines.patch
+scsi-lpfc-fix-invalid-sleeping-context-in-lpfc_sli4_nvmet_alloc.patch
+scsi-lpfc-fix-scheduling-call-while-in-softirq-context-in-lpfc_unreg_rpi.patch
+scsi-lpfc-re-fix-use-after-free-in-lpfc_rq_buf_free.patch
+openat2-reject-resolve_beneath-resolve_in_root.patch
+iio-buffer-fix-demux-update.patch
+iio-adc-rockchip_saradc-fix-missing-clk_disable_unprepare-on-error-in-rockchip_saradc_resume.patch
+iio-imu-st_lsm6dsx-fix-edge-trigger-interrupts.patch
+iio-light-rpr0521-fix-timestamp-alignment-and-prevent-data-leak.patch
+iio-light-st_uvis25-fix-timestamp-alignment-and-prevent-data-leak.patch
+iio-magnetometer-mag3110-fix-alignment-and-data-leak-issues.patch
+iio-pressure-mpl3115-force-alignment-of-buffer.patch
+iio-imu-bmi160-fix-too-large-a-buffer.patch
+iio-imu-bmi160-fix-alignment-and-data-leak-issues.patch
+iio-adc-ti-ads124s08-fix-buffer-being-too-long.patch
+iio-adc-ti-ads124s08-fix-alignment-and-data-leak-issues.patch
+md-cluster-block-reshape-with-remote-resync-job.patch
+md-cluster-fix-deadlock-when-node-is-doing-resync-job.patch
+pinctrl-sunxi-always-call-chained_irq_-enter-exit-in-sunxi_pinctrl_irq_handler.patch
+clk-ingenic-fix-divider-calculation-with-div-tables.patch
+clk-mvebu-a3700-fix-the-xtal-mode-pin-to-mpp1_9.patch
+clk-tegra-do-not-return-0-on-failure.patch
+counter-microchip-tcb-capture-fix-cmr-value-check.patch
+device-dax-core-fix-memory-leak-when-rmmod-dax.ko.patch
+dma-buf-dma-resv-respect-num_fences-when-initializing-the-shared-fence-list.patch
+driver-core-fix-list-corruption-after-device_del.patch
+xen-blkback-set-ring-xenblkd-to-null-after-kthread_stop.patch
+xen-xenbus-allow-watches-discard-events-before-queueing.patch
+xen-xenbus-add-will_handle-callback-support-in-xenbus_watch_path.patch
+xen-xenbus-xen_bus_type-support-will_handle-watch-callback.patch
+xen-xenbus-count-pending-messages-for-each-watch.patch
+xenbus-xenbus_backend-disallow-pending-watch-messages.patch
+memory-jz4780_nemc-fix-an-error-pointer-vs-null-check-in-probe.patch
+memory-renesas-rpc-if-fix-a-node-reference-leak-in-rpcif_probe.patch
+memory-renesas-rpc-if-return-correct-value-to-the-caller-of-rpcif_manual_xfer.patch
+memory-renesas-rpc-if-fix-unbalanced-pm_runtime_enable-in-rpcif_-enable-disable-_rpm.patch
+libnvdimm-namespace-fix-reaping-of-invalidated-block-window-namespace-labels.patch
+platform-x86-intel-vbtn-allow-switch-events-on-acer-switch-alpha-12.patch
+tracing-disable-ftrace-selftests-when-any-tracer-is-running.patch
+mt76-add-back-the-supports_reordering_buffer-flag.patch
+of-fix-linker-section-match-table-corruption.patch
+pci-fix-pci_slot_release-null-pointer-dereference.patch
+regulator-axp20x-fix-dldo2-voltage-control-register-mask-for-axp22x.patch
+remoteproc-sysmon-ensure-remote-notification-ordering.patch
+thermal-drivers-cpufreq_cooling-update-cpufreq_state-only-if-state-has-changed.patch
+rtc-ep93xx-fix-null-pointer-dereference-in-ep93xx_rtc_read_time.patch
+revert-ring-buffer-remove-have_64bit_aligned_access.patch
+null_blk-fix-zone-size-initialization.patch
+null_blk-fail-zone-append-to-conventional-zones.patch
--- /dev/null
+From fc3e62e25c3896855b7c3d72df19ca6be3459c9f Mon Sep 17 00:00:00 2001
+From: Evan Green <evgreen@chromium.org>
+Date: Tue, 29 Sep 2020 13:30:57 -0700
+Subject: soc: qcom: smp2p: Safely acquire spinlock without IRQs
+
+From: Evan Green <evgreen@chromium.org>
+
+commit fc3e62e25c3896855b7c3d72df19ca6be3459c9f upstream.
+
+smp2p_update_bits() should disable interrupts when it acquires its
+spinlock. This is important because without the _irqsave, a priority
+inversion can occur.
+
+This function is called both with interrupts enabled in
+qcom_q6v5_request_stop(), and with interrupts disabled in
+ipa_smp2p_panic_notifier(). IRQ handling of spinlocks should be
+consistent to avoid the panic notifier deadlocking because it's
+sitting on the thread that's already got the lock via _request_stop().
+
+Found via lockdep.
+
+Cc: stable@vger.kernel.org
+Fixes: 50e99641413e7 ("soc: qcom: smp2p: Qualcomm Shared Memory Point to Point")
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Evan Green <evgreen@chromium.org>
+Link: https://lore.kernel.org/r/20200929133040.RESEND.1.Ideabf6dcdfc577cf39ce3d95b0e4aa1ac8b38f0c@changeid
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/soc/qcom/smp2p.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/soc/qcom/smp2p.c
++++ b/drivers/soc/qcom/smp2p.c
+@@ -318,15 +318,16 @@ static int qcom_smp2p_inbound_entry(stru
+ static int smp2p_update_bits(void *data, u32 mask, u32 value)
+ {
+ struct smp2p_entry *entry = data;
++ unsigned long flags;
+ u32 orig;
+ u32 val;
+
+- spin_lock(&entry->lock);
++ spin_lock_irqsave(&entry->lock, flags);
+ val = orig = readl(entry->value);
+ val &= ~mask;
+ val |= value;
+ writel(val, entry->value);
+- spin_unlock(&entry->lock);
++ spin_unlock_irqrestore(&entry->lock, flags);
+
+ if (val != orig)
+ qcom_smp2p_kick(entry->smp2p);
--- /dev/null
+From 236924ee531d6251c8d10e9177b7742a60534ed5 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:15 +0100
+Subject: spi: ar934x: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 236924ee531d6251c8d10e9177b7742a60534ed5 upstream.
+
+If the call to devm_spi_register_controller() fails on probe of the
+Qualcomm Atheros AR934x/QCA95xx SPI driver, the spi_controller struct is
+erroneously not freed. Fix by switching over to the new
+devm_spi_alloc_master() helper.
+
+Moreover, the controller's clock is enabled on probe but not disabled if
+any of the subsequent probe steps fail.
+
+Finally, there's an ordering issue in ar934x_spi_remove() wherein the
+clock is disabled even though the controller is not yet unregistered.
+It is unregistered after ar934x_spi_remove() by the devres framework.
+As long as it is not unregistered, SPI transfers may still be ongoing
+and disabling the clock may break them. It is not possible to use
+devm_spi_register_controller() in this case, so move to the non-devm
+variant.
+
+All of these bugs have existed since the driver was first introduced,
+so it seems fair to fix them together in a single commit.
+
+Fixes: 047980c582af ("spi: add driver for ar934x spi controller")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.7+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.7+
+Cc: Chuanhong Guo <gch981213@gmail.com>
+Link: https://lore.kernel.org/r/1d58367d74d55741e0c2730a51a2b65012c8ab33.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-ar934x.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-ar934x.c
++++ b/drivers/spi/spi-ar934x.c
+@@ -176,10 +176,11 @@ static int ar934x_spi_probe(struct platf
+ if (ret)
+ return ret;
+
+- ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp));
++ ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (!ctlr) {
+ dev_info(&pdev->dev, "failed to allocate spi controller\n");
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto err_clk_disable;
+ }
+
+ /* disable flash mapping and expose spi controller registers */
+@@ -202,7 +203,13 @@ static int ar934x_spi_probe(struct platf
+ sp->clk_freq = clk_get_rate(clk);
+ sp->ctlr = ctlr;
+
+- return devm_spi_register_controller(&pdev->dev, ctlr);
++ ret = spi_register_controller(ctlr);
++ if (!ret)
++ return 0;
++
++err_clk_disable:
++ clk_disable_unprepare(clk);
++ return ret;
+ }
+
+ static int ar934x_spi_remove(struct platform_device *pdev)
+@@ -213,6 +220,7 @@ static int ar934x_spi_remove(struct plat
+ ctlr = dev_get_drvdata(&pdev->dev);
+ sp = spi_controller_get_devdata(ctlr);
+
++ spi_unregister_controller(ctlr);
+ clk_disable_unprepare(sp->clk);
+
+ return 0;
--- /dev/null
+From 0e685017c7ba1a2fe9f6f1e7a9302890747d934c Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sun, 8 Nov 2020 23:41:00 +0100
+Subject: spi: atmel-quadspi: Disable clock in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 0e685017c7ba1a2fe9f6f1e7a9302890747d934c upstream.
+
+If the call to of_device_get_match_data() fails on probe of the Atmel
+QuadSPI driver, the clock "aq->pclk" is erroneously not unprepared and
+disabled. Fix it.
+
+Fixes: 2e5c88887358 ("spi: atmel-quadspi: add support for sam9x60 qspi controller")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.1+
+Cc: Tudor Ambarus <tudor.ambarus@microchip.com>
+Cc: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Link: https://lore.kernel.org/r/8f8dc2815aa97b2378528f08f923bf81e19611f0.1604874488.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/atmel-quadspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -591,7 +591,7 @@ static int atmel_qspi_probe(struct platf
+ if (!aq->caps) {
+ dev_err(&pdev->dev, "Could not retrieve QSPI caps\n");
+ err = -EINVAL;
+- goto exit;
++ goto disable_pclk;
+ }
+
+ if (aq->caps->has_qspick) {
--- /dev/null
+From cac8c821059639b015586abf61623c62cc549a13 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Mon, 7 Dec 2020 15:59:56 +0200
+Subject: spi: atmel-quadspi: Fix AHB memory accesses
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit cac8c821059639b015586abf61623c62cc549a13 upstream.
+
+Following error was seen when mounting a 16MByte ubifs:
+UBIFS error (ubi0:0 pid 1893): check_lpt_type.constprop.6: invalid type (15) in LPT node type
+
+QSPI_IFR.TFRTYP was not set correctly. When data transfer is enabled
+and one wants to access the serial memory through AHB in order to:
+ - read in the serial memory, but not a memory data, for example
+ a JEDEC-ID, QSPI_IFR.TFRTYP must be written to '0' (both sama5d2
+ and sam9x60).
+ - read in the serial memory, and particularly a memory data,
+ TFRTYP must be written to '1' (both sama5d2 and sam9x60).
+ - write in the serial memory, but not a memory data, for example
+ writing the configuration or the QSPI_SR, TFRTYP must be written
+ to '2' for sama5d2 and to '0' for sam9x60.
+ - write in the serial memory in particular to program a memory data,
+ TFRTYP must be written to '3' for sama5d2 and to '1' for sam9x60.
+
+Fix the setting of the QSPI_IFR.TFRTYP field.
+
+Fixes: 2d30ac5ed633 ("mtd: spi-nor: atmel-quadspi: Use spi-mem interface for atmel-quadspi driver")
+Cc: <stable@vger.kernel.org> # v5.0+
+Reported-by: Tom Burkart <tom@aussec.com>
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Link: https://lore.kernel.org/r/20201207135959.154124-2-tudor.ambarus@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/atmel-quadspi.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -365,10 +365,14 @@ static int atmel_qspi_set_cfg(struct atm
+ if (dummy_cycles)
+ ifr |= QSPI_IFR_NBDUM(dummy_cycles);
+
+- /* Set data enable */
+- if (op->data.nbytes)
++ /* Set data enable and data transfer type. */
++ if (op->data.nbytes) {
+ ifr |= QSPI_IFR_DATAEN;
+
++ if (op->addr.nbytes)
++ ifr |= QSPI_IFR_TFRTYP_MEM;
++ }
++
+ /*
+ * If the QSPI controller is set in regular SPI mode, set it in
+ * Serial Memory Mode (SMM).
+@@ -393,7 +397,7 @@ static int atmel_qspi_set_cfg(struct atm
+ atmel_qspi_write(icr, aq, QSPI_WICR);
+ atmel_qspi_write(ifr, aq, QSPI_IFR);
+ } else {
+- if (op->data.dir == SPI_MEM_DATA_OUT)
++ if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
+ ifr |= QSPI_IFR_SAMA5D2_WRITE_TRSFR;
+
+ /* Set QSPI Instruction Frame registers */
--- /dev/null
+From c7b884561cb5b641f3dbba950094110794119a6d Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:17 +0100
+Subject: spi: atmel-quadspi: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit c7b884561cb5b641f3dbba950094110794119a6d upstream.
+
+atmel_qspi_remove() accesses the driver's private data after calling
+spi_unregister_controller() even though that function releases the last
+reference on the spi_controller and thereby frees the private data.
+
+Fix by switching over to the new devm_spi_alloc_master() helper which
+keeps the private data accessible until the driver has unbound.
+
+Fixes: 2d30ac5ed633 ("mtd: spi-nor: atmel-quadspi: Use spi-mem interface for atmel-quadspi driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.0+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.0+
+Cc: Piotr Bugalski <bugalski.piotr@gmail.com>
+Link: https://lore.kernel.org/r/4b05c65cf6f1ea3251484fe9a00b4c65478a1ae3.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/atmel-quadspi.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -535,7 +535,7 @@ static int atmel_qspi_probe(struct platf
+ struct resource *res;
+ int irq, err = 0;
+
+- ctrl = spi_alloc_master(&pdev->dev, sizeof(*aq));
++ ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*aq));
+ if (!ctrl)
+ return -ENOMEM;
+
+@@ -557,8 +557,7 @@ static int atmel_qspi_probe(struct platf
+ aq->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(aq->regs)) {
+ dev_err(&pdev->dev, "missing registers\n");
+- err = PTR_ERR(aq->regs);
+- goto exit;
++ return PTR_ERR(aq->regs);
+ }
+
+ /* Map the AHB memory */
+@@ -566,8 +565,7 @@ static int atmel_qspi_probe(struct platf
+ aq->mem = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(aq->mem)) {
+ dev_err(&pdev->dev, "missing AHB memory\n");
+- err = PTR_ERR(aq->mem);
+- goto exit;
++ return PTR_ERR(aq->mem);
+ }
+
+ aq->mmap_size = resource_size(res);
+@@ -579,15 +577,14 @@ static int atmel_qspi_probe(struct platf
+
+ if (IS_ERR(aq->pclk)) {
+ dev_err(&pdev->dev, "missing peripheral clock\n");
+- err = PTR_ERR(aq->pclk);
+- goto exit;
++ return PTR_ERR(aq->pclk);
+ }
+
+ /* Enable the peripheral clock */
+ err = clk_prepare_enable(aq->pclk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable the peripheral clock\n");
+- goto exit;
++ return err;
+ }
+
+ aq->caps = of_device_get_match_data(&pdev->dev);
+@@ -638,8 +635,6 @@ disable_qspick:
+ clk_disable_unprepare(aq->qspick);
+ disable_pclk:
+ clk_disable_unprepare(aq->pclk);
+-exit:
+- spi_controller_put(ctrl);
+
+ return err;
+ }
--- /dev/null
+From 373afef350a93519b4b8d636b0895da8650b714b Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:01 +0100
+Subject: spi: davinci: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 373afef350a93519b4b8d636b0895da8650b714b upstream.
+
+davinci_spi_remove() accesses the driver's private data after it's been
+freed with spi_master_put().
+
+Fix by moving the spi_master_put() to the end of the function.
+
+Fixes: fe5fd2540947 ("spi: davinci: Use dma_request_chan() for requesting DMA channel")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Cc: <stable@vger.kernel.org> # v4.7+
+Link: https://lore.kernel.org/r/412f7eb1cf8990e0a3a2153f4c577298deab623e.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-davinci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-davinci.c
++++ b/drivers/spi/spi-davinci.c
+@@ -1040,13 +1040,13 @@ static int davinci_spi_remove(struct pla
+ spi_bitbang_stop(&dspi->bitbang);
+
+ clk_disable_unprepare(dspi->clk);
+- spi_master_put(master);
+
+ if (dspi->dma_rx) {
+ dma_release_channel(dspi->dma_rx);
+ dma_release_channel(dspi->dma_tx);
+ }
+
++ spi_master_put(master);
+ return 0;
+ }
+
--- /dev/null
+From 122541f2b10897b08f7f7e6db5f1eb693e51f0a1 Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+Date: Fri, 27 Nov 2020 16:29:47 +0100
+Subject: spi: fsl: fix use of spisel_boot signal on MPC8309
+
+From: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+
+commit 122541f2b10897b08f7f7e6db5f1eb693e51f0a1 upstream.
+
+Commit 0f0581b24bd0 ("spi: fsl: Convert to use CS GPIO descriptors")
+broke the use of the SPISEL_BOOT signal as a chip select on the
+MPC8309.
+
+pdata->max_chipselect, which becomes master->num_chipselect, must be
+initialized to take into account the possibility that there's one more
+chip select in use than the number of GPIO chip selects.
+
+Cc: stable@vger.kernel.org # v5.4+
+Cc: Christophe Leroy <christophe.leroy@c-s.fr>
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Fixes: 0f0581b24bd0 ("spi: fsl: Convert to use CS GPIO descriptors")
+Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+Link: https://lore.kernel.org/r/20201127152947.376-1-rasmus.villemoes@prevas.dk
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-fsl-spi.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -716,10 +716,11 @@ static int of_fsl_spi_probe(struct platf
+ type = fsl_spi_get_type(&ofdev->dev);
+ if (type == TYPE_FSL) {
+ struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
++ bool spisel_boot = false;
+ #if IS_ENABLED(CONFIG_FSL_SOC)
+ struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+- bool spisel_boot = of_property_read_bool(np, "fsl,spisel_boot");
+
++ spisel_boot = of_property_read_bool(np, "fsl,spisel_boot");
+ if (spisel_boot) {
+ pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4);
+ if (!pinfo->immr_spi_cs)
+@@ -734,10 +735,14 @@ static int of_fsl_spi_probe(struct platf
+ * supported on the GRLIB variant.
+ */
+ ret = gpiod_count(dev, "cs");
+- if (ret <= 0)
++ if (ret < 0)
++ ret = 0;
++ if (ret == 0 && !spisel_boot) {
+ pdata->max_chipselect = 1;
+- else
++ } else {
++ pdata->max_chipselect = ret + spisel_boot;
+ pdata->cs_control = fsl_spi_cs_control;
++ }
+ }
+
+ ret = of_address_to_resource(np, 0, &mem);
--- /dev/null
+From 7174dc655ef0578877b0b4598e69619d2be28b4d Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:09 +0100
+Subject: spi: gpio: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 7174dc655ef0578877b0b4598e69619d2be28b4d upstream.
+
+If the call to devm_spi_register_master() fails on probe of the GPIO SPI
+driver, the spi_master struct is erroneously not freed:
+
+After allocating the spi_master, its reference count is 1. The driver
+unconditionally decrements the reference count on unbind using a devm
+action. Before calling devm_spi_register_master(), the driver
+unconditionally increments the reference count because on success,
+that function will decrement the reference count on unbind. However on
+failure, devm_spi_register_master() does *not* decrement the reference
+count, so the spi_master is leaked.
+
+The issue was introduced by commits 8b797490b4db ("spi: gpio: Make sure
+spi_master_put() is called in every error path") and 79567c1a321e ("spi:
+gpio: Use devm_spi_register_master()"), which sought to plug leaks
+introduced by 9b00bc7b901f ("spi: spi-gpio: Rewrite to use GPIO
+descriptors") but missed this remaining leak.
+
+The situation was later aggravated by commit d3b0ffa1d75d ("spi: gpio:
+prevent memory leak in spi_gpio_probe"), which introduced a
+use-after-free because it releases a reference on the spi_master if
+devm_add_action_or_reset() fails even though the function already
+does that.
+
+Fix by switching over to the new devm_spi_alloc_master() helper.
+
+Fixes: 9b00bc7b901f ("spi: spi-gpio: Rewrite to use GPIO descriptors")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Cc: <stable@vger.kernel.org> # v4.17+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.1-: 8b797490b4db: spi: gpio: Make sure spi_master_put() is called in every error path
+Cc: <stable@vger.kernel.org> # v5.1-: 45beec351998: spi: bitbang: Introduce spi_bitbang_init()
+Cc: <stable@vger.kernel.org> # v5.1-: 79567c1a321e: spi: gpio: Use devm_spi_register_master()
+Cc: <stable@vger.kernel.org> # v5.4-: d3b0ffa1d75d: spi: gpio: prevent memory leak in spi_gpio_probe
+Cc: <stable@vger.kernel.org> # v4.17+
+Cc: Navid Emamdoost <navid.emamdoost@gmail.com>
+Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
+Link: https://lore.kernel.org/r/86eaed27431c3d709e3748eb76ceecbfc790dd37.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-gpio.c | 15 ++-------------
+ 1 file changed, 2 insertions(+), 13 deletions(-)
+
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -350,11 +350,6 @@ static int spi_gpio_probe_pdata(struct p
+ return 0;
+ }
+
+-static void spi_gpio_put(void *data)
+-{
+- spi_master_put(data);
+-}
+-
+ static int spi_gpio_probe(struct platform_device *pdev)
+ {
+ int status;
+@@ -363,16 +358,10 @@ static int spi_gpio_probe(struct platfor
+ struct device *dev = &pdev->dev;
+ struct spi_bitbang *bb;
+
+- master = spi_alloc_master(dev, sizeof(*spi_gpio));
++ master = devm_spi_alloc_master(dev, sizeof(*spi_gpio));
+ if (!master)
+ return -ENOMEM;
+
+- status = devm_add_action_or_reset(&pdev->dev, spi_gpio_put, master);
+- if (status) {
+- spi_master_put(master);
+- return status;
+- }
+-
+ if (pdev->dev.of_node)
+ status = spi_gpio_probe_dt(pdev, master);
+ else
+@@ -432,7 +421,7 @@ static int spi_gpio_probe(struct platfor
+ if (status)
+ return status;
+
+- return devm_spi_register_master(&pdev->dev, spi_master_get(master));
++ return devm_spi_register_master(&pdev->dev, master);
+ }
+
+ MODULE_ALIAS("platform:" DRIVER_NAME);
--- /dev/null
+From 24f7033405abe195224ec793dbc3d7a27dec0b98 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:13 +0100
+Subject: spi: mt7621: Disable clock in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 24f7033405abe195224ec793dbc3d7a27dec0b98 upstream.
+
+Commit 702b15cb9712 ("spi: mt7621: fix missing clk_disable_unprepare()
+on error in mt7621_spi_probe") sought to disable the SYS clock on probe
+errors, but only did so for 2 of 3 potentially failing calls: The clock
+needs to be disabled on failure of devm_spi_register_controller() as
+well.
+
+Moreover, the commit purports to fix a bug in commit cbd66c626e16 ("spi:
+mt7621: Move SPI driver out of staging") but in reality the bug has
+existed since the driver was first introduced.
+
+Fixes: 1ab7f2a43558 ("staging: mt7621-spi: add mt7621 support")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v4.17+: 702b15cb9712: spi: mt7621: fix missing clk_disable_unprepare() on error in mt7621_spi_probe
+Cc: <stable@vger.kernel.org> # v4.17+
+Cc: Qinglang Miao <miaoqinglang@huawei.com>
+Link: https://lore.kernel.org/r/36ad42760087952fb7c10aae7d2628547c26a7ec.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-mt7621.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-mt7621.c
++++ b/drivers/spi/spi-mt7621.c
+@@ -382,7 +382,11 @@ static int mt7621_spi_probe(struct platf
+ return ret;
+ }
+
+- return devm_spi_register_controller(&pdev->dev, master);
++ ret = devm_spi_register_controller(&pdev->dev, master);
++ if (ret)
++ clk_disable_unprepare(clk);
++
++ return ret;
+ }
+
+ static int mt7621_spi_remove(struct platform_device *pdev)
--- /dev/null
+From 46b5c4fb87ce8211e0f9b0383dbde72c3652d2ba Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:14 +0100
+Subject: spi: mt7621: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 46b5c4fb87ce8211e0f9b0383dbde72c3652d2ba upstream.
+
+If the calls to device_reset() or devm_spi_register_controller() fail on
+probe of the MediaTek MT7621 SPI driver, the spi_controller struct is
+erroneously not freed. Fix by switching over to the new
+devm_spi_alloc_master() helper.
+
+Additionally, there's an ordering issue in mt7621_spi_remove() wherein
+the spi_controller is unregistered after disabling the SYS clock.
+The correct order is to call spi_unregister_controller() *before* this
+teardown step because bus accesses may still be ongoing until that
+function returns.
+
+All of these bugs have existed since the driver was first introduced,
+so it seems fair to fix them together in a single commit.
+
+Fixes: 1ab7f2a43558 ("staging: mt7621-spi: add mt7621 support")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Stefan Roese <sr@denx.de>
+Cc: <stable@vger.kernel.org> # v4.17+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v4.17+
+Link: https://lore.kernel.org/r/72b680796149f5fcda0b3f530ffb7ee73b04f224.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-mt7621.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-mt7621.c
++++ b/drivers/spi/spi-mt7621.c
+@@ -350,7 +350,7 @@ static int mt7621_spi_probe(struct platf
+ if (status)
+ return status;
+
+- master = spi_alloc_master(&pdev->dev, sizeof(*rs));
++ master = devm_spi_alloc_master(&pdev->dev, sizeof(*rs));
+ if (!master) {
+ dev_info(&pdev->dev, "master allocation failed\n");
+ clk_disable_unprepare(clk);
+@@ -382,7 +382,7 @@ static int mt7621_spi_probe(struct platf
+ return ret;
+ }
+
+- ret = devm_spi_register_controller(&pdev->dev, master);
++ ret = spi_register_controller(master);
+ if (ret)
+ clk_disable_unprepare(clk);
+
+@@ -397,6 +397,7 @@ static int mt7621_spi_remove(struct plat
+ master = dev_get_drvdata(&pdev->dev);
+ rs = spi_controller_get_devdata(master);
+
++ spi_unregister_controller(master);
+ clk_disable_unprepare(rs->clk);
+
+ return 0;
--- /dev/null
+From cc53711b2191cf3b3210283ae89bf0abb98c70a3 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:07 +0100
+Subject: spi: mxic: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit cc53711b2191cf3b3210283ae89bf0abb98c70a3 upstream.
+
+If the calls to devm_clk_get() or devm_ioremap_resource() fail on probe
+of the Macronix SPI driver, the spi_master struct is erroneously not freed.
+
+Fix by switching over to the new devm_spi_alloc_master() helper.
+
+Fixes: b942d80b0a39 ("spi: Add MXIC controller driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.0+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.0+
+Cc: Mason Yang <masonccyang@mxic.com.tw>
+Link: https://lore.kernel.org/r/4fa6857806e7e75741c05d057ac9df3564460114.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-mxic.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+--- a/drivers/spi/spi-mxic.c
++++ b/drivers/spi/spi-mxic.c
+@@ -529,7 +529,7 @@ static int mxic_spi_probe(struct platfor
+ struct mxic_spi *mxic;
+ int ret;
+
+- master = spi_alloc_master(&pdev->dev, sizeof(struct mxic_spi));
++ master = devm_spi_alloc_master(&pdev->dev, sizeof(struct mxic_spi));
+ if (!master)
+ return -ENOMEM;
+
+@@ -574,15 +574,9 @@ static int mxic_spi_probe(struct platfor
+ ret = spi_register_master(master);
+ if (ret) {
+ dev_err(&pdev->dev, "spi_register_master failed\n");
+- goto err_put_master;
++ pm_runtime_disable(&pdev->dev);
+ }
+
+- return 0;
+-
+-err_put_master:
+- spi_master_put(master);
+- pm_runtime_disable(&pdev->dev);
+-
+ return ret;
+ }
+
--- /dev/null
+From 234266a5168bbe8220d263e3aa7aa80cf921c483 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:16 +0100
+Subject: spi: npcm-fiu: Disable clock in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 234266a5168bbe8220d263e3aa7aa80cf921c483 upstream.
+
+If the call to devm_spi_register_master() fails on probe of the NPCM FIU
+SPI driver, the clock "fiu->clk" is erroneously not unprepared and
+disabled. Fix it.
+
+Fixes: ace55c411b11 ("spi: npcm-fiu: add NPCM FIU controller driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.4+
+Cc: Tomer Maimon <tmaimon77@gmail.com>
+Link: https://lore.kernel.org/r/9ae62f4e1cfe542bec57ac2743e6fca9f9548f55.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-npcm-fiu.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-npcm-fiu.c
++++ b/drivers/spi/spi-npcm-fiu.c
+@@ -677,7 +677,7 @@ static int npcm_fiu_probe(struct platfor
+ struct npcm_fiu_spi *fiu;
+ void __iomem *regbase;
+ struct resource *res;
+- int id;
++ int id, ret;
+
+ ctrl = devm_spi_alloc_master(dev, sizeof(*fiu));
+ if (!ctrl)
+@@ -735,7 +735,11 @@ static int npcm_fiu_probe(struct platfor
+ ctrl->num_chipselect = fiu->info->max_cs;
+ ctrl->dev.of_node = dev->of_node;
+
+- return devm_spi_register_master(dev, ctrl);
++ ret = devm_spi_register_master(dev, ctrl);
++ if (ret)
++ clk_disable_unprepare(fiu->clk);
++
++ return ret;
+ }
+
+ static int npcm_fiu_remove(struct platform_device *pdev)
--- /dev/null
+From c575e9113bff5e024d75481613faed5ef9d465b2 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sun, 8 Nov 2020 23:41:00 +0100
+Subject: spi: pic32: Don't leak DMA channels in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit c575e9113bff5e024d75481613faed5ef9d465b2 upstream.
+
+If the calls to devm_request_irq() or devm_spi_register_master() fail
+on probe of the PIC32 SPI driver, the DMA channels requested by
+pic32_spi_dma_prep() are erroneously not released. Plug the leak.
+
+Fixes: 1bcb9f8ceb67 ("spi: spi-pic32: Add PIC32 SPI master driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v4.7+
+Cc: Purna Chandra Mandal <purna.mandal@microchip.com>
+Link: https://lore.kernel.org/r/9624250e3a7aa61274b38219a62375bac1def637.1604874488.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-pic32.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/spi/spi-pic32.c
++++ b/drivers/spi/spi-pic32.c
+@@ -839,6 +839,7 @@ static int pic32_spi_probe(struct platfo
+ return 0;
+
+ err_bailout:
++ pic32_spi_dma_unprep(pic32s);
+ clk_disable_unprepare(pic32s->clk);
+ err_master:
+ spi_master_put(master);
--- /dev/null
+From 5626308bb94d9f930aa5f7c77327df4c6daa7759 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:05 +0100
+Subject: spi: pxa2xx: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 5626308bb94d9f930aa5f7c77327df4c6daa7759 upstream.
+
+pxa2xx_spi_remove() accesses the driver's private data after calling
+spi_unregister_controller() even though that function releases the last
+reference on the spi_controller and thereby frees the private data.
+
+Fix by switching over to the new devm_spi_alloc_master/slave() helper
+which keeps the private data accessible until the driver has unbound.
+
+Fixes: 32e5b57232c0 ("spi: pxa2xx: Fix controller unregister order")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v2.6.17+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v2.6.17+: 32e5b57232c0: spi: pxa2xx: Fix controller unregister order
+Cc: <stable@vger.kernel.org> # v2.6.17+
+Link: https://lore.kernel.org/r/5764b04d4a6e43069ebb7808f64c2f774ac6f193.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-pxa2xx.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-pxa2xx.c
++++ b/drivers/spi/spi-pxa2xx.c
+@@ -1686,9 +1686,9 @@ static int pxa2xx_spi_probe(struct platf
+ }
+
+ if (platform_info->is_slave)
+- controller = spi_alloc_slave(dev, sizeof(struct driver_data));
++ controller = devm_spi_alloc_slave(dev, sizeof(*drv_data));
+ else
+- controller = spi_alloc_master(dev, sizeof(struct driver_data));
++ controller = devm_spi_alloc_master(dev, sizeof(*drv_data));
+
+ if (!controller) {
+ dev_err(&pdev->dev, "cannot alloc spi_controller\n");
+@@ -1911,7 +1911,6 @@ out_error_dma_irq_alloc:
+ free_irq(ssp->irq, drv_data);
+
+ out_error_controller_alloc:
+- spi_controller_put(controller);
+ pxa_ssp_free(ssp);
+ return status;
+ }
--- /dev/null
+From a4729c3506c3eb1a6ca5c0289f4e7cafa4115065 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:10 +0100
+Subject: spi: rb4xx: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit a4729c3506c3eb1a6ca5c0289f4e7cafa4115065 upstream.
+
+If the calls to devm_clk_get(), devm_spi_register_master() or
+clk_prepare_enable() fail on probe of the Mikrotik RB4xx SPI driver,
+the spi_master struct is erroneously not freed.
+
+Fix by switching over to the new devm_spi_alloc_master() helper.
+
+Fixes: 05aec357871f ("spi: Add SPI driver for Mikrotik RB4xx series boards")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v4.2+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v4.2+
+Cc: Bert Vermeulen <bert@biot.com>
+Link: https://lore.kernel.org/r/369bf26d71927f60943b1d9d8f51810f00b0237d.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-rb4xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-rb4xx.c
++++ b/drivers/spi/spi-rb4xx.c
+@@ -143,7 +143,7 @@ static int rb4xx_spi_probe(struct platfo
+ if (IS_ERR(spi_base))
+ return PTR_ERR(spi_base);
+
+- master = spi_alloc_master(&pdev->dev, sizeof(*rbspi));
++ master = devm_spi_alloc_master(&pdev->dev, sizeof(*rbspi));
+ if (!master)
+ return -ENOMEM;
+
--- /dev/null
+From 393f981ca5f797b58b882d42b7621fb6e43c7f5b Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:06 +0100
+Subject: spi: rpc-if: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 393f981ca5f797b58b882d42b7621fb6e43c7f5b upstream.
+
+rpcif_spi_remove() accesses the driver's private data after calling
+spi_unregister_controller() even though that function releases the last
+reference on the spi_controller and thereby frees the private data.
+
+Fix by switching over to the new devm_spi_alloc_master() helper which
+keeps the private data accessible until the driver has unbound.
+
+Fixes: eb8d6d464a27 ("spi: add Renesas RPC-IF driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.9+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.9+
+Cc: Sergei Shtylyov <s.shtylyov@omprussia.ru>
+Link: https://lore.kernel.org/r/c5da472c28021da2f6517441685cef033d40b140.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-rpc-if.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/drivers/spi/spi-rpc-if.c
++++ b/drivers/spi/spi-rpc-if.c
+@@ -134,7 +134,7 @@ static int rpcif_spi_probe(struct platfo
+ struct rpcif *rpc;
+ int error;
+
+- ctlr = spi_alloc_master(&pdev->dev, sizeof(*rpc));
++ ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*rpc));
+ if (!ctlr)
+ return -ENOMEM;
+
+@@ -159,13 +159,8 @@ static int rpcif_spi_probe(struct platfo
+ error = spi_register_controller(ctlr);
+ if (error) {
+ dev_err(&pdev->dev, "spi_register_controller failed\n");
+- goto err_put_ctlr;
++ rpcif_disable_rpm(rpc);
+ }
+- return 0;
+-
+-err_put_ctlr:
+- rpcif_disable_rpm(rpc);
+- spi_controller_put(ctlr);
+
+ return error;
+ }
--- /dev/null
+From 5b8c88462d83331dacb48aeaec8388117fef82e0 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:11 +0100
+Subject: spi: sc18is602: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 5b8c88462d83331dacb48aeaec8388117fef82e0 upstream.
+
+If the call to devm_gpiod_get_optional() fails on probe of the NXP
+SC18IS602/603 SPI driver, the spi_master struct is erroneously not freed.
+
+Fix by switching over to the new devm_spi_alloc_master() helper.
+
+Fixes: f99008013e19 ("spi: sc18is602: Add reset control via gpio pin.")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v4.9+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v4.9+
+Cc: Phil Reid <preid@electromag.com.au>
+Link: https://lore.kernel.org/r/d5f715527b894b91d530fe11a86f51b3184a4e1a.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-sc18is602.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+--- a/drivers/spi/spi-sc18is602.c
++++ b/drivers/spi/spi-sc18is602.c
+@@ -238,13 +238,12 @@ static int sc18is602_probe(struct i2c_cl
+ struct sc18is602_platform_data *pdata = dev_get_platdata(dev);
+ struct sc18is602 *hw;
+ struct spi_master *master;
+- int error;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ return -EINVAL;
+
+- master = spi_alloc_master(dev, sizeof(struct sc18is602));
++ master = devm_spi_alloc_master(dev, sizeof(struct sc18is602));
+ if (!master)
+ return -ENOMEM;
+
+@@ -298,15 +297,7 @@ static int sc18is602_probe(struct i2c_cl
+ master->min_speed_hz = hw->freq / 128;
+ master->max_speed_hz = hw->freq / 4;
+
+- error = devm_spi_register_master(dev, master);
+- if (error)
+- goto error_reg;
+-
+- return 0;
+-
+-error_reg:
+- spi_master_put(master);
+- return error;
++ return devm_spi_register_master(dev, master);
+ }
+
+ static const struct i2c_device_id sc18is602_id[] = {
--- /dev/null
+From 8f96c434dfbc85ffa755d6634c8c1cb2233fcf24 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:02 +0100
+Subject: spi: spi-geni-qcom: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 8f96c434dfbc85ffa755d6634c8c1cb2233fcf24 upstream.
+
+spi_geni_remove() accesses the driver's private data after calling
+spi_unregister_master() even though that function releases the last
+reference on the spi_master and thereby frees the private data.
+
+Moreover, since commit 1a9e489e6128 ("spi: spi-geni-qcom: Use OPP API to
+set clk/perf state"), spi_geni_probe() leaks the spi_master allocation
+if the calls to dev_pm_opp_set_clkname() or dev_pm_opp_of_add_table()
+fail.
+
+Fix by switching over to the new devm_spi_alloc_master() helper which
+keeps the private data accessible until the driver has unbound and also
+avoids the spi_master leak on probe.
+
+Fixes: 561de45f72bd ("spi: spi-geni-qcom: Add SPI driver support for GENI based QUP")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v4.20+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v4.20+
+Cc: Rajendra Nayak <rnayak@codeaurora.org>
+Cc: Girish Mahadevan <girishm@codeaurora.org>
+Link: https://lore.kernel.org/r/dfa1d8c41b8acdfad87ec8654cd124e6e3cb3f31.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-geni-qcom.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-geni-qcom.c
++++ b/drivers/spi/spi-geni-qcom.c
+@@ -603,7 +603,7 @@ static int spi_geni_probe(struct platfor
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+- spi = spi_alloc_master(dev, sizeof(*mas));
++ spi = devm_spi_alloc_master(dev, sizeof(*mas));
+ if (!spi)
+ return -ENOMEM;
+
+@@ -673,7 +673,6 @@ spi_geni_probe_free_irq:
+ free_irq(mas->irq, spi);
+ spi_geni_probe_runtime_disable:
+ pm_runtime_disable(dev);
+- spi_master_put(spi);
+ dev_pm_opp_of_remove_table(&pdev->dev);
+ put_clkname:
+ dev_pm_opp_put_clkname(mas->se.opp_table);
--- /dev/null
+From 0f4ad8d59f33b24dd86739f3be23e6af1a86f5a9 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:08 +0100
+Subject: spi: spi-mtk-nor: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 0f4ad8d59f33b24dd86739f3be23e6af1a86f5a9 upstream.
+
+If the call to devm_spi_register_controller() fails on probe of the
+MediaTek SPI NOR driver, the spi_controller struct is erroneously not
+freed.
+
+Since commit a1daaa991ed1 ("spi: spi-mtk-nor: use dma_alloc_coherent()
+for bounce buffer"), the same happens if the call to
+dmam_alloc_coherent() fails.
+
+Since commit 3bfd9103c7af ("spi: spi-mtk-nor: Add power management
+support"), the same happens if the call to mtk_nor_enable_clk() fails.
+
+Fix by switching over to the new devm_spi_alloc_master() helper.
+
+Fixes: 881d1ee9fe81 ("spi: add support for mediatek spi-nor controller")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Ikjoon Jang <ikjn@chromium.org>
+Cc: <stable@vger.kernel.org> # v5.7+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.7+
+Cc: Chuanhong Guo <gch981213@gmail.com>
+Link: https://lore.kernel.org/r/d5b9f0289465394e73dedb8ec51e180a8f1dffc9.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-mtk-nor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-mtk-nor.c
++++ b/drivers/spi/spi-mtk-nor.c
+@@ -768,7 +768,7 @@ static int mtk_nor_probe(struct platform
+ return -EINVAL;
+ }
+
+- ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp));
++ ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (!ctlr) {
+ dev_err(&pdev->dev, "failed to allocate spi controller\n");
+ return -ENOMEM;
--- /dev/null
+From 6cfd39e212dee2e77a0227ce4e0f55fa06d79f46 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:03 +0100
+Subject: spi: spi-qcom-qspi: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 6cfd39e212dee2e77a0227ce4e0f55fa06d79f46 upstream.
+
+qcom_qspi_remove() accesses the driver's private data after calling
+spi_unregister_master() even though that function releases the last
+reference on the spi_master and thereby frees the private data.
+
+Fix by switching over to the new devm_spi_alloc_master() helper which
+keeps the private data accessible until the driver has unbound.
+
+Fixes: f79a158d37c2 ("spi: spi-qcom-qspi: Use OPP API to set clk/perf state")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.9+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v5.9+
+Cc: Rajendra Nayak <rnayak@codeaurora.org>
+Link: https://lore.kernel.org/r/b6d3c4dce571d78a532fd74f27def0d5dc8d8a24.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-qcom-qspi.c | 42 ++++++++++++++++--------------------------
+ 1 file changed, 16 insertions(+), 26 deletions(-)
+
+--- a/drivers/spi/spi-qcom-qspi.c
++++ b/drivers/spi/spi-qcom-qspi.c
+@@ -462,7 +462,7 @@ static int qcom_qspi_probe(struct platfo
+
+ dev = &pdev->dev;
+
+- master = spi_alloc_master(dev, sizeof(*ctrl));
++ master = devm_spi_alloc_master(dev, sizeof(*ctrl));
+ if (!master)
+ return -ENOMEM;
+
+@@ -473,54 +473,49 @@ static int qcom_qspi_probe(struct platfo
+ spin_lock_init(&ctrl->lock);
+ ctrl->dev = dev;
+ ctrl->base = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(ctrl->base)) {
+- ret = PTR_ERR(ctrl->base);
+- goto exit_probe_master_put;
+- }
++ if (IS_ERR(ctrl->base))
++ return PTR_ERR(ctrl->base);
+
+ ctrl->clks = devm_kcalloc(dev, QSPI_NUM_CLKS,
+ sizeof(*ctrl->clks), GFP_KERNEL);
+- if (!ctrl->clks) {
+- ret = -ENOMEM;
+- goto exit_probe_master_put;
+- }
++ if (!ctrl->clks)
++ return -ENOMEM;
+
+ ctrl->clks[QSPI_CLK_CORE].id = "core";
+ ctrl->clks[QSPI_CLK_IFACE].id = "iface";
+ ret = devm_clk_bulk_get(dev, QSPI_NUM_CLKS, ctrl->clks);
+ if (ret)
+- goto exit_probe_master_put;
++ return ret;
+
+ ctrl->icc_path_cpu_to_qspi = devm_of_icc_get(dev, "qspi-config");
+- if (IS_ERR(ctrl->icc_path_cpu_to_qspi)) {
+- ret = dev_err_probe(dev, PTR_ERR(ctrl->icc_path_cpu_to_qspi),
+- "Failed to get cpu path\n");
+- goto exit_probe_master_put;
+- }
++ if (IS_ERR(ctrl->icc_path_cpu_to_qspi))
++ return dev_err_probe(dev, PTR_ERR(ctrl->icc_path_cpu_to_qspi),
++ "Failed to get cpu path\n");
++
+ /* Set BW vote for register access */
+ ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, Bps_to_icc(1000),
+ Bps_to_icc(1000));
+ if (ret) {
+ dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu: %d\n",
+ __func__, ret);
+- goto exit_probe_master_put;
++ return ret;
+ }
+
+ ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
+ if (ret) {
+ dev_err(ctrl->dev, "%s: ICC disable failed for cpu: %d\n",
+ __func__, ret);
+- goto exit_probe_master_put;
++ return ret;
+ }
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+- goto exit_probe_master_put;
++ return ret;
+ ret = devm_request_irq(dev, ret, qcom_qspi_irq,
+ IRQF_TRIGGER_HIGH, dev_name(dev), ctrl);
+ if (ret) {
+ dev_err(dev, "Failed to request irq %d\n", ret);
+- goto exit_probe_master_put;
++ return ret;
+ }
+
+ master->max_speed_hz = 300000000;
+@@ -537,10 +532,8 @@ static int qcom_qspi_probe(struct platfo
+ master->auto_runtime_pm = true;
+
+ ctrl->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "core");
+- if (IS_ERR(ctrl->opp_table)) {
+- ret = PTR_ERR(ctrl->opp_table);
+- goto exit_probe_master_put;
+- }
++ if (IS_ERR(ctrl->opp_table))
++ return PTR_ERR(ctrl->opp_table);
+ /* OPP table is optional */
+ ret = dev_pm_opp_of_add_table(&pdev->dev);
+ if (ret && ret != -ENODEV) {
+@@ -562,9 +555,6 @@ static int qcom_qspi_probe(struct platfo
+ exit_probe_put_clkname:
+ dev_pm_opp_put_clkname(ctrl->opp_table);
+
+-exit_probe_master_put:
+- spi_master_put(master);
+-
+ return ret;
+ }
+
--- /dev/null
+From e77df3eca12be4b17f13cf9f215cff248c57d98f Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:04 +0100
+Subject: spi: spi-sh: Fix use-after-free on unbind
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit e77df3eca12be4b17f13cf9f215cff248c57d98f upstream.
+
+spi_sh_remove() accesses the driver's private data after calling
+spi_unregister_master() even though that function releases the last
+reference on the spi_master and thereby frees the private data.
+
+Fix by switching over to the new devm_spi_alloc_master() helper which
+keeps the private data accessible until the driver has unbound.
+
+Fixes: 680c1305e259 ("spi/spi_sh: use spi_unregister_master instead of spi_master_put in remove path")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v3.0+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v3.0+
+Cc: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/6d97628b536baf01d5e3e39db61108f84d44c8b2.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-sh.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+--- a/drivers/spi/spi-sh.c
++++ b/drivers/spi/spi-sh.c
+@@ -440,7 +440,7 @@ static int spi_sh_probe(struct platform_
+ if (irq < 0)
+ return irq;
+
+- master = spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data));
++ master = devm_spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "spi_alloc_master error.\n");
+ return -ENOMEM;
+@@ -458,16 +458,14 @@ static int spi_sh_probe(struct platform_
+ break;
+ default:
+ dev_err(&pdev->dev, "No support width\n");
+- ret = -ENODEV;
+- goto error1;
++ return -ENODEV;
+ }
+ ss->irq = irq;
+ ss->master = master;
+ ss->addr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (ss->addr == NULL) {
+ dev_err(&pdev->dev, "ioremap error.\n");
+- ret = -ENOMEM;
+- goto error1;
++ return -ENOMEM;
+ }
+ INIT_LIST_HEAD(&ss->queue);
+ spin_lock_init(&ss->lock);
+@@ -477,7 +475,7 @@ static int spi_sh_probe(struct platform_
+ ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "request_irq error\n");
+- goto error1;
++ return ret;
+ }
+
+ master->num_chipselect = 2;
+@@ -496,9 +494,6 @@ static int spi_sh_probe(struct platform_
+
+ error3:
+ free_irq(irq, ss);
+- error1:
+- spi_master_put(master);
+-
+ return ret;
+ }
+
--- /dev/null
+From 5ef76dac0f2c26aeae4ee79eb830280f16d5aceb Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sun, 8 Nov 2020 23:41:00 +0100
+Subject: spi: st-ssc4: Fix unbalanced pm_runtime_disable() in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 5ef76dac0f2c26aeae4ee79eb830280f16d5aceb upstream.
+
+If the calls to devm_platform_ioremap_resource(), irq_of_parse_and_map()
+or devm_request_irq() fail on probe of the ST SSC4 SPI driver, the
+runtime PM disable depth is incremented even though it was not
+decremented before. Fix it.
+
+Fixes: cd050abeba2a ("spi: st-ssc4: add missed pm_runtime_disable")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.5+
+Cc: Chuhong Yuan <hslester96@gmail.com>
+Link: https://lore.kernel.org/r/fbe8768c30dc829e2d77eabe7be062ca22f84024.1604874488.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-st-ssc4.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-st-ssc4.c
++++ b/drivers/spi/spi-st-ssc4.c
+@@ -375,13 +375,14 @@ static int spi_st_probe(struct platform_
+ ret = devm_spi_register_master(&pdev->dev, master);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register master\n");
+- goto clk_disable;
++ goto rpm_disable;
+ }
+
+ return 0;
+
+-clk_disable:
++rpm_disable:
+ pm_runtime_disable(&pdev->dev);
++clk_disable:
+ clk_disable_unprepare(spi_st->clk);
+ put_master:
+ spi_master_put(master);
--- /dev/null
+From 8853b2503014aca5c793d2c7f0aabc990b32bdad Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sun, 8 Nov 2020 23:41:00 +0100
+Subject: spi: synquacer: Disable clock in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 8853b2503014aca5c793d2c7f0aabc990b32bdad upstream.
+
+If the calls to platform_get_irq() or devm_request_irq() fail on probe
+of the SynQuacer SPI driver, the clock "sspi->clk" is erroneously not
+unprepared and disabled.
+
+If the clock rate "master->max_speed_hz" cannot be determined, the same
+happens and in addition the spi_master struct is not freed.
+
+Fix it.
+
+Fixes: b0823ee35cf9 ("spi: Add spi driver for Socionext SynQuacer platform")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v5.3+
+Cc: Masahisa Kojima <masahisa.kojima@linaro.org>
+Link: https://lore.kernel.org/r/232281df1ab91d8f0f553a62d5f97fc264ace4da.1604874488.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-synquacer.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -657,7 +657,8 @@ static int synquacer_spi_probe(struct pl
+
+ if (!master->max_speed_hz) {
+ dev_err(&pdev->dev, "missing clock source\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto disable_clk;
+ }
+ master->min_speed_hz = master->max_speed_hz / 254;
+
+@@ -670,7 +671,7 @@ static int synquacer_spi_probe(struct pl
+ rx_irq = platform_get_irq(pdev, 0);
+ if (rx_irq <= 0) {
+ ret = rx_irq;
+- goto put_spi;
++ goto disable_clk;
+ }
+ snprintf(sspi->rx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-rx",
+ dev_name(&pdev->dev));
+@@ -678,13 +679,13 @@ static int synquacer_spi_probe(struct pl
+ 0, sspi->rx_irq_name, sspi);
+ if (ret) {
+ dev_err(&pdev->dev, "request rx_irq failed (%d)\n", ret);
+- goto put_spi;
++ goto disable_clk;
+ }
+
+ tx_irq = platform_get_irq(pdev, 1);
+ if (tx_irq <= 0) {
+ ret = tx_irq;
+- goto put_spi;
++ goto disable_clk;
+ }
+ snprintf(sspi->tx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-tx",
+ dev_name(&pdev->dev));
+@@ -692,7 +693,7 @@ static int synquacer_spi_probe(struct pl
+ 0, sspi->tx_irq_name, sspi);
+ if (ret) {
+ dev_err(&pdev->dev, "request tx_irq failed (%d)\n", ret);
+- goto put_spi;
++ goto disable_clk;
+ }
+
+ master->dev.of_node = np;
+@@ -710,7 +711,7 @@ static int synquacer_spi_probe(struct pl
+
+ ret = synquacer_spi_enable(master);
+ if (ret)
+- goto fail_enable;
++ goto disable_clk;
+
+ pm_runtime_set_active(sspi->dev);
+ pm_runtime_enable(sspi->dev);
+@@ -723,7 +724,7 @@ static int synquacer_spi_probe(struct pl
+
+ disable_pm:
+ pm_runtime_disable(sspi->dev);
+-fail_enable:
++disable_clk:
+ clk_disable_unprepare(sspi->clk);
+ put_spi:
+ spi_master_put(master);
--- /dev/null
+From 236761f19a4f373354f1dcf399b57753f1f4b871 Mon Sep 17 00:00:00 2001
+From: Zhuguangqing <zhuguangqing@xiaomi.com>
+Date: Fri, 6 Nov 2020 17:22:43 +0800
+Subject: thermal/drivers/cpufreq_cooling: Update cpufreq_state only if state has changed
+
+From: Zhuguangqing <zhuguangqing@xiaomi.com>
+
+commit 236761f19a4f373354f1dcf399b57753f1f4b871 upstream.
+
+If state has not changed successfully and we updated cpufreq_state,
+next time when the new state is equal to cpufreq_state (not changed
+successfully last time), we will return directly and miss a
+freq_qos_update_request() that should have been.
+
+Fixes: 5130802ddbb1 ("thermal: cpu_cooling: Switch to QoS requests for freq limits")
+Cc: v5.4+ <stable@vger.kernel.org> # v5.4+
+Signed-off-by: Zhuguangqing <zhuguangqing@xiaomi.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20201106092243.15574-1-zhuguangqing83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/thermal/cpufreq_cooling.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/thermal/cpufreq_cooling.c
++++ b/drivers/thermal/cpufreq_cooling.c
+@@ -438,13 +438,11 @@ static int cpufreq_set_cur_state(struct
+ if (cpufreq_cdev->cpufreq_state == state)
+ return 0;
+
+- cpufreq_cdev->cpufreq_state = state;
+-
+ frequency = get_state_freq(cpufreq_cdev, state);
+
+ ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency);
+-
+ if (ret > 0) {
++ cpufreq_cdev->cpufreq_state = state;
+ cpus = cpufreq_cdev->policy->cpus;
+ max_capacity = arch_scale_cpu_capacity(cpumask_first(cpus));
+ capacity = frequency * max_capacity;
--- /dev/null
+From 60efe21e5976d3d4170a8190ca76a271d6419754 Mon Sep 17 00:00:00 2001
+From: Masami Hiramatsu <mhiramat@kernel.org>
+Date: Tue, 8 Dec 2020 17:54:09 +0900
+Subject: tracing: Disable ftrace selftests when any tracer is running
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+commit 60efe21e5976d3d4170a8190ca76a271d6419754 upstream.
+
+Disable ftrace selftests when any tracer (kernel command line options
+like ftrace=, trace_events=, kprobe_events=, and boot-time tracing)
+starts running because selftest can disturb it.
+
+Currently ftrace= and trace_events= are checked, but kprobe_events
+has a different flag, and boot-time tracing didn't checked. This unifies
+the disabled flag and all of those boot-time tracing features sets
+the flag.
+
+This also fixes warnings on kprobe-event selftest
+(CONFIG_FTRACE_STARTUP_TEST=y and CONFIG_KPROBE_EVENTS=y) with boot-time
+tracing (ftrace.event.kprobes.EVENT.probes) like below;
+
+[ 59.803496] trace_kprobe: Testing kprobe tracing:
+[ 59.804258] ------------[ cut here ]------------
+[ 59.805682] WARNING: CPU: 3 PID: 1 at kernel/trace/trace_kprobe.c:1987 kprobe_trace_self_tests_ib
+[ 59.806944] Modules linked in:
+[ 59.807335] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.10.0-rc7+ #172
+[ 59.808029] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1 04/01/204
+[ 59.808999] RIP: 0010:kprobe_trace_self_tests_init+0x5f/0x42b
+[ 59.809696] Code: e8 03 00 00 48 c7 c7 30 8e 07 82 e8 6d 3c 46 ff 48 c7 c6 00 b2 1a 81 48 c7 c7 7
+[ 59.812439] RSP: 0018:ffffc90000013e78 EFLAGS: 00010282
+[ 59.813038] RAX: 00000000ffffffef RBX: 0000000000000000 RCX: 0000000000049443
+[ 59.813780] RDX: 0000000000049403 RSI: 0000000000049403 RDI: 000000000002deb0
+[ 59.814589] RBP: ffffc90000013e90 R08: 0000000000000001 R09: 0000000000000001
+[ 59.815349] R10: 0000000000000001 R11: 0000000000000000 R12: 00000000ffffffef
+[ 59.816138] R13: ffff888004613d80 R14: ffffffff82696940 R15: ffff888004429138
+[ 59.816877] FS: 0000000000000000(0000) GS:ffff88807dcc0000(0000) knlGS:0000000000000000
+[ 59.817772] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 59.818395] CR2: 0000000001a8dd38 CR3: 0000000002222000 CR4: 00000000000006a0
+[ 59.819144] Call Trace:
+[ 59.819469] ? init_kprobe_trace+0x6b/0x6b
+[ 59.819948] do_one_initcall+0x5f/0x300
+[ 59.820392] ? rcu_read_lock_sched_held+0x4f/0x80
+[ 59.820916] kernel_init_freeable+0x22a/0x271
+[ 59.821416] ? rest_init+0x241/0x241
+[ 59.821841] kernel_init+0xe/0x10f
+[ 59.822251] ret_from_fork+0x22/0x30
+[ 59.822683] irq event stamp: 16403349
+[ 59.823121] hardirqs last enabled at (16403359): [<ffffffff810db81e>] console_unlock+0x48e/0x580
+[ 59.824074] hardirqs last disabled at (16403368): [<ffffffff810db786>] console_unlock+0x3f6/0x580
+[ 59.825036] softirqs last enabled at (16403200): [<ffffffff81c0033a>] __do_softirq+0x33a/0x484
+[ 59.825982] softirqs last disabled at (16403087): [<ffffffff81a00f02>] asm_call_irq_on_stack+0x10
+[ 59.827034] ---[ end trace 200c544775cdfeb3 ]---
+[ 59.827635] trace_kprobe: error on probing function entry.
+
+Link: https://lkml.kernel.org/r/160741764955.3448999.3347769358299456915.stgit@devnote2
+
+Fixes: 4d655281eb1b ("tracing/boot Add kprobe event support")
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c | 19 +++++++++++++------
+ kernel/trace/trace.h | 5 +++++
+ kernel/trace/trace_boot.c | 2 ++
+ kernel/trace/trace_events.c | 2 +-
+ kernel/trace/trace_kprobe.c | 9 +++------
+ kernel/trace/trace_selftest.c | 2 +-
+ 6 files changed, 25 insertions(+), 14 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -68,10 +68,21 @@ bool ring_buffer_expanded;
+ static bool __read_mostly tracing_selftest_running;
+
+ /*
+- * If a tracer is running, we do not want to run SELFTEST.
++ * If boot-time tracing including tracers/events via kernel cmdline
++ * is running, we do not want to run SELFTEST.
+ */
+ bool __read_mostly tracing_selftest_disabled;
+
++#ifdef CONFIG_FTRACE_STARTUP_TEST
++void __init disable_tracing_selftest(const char *reason)
++{
++ if (!tracing_selftest_disabled) {
++ tracing_selftest_disabled = true;
++ pr_info("Ftrace startup test is disabled due to %s\n", reason);
++ }
++}
++#endif
++
+ /* Pipe tracepoints to printk */
+ struct trace_iterator *tracepoint_print_iter;
+ int tracepoint_printk;
+@@ -2113,11 +2124,7 @@ int __init register_tracer(struct tracer
+ apply_trace_boot_options();
+
+ /* disable other selftests, since this will break it. */
+- tracing_selftest_disabled = true;
+-#ifdef CONFIG_FTRACE_STARTUP_TEST
+- printk(KERN_INFO "Disabling FTRACE selftests due to running tracer '%s'\n",
+- type->name);
+-#endif
++ disable_tracing_selftest("running a tracer");
+
+ out_unlock:
+ return ret;
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -896,6 +896,8 @@ extern bool ring_buffer_expanded;
+ extern bool tracing_selftest_disabled;
+
+ #ifdef CONFIG_FTRACE_STARTUP_TEST
++extern void __init disable_tracing_selftest(const char *reason);
++
+ extern int trace_selftest_startup_function(struct tracer *trace,
+ struct trace_array *tr);
+ extern int trace_selftest_startup_function_graph(struct tracer *trace,
+@@ -919,6 +921,9 @@ extern int trace_selftest_startup_branch
+ */
+ #define __tracer_data __refdata
+ #else
++static inline void __init disable_tracing_selftest(const char *reason)
++{
++}
+ /* Tracers are seldom changed. Optimize when selftests are disabled. */
+ #define __tracer_data __read_mostly
+ #endif /* CONFIG_FTRACE_STARTUP_TEST */
+--- a/kernel/trace/trace_boot.c
++++ b/kernel/trace/trace_boot.c
+@@ -344,6 +344,8 @@ static int __init trace_boot_init(void)
+ trace_boot_init_one_instance(tr, trace_node);
+ trace_boot_init_instances(trace_node);
+
++ disable_tracing_selftest("running boot-time tracing");
++
+ return 0;
+ }
+ /*
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -3201,7 +3201,7 @@ static __init int setup_trace_event(char
+ {
+ strlcpy(bootup_event_buf, str, COMMAND_LINE_SIZE);
+ ring_buffer_expanded = true;
+- tracing_selftest_disabled = true;
++ disable_tracing_selftest("running event tracing");
+
+ return 1;
+ }
+--- a/kernel/trace/trace_kprobe.c
++++ b/kernel/trace/trace_kprobe.c
+@@ -25,11 +25,12 @@
+
+ /* Kprobe early definition from command line */
+ static char kprobe_boot_events_buf[COMMAND_LINE_SIZE] __initdata;
+-static bool kprobe_boot_events_enabled __initdata;
+
+ static int __init set_kprobe_boot_events(char *str)
+ {
+ strlcpy(kprobe_boot_events_buf, str, COMMAND_LINE_SIZE);
++ disable_tracing_selftest("running kprobe events");
++
+ return 0;
+ }
+ __setup("kprobe_event=", set_kprobe_boot_events);
+@@ -1887,8 +1888,6 @@ static __init void setup_boot_kprobe_eve
+ ret = trace_run_command(cmd, create_or_delete_trace_kprobe);
+ if (ret)
+ pr_warn("Failed to add event(%d): %s\n", ret, cmd);
+- else
+- kprobe_boot_events_enabled = true;
+
+ cmd = p;
+ }
+@@ -1973,10 +1972,8 @@ static __init int kprobe_trace_self_test
+ if (tracing_is_disabled())
+ return -ENODEV;
+
+- if (kprobe_boot_events_enabled) {
+- pr_info("Skipping kprobe tests due to kprobe_event on cmdline\n");
++ if (tracing_selftest_disabled)
+ return 0;
+- }
+
+ target = kprobe_trace_selftest_target;
+
+--- a/kernel/trace/trace_selftest.c
++++ b/kernel/trace/trace_selftest.c
+@@ -787,7 +787,7 @@ trace_selftest_startup_function_graph(st
+
+ /* Have we just recovered from a hang? */
+ if (graph_hang_thresh > GRAPH_MAX_FUNC_TEST) {
+- tracing_selftest_disabled = true;
++ disable_tracing_selftest("recovering from a hang");
+ ret = -1;
+ goto out;
+ }
--- /dev/null
+From 1c728719a4da6e654afb9cc047164755072ed7c9 Mon Sep 17 00:00:00 2001
+From: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Date: Mon, 14 Dec 2020 10:25:57 +0100
+Subject: xen-blkback: set ring->xenblkd to NULL after kthread_stop()
+
+From: Pawel Wieczorkiewicz <wipawel@amazon.de>
+
+commit 1c728719a4da6e654afb9cc047164755072ed7c9 upstream.
+
+When xen_blkif_disconnect() is called, the kernel thread behind the
+block interface is stopped by calling kthread_stop(ring->xenblkd).
+The ring->xenblkd thread pointer being non-NULL determines if the
+thread has been already stopped.
+Normally, the thread's function xen_blkif_schedule() sets the
+ring->xenblkd to NULL, when the thread's main loop ends.
+
+However, when the thread has not been started yet (i.e.
+wake_up_process() has not been called on it), the xen_blkif_schedule()
+function would not be called yet.
+
+In such case the kthread_stop() call returns -EINTR and the
+ring->xenblkd remains dangling.
+When this happens, any consecutive call to xen_blkif_disconnect (for
+example in frontend_changed() callback) leads to a kernel crash in
+kthread_stop() (e.g. NULL pointer dereference in exit_creds()).
+
+This is XSA-350.
+
+Cc: <stable@vger.kernel.org> # 4.12
+Fixes: a24fa22ce22a ("xen/blkback: don't use xen_blkif_get() in xen-blkback kthread")
+Reported-by: Olivier Benjamin <oliben@amazon.com>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Julien Grall <jgrall@amazon.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/xen-blkback/xenbus.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/block/xen-blkback/xenbus.c
++++ b/drivers/block/xen-blkback/xenbus.c
+@@ -274,6 +274,7 @@ static int xen_blkif_disconnect(struct x
+
+ if (ring->xenblkd) {
+ kthread_stop(ring->xenblkd);
++ ring->xenblkd = NULL;
+ wake_up(&ring->shutdown_wq);
+ }
+
--- /dev/null
+From 2e85d32b1c865bec703ce0c962221a5e955c52c2 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:04:18 +0100
+Subject: xen/xenbus: Add 'will_handle' callback support in xenbus_watch_path()
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 2e85d32b1c865bec703ce0c962221a5e955c52c2 upstream.
+
+Some code does not directly make 'xenbus_watch' object and call
+'register_xenbus_watch()' but use 'xenbus_watch_path()' instead. This
+commit adds support of 'will_handle' callback in the
+'xenbus_watch_path()' and it's wrapper, 'xenbus_watch_pathfmt()'.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/xen-blkback/xenbus.c | 3 ++-
+ drivers/net/xen-netback/xenbus.c | 2 +-
+ drivers/xen/xen-pciback/xenbus.c | 2 +-
+ drivers/xen/xenbus/xenbus_client.c | 9 +++++++--
+ drivers/xen/xenbus/xenbus_probe.c | 2 +-
+ include/xen/xenbus.h | 6 +++++-
+ 6 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/drivers/block/xen-blkback/xenbus.c
++++ b/drivers/block/xen-blkback/xenbus.c
+@@ -676,7 +676,8 @@ static int xen_blkbk_probe(struct xenbus
+ /* setup back pointer */
+ be->blkif->be = be;
+
+- err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed,
++ err = xenbus_watch_pathfmt(dev, &be->backend_watch, NULL,
++ backend_changed,
+ "%s/%s", dev->nodename, "physical-device");
+ if (err)
+ goto fail;
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -824,7 +824,7 @@ static void connect(struct backend_info
+ xenvif_carrier_on(be->vif);
+
+ unregister_hotplug_status_watch(be);
+- err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
++ err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL,
+ hotplug_status_changed,
+ "%s/%s", dev->nodename, "hotplug-status");
+ if (!err)
+--- a/drivers/xen/xen-pciback/xenbus.c
++++ b/drivers/xen/xen-pciback/xenbus.c
+@@ -689,7 +689,7 @@ static int xen_pcibk_xenbus_probe(struct
+
+ /* watch the backend node for backend configuration information */
+ err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch,
+- xen_pcibk_be_watch);
++ NULL, xen_pcibk_be_watch);
+ if (err)
+ goto out;
+
+--- a/drivers/xen/xenbus/xenbus_client.c
++++ b/drivers/xen/xenbus/xenbus_client.c
+@@ -127,19 +127,22 @@ EXPORT_SYMBOL_GPL(xenbus_strstate);
+ */
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+ struct xenbus_watch *watch,
++ bool (*will_handle)(struct xenbus_watch *,
++ const char *, const char *),
+ void (*callback)(struct xenbus_watch *,
+ const char *, const char *))
+ {
+ int err;
+
+ watch->node = path;
+- watch->will_handle = NULL;
++ watch->will_handle = will_handle;
+ watch->callback = callback;
+
+ err = register_xenbus_watch(watch);
+
+ if (err) {
+ watch->node = NULL;
++ watch->will_handle = NULL;
+ watch->callback = NULL;
+ xenbus_dev_fatal(dev, err, "adding watch on %s", path);
+ }
+@@ -166,6 +169,8 @@ EXPORT_SYMBOL_GPL(xenbus_watch_path);
+ */
+ int xenbus_watch_pathfmt(struct xenbus_device *dev,
+ struct xenbus_watch *watch,
++ bool (*will_handle)(struct xenbus_watch *,
++ const char *, const char *),
+ void (*callback)(struct xenbus_watch *,
+ const char *, const char *),
+ const char *pathfmt, ...)
+@@ -182,7 +187,7 @@ int xenbus_watch_pathfmt(struct xenbus_d
+ xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
+ return -ENOMEM;
+ }
+- err = xenbus_watch_path(dev, path, watch, callback);
++ err = xenbus_watch_path(dev, path, watch, will_handle, callback);
+
+ if (err)
+ kfree(path);
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -136,7 +136,7 @@ static int watch_otherend(struct xenbus_
+ container_of(dev->dev.bus, struct xen_bus_type, bus);
+
+ return xenbus_watch_pathfmt(dev, &dev->otherend_watch,
+- bus->otherend_changed,
++ NULL, bus->otherend_changed,
+ "%s/%s", dev->otherend, "state");
+ }
+
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -204,10 +204,14 @@ void xenbus_probe(struct work_struct *);
+
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+ struct xenbus_watch *watch,
++ bool (*will_handle)(struct xenbus_watch *,
++ const char *, const char *),
+ void (*callback)(struct xenbus_watch *,
+ const char *, const char *));
+-__printf(4, 5)
++__printf(5, 6)
+ int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch,
++ bool (*will_handle)(struct xenbus_watch *,
++ const char *, const char *),
+ void (*callback)(struct xenbus_watch *,
+ const char *, const char *),
+ const char *pathfmt, ...);
--- /dev/null
+From fed1755b118147721f2c87b37b9d66e62c39b668 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:02:45 +0100
+Subject: xen/xenbus: Allow watches discard events before queueing
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit fed1755b118147721f2c87b37b9d66e62c39b668 upstream.
+
+If handling logics of watch events are slower than the events enqueue
+logic and the events can be created from the guests, the guests could
+trigger memory pressure by intensively inducing the events, because it
+will create a huge number of pending events that exhausting the memory.
+
+Fortunately, some watch events could be ignored, depending on its
+handler callback. For example, if the callback has interest in only one
+single path, the watch wouldn't want multiple pending events. Or, some
+watches could ignore events to same path.
+
+To let such watches to volutarily help avoiding the memory pressure
+situation, this commit introduces new watch callback, 'will_handle'. If
+it is not NULL, it will be called for each new event just before
+enqueuing it. Then, if the callback returns false, the event will be
+discarded. No watch is using the callback for now, though.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/xen-netback/xenbus.c | 4 ++++
+ drivers/xen/xenbus/xenbus_client.c | 1 +
+ drivers/xen/xenbus/xenbus_xs.c | 5 ++++-
+ include/xen/xenbus.h | 7 +++++++
+ 4 files changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -557,12 +557,14 @@ static int xen_register_credit_watch(str
+ return -ENOMEM;
+ snprintf(node, maxlen, "%s/rate", dev->nodename);
+ vif->credit_watch.node = node;
++ vif->credit_watch.will_handle = NULL;
+ vif->credit_watch.callback = xen_net_rate_changed;
+ err = register_xenbus_watch(&vif->credit_watch);
+ if (err) {
+ pr_err("Failed to set watcher %s\n", vif->credit_watch.node);
+ kfree(node);
+ vif->credit_watch.node = NULL;
++ vif->credit_watch.will_handle = NULL;
+ vif->credit_watch.callback = NULL;
+ }
+ return err;
+@@ -609,6 +611,7 @@ static int xen_register_mcast_ctrl_watch
+ snprintf(node, maxlen, "%s/request-multicast-control",
+ dev->otherend);
+ vif->mcast_ctrl_watch.node = node;
++ vif->mcast_ctrl_watch.will_handle = NULL;
+ vif->mcast_ctrl_watch.callback = xen_mcast_ctrl_changed;
+ err = register_xenbus_watch(&vif->mcast_ctrl_watch);
+ if (err) {
+@@ -616,6 +619,7 @@ static int xen_register_mcast_ctrl_watch
+ vif->mcast_ctrl_watch.node);
+ kfree(node);
+ vif->mcast_ctrl_watch.node = NULL;
++ vif->mcast_ctrl_watch.will_handle = NULL;
+ vif->mcast_ctrl_watch.callback = NULL;
+ }
+ return err;
+--- a/drivers/xen/xenbus/xenbus_client.c
++++ b/drivers/xen/xenbus/xenbus_client.c
+@@ -133,6 +133,7 @@ int xenbus_watch_path(struct xenbus_devi
+ int err;
+
+ watch->node = path;
++ watch->will_handle = NULL;
+ watch->callback = callback;
+
+ err = register_xenbus_watch(watch);
+--- a/drivers/xen/xenbus/xenbus_xs.c
++++ b/drivers/xen/xenbus/xenbus_xs.c
+@@ -705,7 +705,10 @@ int xs_watch_msg(struct xs_watch_event *
+
+ spin_lock(&watches_lock);
+ event->handle = find_watch(event->token);
+- if (event->handle != NULL) {
++ if (event->handle != NULL &&
++ (!event->handle->will_handle ||
++ event->handle->will_handle(event->handle,
++ event->path, event->token))) {
+ spin_lock(&watch_events_lock);
+ list_add_tail(&event->list, &watch_events);
+ wake_up(&watch_events_waitq);
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -61,6 +61,13 @@ struct xenbus_watch
+ /* Path being watched. */
+ const char *node;
+
++ /*
++ * Called just before enqueing new event while a spinlock is held.
++ * The event will be discarded if this callback returns false.
++ */
++ bool (*will_handle)(struct xenbus_watch *,
++ const char *path, const char *token);
++
+ /* Callback (executed in a process context with no locks held). */
+ void (*callback)(struct xenbus_watch *,
+ const char *path, const char *token);
--- /dev/null
+From 3dc86ca6b4c8cfcba9da7996189d1b5a358a94fc Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:07:13 +0100
+Subject: xen/xenbus: Count pending messages for each watch
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 3dc86ca6b4c8cfcba9da7996189d1b5a358a94fc upstream.
+
+This commit adds a counter of pending messages for each watch in the
+struct. It is used to skip unnecessary pending messages lookup in
+'unregister_xenbus_watch()'. It could also be used in 'will_handle'
+callback.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/xenbus/xenbus_xs.c | 29 ++++++++++++++++++-----------
+ include/xen/xenbus.h | 2 ++
+ 2 files changed, 20 insertions(+), 11 deletions(-)
+
+--- a/drivers/xen/xenbus/xenbus_xs.c
++++ b/drivers/xen/xenbus/xenbus_xs.c
+@@ -711,6 +711,7 @@ int xs_watch_msg(struct xs_watch_event *
+ event->path, event->token))) {
+ spin_lock(&watch_events_lock);
+ list_add_tail(&event->list, &watch_events);
++ event->handle->nr_pending++;
+ wake_up(&watch_events_waitq);
+ spin_unlock(&watch_events_lock);
+ } else
+@@ -768,6 +769,8 @@ int register_xenbus_watch(struct xenbus_
+
+ sprintf(token, "%lX", (long)watch);
+
++ watch->nr_pending = 0;
++
+ down_read(&xs_watch_rwsem);
+
+ spin_lock(&watches_lock);
+@@ -817,11 +820,14 @@ void unregister_xenbus_watch(struct xenb
+
+ /* Cancel pending watch events. */
+ spin_lock(&watch_events_lock);
+- list_for_each_entry_safe(event, tmp, &watch_events, list) {
+- if (event->handle != watch)
+- continue;
+- list_del(&event->list);
+- kfree(event);
++ if (watch->nr_pending) {
++ list_for_each_entry_safe(event, tmp, &watch_events, list) {
++ if (event->handle != watch)
++ continue;
++ list_del(&event->list);
++ kfree(event);
++ }
++ watch->nr_pending = 0;
+ }
+ spin_unlock(&watch_events_lock);
+
+@@ -868,7 +874,6 @@ void xs_suspend_cancel(void)
+
+ static int xenwatch_thread(void *unused)
+ {
+- struct list_head *ent;
+ struct xs_watch_event *event;
+
+ xenwatch_pid = current->pid;
+@@ -883,13 +888,15 @@ static int xenwatch_thread(void *unused)
+ mutex_lock(&xenwatch_mutex);
+
+ spin_lock(&watch_events_lock);
+- ent = watch_events.next;
+- if (ent != &watch_events)
+- list_del(ent);
++ event = list_first_entry_or_null(&watch_events,
++ struct xs_watch_event, list);
++ if (event) {
++ list_del(&event->list);
++ event->handle->nr_pending--;
++ }
+ spin_unlock(&watch_events_lock);
+
+- if (ent != &watch_events) {
+- event = list_entry(ent, struct xs_watch_event, list);
++ if (event) {
+ event->handle->callback(event->handle, event->path,
+ event->token);
+ kfree(event);
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -61,6 +61,8 @@ struct xenbus_watch
+ /* Path being watched. */
+ const char *node;
+
++ unsigned int nr_pending;
++
+ /*
+ * Called just before enqueing new event while a spinlock is held.
+ * The event will be discarded if this callback returns false.
--- /dev/null
+From be987200fbaceaef340872841d4f7af2c5ee8dc3 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:05:47 +0100
+Subject: xen/xenbus/xen_bus_type: Support will_handle watch callback
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit be987200fbaceaef340872841d4f7af2c5ee8dc3 upstream.
+
+This commit adds support of the 'will_handle' watch callback for
+'xen_bus_type' users.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/xenbus/xenbus.h | 2 ++
+ drivers/xen/xenbus/xenbus_probe.c | 3 ++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/xen/xenbus/xenbus.h
++++ b/drivers/xen/xenbus/xenbus.h
+@@ -44,6 +44,8 @@ struct xen_bus_type {
+ int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE], const char *nodename);
+ int (*probe)(struct xen_bus_type *bus, const char *type,
+ const char *dir);
++ bool (*otherend_will_handle)(struct xenbus_watch *watch,
++ const char *path, const char *token);
+ void (*otherend_changed)(struct xenbus_watch *watch, const char *path,
+ const char *token);
+ struct bus_type bus;
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -136,7 +136,8 @@ static int watch_otherend(struct xenbus_
+ container_of(dev->dev.bus, struct xen_bus_type, bus);
+
+ return xenbus_watch_pathfmt(dev, &dev->otherend_watch,
+- NULL, bus->otherend_changed,
++ bus->otherend_will_handle,
++ bus->otherend_changed,
+ "%s/%s", dev->otherend, "state");
+ }
+
--- /dev/null
+From 9996bd494794a2fe393e97e7a982388c6249aa76 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:08:40 +0100
+Subject: xenbus/xenbus_backend: Disallow pending watch messages
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 9996bd494794a2fe393e97e7a982388c6249aa76 upstream.
+
+'xenbus_backend' watches 'state' of devices, which is writable by
+guests. Hence, if guests intensively updates it, dom0 will have lots of
+pending events that exhausting memory of dom0. In other words, guests
+can trigger dom0 memory pressure. This is known as XSA-349. However,
+the watch callback of it, 'frontend_changed()', reads only 'state', so
+doesn't need to have the pending events.
+
+To avoid the problem, this commit disallows pending watch messages for
+'xenbus_backend' using the 'will_handle()' watch callback.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/xenbus/xenbus_probe_backend.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/xen/xenbus/xenbus_probe_backend.c
++++ b/drivers/xen/xenbus/xenbus_probe_backend.c
+@@ -180,6 +180,12 @@ static int xenbus_probe_backend(struct x
+ return err;
+ }
+
++static bool frontend_will_handle(struct xenbus_watch *watch,
++ const char *path, const char *token)
++{
++ return watch->nr_pending == 0;
++}
++
+ static void frontend_changed(struct xenbus_watch *watch,
+ const char *path, const char *token)
+ {
+@@ -191,6 +197,7 @@ static struct xen_bus_type xenbus_backen
+ .levels = 3, /* backend/type/<frontend>/<id> */
+ .get_bus_id = backend_bus_id,
+ .probe = xenbus_probe_backend,
++ .otherend_will_handle = frontend_will_handle,
+ .otherend_changed = frontend_changed,
+ .bus = {
+ .name = "xen-backend",