From: Sasha Levin Date: Tue, 6 Sep 2022 03:26:09 +0000 (-0400) Subject: Fixes for 5.19 X-Git-Tag: v5.10.142~45 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0b31783e835c1a792b8f11343f5bea1426d452e5;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.19 Signed-off-by: Sasha Levin --- diff --git a/queue-5.19/clk-bcm-rpi-add-missing-newline.patch b/queue-5.19/clk-bcm-rpi-add-missing-newline.patch new file mode 100644 index 00000000000..24cf21f625a --- /dev/null +++ b/queue-5.19/clk-bcm-rpi-add-missing-newline.patch @@ -0,0 +1,56 @@ +From 493e6bd4b4c31ae8aa65bf9882f6387df94875ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Jul 2022 17:49:52 +0200 +Subject: clk: bcm: rpi: Add missing newline + +From: Stefan Wahren + +[ 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 +Link: https://lore.kernel.org/r/20220713154953.3336-3-stefan.wahren@i2se.com +Acked-by: Florian Fainelli +Reviewed-by: Ivan T. Ivanov +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/clk-bcm-rpi-fix-error-handling-of-raspberrypi_fw_get.patch b/queue-5.19/clk-bcm-rpi-fix-error-handling-of-raspberrypi_fw_get.patch new file mode 100644 index 00000000000..f8abc5ab37a --- /dev/null +++ b/queue-5.19/clk-bcm-rpi-fix-error-handling-of-raspberrypi_fw_get.patch @@ -0,0 +1,40 @@ +From 4de26bb3e0c989ca39b96aaccc7898be5d95fccc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Jun 2022 10:36:43 +0200 +Subject: clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate + +From: Stefan Wahren + +[ 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 +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 +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/clk-bcm-rpi-prevent-out-of-bounds-access.patch b/queue-5.19/clk-bcm-rpi-prevent-out-of-bounds-access.patch new file mode 100644 index 00000000000..74151c7396c --- /dev/null +++ b/queue-5.19/clk-bcm-rpi-prevent-out-of-bounds-access.patch @@ -0,0 +1,50 @@ +From 47500b9921bbed02d432959d896ade17bca706f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Jul 2022 17:49:51 +0200 +Subject: clk: bcm: rpi: Prevent out-of-bounds access + +From: Stefan Wahren + +[ 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 +Signed-off-by: Stefan Wahren +Link: https://lore.kernel.org/r/20220713154953.3336-2-stefan.wahren@i2se.com +Acked-by: Florian Fainelli +Reviewed-by: Ivan T. Ivanov +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/clk-core-fix-runtime-pm-sequence-in-clk_core_unprepa.patch b/queue-5.19/clk-core-fix-runtime-pm-sequence-in-clk_core_unprepa.patch new file mode 100644 index 00000000000..438e6715013 --- /dev/null +++ b/queue-5.19/clk-core-fix-runtime-pm-sequence-in-clk_core_unprepa.patch @@ -0,0 +1,50 @@ +From d0d55da67197add5fe43b9796aa9b408cbe17fd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Nícolas F. R. A. Prado +Link: https://lore.kernel.org/r/20220822081424.1310926-3-wenst@chromium.org +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/clk-core-honor-clk_ops_parent_enable-for-clk-gate-op.patch b/queue-5.19/clk-core-honor-clk_ops_parent_enable-for-clk-gate-op.patch new file mode 100644 index 00000000000..3961ca0b9a5 --- /dev/null +++ b/queue-5.19/clk-core-honor-clk_ops_parent_enable-for-clk-gate-op.patch @@ -0,0 +1,127 @@ +From b64e986cc7eac523608441c96647fd5690560016 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Nícolas F. R. A. Prado +Tested-by: Nícolas F. R. A. Prado +Link: https://lore.kernel.org/r/20220822081424.1310926-2-wenst@chromium.org +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/clk-ti-fix-missing-of_node_get-ti_find_clock_provide.patch b/queue-5.19/clk-ti-fix-missing-of_node_get-ti_find_clock_provide.patch new file mode 100644 index 00000000000..be016b64601 --- /dev/null +++ b/queue-5.19/clk-ti-fix-missing-of_node_get-ti_find_clock_provide.patch @@ -0,0 +1,37 @@ +From 35bed605106d15880435c06b4460002225779edd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Jun 2022 12:11:18 +0300 +Subject: clk: ti: Fix missing of_node_get() ti_find_clock_provider() + +From: Tony Lindgren + +[ 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 +Link: https://lore.kernel.org/r/20220621091118.33930-1-tony@atomide.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/drm-i915-reg-fix-spelling-mistake-unsupport-unsuppor.patch b/queue-5.19/drm-i915-reg-fix-spelling-mistake-unsupport-unsuppor.patch new file mode 100644 index 00000000000..b643f742ea3 --- /dev/null +++ b/queue-5.19/drm-i915-reg-fix-spelling-mistake-unsupport-unsuppor.patch @@ -0,0 +1,38 @@ +From e5c2cb3b506b73aad5a46ff2ace39d3613eae2da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Aug 2022 13:02:47 +0800 +Subject: drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" + +From: Colin Ian King + +[ 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 +Signed-off-by: Zhi Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20220315202449.2952845-1-colin.i.king@gmail.com +Reviewed-by: Zhi Wang +Signed-off-by: Zhenyu Wang +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/gpio-pca953x-add-mutex_lock-for-regcache-sync-in-pm.patch b/queue-5.19/gpio-pca953x-add-mutex_lock-for-regcache-sync-in-pm.patch new file mode 100644 index 00000000000..9041781ddec --- /dev/null +++ b/queue-5.19/gpio-pca953x-add-mutex_lock-for-regcache-sync-in-pm.patch @@ -0,0 +1,65 @@ +From 823bab1e4cbda849a2c60208c4e4ffca2b8fd66d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Aug 2022 18:37:35 +0800 +Subject: gpio: pca953x: Add mutex_lock for regcache sync in PM + +From: Haibo Chen + +[ 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 +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/gpio-realtek-otto-switch-to-32-bit-i-o.patch b/queue-5.19/gpio-realtek-otto-switch-to-32-bit-i-o.patch new file mode 100644 index 00000000000..8ba37229144 --- /dev/null +++ b/queue-5.19/gpio-realtek-otto-switch-to-32-bit-i-o.patch @@ -0,0 +1,362 @@ +From d2d129a18b94ed33bb9972fa1eb98e01bf0233fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Aug 2022 21:21:15 +0200 +Subject: gpio: realtek-otto: switch to 32-bit I/O + +From: Sander Vanheule + +[ 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 # DGS-1210-52 +Reported-by: Birger Koblitz # GS728TP +Reported-by: Jan Hoffmann # 1920-16G +Fixes: 0d82fb1127fb ("gpio: Add Realtek Otto GPIO support") +Signed-off-by: Sander Vanheule +Cc: Paul Cercueil +Reviewed-by: Linus Walleij +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/hwmon-gpio-fan-fix-array-out-of-bounds-access.patch b/queue-5.19/hwmon-gpio-fan-fix-array-out-of-bounds-access.patch new file mode 100644 index 00000000000..1bcf3c46a08 --- /dev/null +++ b/queue-5.19/hwmon-gpio-fan-fix-array-out-of-bounds-access.patch @@ -0,0 +1,100 @@ +From 25ff27d7f416196b79093b9798527992066c56aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Aug 2022 03:11:01 +0200 +Subject: hwmon: (gpio-fan) Fix array out of bounds access + +From: Armin Wolf + +[ 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 +Link: https://lore.kernel.org/r/20220830011101.178843-1-W_Armin@gmx.de +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/input-rk805-pwrkey-fix-module-autoloading.patch b/queue-5.19/input-rk805-pwrkey-fix-module-autoloading.patch new file mode 100644 index 00000000000..fc3f0f1a969 --- /dev/null +++ b/queue-5.19/input-rk805-pwrkey-fix-module-autoloading.patch @@ -0,0 +1,37 @@ +From d06ef266e7b1ad60c20427aecd3f6a36025486ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Aug 2022 16:33:18 -0700 +Subject: Input: rk805-pwrkey - fix module autoloading + +From: Peter Robinson + +[ 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 +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20220612225437.3628788-1-pbrobinson@gmail.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + 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 "); + MODULE_DESCRIPTION("RK805 PMIC Power Key driver"); + MODULE_LICENSE("GPL"); +-- +2.35.1 + diff --git a/queue-5.19/kvm-vmx-heed-the-msr-argument-in-msr_write_intercept.patch b/queue-5.19/kvm-vmx-heed-the-msr-argument-in-msr_write_intercept.patch new file mode 100644 index 00000000000..3d20b2cb169 --- /dev/null +++ b/queue-5.19/kvm-vmx-heed-the-msr-argument-in-msr_write_intercept.patch @@ -0,0 +1,45 @@ +From 8ecc8f3c9ed11d8693e714377d85ae7b9bba0c6a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Aug 2022 14:30:50 -0700 +Subject: KVM: VMX: Heed the 'msr' argument in msr_write_intercepted() + +From: Jim Mattson + +[ 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 +Signed-off-by: Jim Mattson +Reviewed-by: Sean Christopherson +Message-Id: <20220810213050.2655000-1-jmattson@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/kvm-x86-mask-off-unsupported-and-unknown-bits-of-ia3.patch b/queue-5.19/kvm-x86-mask-off-unsupported-and-unknown-bits-of-ia3.patch new file mode 100644 index 00000000000..f6bfec4bde4 --- /dev/null +++ b/queue-5.19/kvm-x86-mask-off-unsupported-and-unknown-bits-of-ia3.patch @@ -0,0 +1,84 @@ +From 5eacee80f758aa15446c59776b1352e93a719c78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Fixes: 5b76a3cff011 ("KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry") +Signed-off-by: Jim Mattson +Reviewed-by: Vipin Sharma +Reviewed-by: Xiaoyao Li +Message-Id: <20220830174947.2182144-1-jmattson@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/mm-pagewalk-fix-race-between-unmap-and-page-walker.patch b/queue-5.19/mm-pagewalk-fix-race-between-unmap-and-page-walker.patch new file mode 100644 index 00000000000..be24d626aee --- /dev/null +++ b/queue-5.19/mm-pagewalk-fix-race-between-unmap-and-page-walker.patch @@ -0,0 +1,166 @@ +From 1f6d37c3ab46270c3ca28af87f38ca90284df18c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Steven Price +Cc: Vlastimil Babka +Cc: Thomas Hellström +Cc: Konstantin Khlebnikov +Cc: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/powerpc-papr_scm-ensure-rc-is-always-initialized-in-.patch b/queue-5.19/powerpc-papr_scm-ensure-rc-is-always-initialized-in-.patch new file mode 100644 index 00000000000..e2e96f2771a --- /dev/null +++ b/queue-5.19/powerpc-papr_scm-ensure-rc-is-always-initialized-in-.patch @@ -0,0 +1,67 @@ +From c52d3c66e210c63915002fc4b35a8c08fa5d3322 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Michael Ellerman +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 +--- + 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 + diff --git a/queue-5.19/powerpc-papr_scm-fix-nvdimm-event-mappings.patch b/queue-5.19/powerpc-papr_scm-fix-nvdimm-event-mappings.patch new file mode 100644 index 00000000000..63b2c7c1df9 --- /dev/null +++ b/queue-5.19/powerpc-papr_scm-fix-nvdimm-event-mappings.patch @@ -0,0 +1,200 @@ +From 4475bdd045b76199b897e3442022aea56fdc9bb5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Aug 2022 13:18:52 +0530 +Subject: powerpc/papr_scm: Fix nvdimm event mappings + +From: Kajol Jain + +[ 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 +Signed-off-by: Kajol Jain +Reviewed-by: Vaibhav Jain +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220804074852.55157-1-kjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/revert-clk-core-honor-clk_ops_parent_enable-for-clk-.patch b/queue-5.19/revert-clk-core-honor-clk_ops_parent_enable-for-clk-.patch new file mode 100644 index 00000000000..a60b0edd034 --- /dev/null +++ b/queue-5.19/revert-clk-core-honor-clk_ops_parent_enable-for-clk-.patch @@ -0,0 +1,117 @@ +From 3528b970373ccdbffdbd557922a560cc8467ddcf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Chen-Yu Tsai +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 +Link: https://lore.kernel.org/r/20220831175326.2523912-1-sboyd@kernel.org +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/riscv-kvm-move-extern-sbi_ext-declarations-to-a-head.patch b/queue-5.19/riscv-kvm-move-extern-sbi_ext-declarations-to-a-head.patch new file mode 100644 index 00000000000..be4571b1f43 --- /dev/null +++ b/queue-5.19/riscv-kvm-move-extern-sbi_ext-declarations-to-a-head.patch @@ -0,0 +1,89 @@ +From bdefff01475f8510fac7b0928603aa87efbdb48c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Aug 2022 15:12:36 +0100 +Subject: riscv: kvm: move extern sbi_ext declarations to a header + +From: Conor Dooley + +[ 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 +Signed-off-by: Conor Dooley +Signed-off-by: Anup Patel +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.19/series b/queue-5.19/series index 8f9dbb0a66c..2b8e378873f 100644 --- a/queue-5.19/series +++ b/queue-5.19/series @@ -82,3 +82,22 @@ binder-fix-uaf-of-ref-proc-caused-by-race-condition.patch 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 diff --git a/queue-5.19/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch b/queue-5.19/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch new file mode 100644 index 00000000000..e46d311b43a --- /dev/null +++ b/queue-5.19/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch @@ -0,0 +1,40 @@ +From a6fed8be252332eacd740d2fb5b367c8b7afa2d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Sep 2022 18:35:20 +0300 +Subject: xen/grants: prevent integer overflow in gnttab_dma_alloc_pages() + +From: Dan Carpenter + +[ 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 +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/YxDROJqu/RPvR0bi@kili +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + 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 +