--- /dev/null
+From 493e6bd4b4c31ae8aa65bf9882f6387df94875ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 17:49:52 +0200
+Subject: clk: bcm: rpi: Add missing newline
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit 13b5cf8d6a0d4a5d289e1ed046cadc63b416db85 ]
+
+Some log messages lacks the final newline. So add them.
+
+Fixes: 93d2725affd6 ("clk: bcm: rpi: Discover the firmware clocks")
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Link: https://lore.kernel.org/r/20220713154953.3336-3-stefan.wahren@i2se.com
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Ivan T. Ivanov <iivanov@suse.de>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
+index e495f5f382ab9..4df921d1e21ca 100644
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -220,7 +220,7 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
+ ret = raspberrypi_clock_property(rpi->firmware, data,
+ RPI_FIRMWARE_SET_CLOCK_RATE, &_rate);
+ if (ret)
+- dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d",
++ dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d\n",
+ clk_hw_get_name(hw), ret);
+
+ return ret;
+@@ -288,7 +288,7 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
+ RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
+ &min_rate);
+ if (ret) {
+- dev_err(rpi->dev, "Failed to get clock %d min freq: %d",
++ dev_err(rpi->dev, "Failed to get clock %d min freq: %d\n",
+ id, ret);
+ return ERR_PTR(ret);
+ }
+@@ -365,7 +365,7 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
+ struct raspberrypi_clk_variant *variant;
+
+ if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) {
+- dev_err(rpi->dev, "Unknown clock id: %u", clks->id);
++ dev_err(rpi->dev, "Unknown clock id: %u\n", clks->id);
+ return -EINVAL;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 4de26bb3e0c989ca39b96aaccc7898be5d95fccc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jun 2022 10:36:43 +0200
+Subject: clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit 35f73cca1cecda0c1f8bb7d8be4ce5cd2d46ae8c ]
+
+The function raspberrypi_fw_get_rate (e.g. used for the recalc_rate
+hook) can fail to get the clock rate from the firmware. In this case
+we cannot return a signed error value, which would be casted to
+unsigned long. Fix this by returning 0 instead.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Link: https://lore.kernel.org/r/20220625083643.4012-1-stefan.wahren@i2se.com
+Fixes: 4e85e535e6cc ("clk: bcm283x: add driver interfacing with Raspberry Pi's firmware")
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
+index 73518009a0f20..39d63c983d62c 100644
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -203,7 +203,7 @@ static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
+ ret = raspberrypi_clock_property(rpi->firmware, data,
+ RPI_FIRMWARE_GET_CLOCK_RATE, &val);
+ if (ret)
+- return ret;
++ return 0;
+
+ return val;
+ }
+--
+2.35.1
+
--- /dev/null
+From 47500b9921bbed02d432959d896ade17bca706f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 17:49:51 +0200
+Subject: clk: bcm: rpi: Prevent out-of-bounds access
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit bc163555603e4ae9c817675ad80d618a4cdbfa2d ]
+
+The while loop in raspberrypi_discover_clocks() relies on the assumption
+that the id of the last clock element is zero. Because this data comes
+from the Videocore firmware and it doesn't guarantuee such a behavior
+this could lead to out-of-bounds access. So fix this by providing
+a sentinel element.
+
+Fixes: 93d2725affd6 ("clk: bcm: rpi: Discover the firmware clocks")
+Link: https://github.com/raspberrypi/firmware/issues/1688
+Suggested-by: Phil Elwell <phil@raspberrypi.com>
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Link: https://lore.kernel.org/r/20220713154953.3336-2-stefan.wahren@i2se.com
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Ivan T. Ivanov <iivanov@suse.de>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
+index 39d63c983d62c..e495f5f382ab9 100644
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -344,8 +344,13 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
+ struct rpi_firmware_get_clocks_response *clks;
+ int ret;
+
++ /*
++ * The firmware doesn't guarantee that the last element of
++ * RPI_FIRMWARE_GET_CLOCKS is zeroed. So allocate an additional
++ * zero element as sentinel.
++ */
+ clks = devm_kcalloc(rpi->dev,
+- RPI_FIRMWARE_NUM_CLK_ID, sizeof(*clks),
++ RPI_FIRMWARE_NUM_CLK_ID + 1, sizeof(*clks),
+ GFP_KERNEL);
+ if (!clks)
+ return -ENOMEM;
+--
+2.35.1
+
--- /dev/null
+From d0d55da67197add5fe43b9796aa9b408cbe17fd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Aug 2022 16:14:24 +0800
+Subject: clk: core: Fix runtime PM sequence in clk_core_unprepare()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 4b592061f7b3971c70e8b72fc42aaead47c24701 ]
+
+In the original commit 9a34b45397e5 ("clk: Add support for runtime PM"),
+the commit message mentioned that pm_runtime_put_sync() would be done
+at the end of clk_core_unprepare(). This mirrors the operations in
+clk_core_prepare() in the opposite order.
+
+However, the actual code that was added wasn't in the order the commit
+message described. Move clk_pm_runtime_put() to the end of
+clk_core_unprepare() so that it is in the correct order.
+
+Fixes: 9a34b45397e5 ("clk: Add support for runtime PM")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20220822081424.1310926-3-wenst@chromium.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index f00d4c1158d72..f246d66f8261f 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -840,10 +840,9 @@ static void clk_core_unprepare(struct clk_core *core)
+ if (core->ops->unprepare)
+ core->ops->unprepare(core->hw);
+
+- clk_pm_runtime_put(core);
+-
+ trace_clk_unprepare_complete(core);
+ clk_core_unprepare(core->parent);
++ clk_pm_runtime_put(core);
+ }
+
+ static void clk_core_unprepare_lock(struct clk_core *core)
+--
+2.35.1
+
--- /dev/null
+From b64e986cc7eac523608441c96647fd5690560016 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Aug 2022 16:14:23 +0800
+Subject: clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 35b0fac808b95eea1212f8860baf6ad25b88b087 ]
+
+In the previous commits that added CLK_OPS_PARENT_ENABLE, support for
+this flag was only added to rate change operations (rate setting and
+reparent) and disabling unused subtree. It was not added to the
+clock gate related operations. Any hardware driver that needs it for
+these operations will either see bogus results, or worse, hang.
+
+This has been seen on MT8192 and MT8195, where the imp_ii2_* clk
+drivers set this, but dumping debugfs clk_summary would cause it
+to hang.
+
+Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)")
+Fixes: a4b3518d146f ("clk: core: support clocks which requires parents enable (part 1)")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20220822081424.1310926-2-wenst@chromium.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index f00d4c1158d72..03427e3be727f 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -196,6 +196,9 @@ static bool clk_core_rate_is_protected(struct clk_core *core)
+ return core->protect_count;
+ }
+
++static int clk_core_prepare_enable(struct clk_core *core);
++static void clk_core_disable_unprepare(struct clk_core *core);
++
+ static bool clk_core_is_prepared(struct clk_core *core)
+ {
+ bool ret = false;
+@@ -208,7 +211,11 @@ static bool clk_core_is_prepared(struct clk_core *core)
+ return core->prepare_count;
+
+ if (!clk_pm_runtime_get(core)) {
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_prepare_enable(core->parent);
+ ret = core->ops->is_prepared(core->hw);
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_disable_unprepare(core->parent);
+ clk_pm_runtime_put(core);
+ }
+
+@@ -244,7 +251,13 @@ static bool clk_core_is_enabled(struct clk_core *core)
+ }
+ }
+
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_prepare_enable(core->parent);
++
+ ret = core->ops->is_enabled(core->hw);
++
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_disable_unprepare(core->parent);
+ done:
+ if (core->rpm_enabled)
+ pm_runtime_put(core->dev);
+@@ -812,6 +825,9 @@ int clk_rate_exclusive_get(struct clk *clk)
+ }
+ EXPORT_SYMBOL_GPL(clk_rate_exclusive_get);
+
++static int clk_core_enable_lock(struct clk_core *core);
++static void clk_core_disable_lock(struct clk_core *core);
++
+ static void clk_core_unprepare(struct clk_core *core)
+ {
+ lockdep_assert_held(&prepare_lock);
+@@ -835,6 +851,9 @@ static void clk_core_unprepare(struct clk_core *core)
+
+ WARN(core->enable_count > 0, "Unpreparing enabled %s\n", core->name);
+
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_enable_lock(core->parent);
++
+ trace_clk_unprepare(core);
+
+ if (core->ops->unprepare)
+@@ -843,6 +862,9 @@ static void clk_core_unprepare(struct clk_core *core)
+ clk_pm_runtime_put(core);
+
+ trace_clk_unprepare_complete(core);
++
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_disable_lock(core->parent);
+ clk_core_unprepare(core->parent);
+ }
+
+@@ -891,6 +913,9 @@ static int clk_core_prepare(struct clk_core *core)
+ if (ret)
+ goto runtime_put;
+
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_enable_lock(core->parent);
++
+ trace_clk_prepare(core);
+
+ if (core->ops->prepare)
+@@ -898,6 +923,9 @@ static int clk_core_prepare(struct clk_core *core)
+
+ trace_clk_prepare_complete(core);
+
++ if (core->flags & CLK_OPS_PARENT_ENABLE)
++ clk_core_disable_lock(core->parent);
++
+ if (ret)
+ goto unprepare;
+ }
+--
+2.35.1
+
--- /dev/null
+From 35bed605106d15880435c06b4460002225779edd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 12:11:18 +0300
+Subject: clk: ti: Fix missing of_node_get() ti_find_clock_provider()
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 26f2da0d2f823dc7180b0505d46318f64d1e0a7a ]
+
+For ti_find_clock_provider() we want to return the np with refcount
+incremented. However we are missing of_node_get() for the
+clock-output-names case that causes refcount warnings.
+
+Fixes: 51f661ef9a10 ("clk: ti: Add ti_find_clock_provider() to use clock-output-names")
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20220621091118.33930-1-tony@atomide.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/clk.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
+index 3463579220b51..121d8610beb15 100644
+--- a/drivers/clk/ti/clk.c
++++ b/drivers/clk/ti/clk.c
+@@ -143,6 +143,7 @@ static struct device_node *ti_find_clock_provider(struct device_node *from,
+ continue;
+
+ if (!strncmp(n, tmp, strlen(tmp))) {
++ of_node_get(np);
+ found = true;
+ break;
+ }
+--
+2.35.1
+
--- /dev/null
+From e5c2cb3b506b73aad5a46ff2ace39d3613eae2da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Aug 2022 13:02:47 +0800
+Subject: drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported"
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit 233f56745be446b289edac2ba8184c09365c005e ]
+
+There is a spelling mistake in a gvt_vgpu_err error message. Fix it.
+
+Fixes: 695fbc08d80f ("drm/i915/gvt: replace the gvt_err with gvt_vgpu_err")
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20220315202449.2952845-1-colin.i.king@gmail.com
+Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gvt/handlers.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
+index beea5895e4992..73e74a6a76037 100644
+--- a/drivers/gpu/drm/i915/gvt/handlers.c
++++ b/drivers/gpu/drm/i915/gvt/handlers.c
+@@ -905,7 +905,7 @@ static int update_fdi_rx_iir_status(struct intel_vgpu *vgpu,
+ else if (FDI_RX_IMR_TO_PIPE(offset) != INVALID_INDEX)
+ index = FDI_RX_IMR_TO_PIPE(offset);
+ else {
+- gvt_vgpu_err("Unsupport registers %x\n", offset);
++ gvt_vgpu_err("Unsupported registers %x\n", offset);
+ return -EINVAL;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 823bab1e4cbda849a2c60208c4e4ffca2b8fd66d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Aug 2022 18:37:35 +0800
+Subject: gpio: pca953x: Add mutex_lock for regcache sync in PM
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 518e26f11af2fe4f5bebf9a0351595d508c7077f ]
+
+The regcache sync will set the cache_bypass = true, at that
+time, when there is regmap write operation, it will bypass
+the regmap cache, then the regcache sync will write back the
+value from cache to register, which is not as our expectation.
+
+Though regmap already use its internal lock to avoid such issue,
+but this driver force disable the regmap internal lock in its
+regmap config: disable_locking = true
+
+To avoid this issue, use the driver's own lock to do the protect
+in system PM.
+
+Fixes: b76574300504 ("gpio: pca953x: Restore registers after suspend/resume cycle")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-pca953x.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index ecd7d169470b0..2925f4d8cef36 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -1175,7 +1175,9 @@ static int pca953x_suspend(struct device *dev)
+ {
+ struct pca953x_chip *chip = dev_get_drvdata(dev);
+
++ mutex_lock(&chip->i2c_lock);
+ regcache_cache_only(chip->regmap, true);
++ mutex_unlock(&chip->i2c_lock);
+
+ if (atomic_read(&chip->wakeup_path))
+ device_set_wakeup_path(dev);
+@@ -1198,13 +1200,17 @@ static int pca953x_resume(struct device *dev)
+ }
+ }
+
++ mutex_lock(&chip->i2c_lock);
+ regcache_cache_only(chip->regmap, false);
+ regcache_mark_dirty(chip->regmap);
+ ret = pca953x_regcache_sync(dev);
+- if (ret)
++ if (ret) {
++ mutex_unlock(&chip->i2c_lock);
+ return ret;
++ }
+
+ ret = regcache_sync(chip->regmap);
++ mutex_unlock(&chip->i2c_lock);
+ if (ret) {
+ dev_err(dev, "Failed to restore register map: %d\n", ret);
+ return ret;
+--
+2.35.1
+
--- /dev/null
+From d2d129a18b94ed33bb9972fa1eb98e01bf0233fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Aug 2022 21:21:15 +0200
+Subject: gpio: realtek-otto: switch to 32-bit I/O
+
+From: Sander Vanheule <sander@svanheule.net>
+
+[ Upstream commit ee0175b3b44288c74d5292c2a9c2c154f6c0317e ]
+
+By using 16-bit I/O on the GPIO peripheral, which is apparently not safe
+on MIPS, the IMR can end up containing garbage. This then results in
+interrupt triggers for lines that don't have an interrupt handler
+associated. The irq_desc lookup fails, and the ISR will not be cleared,
+keeping the CPU busy until reboot, or until another IMR operation
+restores the correct value. This situation appears to happen very
+rarely, for < 0.5% of IMR writes.
+
+Instead of using 8-bit or 16-bit I/O operations on the 32-bit memory
+mapped peripheral registers, switch to using 32-bit I/O only, operating
+on the entire bank for all single bit line settings. For 2-bit line
+settings, with 16-bit port values, stick to manual (un)packing.
+
+This issue has been seen on RTL8382M (HPE 1920-16G), RTL8391M (Netgear
+GS728TP v2), and RTL8393M (D-Link DGS-1210-52 F3, Zyxel GS1900-48).
+
+Reported-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> # DGS-1210-52
+Reported-by: Birger Koblitz <mail@birger-koblitz.de> # GS728TP
+Reported-by: Jan Hoffmann <jan@3e8.eu> # 1920-16G
+Fixes: 0d82fb1127fb ("gpio: Add Realtek Otto GPIO support")
+Signed-off-by: Sander Vanheule <sander@svanheule.net>
+Cc: Paul Cercueil <paul@crapouillou.net>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-realtek-otto.c | 166 ++++++++++++++++---------------
+ 1 file changed, 85 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c
+index 63dcf42f7c206..d6418f89d3f63 100644
+--- a/drivers/gpio/gpio-realtek-otto.c
++++ b/drivers/gpio/gpio-realtek-otto.c
+@@ -46,10 +46,20 @@
+ * @lock: Lock for accessing the IRQ registers and values
+ * @intr_mask: Mask for interrupts lines
+ * @intr_type: Interrupt type selection
++ * @bank_read: Read a bank setting as a single 32-bit value
++ * @bank_write: Write a bank setting as a single 32-bit value
++ * @imr_line_pos: Bit shift of an IRQ line's IMR value.
++ *
++ * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed
++ * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign)
++ * a value from (to) these registers. The IMR register consists of four 16-bit
++ * port values, packed into two 32-bit registers. Use @imr_line_pos to get the
++ * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than
++ * 32 overflow into the second register.
+ *
+ * Because the interrupt mask register (IMR) combines the function of IRQ type
+ * selection and masking, two extra values are stored. @intr_mask is used to
+- * mask/unmask the interrupts for a GPIO port, and @intr_type is used to store
++ * mask/unmask the interrupts for a GPIO line, and @intr_type is used to store
+ * the selected interrupt types. The logical AND of these values is written to
+ * IMR on changes.
+ */
+@@ -59,10 +69,11 @@ struct realtek_gpio_ctrl {
+ void __iomem *cpumask_base;
+ struct cpumask cpu_irq_maskable;
+ raw_spinlock_t lock;
+- u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];
+- u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK];
+- unsigned int (*port_offset_u8)(unsigned int port);
+- unsigned int (*port_offset_u16)(unsigned int port);
++ u8 intr_mask[REALTEK_GPIO_MAX];
++ u8 intr_type[REALTEK_GPIO_MAX];
++ u32 (*bank_read)(void __iomem *reg);
++ void (*bank_write)(void __iomem *reg, u32 value);
++ unsigned int (*line_imr_pos)(unsigned int line);
+ };
+
+ /* Expand with more flags as devices with other quirks are added */
+@@ -101,14 +112,22 @@ static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)
+ * port. The two interrupt mask registers store two bits per GPIO, so use u16
+ * values.
+ */
+-static unsigned int realtek_gpio_port_offset_u8(unsigned int port)
++static u32 realtek_gpio_bank_read_swapped(void __iomem *reg)
+ {
+- return port;
++ return ioread32be(reg);
+ }
+
+-static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
++static void realtek_gpio_bank_write_swapped(void __iomem *reg, u32 value)
+ {
+- return 2 * port;
++ iowrite32be(value, reg);
++}
++
++static unsigned int realtek_gpio_line_imr_pos_swapped(unsigned int line)
++{
++ unsigned int port_pin = line % 8;
++ unsigned int port = line / 8;
++
++ return 2 * (8 * (port ^ 1) + port_pin);
+ }
+
+ /*
+@@ -119,66 +138,67 @@ static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
+ * per GPIO, so use u16 values. The first register contains ports 1 and 0, the
+ * second ports 3 and 2.
+ */
+-static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port)
++static u32 realtek_gpio_bank_read(void __iomem *reg)
+ {
+- return 3 - port;
++ return ioread32(reg);
+ }
+
+-static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port)
++static void realtek_gpio_bank_write(void __iomem *reg, u32 value)
+ {
+- return 2 * (port ^ 1);
++ iowrite32(value, reg);
+ }
+
+-static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl,
+- unsigned int port, u16 irq_type, u16 irq_mask)
++static unsigned int realtek_gpio_line_imr_pos(unsigned int line)
+ {
+- iowrite16(irq_type & irq_mask,
+- ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port));
++ return 2 * line;
+ }
+
+-static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl,
+- unsigned int port, u8 mask)
++static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, u32 mask)
+ {
+- iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
++ ctrl->bank_write(ctrl->base + REALTEK_GPIO_REG_ISR, mask);
+ }
+
+-static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port)
++static u32 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl)
+ {
+- return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
++ return ctrl->bank_read(ctrl->base + REALTEK_GPIO_REG_ISR);
+ }
+
+-/* Set the rising and falling edge mask bits for a GPIO port pin */
+-static u16 realtek_gpio_imr_bits(unsigned int pin, u16 value)
++/* Set the rising and falling edge mask bits for a GPIO pin */
++static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigned int line)
+ {
+- return (value & REALTEK_GPIO_IMR_LINE_MASK) << 2 * pin;
++ void __iomem *reg = ctrl->base + REALTEK_GPIO_REG_IMR;
++ unsigned int line_shift = ctrl->line_imr_pos(line);
++ unsigned int shift = line_shift % 32;
++ u32 irq_type = ctrl->intr_type[line];
++ u32 irq_mask = ctrl->intr_mask[line];
++ u32 reg_val;
++
++ reg += 4 * (line_shift / 32);
++ reg_val = ioread32(reg);
++ reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift);
++ reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift;
++ iowrite32(reg_val, reg);
+ }
+
+ static void realtek_gpio_irq_ack(struct irq_data *data)
+ {
+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
+ irq_hw_number_t line = irqd_to_hwirq(data);
+- unsigned int port = line / 8;
+- unsigned int port_pin = line % 8;
+
+- realtek_gpio_clear_isr(ctrl, port, BIT(port_pin));
++ realtek_gpio_clear_isr(ctrl, BIT(line));
+ }
+
+ static void realtek_gpio_irq_unmask(struct irq_data *data)
+ {
+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
+ unsigned int line = irqd_to_hwirq(data);
+- unsigned int port = line / 8;
+- unsigned int port_pin = line % 8;
+ unsigned long flags;
+- u16 m;
+
+ gpiochip_enable_irq(&ctrl->gc, line);
+
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
+- m = ctrl->intr_mask[port];
+- m |= realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
+- ctrl->intr_mask[port] = m;
+- realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m);
++ ctrl->intr_mask[line] = REALTEK_GPIO_IMR_LINE_MASK;
++ realtek_gpio_update_line_imr(ctrl, line);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
+ }
+
+@@ -186,16 +206,11 @@ static void realtek_gpio_irq_mask(struct irq_data *data)
+ {
+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
+ unsigned int line = irqd_to_hwirq(data);
+- unsigned int port = line / 8;
+- unsigned int port_pin = line % 8;
+ unsigned long flags;
+- u16 m;
+
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
+- m = ctrl->intr_mask[port];
+- m &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
+- ctrl->intr_mask[port] = m;
+- realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m);
++ ctrl->intr_mask[line] = 0;
++ realtek_gpio_update_line_imr(ctrl, line);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
+
+ gpiochip_disable_irq(&ctrl->gc, line);
+@@ -205,10 +220,8 @@ static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_ty
+ {
+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
+ unsigned int line = irqd_to_hwirq(data);
+- unsigned int port = line / 8;
+- unsigned int port_pin = line % 8;
+ unsigned long flags;
+- u16 type, t;
++ u8 type;
+
+ switch (flow_type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_FALLING:
+@@ -227,11 +240,8 @@ static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_ty
+ irq_set_handler_locked(data, handle_edge_irq);
+
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
+- t = ctrl->intr_type[port];
+- t &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
+- t |= realtek_gpio_imr_bits(port_pin, type);
+- ctrl->intr_type[port] = t;
+- realtek_gpio_write_imr(ctrl, port, t, ctrl->intr_mask[port]);
++ ctrl->intr_type[line] = type;
++ realtek_gpio_update_line_imr(ctrl, line);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
+
+ return 0;
+@@ -242,28 +252,21 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc)
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+ struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
+ struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+- unsigned int lines_done;
+- unsigned int port_pin_count;
+ unsigned long status;
+ int offset;
+
+ chained_irq_enter(irq_chip, desc);
+
+- for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) {
+- status = realtek_gpio_read_isr(ctrl, lines_done / 8);
+- port_pin_count = min(gc->ngpio - lines_done, 8U);
+- for_each_set_bit(offset, &status, port_pin_count)
+- generic_handle_domain_irq(gc->irq.domain, offset + lines_done);
+- }
++ status = realtek_gpio_read_isr(ctrl);
++ for_each_set_bit(offset, &status, gc->ngpio)
++ generic_handle_domain_irq(gc->irq.domain, offset);
+
+ chained_irq_exit(irq_chip, desc);
+ }
+
+-static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl,
+- unsigned int port, int cpu)
++static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, int cpu)
+ {
+- return ctrl->cpumask_base + ctrl->port_offset_u8(port) +
+- REALTEK_GPIO_PORTS_PER_BANK * cpu;
++ return ctrl->cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu;
+ }
+
+ static int realtek_gpio_irq_set_affinity(struct irq_data *data,
+@@ -271,12 +274,10 @@ static int realtek_gpio_irq_set_affinity(struct irq_data *data,
+ {
+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
+ unsigned int line = irqd_to_hwirq(data);
+- unsigned int port = line / 8;
+- unsigned int port_pin = line % 8;
+ void __iomem *irq_cpu_mask;
+ unsigned long flags;
+ int cpu;
+- u8 v;
++ u32 v;
+
+ if (!ctrl->cpumask_base)
+ return -ENXIO;
+@@ -284,15 +285,15 @@ static int realtek_gpio_irq_set_affinity(struct irq_data *data,
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
+
+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
+- irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
+- v = ioread8(irq_cpu_mask);
++ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu);
++ v = ctrl->bank_read(irq_cpu_mask);
+
+ if (cpumask_test_cpu(cpu, dest))
+- v |= BIT(port_pin);
++ v |= BIT(line);
+ else
+- v &= ~BIT(port_pin);
++ v &= ~BIT(line);
+
+- iowrite8(v, irq_cpu_mask);
++ ctrl->bank_write(irq_cpu_mask, v);
+ }
+
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
+@@ -305,16 +306,17 @@ static int realtek_gpio_irq_set_affinity(struct irq_data *data,
+ static int realtek_gpio_irq_init(struct gpio_chip *gc)
+ {
+ struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
+- unsigned int port;
++ u32 mask_all = GENMASK(gc->ngpio - 1, 0);
++ unsigned int line;
+ int cpu;
+
+- for (port = 0; (port * 8) < gc->ngpio; port++) {
+- realtek_gpio_write_imr(ctrl, port, 0, 0);
+- realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
++ for (line = 0; line < gc->ngpio; line++)
++ realtek_gpio_update_line_imr(ctrl, line);
+
+- for_each_cpu(cpu, &ctrl->cpu_irq_maskable)
+- iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu));
+- }
++ realtek_gpio_clear_isr(ctrl, mask_all);
++
++ for_each_cpu(cpu, &ctrl->cpu_irq_maskable)
++ ctrl->bank_write(realtek_gpio_irq_cpu_mask(ctrl, cpu), mask_all);
+
+ return 0;
+ }
+@@ -387,12 +389,14 @@ static int realtek_gpio_probe(struct platform_device *pdev)
+
+ if (dev_flags & GPIO_PORTS_REVERSED) {
+ bgpio_flags = 0;
+- ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev;
+- ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev;
++ ctrl->bank_read = realtek_gpio_bank_read;
++ ctrl->bank_write = realtek_gpio_bank_write;
++ ctrl->line_imr_pos = realtek_gpio_line_imr_pos;
+ } else {
+ bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
+- ctrl->port_offset_u8 = realtek_gpio_port_offset_u8;
+- ctrl->port_offset_u16 = realtek_gpio_port_offset_u16;
++ ctrl->bank_read = realtek_gpio_bank_read_swapped;
++ ctrl->bank_write = realtek_gpio_bank_write_swapped;
++ ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped;
+ }
+
+ err = bgpio_init(&ctrl->gc, dev, 4,
+--
+2.35.1
+
--- /dev/null
+From 25ff27d7f416196b79093b9798527992066c56aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 03:11:01 +0200
+Subject: hwmon: (gpio-fan) Fix array out of bounds access
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit f233d2be38dbbb22299192292983037f01ab363c ]
+
+The driver does not check if the cooling state passed to
+gpio_fan_set_cur_state() exceeds the maximum cooling state as
+stored in fan_data->num_speeds. Since the cooling state is later
+used as an array index in set_fan_speed(), an array out of bounds
+access can occur.
+This can be exploited by setting the state of the thermal cooling device
+to arbitrary values, causing for example a kernel oops when unavailable
+memory is accessed this way.
+
+Example kernel oops:
+[ 807.987276] Unable to handle kernel paging request at virtual address ffffff80d0588064
+[ 807.987369] Mem abort info:
+[ 807.987398] ESR = 0x96000005
+[ 807.987428] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 807.987477] SET = 0, FnV = 0
+[ 807.987507] EA = 0, S1PTW = 0
+[ 807.987536] FSC = 0x05: level 1 translation fault
+[ 807.987570] Data abort info:
+[ 807.987763] ISV = 0, ISS = 0x00000005
+[ 807.987801] CM = 0, WnR = 0
+[ 807.987832] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001165000
+[ 807.987872] [ffffff80d0588064] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
+[ 807.987961] Internal error: Oops: 96000005 [#1] PREEMPT SMP
+[ 807.987992] Modules linked in: cmac algif_hash aes_arm64 algif_skcipher af_alg bnep hci_uart btbcm bluetooth ecdh_generic ecc 8021q garp stp llc snd_soc_hdmi_codec brcmfmac vc4 brcmutil cec drm_kms_helper snd_soc_core cfg80211 snd_compress bcm2835_codec(C) snd_pcm_dmaengine syscopyarea bcm2835_isp(C) bcm2835_v4l2(C) sysfillrect v4l2_mem2mem bcm2835_mmal_vchiq(C) raspberrypi_hwmon sysimgblt videobuf2_dma_contig videobuf2_vmalloc fb_sys_fops videobuf2_memops rfkill videobuf2_v4l2 videobuf2_common i2c_bcm2835 snd_bcm2835(C) videodev snd_pcm snd_timer snd mc vc_sm_cma(C) gpio_fan uio_pdrv_genirq uio drm fuse drm_panel_orientation_quirks backlight ip_tables x_tables ipv6
+[ 807.988508] CPU: 0 PID: 1321 Comm: bash Tainted: G C 5.15.56-v8+ #1575
+[ 807.988548] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT)
+[ 807.988574] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 807.988608] pc : set_fan_speed.part.5+0x34/0x80 [gpio_fan]
+[ 807.988654] lr : gpio_fan_set_cur_state+0x34/0x50 [gpio_fan]
+[ 807.988691] sp : ffffffc008cf3bd0
+[ 807.988710] x29: ffffffc008cf3bd0 x28: ffffff80019edac0 x27: 0000000000000000
+[ 807.988762] x26: 0000000000000000 x25: 0000000000000000 x24: ffffff800747c920
+[ 807.988787] x23: 000000000000000a x22: ffffff800369f000 x21: 000000001999997c
+[ 807.988854] x20: ffffff800369f2e8 x19: ffffff8002ae8080 x18: 0000000000000000
+[ 807.988877] x17: 0000000000000000 x16: 0000000000000000 x15: 000000559e271b70
+[ 807.988938] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
+[ 807.988960] x11: 0000000000000000 x10: ffffffc008cf3c20 x9 : ffffffcfb60c741c
+[ 807.989018] x8 : 000000000000000a x7 : 00000000ffffffc9 x6 : 0000000000000009
+[ 807.989040] x5 : 000000000000002a x4 : 0000000000000000 x3 : ffffff800369f2e8
+[ 807.989062] x2 : 000000000000e780 x1 : 0000000000000001 x0 : ffffff80d0588060
+[ 807.989084] Call trace:
+[ 807.989091] set_fan_speed.part.5+0x34/0x80 [gpio_fan]
+[ 807.989113] gpio_fan_set_cur_state+0x34/0x50 [gpio_fan]
+[ 807.989199] cur_state_store+0x84/0xd0
+[ 807.989221] dev_attr_store+0x20/0x38
+[ 807.989262] sysfs_kf_write+0x4c/0x60
+[ 807.989282] kernfs_fop_write_iter+0x130/0x1c0
+[ 807.989298] new_sync_write+0x10c/0x190
+[ 807.989315] vfs_write+0x254/0x378
+[ 807.989362] ksys_write+0x70/0xf8
+[ 807.989379] __arm64_sys_write+0x24/0x30
+[ 807.989424] invoke_syscall+0x4c/0x110
+[ 807.989442] el0_svc_common.constprop.3+0xfc/0x120
+[ 807.989458] do_el0_svc+0x2c/0x90
+[ 807.989473] el0_svc+0x24/0x60
+[ 807.989544] el0t_64_sync_handler+0x90/0xb8
+[ 807.989558] el0t_64_sync+0x1a0/0x1a4
+[ 807.989579] Code: b9403801 f9402800 7100003f 8b35cc00 (b9400416)
+[ 807.989627] ---[ end trace 8ded4c918658445b ]---
+
+Fix this by checking the cooling state and return an error if it
+exceeds the maximum cooling state.
+
+Tested on a Raspberry Pi 3.
+
+Fixes: b5cf88e46bad ("(gpio-fan): Add thermal control hooks")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20220830011101.178843-1-W_Armin@gmx.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/gpio-fan.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
+index befe989ca7b94..fbf3f5a4ecb67 100644
+--- a/drivers/hwmon/gpio-fan.c
++++ b/drivers/hwmon/gpio-fan.c
+@@ -391,6 +391,9 @@ static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev,
+ if (!fan_data)
+ return -EINVAL;
+
++ if (state >= fan_data->num_speed)
++ return -EINVAL;
++
+ set_fan_speed(fan_data, state);
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From d06ef266e7b1ad60c20427aecd3f6a36025486ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Aug 2022 16:33:18 -0700
+Subject: Input: rk805-pwrkey - fix module autoloading
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit 99077ad668ddd9b4823cc8ce3f3c7a3fc56f6fd9 ]
+
+Add the module alias so the rk805-pwrkey driver will
+autoload when built as a module.
+
+Fixes: 5a35b85c2d92 ("Input: add power key driver for Rockchip RK805 PMIC")
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20220612225437.3628788-1-pbrobinson@gmail.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/rk805-pwrkey.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/input/misc/rk805-pwrkey.c b/drivers/input/misc/rk805-pwrkey.c
+index 3fb64dbda1a21..76873aa005b41 100644
+--- a/drivers/input/misc/rk805-pwrkey.c
++++ b/drivers/input/misc/rk805-pwrkey.c
+@@ -98,6 +98,7 @@ static struct platform_driver rk805_pwrkey_driver = {
+ };
+ module_platform_driver(rk805_pwrkey_driver);
+
++MODULE_ALIAS("platform:rk805-pwrkey");
+ MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
+ MODULE_DESCRIPTION("RK805 PMIC Power Key driver");
+ MODULE_LICENSE("GPL");
+--
+2.35.1
+
--- /dev/null
+From 8ecc8f3c9ed11d8693e714377d85ae7b9bba0c6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Aug 2022 14:30:50 -0700
+Subject: KVM: VMX: Heed the 'msr' argument in msr_write_intercepted()
+
+From: Jim Mattson <jmattson@google.com>
+
+[ Upstream commit 020dac4187968535f089f83f376a72beb3451311 ]
+
+Regardless of the 'msr' argument passed to the VMX version of
+msr_write_intercepted(), the function always checks to see if a
+specific MSR (IA32_SPEC_CTRL) is intercepted for write. This behavior
+seems unintentional and unexpected.
+
+Modify the function so that it checks to see if the provided 'msr'
+index is intercepted for write.
+
+Fixes: 67f4b9969c30 ("KVM: nVMX: Handle dynamic MSR intercept toggling")
+Cc: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220810213050.2655000-1-jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/vmx.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 0aaea87a14597..b09a50e0af29d 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -835,8 +835,7 @@ static bool msr_write_intercepted(struct vcpu_vmx *vmx, u32 msr)
+ if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS))
+ return true;
+
+- return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap,
+- MSR_IA32_SPEC_CTRL);
++ return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap, msr);
+ }
+
+ unsigned int __vmx_vcpu_run_flags(struct vcpu_vmx *vmx)
+--
+2.35.1
+
--- /dev/null
+From 5eacee80f758aa15446c59776b1352e93a719c78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 10:49:47 -0700
+Subject: KVM: x86: Mask off unsupported and unknown bits of
+ IA32_ARCH_CAPABILITIES
+
+From: Jim Mattson <jmattson@google.com>
+
+[ Upstream commit 0204750bd4c6ccc2fb7417618477f10373b33f56 ]
+
+KVM should not claim to virtualize unknown IA32_ARCH_CAPABILITIES
+bits. When kvm_get_arch_capabilities() was originally written, there
+were only a few bits defined in this MSR, and KVM could virtualize all
+of them. However, over the years, several bits have been defined that
+KVM cannot just blindly pass through to the guest without additional
+work (such as virtualizing an MSR promised by the
+IA32_ARCH_CAPABILITES feature bit).
+
+Define a mask of supported IA32_ARCH_CAPABILITIES bits, and mask off
+any other bits that are set in the hardware MSR.
+
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Fixes: 5b76a3cff011 ("KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry")
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Reviewed-by: Vipin Sharma <vipinsh@google.com>
+Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Message-Id: <20220830174947.2182144-1-jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/x86.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index bc411d19dac08..55de0d1981e52 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1570,12 +1570,32 @@ static const u32 msr_based_features_all[] = {
+ static u32 msr_based_features[ARRAY_SIZE(msr_based_features_all)];
+ static unsigned int num_msr_based_features;
+
++/*
++ * Some IA32_ARCH_CAPABILITIES bits have dependencies on MSRs that KVM
++ * does not yet virtualize. These include:
++ * 10 - MISC_PACKAGE_CTRLS
++ * 11 - ENERGY_FILTERING_CTL
++ * 12 - DOITM
++ * 18 - FB_CLEAR_CTRL
++ * 21 - XAPIC_DISABLE_STATUS
++ * 23 - OVERCLOCKING_STATUS
++ */
++
++#define KVM_SUPPORTED_ARCH_CAP \
++ (ARCH_CAP_RDCL_NO | ARCH_CAP_IBRS_ALL | ARCH_CAP_RSBA | \
++ ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \
++ ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
++ ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
++ ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO)
++
+ static u64 kvm_get_arch_capabilities(void)
+ {
+ u64 data = 0;
+
+- if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
++ if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) {
+ rdmsrl(MSR_IA32_ARCH_CAPABILITIES, data);
++ data &= KVM_SUPPORTED_ARCH_CAP;
++ }
+
+ /*
+ * If nx_huge_pages is enabled, KVM's shadow paging will ensure that
+@@ -1623,9 +1643,6 @@ static u64 kvm_get_arch_capabilities(void)
+ */
+ }
+
+- /* Guests don't need to know "Fill buffer clear control" exists */
+- data &= ~ARCH_CAP_FB_CLEAR_CTRL;
+-
+ return data;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 1f6d37c3ab46270c3ca28af87f38ca90284df18c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 12:26:12 +0100
+Subject: mm: pagewalk: Fix race between unmap and page walker
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Steven Price <steven.price@arm.com>
+
+[ Upstream commit 8782fb61cc848364e1e1599d76d3c9dd58a1cc06 ]
+
+The mmap lock protects the page walker from changes to the page tables
+during the walk. However a read lock is insufficient to protect those
+areas which don't have a VMA as munmap() detaches the VMAs before
+downgrading to a read lock and actually tearing down PTEs/page tables.
+
+For users of walk_page_range() the solution is to simply call pte_hole()
+immediately without checking the actual page tables when a VMA is not
+present. We now never call __walk_page_range() without a valid vma.
+
+For walk_page_range_novma() the locking requirements are tightened to
+require the mmap write lock to be taken, and then walking the pgd
+directly with 'no_vma' set.
+
+This in turn means that all page walkers either have a valid vma, or
+it's that special 'novma' case for page table debugging. As a result,
+all the odd '(!walk->vma && !walk->no_vma)' tests can be removed.
+
+Fixes: dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap")
+Reported-by: Jann Horn <jannh@google.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Konstantin Khlebnikov <koct9i@gmail.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/mm/pageattr.c | 4 ++--
+ mm/pagewalk.c | 21 ++++++++++++---------
+ mm/ptdump.c | 4 ++--
+ 3 files changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
+index 5e49e4b4a4ccc..86c56616e5dea 100644
+--- a/arch/riscv/mm/pageattr.c
++++ b/arch/riscv/mm/pageattr.c
+@@ -118,10 +118,10 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,
+ if (!numpages)
+ return 0;
+
+- mmap_read_lock(&init_mm);
++ mmap_write_lock(&init_mm);
+ ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL,
+ &masks);
+- mmap_read_unlock(&init_mm);
++ mmap_write_unlock(&init_mm);
+
+ flush_tlb_kernel_range(start, end);
+
+diff --git a/mm/pagewalk.c b/mm/pagewalk.c
+index 9b3db11a4d1db..fa7a3d21a7518 100644
+--- a/mm/pagewalk.c
++++ b/mm/pagewalk.c
+@@ -110,7 +110,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
+ do {
+ again:
+ next = pmd_addr_end(addr, end);
+- if (pmd_none(*pmd) || (!walk->vma && !walk->no_vma)) {
++ if (pmd_none(*pmd)) {
+ if (ops->pte_hole)
+ err = ops->pte_hole(addr, next, depth, walk);
+ if (err)
+@@ -171,7 +171,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
+ do {
+ again:
+ next = pud_addr_end(addr, end);
+- if (pud_none(*pud) || (!walk->vma && !walk->no_vma)) {
++ if (pud_none(*pud)) {
+ if (ops->pte_hole)
+ err = ops->pte_hole(addr, next, depth, walk);
+ if (err)
+@@ -366,19 +366,19 @@ static int __walk_page_range(unsigned long start, unsigned long end,
+ struct vm_area_struct *vma = walk->vma;
+ const struct mm_walk_ops *ops = walk->ops;
+
+- if (vma && ops->pre_vma) {
++ if (ops->pre_vma) {
+ err = ops->pre_vma(start, end, walk);
+ if (err)
+ return err;
+ }
+
+- if (vma && is_vm_hugetlb_page(vma)) {
++ if (is_vm_hugetlb_page(vma)) {
+ if (ops->hugetlb_entry)
+ err = walk_hugetlb_range(start, end, walk);
+ } else
+ err = walk_pgd_range(start, end, walk);
+
+- if (vma && ops->post_vma)
++ if (ops->post_vma)
+ ops->post_vma(walk);
+
+ return err;
+@@ -450,9 +450,13 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
+ if (!vma) { /* after the last vma */
+ walk.vma = NULL;
+ next = end;
++ if (ops->pte_hole)
++ err = ops->pte_hole(start, next, -1, &walk);
+ } else if (start < vma->vm_start) { /* outside vma */
+ walk.vma = NULL;
+ next = min(end, vma->vm_start);
++ if (ops->pte_hole)
++ err = ops->pte_hole(start, next, -1, &walk);
+ } else { /* inside vma */
+ walk.vma = vma;
+ next = min(end, vma->vm_end);
+@@ -470,9 +474,8 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
+ }
+ if (err < 0)
+ break;
+- }
+- if (walk.vma || walk.ops->pte_hole)
+ err = __walk_page_range(start, next, &walk);
++ }
+ if (err)
+ break;
+ } while (start = next, start < end);
+@@ -501,9 +504,9 @@ int walk_page_range_novma(struct mm_struct *mm, unsigned long start,
+ if (start >= end || !walk.mm)
+ return -EINVAL;
+
+- mmap_assert_locked(walk.mm);
++ mmap_assert_write_locked(walk.mm);
+
+- return __walk_page_range(start, end, &walk);
++ return walk_pgd_range(start, end, &walk);
+ }
+
+ int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops,
+diff --git a/mm/ptdump.c b/mm/ptdump.c
+index eea3d28d173c2..8adab455a68b3 100644
+--- a/mm/ptdump.c
++++ b/mm/ptdump.c
+@@ -152,13 +152,13 @@ void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd)
+ {
+ const struct ptdump_range *range = st->range;
+
+- mmap_read_lock(mm);
++ mmap_write_lock(mm);
+ while (range->start != range->end) {
+ walk_page_range_novma(mm, range->start, range->end,
+ &ptdump_ops, pgd, st);
+ range++;
+ }
+- mmap_read_unlock(mm);
++ mmap_write_unlock(mm);
+
+ /* Flush out the last page */
+ st->note_page(st, 0, -1, 0);
+--
+2.35.1
+
--- /dev/null
+From c52d3c66e210c63915002fc4b35a8c08fa5d3322 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 08:12:56 -0700
+Subject: powerpc/papr_scm: Ensure rc is always initialized in
+ papr_scm_pmu_register()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 6cf07810e9ef8535d60160d13bf0fd05f2af38e7 ]
+
+Clang warns:
+
+ arch/powerpc/platforms/pseries/papr_scm.c:492:6: warning: variable 'rc' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
+ if (!p->stat_buffer_len)
+ ^~~~~~~~~~~~~~~~~~~
+ arch/powerpc/platforms/pseries/papr_scm.c:523:64: note: uninitialized use occurs here
+ dev_info(&p->pdev->dev, "nvdimm pmu didn't register rc=%d\n", rc);
+ ^~
+ include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
+ dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
+ ^~~~~~~~~~~
+ include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
+ _p_func(dev, fmt, ##__VA_ARGS__); \
+ ^~~~~~~~~~~
+ arch/powerpc/platforms/pseries/papr_scm.c:492:2: note: remove the 'if' if its condition is always false
+ if (!p->stat_buffer_len)
+ ^~~~~~~~~~~~~~~~~~~~~~~~
+ arch/powerpc/platforms/pseries/papr_scm.c:484:8: note: initialize the variable 'rc' to silence this warning
+ int rc, nodeid;
+ ^
+ = 0
+ 1 warning generated.
+
+The call to papr_scm_pmu_check_events() was eliminated but a return code
+was not added to the if statement. Add the same return code from
+papr_scm_pmu_check_events() for this condition so there is no more
+warning.
+
+Fixes: 9b1ac04698a4 ("powerpc/papr_scm: Fix nvdimm event mappings")
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://github.com/ClangBuiltLinux/linux/issues/1701
+Link: https://lore.kernel.org/r/20220830151256.1473169-1-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/papr_scm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
+index 16bac4e0d7a21..92074a6c49d43 100644
+--- a/arch/powerpc/platforms/pseries/papr_scm.c
++++ b/arch/powerpc/platforms/pseries/papr_scm.c
+@@ -489,8 +489,10 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
+ goto pmu_err_print;
+ }
+
+- if (!p->stat_buffer_len)
++ if (!p->stat_buffer_len) {
++ rc = -ENOENT;
+ goto pmu_check_events_err;
++ }
+
+ nd_pmu->pmu.task_ctx_nr = perf_invalid_context;
+ nd_pmu->pmu.name = nvdimm_name(p->nvdimm);
+--
+2.35.1
+
--- /dev/null
+From 4475bdd045b76199b897e3442022aea56fdc9bb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 13:18:52 +0530
+Subject: powerpc/papr_scm: Fix nvdimm event mappings
+
+From: Kajol Jain <kjain@linux.ibm.com>
+
+[ Upstream commit 9b1ac04698a4bfec146322502cdcd9904c1777fa ]
+
+Commit 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
+added performance monitoring support for papr-scm nvdimm devices via
+perf interface. Commit also added an array in papr_scm_priv
+structure called "nvdimm_events_map", which got filled based on the
+result of H_SCM_PERFORMANCE_STATS hcall.
+
+Currently there is an assumption that the order of events in the
+stats buffer, returned by the hypervisor is same. And order also
+happens to matches with the events specified in nvdimm driver code.
+But this assumption is not documented in Power Architecture
+Platform Requirements (PAPR) document. Although the order
+of events happens to be same on current generation od system, but
+it might not be true in future generation systems. Fix the issue, by
+adding a static mapping for nvdimm events to corresponding stat-id,
+and removing the dynamic map from papr_scm_priv structure. Also
+remove the function papr_scm_pmu_check_events from papr_scm.c file,
+as we no longer need to copy stat-ids dynamically.
+
+Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
+Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
+Reviewed-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220804074852.55157-1-kjain@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/papr_scm.c | 88 +++++++----------------
+ 1 file changed, 27 insertions(+), 61 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
+index 82cae08976bcd..16bac4e0d7a21 100644
+--- a/arch/powerpc/platforms/pseries/papr_scm.c
++++ b/arch/powerpc/platforms/pseries/papr_scm.c
+@@ -124,9 +124,6 @@ struct papr_scm_priv {
+
+ /* The bits which needs to be overridden */
+ u64 health_bitmap_inject_mask;
+-
+- /* array to have event_code and stat_id mappings */
+- u8 *nvdimm_events_map;
+ };
+
+ static int papr_scm_pmem_flush(struct nd_region *nd_region,
+@@ -350,6 +347,25 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
+ #ifdef CONFIG_PERF_EVENTS
+ #define to_nvdimm_pmu(_pmu) container_of(_pmu, struct nvdimm_pmu, pmu)
+
++static const char * const nvdimm_events_map[] = {
++ [1] = "CtlResCt",
++ [2] = "CtlResTm",
++ [3] = "PonSecs ",
++ [4] = "MemLife ",
++ [5] = "CritRscU",
++ [6] = "HostLCnt",
++ [7] = "HostSCnt",
++ [8] = "HostSDur",
++ [9] = "HostLDur",
++ [10] = "MedRCnt ",
++ [11] = "MedWCnt ",
++ [12] = "MedRDur ",
++ [13] = "MedWDur ",
++ [14] = "CchRHCnt",
++ [15] = "CchWHCnt",
++ [16] = "FastWCnt",
++};
++
+ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count)
+ {
+ struct papr_scm_perf_stat *stat;
+@@ -357,11 +373,15 @@ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev,
+ struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data;
+ int rc, size;
+
++ /* Invalid eventcode */
++ if (event->attr.config == 0 || event->attr.config >= ARRAY_SIZE(nvdimm_events_map))
++ return -EINVAL;
++
+ /* Allocate request buffer enough to hold single performance stat */
+ size = sizeof(struct papr_scm_perf_stats) +
+ sizeof(struct papr_scm_perf_stat);
+
+- if (!p || !p->nvdimm_events_map)
++ if (!p)
+ return -EINVAL;
+
+ stats = kzalloc(size, GFP_KERNEL);
+@@ -370,7 +390,7 @@ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev,
+
+ stat = &stats->scm_statistic[0];
+ memcpy(&stat->stat_id,
+- &p->nvdimm_events_map[event->attr.config * sizeof(stat->stat_id)],
++ nvdimm_events_map[event->attr.config],
+ sizeof(stat->stat_id));
+ stat->stat_val = 0;
+
+@@ -458,56 +478,6 @@ static void papr_scm_pmu_del(struct perf_event *event, int flags)
+ papr_scm_pmu_read(event);
+ }
+
+-static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu *nd_pmu)
+-{
+- struct papr_scm_perf_stat *stat;
+- struct papr_scm_perf_stats *stats;
+- u32 available_events;
+- int index, rc = 0;
+-
+- if (!p->stat_buffer_len)
+- return -ENOENT;
+-
+- available_events = (p->stat_buffer_len - sizeof(struct papr_scm_perf_stats))
+- / sizeof(struct papr_scm_perf_stat);
+- if (available_events == 0)
+- return -EOPNOTSUPP;
+-
+- /* Allocate the buffer for phyp where stats are written */
+- stats = kzalloc(p->stat_buffer_len, GFP_KERNEL);
+- if (!stats) {
+- rc = -ENOMEM;
+- return rc;
+- }
+-
+- /* Called to get list of events supported */
+- rc = drc_pmem_query_stats(p, stats, 0);
+- if (rc)
+- goto out;
+-
+- /*
+- * Allocate memory and populate nvdimm_event_map.
+- * Allocate an extra element for NULL entry
+- */
+- p->nvdimm_events_map = kcalloc(available_events + 1,
+- sizeof(stat->stat_id),
+- GFP_KERNEL);
+- if (!p->nvdimm_events_map) {
+- rc = -ENOMEM;
+- goto out;
+- }
+-
+- /* Copy all stat_ids to event map */
+- for (index = 0, stat = stats->scm_statistic;
+- index < available_events; index++, ++stat) {
+- memcpy(&p->nvdimm_events_map[index * sizeof(stat->stat_id)],
+- &stat->stat_id, sizeof(stat->stat_id));
+- }
+-out:
+- kfree(stats);
+- return rc;
+-}
+-
+ static void papr_scm_pmu_register(struct papr_scm_priv *p)
+ {
+ struct nvdimm_pmu *nd_pmu;
+@@ -519,8 +489,7 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
+ goto pmu_err_print;
+ }
+
+- rc = papr_scm_pmu_check_events(p, nd_pmu);
+- if (rc)
++ if (!p->stat_buffer_len)
+ goto pmu_check_events_err;
+
+ nd_pmu->pmu.task_ctx_nr = perf_invalid_context;
+@@ -539,7 +508,7 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
+
+ rc = register_nvdimm_pmu(nd_pmu, p->pdev);
+ if (rc)
+- goto pmu_register_err;
++ goto pmu_check_events_err;
+
+ /*
+ * Set archdata.priv value to nvdimm_pmu structure, to handle the
+@@ -548,8 +517,6 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
+ p->pdev->archdata.priv = nd_pmu;
+ return;
+
+-pmu_register_err:
+- kfree(p->nvdimm_events_map);
+ pmu_check_events_err:
+ kfree(nd_pmu);
+ pmu_err_print:
+@@ -1560,7 +1527,6 @@ static int papr_scm_remove(struct platform_device *pdev)
+ unregister_nvdimm_pmu(pdev->archdata.priv);
+
+ pdev->archdata.priv = NULL;
+- kfree(p->nvdimm_events_map);
+ kfree(p->bus_desc.provider_name);
+ kfree(p);
+
+--
+2.35.1
+
--- /dev/null
+From 3528b970373ccdbffdbd557922a560cc8467ddcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Aug 2022 10:53:25 -0700
+Subject: Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops"
+
+From: Stephen Boyd <sboyd@kernel.org>
+
+[ Upstream commit abb5f3f4b1f5f0ad50eb067a00051d3587dec9fb ]
+
+This reverts commit 35b0fac808b95eea1212f8860baf6ad25b88b087. Alexander
+reports that it causes boot failures on i.MX8M Plus based boards
+(specifically imx8mp-tqma8mpql-mba8mpxl.dts).
+
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Cc: Chen-Yu Tsai <wenst@chromium.org>
+Fixes: 35b0fac808b9 ("clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops")
+Link: https://lore.kernel.org/r/12115951.O9o76ZdvQC@steina-w
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20220831175326.2523912-1-sboyd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 28 ----------------------------
+ 1 file changed, 28 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 03427e3be727f..f00d4c1158d72 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -196,9 +196,6 @@ static bool clk_core_rate_is_protected(struct clk_core *core)
+ return core->protect_count;
+ }
+
+-static int clk_core_prepare_enable(struct clk_core *core);
+-static void clk_core_disable_unprepare(struct clk_core *core);
+-
+ static bool clk_core_is_prepared(struct clk_core *core)
+ {
+ bool ret = false;
+@@ -211,11 +208,7 @@ static bool clk_core_is_prepared(struct clk_core *core)
+ return core->prepare_count;
+
+ if (!clk_pm_runtime_get(core)) {
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_prepare_enable(core->parent);
+ ret = core->ops->is_prepared(core->hw);
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_disable_unprepare(core->parent);
+ clk_pm_runtime_put(core);
+ }
+
+@@ -251,13 +244,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
+ }
+ }
+
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_prepare_enable(core->parent);
+-
+ ret = core->ops->is_enabled(core->hw);
+-
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_disable_unprepare(core->parent);
+ done:
+ if (core->rpm_enabled)
+ pm_runtime_put(core->dev);
+@@ -825,9 +812,6 @@ int clk_rate_exclusive_get(struct clk *clk)
+ }
+ EXPORT_SYMBOL_GPL(clk_rate_exclusive_get);
+
+-static int clk_core_enable_lock(struct clk_core *core);
+-static void clk_core_disable_lock(struct clk_core *core);
+-
+ static void clk_core_unprepare(struct clk_core *core)
+ {
+ lockdep_assert_held(&prepare_lock);
+@@ -851,9 +835,6 @@ static void clk_core_unprepare(struct clk_core *core)
+
+ WARN(core->enable_count > 0, "Unpreparing enabled %s\n", core->name);
+
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_enable_lock(core->parent);
+-
+ trace_clk_unprepare(core);
+
+ if (core->ops->unprepare)
+@@ -862,9 +843,6 @@ static void clk_core_unprepare(struct clk_core *core)
+ clk_pm_runtime_put(core);
+
+ trace_clk_unprepare_complete(core);
+-
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_disable_lock(core->parent);
+ clk_core_unprepare(core->parent);
+ }
+
+@@ -913,9 +891,6 @@ static int clk_core_prepare(struct clk_core *core)
+ if (ret)
+ goto runtime_put;
+
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_enable_lock(core->parent);
+-
+ trace_clk_prepare(core);
+
+ if (core->ops->prepare)
+@@ -923,9 +898,6 @@ static int clk_core_prepare(struct clk_core *core)
+
+ trace_clk_prepare_complete(core);
+
+- if (core->flags & CLK_OPS_PARENT_ENABLE)
+- clk_core_disable_lock(core->parent);
+-
+ if (ret)
+ goto unprepare;
+ }
+--
+2.35.1
+
--- /dev/null
+From bdefff01475f8510fac7b0928603aa87efbdb48c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Aug 2022 15:12:36 +0100
+Subject: riscv: kvm: move extern sbi_ext declarations to a header
+
+From: Conor Dooley <conor.dooley@microchip.com>
+
+[ Upstream commit 3e5e56c60a14776e2a49837b55b03bc193fd91f7 ]
+
+Sparse complains about missing statics in the declarations of several
+variables:
+arch/riscv/kvm/vcpu_sbi_replace.c:38:37: warning: symbol 'vcpu_sbi_ext_time' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_replace.c:73:37: warning: symbol 'vcpu_sbi_ext_ipi' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_replace.c:126:37: warning: symbol 'vcpu_sbi_ext_rfence' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_replace.c:170:37: warning: symbol 'vcpu_sbi_ext_srst' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_base.c:69:37: warning: symbol 'vcpu_sbi_ext_base' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_base.c:90:37: warning: symbol 'vcpu_sbi_ext_experimental' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_base.c:96:37: warning: symbol 'vcpu_sbi_ext_vendor' was not declared. Should it be static?
+arch/riscv/kvm/vcpu_sbi_hsm.c:115:37: warning: symbol 'vcpu_sbi_ext_hsm' was not declared. Should it be static?
+
+These variables are however used in vcpu_sbi.c where they are declared
+as extern. Move them to kvm_vcpu_sbi.h which is handily already
+included by the three other files.
+
+Fixes: a046c2d8578c ("RISC-V: KVM: Reorganize SBI code by moving SBI v0.1 to its own file")
+Fixes: 5f862df5585c ("RISC-V: KVM: Add v0.1 replacement SBI extensions defined in v0.2")
+Fixes: 3e1d86569c21 ("RISC-V: KVM: Add SBI HSM extension in KVM")
+Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Anup Patel <anup@brainfault.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/kvm_vcpu_sbi.h | 12 ++++++++++++
+ arch/riscv/kvm/vcpu_sbi.c | 12 +-----------
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
+index 83d6d4d2b1dff..26a446a34057b 100644
+--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
++++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
+@@ -33,4 +33,16 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
+ u32 type, u64 flags);
+ const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid);
+
++#ifdef CONFIG_RISCV_SBI_V01
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
++#endif
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
++extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
++
+ #endif /* __RISCV_KVM_VCPU_SBI_H__ */
+diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
+index d45e7da3f0d32..f96991d230bfc 100644
+--- a/arch/riscv/kvm/vcpu_sbi.c
++++ b/arch/riscv/kvm/vcpu_sbi.c
+@@ -32,23 +32,13 @@ static int kvm_linux_err_map_sbi(int err)
+ };
+ }
+
+-#ifdef CONFIG_RISCV_SBI_V01
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
+-#else
++#ifndef CONFIG_RISCV_SBI_V01
+ static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01 = {
+ .extid_start = -1UL,
+ .extid_end = -1UL,
+ .handler = NULL,
+ };
+ #endif
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
+-extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
+
+ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
+ &vcpu_sbi_ext_v01,
+--
+2.35.1
+
binder-fix-alloc-vma_vm_mm-null-ptr-dereference.patch
cifs-fix-small-mempool-leak-in-smb2_negotiate.patch
usb-dwc3-qcom-fix-use-after-free-on-runtime-pm-wakeu.patch
+kvm-vmx-heed-the-msr-argument-in-msr_write_intercept.patch
+riscv-kvm-move-extern-sbi_ext-declarations-to-a-head.patch
+clk-ti-fix-missing-of_node_get-ti_find_clock_provide.patch
+drm-i915-reg-fix-spelling-mistake-unsupport-unsuppor.patch
+clk-core-honor-clk_ops_parent_enable-for-clk-gate-op.patch
+revert-clk-core-honor-clk_ops_parent_enable-for-clk-.patch
+clk-core-fix-runtime-pm-sequence-in-clk_core_unprepa.patch
+input-rk805-pwrkey-fix-module-autoloading.patch
+powerpc-papr_scm-fix-nvdimm-event-mappings.patch
+clk-bcm-rpi-fix-error-handling-of-raspberrypi_fw_get.patch
+clk-bcm-rpi-prevent-out-of-bounds-access.patch
+clk-bcm-rpi-add-missing-newline.patch
+hwmon-gpio-fan-fix-array-out-of-bounds-access.patch
+gpio-pca953x-add-mutex_lock-for-regcache-sync-in-pm.patch
+gpio-realtek-otto-switch-to-32-bit-i-o.patch
+kvm-x86-mask-off-unsupported-and-unknown-bits-of-ia3.patch
+powerpc-papr_scm-ensure-rc-is-always-initialized-in-.patch
+xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch
+mm-pagewalk-fix-race-between-unmap-and-page-walker.patch
--- /dev/null
+From a6fed8be252332eacd740d2fb5b367c8b7afa2d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Sep 2022 18:35:20 +0300
+Subject: xen/grants: prevent integer overflow in gnttab_dma_alloc_pages()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit e9ea0b30ada008f4e65933f449db6894832cb242 ]
+
+The change from kcalloc() to kvmalloc() means that arg->nr_pages
+might now be large enough that the "args->nr_pages << PAGE_SHIFT" can
+result in an integer overflow.
+
+Fixes: b3f7931f5c61 ("xen/gntdev: switch from kcalloc() to kvcalloc()")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/YxDROJqu/RPvR0bi@kili
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/grant-table.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
+index 738029de3c672..e1ec725c2819d 100644
+--- a/drivers/xen/grant-table.c
++++ b/drivers/xen/grant-table.c
+@@ -1047,6 +1047,9 @@ int gnttab_dma_alloc_pages(struct gnttab_dma_alloc_args *args)
+ size_t size;
+ int i, ret;
+
++ if (args->nr_pages < 0 || args->nr_pages > (INT_MAX >> PAGE_SHIFT))
++ return -ENOMEM;
++
+ size = args->nr_pages << PAGE_SHIFT;
+ if (args->coherent)
+ args->vaddr = dma_alloc_coherent(args->dev, size,
+--
+2.35.1
+