--- /dev/null
+From 7290f59231910ccba427d441a6e8b8c6f6112448 Mon Sep 17 00:00:00 2001
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+Date: Fri, 11 Oct 2024 09:22:41 +0800
+Subject: apparmor: test: Fix memory leak for aa_unpack_strdup()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+commit 7290f59231910ccba427d441a6e8b8c6f6112448 upstream.
+
+The string allocated by kmemdup() in aa_unpack_strdup() is not
+freed and cause following memory leaks, free them to fix it.
+
+ unreferenced object 0xffffff80c6af8a50 (size 8):
+ comm "kunit_try_catch", pid 225, jiffies 4294894407
+ hex dump (first 8 bytes):
+ 74 65 73 74 69 6e 67 00 testing.
+ backtrace (crc 5eab668b):
+ [<0000000001e3714d>] kmemleak_alloc+0x34/0x40
+ [<000000006e6c7776>] __kmalloc_node_track_caller_noprof+0x300/0x3e0
+ [<000000006870467c>] kmemdup_noprof+0x34/0x60
+ [<000000001176bb03>] aa_unpack_strdup+0xd0/0x18c
+ [<000000008ecde918>] policy_unpack_test_unpack_strdup_with_null_name+0xf8/0x3ec
+ [<0000000032ef8f77>] kunit_try_run_case+0x13c/0x3ac
+ [<00000000f3edea23>] kunit_generic_run_threadfn_adapter+0x80/0xec
+ [<00000000adf936cf>] kthread+0x2e8/0x374
+ [<0000000041bb1628>] ret_from_fork+0x10/0x20
+ unreferenced object 0xffffff80c2a29090 (size 8):
+ comm "kunit_try_catch", pid 227, jiffies 4294894409
+ hex dump (first 8 bytes):
+ 74 65 73 74 69 6e 67 00 testing.
+ backtrace (crc 5eab668b):
+ [<0000000001e3714d>] kmemleak_alloc+0x34/0x40
+ [<000000006e6c7776>] __kmalloc_node_track_caller_noprof+0x300/0x3e0
+ [<000000006870467c>] kmemdup_noprof+0x34/0x60
+ [<000000001176bb03>] aa_unpack_strdup+0xd0/0x18c
+ [<0000000046a45c1a>] policy_unpack_test_unpack_strdup_with_name+0xd0/0x3c4
+ [<0000000032ef8f77>] kunit_try_run_case+0x13c/0x3ac
+ [<00000000f3edea23>] kunit_generic_run_threadfn_adapter+0x80/0xec
+ [<00000000adf936cf>] kthread+0x2e8/0x374
+ [<0000000041bb1628>] ret_from_fork+0x10/0x20
+
+Cc: stable@vger.kernel.org
+Fixes: 4d944bcd4e73 ("apparmor: add AppArmor KUnit tests for policy unpack")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ security/apparmor/policy_unpack_test.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/security/apparmor/policy_unpack_test.c
++++ b/security/apparmor/policy_unpack_test.c
+@@ -281,6 +281,8 @@ static void policy_unpack_test_unpack_st
+ ((uintptr_t)puf->e->start <= (uintptr_t)string)
+ && ((uintptr_t)string <= (uintptr_t)puf->e->end));
+ KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
++
++ kfree(string);
+ }
+
+ static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test)
+@@ -296,6 +298,8 @@ static void policy_unpack_test_unpack_st
+ ((uintptr_t)puf->e->start <= (uintptr_t)string)
+ && ((uintptr_t)string <= (uintptr_t)puf->e->end));
+ KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
++
++ kfree(string);
+ }
+
+ static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test)
+@@ -313,6 +317,8 @@ static void policy_unpack_test_unpack_st
+ KUNIT_EXPECT_EQ(test, size, 0);
+ KUNIT_EXPECT_NULL(test, string);
+ KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
++
++ kfree(string);
+ }
+
+ static void policy_unpack_test_unpack_nameX_with_null_name(struct kunit *test)
--- /dev/null
+From b682aa788e5f9f1ddacdfbb453e49fd3f4e83721 Mon Sep 17 00:00:00 2001
+From: Ilya Zverev <ilya@zverev.info>
+Date: Wed, 27 Nov 2024 15:44:20 +0200
+Subject: ASoC: amd: yc: Add a quirk for microfone on Lenovo ThinkPad P14s Gen 5 21MES00B00
+
+From: Ilya Zverev <ilya@zverev.info>
+
+commit b682aa788e5f9f1ddacdfbb453e49fd3f4e83721 upstream.
+
+New ThinkPads need new quirk entries. Ilya has tested this one.
+Laptop product id is 21MES00B00, though the shorthand 21ME works.
+
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219533
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilya Zverev <ilya@zverev.info>
+Link: https://patch.msgid.link/20241127134420.14471-1-ilya@zverev.info
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -245,6 +245,13 @@ static const struct dmi_system_id yc_acp
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21ME"),
++ }
++ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82QF"),
+ }
+ },
--- /dev/null
+From 1157733344651ca505e259d6554591ff156922fa Mon Sep 17 00:00:00 2001
+From: Qiu-ji Chen <chenqiuji666@gmail.com>
+Date: Mon, 30 Sep 2024 18:12:16 +0800
+Subject: ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata()
+
+From: Qiu-ji Chen <chenqiuji666@gmail.com>
+
+commit 1157733344651ca505e259d6554591ff156922fa upstream.
+
+An atomicity violation occurs when the validity of the variables
+da7219->clk_src and da7219->mclk_rate is being assessed. Since the entire
+assessment is not protected by a lock, the da7219 variable might still be
+in flux during the assessment, rendering this check invalid.
+
+To fix this issue, we recommend adding a lock before the block
+if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) so that
+the legitimacy check for da7219->clk_src and da7219->mclk_rate is
+protected by the lock, ensuring the validity of the check.
+
+This possible bug is found by an experimental static analysis tool
+developed by our team. This tool analyzes the locking APIs
+to extract function pairs that can be concurrently executed, and then
+analyzes the instructions in the paired functions to identify possible
+concurrency bugs including data races and atomicity violations.
+
+Fixes: 6d817c0e9fd7 ("ASoC: codecs: Add da7219 codec driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Qiu-ji Chen <chenqiuji666@gmail.com>
+Link: https://patch.msgid.link/20240930101216.23723-1-chenqiuji666@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/da7219.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/codecs/da7219.c
++++ b/sound/soc/codecs/da7219.c
+@@ -1167,17 +1167,20 @@ static int da7219_set_dai_sysclk(struct
+ struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
+ int ret = 0;
+
+- if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
++ mutex_lock(&da7219->pll_lock);
++
++ if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) {
++ mutex_unlock(&da7219->pll_lock);
+ return 0;
++ }
+
+ if ((freq < 2000000) || (freq > 54000000)) {
++ mutex_unlock(&da7219->pll_lock);
+ dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
+ freq);
+ return -EINVAL;
+ }
+
+- mutex_lock(&da7219->pll_lock);
+-
+ switch (clk_id) {
+ case DA7219_CLKSRC_MCLK_SQR:
+ snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
--- /dev/null
+From 9d4f9f6a7bb1afbde57d08c98f2db4ff019ee19d Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Date: Wed, 6 Nov 2024 10:18:17 +0200
+Subject: ASoC: da7213: Populate max_register to regmap_config
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 9d4f9f6a7bb1afbde57d08c98f2db4ff019ee19d upstream.
+
+On the Renesas RZ/G3S SMARC Carrier II board having a DA7212 codec (using
+da7213 driver) connected to one SSIF-2 available on the Renesas RZ/G3S SoC
+it has been discovered that using the runtime PM API for suspend/resume
+(as will be proposed in the following commits) leads to the codec not
+being propertly initialized after resume. This is because w/o
+max_register populated to regmap_config the regcache_rbtree_sync()
+breaks on base_reg > max condition and the regcache_sync_block() call is
+skipped.
+
+Fixes: ef5c2eba2412 ("ASoC: codecs: Add da7213 codec")
+Cc: stable@vger.kernel.org
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20241106081826.1211088-23-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/da7213.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/soc/codecs/da7213.c
++++ b/sound/soc/codecs/da7213.c
+@@ -2136,6 +2136,7 @@ static const struct regmap_config da7213
+ .reg_bits = 8,
+ .val_bits = 8,
+
++ .max_register = DA7213_TONE_GEN_OFF_PER,
+ .reg_defaults = da7213_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(da7213_reg_defaults),
+ .volatile_reg = da7213_volatile_register,
--- /dev/null
+From 5fe6caa62b07fd39cd6a28acc8f92ba2955e11a6 Mon Sep 17 00:00:00 2001
+From: Andrej Shadura <andrew.shadura@collabora.co.uk>
+Date: Wed, 9 Oct 2024 14:14:24 +0200
+Subject: Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}()
+
+From: Andrej Shadura <andrew.shadura@collabora.co.uk>
+
+commit 5fe6caa62b07fd39cd6a28acc8f92ba2955e11a6 upstream.
+
+Commit 9bf4e919ccad worked around an issue introduced after an innocuous
+optimisation change in LLVM main:
+
+> len is defined as an 'int' because it is assigned from
+> '__user int *optlen'. However, it is clamped against the result of
+> sizeof(), which has a type of 'size_t' ('unsigned long' for 64-bit
+> platforms). This is done with min_t() because min() requires compatible
+> types, which results in both len and the result of sizeof() being casted
+> to 'unsigned int', meaning len changes signs and the result of sizeof()
+> is truncated. From there, len is passed to copy_to_user(), which has a
+> third parameter type of 'unsigned long', so it is widened and changes
+> signs again. This excessive casting in combination with the KCSAN
+> instrumentation causes LLVM to fail to eliminate the __bad_copy_from()
+> call, failing the build.
+
+The same issue occurs in rfcomm in functions rfcomm_sock_getsockopt and
+rfcomm_sock_getsockopt_old.
+
+Change the type of len to size_t in both rfcomm_sock_getsockopt and
+rfcomm_sock_getsockopt_old and replace min_t() with min().
+
+Cc: stable@vger.kernel.org
+Co-authored-by: Aleksei Vetrov <vvvvvv@google.com>
+Improves: 9bf4e919ccad ("Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old()")
+Link: https://github.com/ClangBuiltLinux/linux/issues/2007
+Link: https://github.com/llvm/llvm-project/issues/85647
+Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/rfcomm/sock.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -729,7 +729,8 @@ static int rfcomm_sock_getsockopt_old(st
+ struct sock *l2cap_sk;
+ struct l2cap_conn *conn;
+ struct rfcomm_conninfo cinfo;
+- int len, err = 0;
++ int err = 0;
++ size_t len;
+ u32 opt;
+
+ BT_DBG("sk %p", sk);
+@@ -783,7 +784,7 @@ static int rfcomm_sock_getsockopt_old(st
+ cinfo.hci_handle = conn->hcon->handle;
+ memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
+
+- len = min_t(unsigned int, len, sizeof(cinfo));
++ len = min(len, sizeof(cinfo));
+ if (copy_to_user(optval, (char *) &cinfo, len))
+ err = -EFAULT;
+
+@@ -802,7 +803,8 @@ static int rfcomm_sock_getsockopt(struct
+ {
+ struct sock *sk = sock->sk;
+ struct bt_security sec;
+- int len, err = 0;
++ int err = 0;
++ size_t len;
+
+ BT_DBG("sk %p", sk);
+
+@@ -827,7 +829,7 @@ static int rfcomm_sock_getsockopt(struct
+ sec.level = rfcomm_pi(sk)->sec_level;
+ sec.key_size = 0;
+
+- len = min_t(unsigned int, len, sizeof(sec));
++ len = min(len, sizeof(sec));
+ if (copy_to_user(optval, (char *) &sec, len))
+ err = -EFAULT;
+
--- /dev/null
+From 6e4bf018bb040955da53dae9f8628ef8fcec2dbe Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
+Date: Thu, 14 Nov 2024 16:49:21 -0600
+Subject: clk: clk-loongson2: Fix memory corruption bug in struct loongson2_clk_provider
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+commit 6e4bf018bb040955da53dae9f8628ef8fcec2dbe upstream.
+
+Some heap space is allocated for the flexible structure `struct
+clk_hw_onecell_data` and its flexible-array member `hws` through
+the composite structure `struct loongson2_clk_provider` in function
+`loongson2_clk_probe()`, as shown below:
+
+289 struct loongson2_clk_provider *clp;
+ ...
+296 for (p = data; p->name; p++)
+297 clks_num++;
+298
+299 clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num),
+300 GFP_KERNEL);
+
+Then some data is written into the flexible array:
+
+350 clp->clk_data.hws[p->id] = hw;
+
+This corrupts `clk_lock`, which is the spinlock variable immediately
+following the `clk_data` member in `struct loongson2_clk_provider`:
+
+struct loongson2_clk_provider {
+ void __iomem *base;
+ struct device *dev;
+ struct clk_hw_onecell_data clk_data;
+ spinlock_t clk_lock; /* protect access to DIV registers */
+};
+
+The problem is that the flexible structure is currently placed in the
+middle of `struct loongson2_clk_provider` instead of at the end.
+
+Fix this by moving `struct clk_hw_onecell_data clk_data;` to the end of
+`struct loongson2_clk_provider`. Also, add a code comment to help
+prevent this from happening again in case new members are added to the
+structure in the future.
+
+This change also fixes the following -Wflex-array-member-not-at-end
+warning:
+
+drivers/clk/clk-loongson2.c:32:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
+
+Fixes: 9796ec0bd04b ("clk: clk-loongson2: Refactor driver for adding new platforms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/ZzZ-cd_EFXs6qFaH@kspp
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clk/clk-loongson2.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk-loongson2.c b/drivers/clk/clk-loongson2.c
+index 820bb1e9e3b7..e99ba79feec6 100644
+--- a/drivers/clk/clk-loongson2.c
++++ b/drivers/clk/clk-loongson2.c
+@@ -29,8 +29,10 @@ enum loongson2_clk_type {
+ struct loongson2_clk_provider {
+ void __iomem *base;
+ struct device *dev;
+- struct clk_hw_onecell_data clk_data;
+ spinlock_t clk_lock; /* protect access to DIV registers */
++
++ /* Must be last --ends in a flexible-array member. */
++ struct clk_hw_onecell_data clk_data;
+ };
+
+ struct loongson2_clk_data {
+--
+2.47.1
+
--- /dev/null
+From 02fb4f0084331ef72c28d0c70fcb15d1bea369ec Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
+Date: Thu, 14 Nov 2024 17:55:16 -0600
+Subject: clk: clk-loongson2: Fix potential buffer overflow in flexible-array member access
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+commit 02fb4f0084331ef72c28d0c70fcb15d1bea369ec upstream.
+
+Flexible-array member `hws` in `struct clk_hw_onecell_data` is annotated
+with the `counted_by()` attribute. This means that when memory is
+allocated for this array, the _counter_, which in this case is member
+`num` in the flexible structure, should be set to the maximum number of
+elements the flexible array can contain, or fewer.
+
+In this case, the total number of elements for the flexible array is
+determined by variable `clks_num` when allocating heap space via
+`devm_kzalloc()`, as shown below:
+
+289 struct loongson2_clk_provider *clp;
+ ...
+296 for (p = data; p->name; p++)
+297 clks_num++;
+298
+299 clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num),
+300 GFP_KERNEL);
+
+So, `clp->clk_data.num` should be set to `clks_num` or less, and not
+exceed `clks_num`, as is currently the case. Otherwise, if data is
+written into `clp->clk_data.hws[clks_num]`, the instrumentation
+provided by the compiler won't detect the overflow, leading to a
+memory corruption bug at runtime.
+
+Fix this issue by setting `clp->clk_data.num` to `clks_num`.
+
+Fixes: 9796ec0bd04b ("clk: clk-loongson2: Refactor driver for adding new platforms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/ZzaN5MpmMr0hwHw9@kspp
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clk/clk-loongson2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk-loongson2.c b/drivers/clk/clk-loongson2.c
+index e99ba79feec6..7082b4309c6f 100644
+--- a/drivers/clk/clk-loongson2.c
++++ b/drivers/clk/clk-loongson2.c
+@@ -306,7 +306,7 @@ static int loongson2_clk_probe(struct platform_device *pdev)
+ return PTR_ERR(clp->base);
+
+ spin_lock_init(&clp->clk_lock);
+- clp->clk_data.num = clks_num + 1;
++ clp->clk_data.num = clks_num;
+ clp->dev = dev;
+
+ for (i = 0; i < clks_num; i++) {
+--
+2.47.1
+
--- /dev/null
+From ce8f9fb651fac95dd41f69afe54d935420b945bd Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Thu, 17 Oct 2024 21:07:45 +0200
+Subject: comedi: Flush partial mappings in error case
+
+From: Jann Horn <jannh@google.com>
+
+commit ce8f9fb651fac95dd41f69afe54d935420b945bd upstream.
+
+If some remap_pfn_range() calls succeeded before one failed, we still have
+buffer pages mapped into the userspace page tables when we drop the buffer
+reference with comedi_buf_map_put(bm). The userspace mappings are only
+cleaned up later in the mmap error path.
+
+Fix it by explicitly flushing all mappings in our VMA on the error path.
+
+See commit 79a61cc3fc04 ("mm: avoid leaving partial pfn mappings around in
+error case").
+
+Cc: stable@vger.kernel.org
+Fixes: ed9eccbe8970 ("Staging: add comedi core")
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://lore.kernel.org/r/20241017-comedi-tlb-v3-1-16b82f9372ce@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/comedi/comedi_fops.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/comedi/comedi_fops.c
++++ b/drivers/comedi/comedi_fops.c
+@@ -2407,6 +2407,18 @@ static int comedi_mmap(struct file *file
+
+ start += PAGE_SIZE;
+ }
++
++#ifdef CONFIG_MMU
++ /*
++ * Leaving behind a partial mapping of a buffer we're about to
++ * drop is unsafe, see remap_pfn_range_notrack().
++ * We need to zap the range here ourselves instead of relying
++ * on the automatic zapping in remap_pfn_range() because we call
++ * remap_pfn_range() in a loop.
++ */
++ if (retval)
++ zap_vma_ptes(vma, vma->vm_start, size);
++#endif
+ }
+
+ if (retval == 0) {
--- /dev/null
+From f06e108a3dc53c0f5234d18de0bd224753db5019 Mon Sep 17 00:00:00 2001
+From: Jan Hendrik Farr <kernel@jfarr.cc>
+Date: Tue, 29 Oct 2024 15:00:36 +0100
+Subject: Compiler Attributes: disable __counted_by for clang < 19.1.3
+
+From: Jan Hendrik Farr <kernel@jfarr.cc>
+
+commit f06e108a3dc53c0f5234d18de0bd224753db5019 upstream.
+
+This patch disables __counted_by for clang versions < 19.1.3 because
+of the two issues listed below. It does this by introducing
+CONFIG_CC_HAS_COUNTED_BY.
+
+1. clang < 19.1.2 has a bug that can lead to __bdos returning 0:
+https://github.com/llvm/llvm-project/pull/110497
+
+2. clang < 19.1.3 has a bug that can lead to __bdos being off by 4:
+https://github.com/llvm/llvm-project/pull/112636
+
+Fixes: c8248faf3ca2 ("Compiler Attributes: counted_by: Adjust name and identifier expansion")
+Cc: stable@vger.kernel.org # 6.6.x: 16c31dd7fdf6: Compiler Attributes: counted_by: bump min gcc version
+Cc: stable@vger.kernel.org # 6.6.x: 2993eb7a8d34: Compiler Attributes: counted_by: fixup clang URL
+Cc: stable@vger.kernel.org # 6.6.x: 231dc3f0c936: lkdtm/bugs: Improve warning message for compilers without counted_by support
+Cc: stable@vger.kernel.org # 6.6.x
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Closes: https://lore.kernel.org/all/20240913164630.GA4091534@thelio-3990X/
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202409260949.a1254989-oliver.sang@intel.com
+Link: https://lore.kernel.org/all/Zw8iawAF5W2uzGuh@archlinux/T/#m204c09f63c076586a02d194b87dffc7e81b8de7b
+Suggested-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Jan Hendrik Farr <kernel@jfarr.cc>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
+Reviewed-by: Thorsten Blum <thorsten.blum@linux.dev>
+Link: https://lore.kernel.org/r/20241029140036.577804-2-kernel@jfarr.cc
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/lkdtm/bugs.c | 2 +-
+ include/linux/compiler_attributes.h | 13 -------------
+ include/linux/compiler_types.h | 19 +++++++++++++++++++
+ init/Kconfig | 9 +++++++++
+ lib/overflow_kunit.c | 2 +-
+ 5 files changed, 30 insertions(+), 15 deletions(-)
+
+--- a/drivers/misc/lkdtm/bugs.c
++++ b/drivers/misc/lkdtm/bugs.c
+@@ -445,7 +445,7 @@ static void lkdtm_FAM_BOUNDS(void)
+
+ pr_err("FAIL: survived access of invalid flexible array member index!\n");
+
+- if (!__has_attribute(__counted_by__))
++ if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY))
+ pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by\n",
+ lkdtm_kernel_info);
+ else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
+--- a/include/linux/compiler_attributes.h
++++ b/include/linux/compiler_attributes.h
+@@ -95,19 +95,6 @@
+ #endif
+
+ /*
+- * Optional: only supported since gcc >= 15
+- * Optional: only supported since clang >= 18
+- *
+- * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
+- * clang: https://github.com/llvm/llvm-project/pull/76348
+- */
+-#if __has_attribute(__counted_by__)
+-# define __counted_by(member) __attribute__((__counted_by__(member)))
+-#else
+-# define __counted_by(member)
+-#endif
+-
+-/*
+ * Optional: not supported by gcc
+ * Optional: only supported since clang >= 14.0
+ *
+--- a/include/linux/compiler_types.h
++++ b/include/linux/compiler_types.h
+@@ -324,6 +324,25 @@ struct ftrace_likely_data {
+ #endif
+
+ /*
++ * Optional: only supported since gcc >= 15
++ * Optional: only supported since clang >= 18
++ *
++ * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
++ * clang: https://github.com/llvm/llvm-project/pull/76348
++ *
++ * __bdos on clang < 19.1.2 can erroneously return 0:
++ * https://github.com/llvm/llvm-project/pull/110497
++ *
++ * __bdos on clang < 19.1.3 can be off by 4:
++ * https://github.com/llvm/llvm-project/pull/112636
++ */
++#ifdef CONFIG_CC_HAS_COUNTED_BY
++# define __counted_by(member) __attribute__((__counted_by__(member)))
++#else
++# define __counted_by(member)
++#endif
++
++/*
+ * Apply __counted_by() when the Endianness matches to increase test coverage.
+ */
+ #ifdef __LITTLE_ENDIAN
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -109,6 +109,15 @@ config CC_HAS_ASM_INLINE
+ config CC_HAS_NO_PROFILE_FN_ATTR
+ def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror)
+
++config CC_HAS_COUNTED_BY
++ # TODO: when gcc 15 is released remove the build test and add
++ # a gcc version check
++ def_bool $(success,echo 'struct flex { int count; int array[] __attribute__((__counted_by__(count))); };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
++ # clang needs to be at least 19.1.3 to avoid __bdos miscalculations
++ # https://github.com/llvm/llvm-project/pull/110497
++ # https://github.com/llvm/llvm-project/pull/112636
++ depends on !(CC_IS_CLANG && CLANG_VERSION < 190103)
++
+ config PAHOLE_VERSION
+ int
+ default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
+--- a/lib/overflow_kunit.c
++++ b/lib/overflow_kunit.c
+@@ -1187,7 +1187,7 @@ static void DEFINE_FLEX_test(struct kuni
+ {
+ /* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */
+ DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2);
+-#if __has_attribute(__counted_by__)
++#ifdef CONFIG_CC_HAS_COUNTED_BY
+ int expected_raw_size = sizeof(struct foo);
+ #else
+ int expected_raw_size = sizeof(struct foo) + 2 * sizeof(s16);
--- /dev/null
+From 3b2f2d22fb424e9bebda4dbf6676cbfc7f9f62cd Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 16 Oct 2024 17:00:42 -0700
+Subject: crypto: x86/aegis128 - access 32-bit arguments as 32-bit
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 3b2f2d22fb424e9bebda4dbf6676cbfc7f9f62cd upstream.
+
+Fix the AEGIS assembly code to access 'unsigned int' arguments as 32-bit
+values instead of 64-bit, since the upper bits of the corresponding
+64-bit registers are not guaranteed to be zero.
+
+Note: there haven't been any reports of this bug actually causing
+incorrect behavior. Neither gcc nor clang guarantee zero-extension to
+64 bits, but zero-extension is likely to happen in practice because most
+instructions that operate on 32-bit registers zero-extend to 64 bits.
+
+Fixes: 1d373d4e8e15 ("crypto: x86 - Add optimized AEGIS implementations")
+Cc: stable@vger.kernel.org
+Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/crypto/aegis128-aesni-asm.S | 29 +++++++++++++++--------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+--- a/arch/x86/crypto/aegis128-aesni-asm.S
++++ b/arch/x86/crypto/aegis128-aesni-asm.S
+@@ -21,7 +21,7 @@
+ #define T1 %xmm7
+
+ #define STATEP %rdi
+-#define LEN %rsi
++#define LEN %esi
+ #define SRC %rdx
+ #define DST %rcx
+
+@@ -76,32 +76,32 @@ SYM_FUNC_START_LOCAL(__load_partial)
+ xor %r9d, %r9d
+ pxor MSG, MSG
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x1, %r8
+ jz .Lld_partial_1
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x1E, %r8
+ add SRC, %r8
+ mov (%r8), %r9b
+
+ .Lld_partial_1:
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x2, %r8
+ jz .Lld_partial_2
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x1C, %r8
+ add SRC, %r8
+ shl $0x10, %r9
+ mov (%r8), %r9w
+
+ .Lld_partial_2:
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x4, %r8
+ jz .Lld_partial_4
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x18, %r8
+ add SRC, %r8
+ shl $32, %r9
+@@ -111,11 +111,11 @@ SYM_FUNC_START_LOCAL(__load_partial)
+ .Lld_partial_4:
+ movq %r9, MSG
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x8, %r8
+ jz .Lld_partial_8
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x10, %r8
+ add SRC, %r8
+ pslldq $8, MSG
+@@ -139,7 +139,7 @@ SYM_FUNC_END(__load_partial)
+ * %r10
+ */
+ SYM_FUNC_START_LOCAL(__store_partial)
+- mov LEN, %r8
++ mov LEN, %r8d
+ mov DST, %r9
+
+ movq T0, %r10
+@@ -677,7 +677,7 @@ SYM_TYPED_FUNC_START(crypto_aegis128_aes
+ call __store_partial
+
+ /* mask with byte count: */
+- movq LEN, T0
++ movd LEN, T0
+ punpcklbw T0, T0
+ punpcklbw T0, T0
+ punpcklbw T0, T0
+@@ -702,7 +702,8 @@ SYM_FUNC_END(crypto_aegis128_aesni_dec_t
+
+ /*
+ * void crypto_aegis128_aesni_final(void *state, void *tag_xor,
+- * u64 assoclen, u64 cryptlen);
++ * unsigned int assoclen,
++ * unsigned int cryptlen);
+ */
+ SYM_FUNC_START(crypto_aegis128_aesni_final)
+ FRAME_BEGIN
+@@ -715,8 +716,8 @@ SYM_FUNC_START(crypto_aegis128_aesni_fin
+ movdqu 0x40(STATEP), STATE4
+
+ /* prepare length block: */
+- movq %rdx, MSG
+- movq %rcx, T0
++ movd %edx, MSG
++ movd %ecx, T0
+ pslldq $8, T0
+ pxor T0, MSG
+ psllq $3, MSG /* multiply by 8 (to get bit count) */
--- /dev/null
+From d1d1c117f39b2057d1e978f26a8bd9631ddb193b Mon Sep 17 00:00:00 2001
+From: Angelo Dureghello <adureghello@baylibre.com>
+Date: Thu, 3 Oct 2024 19:29:01 +0200
+Subject: dt-bindings: iio: dac: ad3552r: fix maximum spi speed
+
+From: Angelo Dureghello <adureghello@baylibre.com>
+
+commit d1d1c117f39b2057d1e978f26a8bd9631ddb193b upstream.
+
+Fix maximum SPI clock speed, as per datasheet (Rev. B, page 6).
+
+Fixes: b0a96c5f599e ("dt-bindings: iio: dac: Add adi,ad3552r.yaml")
+Cc: stable@vger.kernel.org
+Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://patch.msgid.link/20241003-wip-bl-ad3552r-axi-v0-iio-testing-v4-4-ceb157487329@baylibre.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
++++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
+@@ -30,7 +30,7 @@ properties:
+ maxItems: 1
+
+ spi-max-frequency:
+- maximum: 30000000
++ maximum: 66000000
+
+ reset-gpios:
+ maxItems: 1
--- /dev/null
+From ffb30875172eabff727e2896f097ccd4bb68723f Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 15 Oct 2024 08:58:47 +0200
+Subject: dt-bindings: pinctrl: samsung: Fix interrupt constraint for variants with fallbacks
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+commit ffb30875172eabff727e2896f097ccd4bb68723f upstream.
+
+Commit 904140fa4553 ("dt-bindings: pinctrl: samsung: use Exynos7
+fallbacks for newer wake-up controllers") added
+samsung,exynos7-wakeup-eint fallback to some compatibles, so the
+intention in the if:then: conditions was to handle the cases:
+
+1. Single Exynos7 compatible or Exynos5433+Exynos7 or
+ Exynos7885+Exynos7: only one interrupt
+
+2. Exynos850+Exynos7: no interrupts
+
+This was not implemented properly however and if:then: block matches
+only single Exynos5433 or Exynos7885 compatibles, which do not exist in
+DTS anymore, so basically is a no-op and no enforcement on number of
+interrupts is made by the binding.
+
+Fix the if:then: condition so interrupts in the Exynos5433 and
+Exynos7885 wake-up pin controller will be properly constrained.
+
+Fixes: 904140fa4553 ("dt-bindings: pinctrl: samsung: use Exynos7 fallbacks for newer wake-up controllers")
+Cc: stable@vger.kernel.org
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20241015065848.29429-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml | 19 +++++-----
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
+@@ -91,14 +91,17 @@ allOf:
+ - if:
+ properties:
+ compatible:
+- # Match without "contains", to skip newer variants which are still
+- # compatible with samsung,exynos7-wakeup-eint
+- enum:
+- - samsung,s5pv210-wakeup-eint
+- - samsung,exynos4210-wakeup-eint
+- - samsung,exynos5433-wakeup-eint
+- - samsung,exynos7-wakeup-eint
+- - samsung,exynos7885-wakeup-eint
++ oneOf:
++ # Match without "contains", to skip newer variants which are still
++ # compatible with samsung,exynos7-wakeup-eint
++ - enum:
++ - samsung,exynos4210-wakeup-eint
++ - samsung,exynos7-wakeup-eint
++ - samsung,s5pv210-wakeup-eint
++ - contains:
++ enum:
++ - samsung,exynos5433-wakeup-eint
++ - samsung,exynos7885-wakeup-eint
+ then:
+ properties:
+ interrupts:
--- /dev/null
+From 184fa506e392eb78364d9283c961217ff2c0617b Mon Sep 17 00:00:00 2001
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Date: Mon, 28 Oct 2024 11:23:36 +0800
+Subject: exfat: fix out-of-bounds access of directory entries
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+commit 184fa506e392eb78364d9283c961217ff2c0617b upstream.
+
+In the case of the directory size is greater than or equal to
+the cluster size, if start_clu becomes an EOF cluster(an invalid
+cluster) due to file system corruption, then the directory entry
+where ei->hint_femp.eidx hint is outside the directory, resulting
+in an out-of-bounds access, which may cause further file system
+corruption.
+
+This commit adds a check for start_clu, if it is an invalid cluster,
+the file or directory will be treated as empty.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Co-developed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/namei.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -637,14 +637,26 @@ static int exfat_find(struct inode *dir,
+ info->size = le64_to_cpu(ep2->dentry.stream.valid_size);
+ info->valid_size = le64_to_cpu(ep2->dentry.stream.valid_size);
+ info->size = le64_to_cpu(ep2->dentry.stream.size);
++
++ info->start_clu = le32_to_cpu(ep2->dentry.stream.start_clu);
++ if (!is_valid_cluster(sbi, info->start_clu) && info->size) {
++ exfat_warn(sb, "start_clu is invalid cluster(0x%x)",
++ info->start_clu);
++ info->size = 0;
++ info->valid_size = 0;
++ }
++
++ if (info->valid_size > info->size) {
++ exfat_warn(sb, "valid_size(%lld) is greater than size(%lld)",
++ info->valid_size, info->size);
++ info->valid_size = info->size;
++ }
++
+ if (info->size == 0) {
+ info->flags = ALLOC_NO_FAT_CHAIN;
+ info->start_clu = EXFAT_EOF_CLUSTER;
+- } else {
++ } else
+ info->flags = ep2->dentry.stream.flags;
+- info->start_clu =
+- le32_to_cpu(ep2->dentry.stream.start_clu);
+- }
+
+ exfat_get_entry_time(sbi, &info->crtime,
+ ep->dentry.file.create_tz,
--- /dev/null
+From 02dffe9ab092fc4c8800aee68cb7eafd37a980c4 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Sat, 26 Oct 2024 13:06:15 +0900
+Subject: exfat: fix uninit-value in __exfat_get_dentry_set
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit 02dffe9ab092fc4c8800aee68cb7eafd37a980c4 upstream.
+
+There is no check if stream size and start_clu are invalid.
+If start_clu is EOF cluster and stream size is 4096, It will
+cause uninit value access. because ei->hint_femp.eidx could
+be 128(if cluster size is 4K) and wrong hint will allocate
+next cluster. and this cluster will be same with the cluster
+that is allocated by exfat_extend_valid_size(). The previous
+patch will check invalid start_clu, but for clarity, initialize
+hint_femp.eidx to zero.
+
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+01218003be74b5e1213a@syzkaller.appspotmail.com
+Tested-by: syzbot+01218003be74b5e1213a@syzkaller.appspotmail.com
+Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/namei.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -345,6 +345,7 @@ static int exfat_find_empty_entry(struct
+ if (ei->start_clu == EXFAT_EOF_CLUSTER) {
+ ei->start_clu = clu.dir;
+ p_dir->dir = clu.dir;
++ hint_femp.eidx = 0;
+ }
+
+ /* append to the FAT chain */
--- /dev/null
+From 4a622e4d477bb12ad5ed4abbc7ad1365de1fa347 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 23 Oct 2024 00:25:37 -0400
+Subject: ext4: fix FS_IOC_GETFSMAP handling
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 4a622e4d477bb12ad5ed4abbc7ad1365de1fa347 upstream.
+
+The original implementation ext4's FS_IOC_GETFSMAP handling only
+worked when the range of queried blocks included at least one free
+(unallocated) block range. This is because how the metadata blocks
+were emitted was as a side effect of ext4_mballoc_query_range()
+calling ext4_getfsmap_datadev_helper(), and that function was only
+called when a free block range was identified. As a result, this
+caused generic/365 to fail.
+
+Fix this by creating a new function ext4_getfsmap_meta_helper() which
+gets called so that blocks before the first free block range in a
+block group can get properly reported.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/fsmap.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ fs/ext4/mballoc.c | 18 ++++++++++++++----
+ fs/ext4/mballoc.h | 1 +
+ 3 files changed, 68 insertions(+), 5 deletions(-)
+
+--- a/fs/ext4/fsmap.c
++++ b/fs/ext4/fsmap.c
+@@ -185,6 +185,56 @@ static inline ext4_fsblk_t ext4_fsmap_ne
+ return fmr->fmr_physical + fmr->fmr_length;
+ }
+
++static int ext4_getfsmap_meta_helper(struct super_block *sb,
++ ext4_group_t agno, ext4_grpblk_t start,
++ ext4_grpblk_t len, void *priv)
++{
++ struct ext4_getfsmap_info *info = priv;
++ struct ext4_fsmap *p;
++ struct ext4_fsmap *tmp;
++ struct ext4_sb_info *sbi = EXT4_SB(sb);
++ ext4_fsblk_t fsb, fs_start, fs_end;
++ int error;
++
++ fs_start = fsb = (EXT4_C2B(sbi, start) +
++ ext4_group_first_block_no(sb, agno));
++ fs_end = fs_start + EXT4_C2B(sbi, len);
++
++ /* Return relevant extents from the meta_list */
++ list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
++ if (p->fmr_physical < info->gfi_next_fsblk) {
++ list_del(&p->fmr_list);
++ kfree(p);
++ continue;
++ }
++ if (p->fmr_physical <= fs_start ||
++ p->fmr_physical + p->fmr_length <= fs_end) {
++ /* Emit the retained free extent record if present */
++ if (info->gfi_lastfree.fmr_owner) {
++ error = ext4_getfsmap_helper(sb, info,
++ &info->gfi_lastfree);
++ if (error)
++ return error;
++ info->gfi_lastfree.fmr_owner = 0;
++ }
++ error = ext4_getfsmap_helper(sb, info, p);
++ if (error)
++ return error;
++ fsb = p->fmr_physical + p->fmr_length;
++ if (info->gfi_next_fsblk < fsb)
++ info->gfi_next_fsblk = fsb;
++ list_del(&p->fmr_list);
++ kfree(p);
++ continue;
++ }
++ }
++ if (info->gfi_next_fsblk < fsb)
++ info->gfi_next_fsblk = fsb;
++
++ return 0;
++}
++
++
+ /* Transform a blockgroup's free record into a fsmap */
+ static int ext4_getfsmap_datadev_helper(struct super_block *sb,
+ ext4_group_t agno, ext4_grpblk_t start,
+@@ -539,6 +589,7 @@ static int ext4_getfsmap_datadev(struct
+ error = ext4_mballoc_query_range(sb, info->gfi_agno,
+ EXT4_B2C(sbi, info->gfi_low.fmr_physical),
+ EXT4_B2C(sbi, info->gfi_high.fmr_physical),
++ ext4_getfsmap_meta_helper,
+ ext4_getfsmap_datadev_helper, info);
+ if (error)
+ goto err;
+@@ -560,7 +611,8 @@ static int ext4_getfsmap_datadev(struct
+
+ /* Report any gaps at the end of the bg */
+ info->gfi_last = true;
+- error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster, 0, info);
++ error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1,
++ 0, info);
+ if (error)
+ goto err;
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -6998,13 +6998,14 @@ int
+ ext4_mballoc_query_range(
+ struct super_block *sb,
+ ext4_group_t group,
+- ext4_grpblk_t start,
++ ext4_grpblk_t first,
+ ext4_grpblk_t end,
++ ext4_mballoc_query_range_fn meta_formatter,
+ ext4_mballoc_query_range_fn formatter,
+ void *priv)
+ {
+ void *bitmap;
+- ext4_grpblk_t next;
++ ext4_grpblk_t start, next;
+ struct ext4_buddy e4b;
+ int error;
+
+@@ -7015,10 +7016,19 @@ ext4_mballoc_query_range(
+
+ ext4_lock_group(sb, group);
+
+- start = max(e4b.bd_info->bb_first_free, start);
++ start = max(e4b.bd_info->bb_first_free, first);
+ if (end >= EXT4_CLUSTERS_PER_GROUP(sb))
+ end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+-
++ if (meta_formatter && start != first) {
++ if (start > end)
++ start = end;
++ ext4_unlock_group(sb, group);
++ error = meta_formatter(sb, group, first, start - first,
++ priv);
++ if (error)
++ goto out_unload;
++ ext4_lock_group(sb, group);
++ }
+ while (start <= end) {
+ start = mb_find_next_zero_bit(bitmap, end + 1, start);
+ if (start > end)
+--- a/fs/ext4/mballoc.h
++++ b/fs/ext4/mballoc.h
+@@ -259,6 +259,7 @@ ext4_mballoc_query_range(
+ ext4_group_t agno,
+ ext4_grpblk_t start,
+ ext4_grpblk_t end,
++ ext4_mballoc_query_range_fn meta_formatter,
+ ext4_mballoc_query_range_fn formatter,
+ void *priv);
+
--- /dev/null
+From 902cc179c931a033cd7f4242353aa2733bf8524c Mon Sep 17 00:00:00 2001
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Thu, 3 Oct 2024 21:53:37 +0900
+Subject: ext4: supress data-race warnings in ext4_free_inodes_{count,set}()
+
+From: Jeongjun Park <aha310510@gmail.com>
+
+commit 902cc179c931a033cd7f4242353aa2733bf8524c upstream.
+
+find_group_other() and find_group_orlov() read *_lo, *_hi with
+ext4_free_inodes_count without additional locking. This can cause
+data-race warning, but since the lock is held for most writes and free
+inodes value is generally not a problem even if it is incorrect, it is
+more appropriate to use READ_ONCE()/WRITE_ONCE() than to add locking.
+
+==================================================================
+BUG: KCSAN: data-race in ext4_free_inodes_count / ext4_free_inodes_set
+
+write to 0xffff88810404300e of 2 bytes by task 6254 on cpu 1:
+ ext4_free_inodes_set+0x1f/0x80 fs/ext4/super.c:405
+ __ext4_new_inode+0x15ca/0x2200 fs/ext4/ialloc.c:1216
+ ext4_symlink+0x242/0x5a0 fs/ext4/namei.c:3391
+ vfs_symlink+0xca/0x1d0 fs/namei.c:4615
+ do_symlinkat+0xe3/0x340 fs/namei.c:4641
+ __do_sys_symlinkat fs/namei.c:4657 [inline]
+ __se_sys_symlinkat fs/namei.c:4654 [inline]
+ __x64_sys_symlinkat+0x5e/0x70 fs/namei.c:4654
+ x64_sys_call+0x1dda/0x2d60 arch/x86/include/generated/asm/syscalls_64.h:267
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x54/0x120 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+read to 0xffff88810404300e of 2 bytes by task 6257 on cpu 0:
+ ext4_free_inodes_count+0x1c/0x80 fs/ext4/super.c:349
+ find_group_other fs/ext4/ialloc.c:594 [inline]
+ __ext4_new_inode+0x6ec/0x2200 fs/ext4/ialloc.c:1017
+ ext4_symlink+0x242/0x5a0 fs/ext4/namei.c:3391
+ vfs_symlink+0xca/0x1d0 fs/namei.c:4615
+ do_symlinkat+0xe3/0x340 fs/namei.c:4641
+ __do_sys_symlinkat fs/namei.c:4657 [inline]
+ __se_sys_symlinkat fs/namei.c:4654 [inline]
+ __x64_sys_symlinkat+0x5e/0x70 fs/namei.c:4654
+ x64_sys_call+0x1dda/0x2d60 arch/x86/include/generated/asm/syscalls_64.h:267
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x54/0x120 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Link: https://patch.msgid.link/20241003125337.47283-1-aha310510@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -353,9 +353,9 @@ __u32 ext4_free_group_clusters(struct su
+ __u32 ext4_free_inodes_count(struct super_block *sb,
+ struct ext4_group_desc *bg)
+ {
+- return le16_to_cpu(bg->bg_free_inodes_count_lo) |
++ return le16_to_cpu(READ_ONCE(bg->bg_free_inodes_count_lo)) |
+ (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+- (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
++ (__u32)le16_to_cpu(READ_ONCE(bg->bg_free_inodes_count_hi)) << 16 : 0);
+ }
+
+ __u32 ext4_used_dirs_count(struct super_block *sb,
+@@ -409,9 +409,9 @@ void ext4_free_group_clusters_set(struct
+ void ext4_free_inodes_set(struct super_block *sb,
+ struct ext4_group_desc *bg, __u32 count)
+ {
+- bg->bg_free_inodes_count_lo = cpu_to_le16((__u16)count);
++ WRITE_ONCE(bg->bg_free_inodes_count_lo, cpu_to_le16((__u16)count));
+ if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+- bg->bg_free_inodes_count_hi = cpu_to_le16(count >> 16);
++ WRITE_ONCE(bg->bg_free_inodes_count_hi, cpu_to_le16(count >> 16));
+ }
+
+ void ext4_used_dirs_set(struct super_block *sb,
--- /dev/null
+From 21d1b618b6b9da46c5116c640ac4b1cc8d40d63a Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Mon, 18 Nov 2024 17:33:13 +0100
+Subject: fsnotify: Fix ordering of iput() and watched_objects decrement
+
+From: Jann Horn <jannh@google.com>
+
+commit 21d1b618b6b9da46c5116c640ac4b1cc8d40d63a upstream.
+
+Ensure the superblock is kept alive until we're done with iput().
+Holding a reference to an inode is not allowed unless we ensure the
+superblock stays alive, which fsnotify does by keeping the
+watched_objects count elevated, so iput() must happen before the
+watched_objects decrement.
+This can lead to a UAF of something like sb->s_fs_info in tmpfs, but the
+UAF is hard to hit because race orderings that oops are more likely, thanks
+to the CHECK_DATA_CORRUPTION() block in generic_shutdown_super().
+
+Also, ensure that fsnotify_put_sb_watched_objects() doesn't call
+fsnotify_sb_watched_objects() on a superblock that may have already been
+freed, which would cause a UAF read of sb->s_fsnotify_info.
+
+Cc: stable@kernel.org
+Fixes: d2f277e26f52 ("fsnotify: rename fsnotify_{get,put}_sb_connectors()")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/notify/mark.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/fs/notify/mark.c b/fs/notify/mark.c
+index c45b222cf9c1..4981439e6209 100644
+--- a/fs/notify/mark.c
++++ b/fs/notify/mark.c
+@@ -138,8 +138,11 @@ static void fsnotify_get_sb_watched_objects(struct super_block *sb)
+
+ static void fsnotify_put_sb_watched_objects(struct super_block *sb)
+ {
+- if (atomic_long_dec_and_test(fsnotify_sb_watched_objects(sb)))
+- wake_up_var(fsnotify_sb_watched_objects(sb));
++ atomic_long_t *watched_objects = fsnotify_sb_watched_objects(sb);
++
++ /* the superblock can go away after this decrement */
++ if (atomic_long_dec_and_test(watched_objects))
++ wake_up_var(watched_objects);
+ }
+
+ static void fsnotify_get_inode_ref(struct inode *inode)
+@@ -150,8 +153,11 @@ static void fsnotify_get_inode_ref(struct inode *inode)
+
+ static void fsnotify_put_inode_ref(struct inode *inode)
+ {
+- fsnotify_put_sb_watched_objects(inode->i_sb);
++ /* read ->i_sb before the inode can go away */
++ struct super_block *sb = inode->i_sb;
++
+ iput(inode);
++ fsnotify_put_sb_watched_objects(sb);
+ }
+
+ /*
+--
+2.47.1
+
--- /dev/null
+From aa52c54da40d9eee3ba87c05cdcb0cd07c04fa13 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Wed, 13 Nov 2024 16:40:34 +0100
+Subject: fsnotify: fix sending inotify event with unexpected filename
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit aa52c54da40d9eee3ba87c05cdcb0cd07c04fa13 upstream.
+
+We got a report that adding a fanotify filsystem watch prevents tail -f
+from receiving events.
+
+Reproducer:
+
+1. Create 3 windows / login sessions. Become root in each session.
+2. Choose a mounted filesystem that is pretty quiet; I picked /boot.
+3. In the first window, run: fsnotifywait -S -m /boot
+4. In the second window, run: echo data >> /boot/foo
+5. In the third window, run: tail -f /boot/foo
+6. Go back to the second window and run: echo more data >> /boot/foo
+7. Observe that the tail command doesn't show the new data.
+8. In the first window, hit control-C to interrupt fsnotifywait.
+9. In the second window, run: echo still more data >> /boot/foo
+10. Observe that the tail command in the third window has now printed
+the missing data.
+
+When stracing tail, we observed that when fanotify filesystem mark is
+set, tail does get the inotify event, but the event is receieved with
+the filename:
+
+read(4, "\1\0\0\0\2\0\0\0\0\0\0\0\20\0\0\0foo\0\0\0\0\0\0\0\0\0\0\0\0\0",
+50) = 32
+
+This is unexpected, because tail is watching the file itself and not its
+parent and is inconsistent with the inotify event received by tail when
+fanotify filesystem mark is not set:
+
+read(4, "\1\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0", 50) = 16
+
+The inteference between different fsnotify groups was caused by the fact
+that the mark on the sb requires the filename, so the filename is passed
+to fsnotify(). Later on, fsnotify_handle_event() tries to take care of
+not passing the filename to groups (such as inotify) that are interested
+in the filename only when the parent is watching.
+
+But the logic was incorrect for the case that no group is watching the
+parent, some groups are watching the sb and some watching the inode.
+
+Reported-by: Miklos Szeredi <miklos@szeredi.hu>
+Fixes: 7372e79c9eb9 ("fanotify: fix logic of reporting name info with watched parent")
+Cc: stable@vger.kernel.org # 5.10+
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/notify/fsnotify.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+--- a/fs/notify/fsnotify.c
++++ b/fs/notify/fsnotify.c
+@@ -333,16 +333,19 @@ static int fsnotify_handle_event(struct
+ if (!inode_mark)
+ return 0;
+
+- if (mask & FS_EVENT_ON_CHILD) {
+- /*
+- * Some events can be sent on both parent dir and child marks
+- * (e.g. FS_ATTRIB). If both parent dir and child are
+- * watching, report the event once to parent dir with name (if
+- * interested) and once to child without name (if interested).
+- * The child watcher is expecting an event without a file name
+- * and without the FS_EVENT_ON_CHILD flag.
+- */
+- mask &= ~FS_EVENT_ON_CHILD;
++ /*
++ * Some events can be sent on both parent dir and child marks (e.g.
++ * FS_ATTRIB). If both parent dir and child are watching, report the
++ * event once to parent dir with name (if interested) and once to child
++ * without name (if interested).
++ *
++ * In any case regardless whether the parent is watching or not, the
++ * child watcher is expecting an event without the FS_EVENT_ON_CHILD
++ * flag. The file name is expected if and only if this is a directory
++ * event.
++ */
++ mask &= ~FS_EVENT_ON_CHILD;
++ if (!(mask & ALL_FSNOTIFY_DIRENT_EVENTS)) {
+ dir = NULL;
+ name = NULL;
+ }
--- /dev/null
+From 70602f529e4d76798c95aeed5ce2a8d36263abe5 Mon Sep 17 00:00:00 2001
+From: Angelo Dureghello <adureghello@baylibre.com>
+Date: Tue, 8 Oct 2024 17:43:33 +0200
+Subject: iio: dac: adi-axi-dac: fix wrong register bitfield
+
+From: Angelo Dureghello <adureghello@baylibre.com>
+
+commit 70602f529e4d76798c95aeed5ce2a8d36263abe5 upstream.
+
+Fix ADI_DAC_R1_MODE of AXI_DAC_REG_CNTRL_2.
+
+Both generic DAC and ad3552r DAC IPs docs are reporting
+bit 5 for it.
+
+Link: https://wiki.analog.com/resources/fpga/docs/axi_dac_ip
+Fixes: 4e3949a192e4 ("iio: dac: add support for AXI DAC IP core")
+Cc: stable@vger.kernel.org
+Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20241008-wip-bl-ad3552r-axi-v0-iio-testing-v5-1-3d410944a63d@baylibre.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/adi-axi-dac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c
+index 0cb00f3bec04..b8b4171b8043 100644
+--- a/drivers/iio/dac/adi-axi-dac.c
++++ b/drivers/iio/dac/adi-axi-dac.c
+@@ -46,7 +46,7 @@
+ #define AXI_DAC_REG_CNTRL_1 0x0044
+ #define AXI_DAC_SYNC BIT(0)
+ #define AXI_DAC_REG_CNTRL_2 0x0048
+-#define ADI_DAC_R1_MODE BIT(4)
++#define ADI_DAC_R1_MODE BIT(5)
+ #define AXI_DAC_DRP_STATUS 0x0074
+ #define AXI_DAC_DRP_LOCKED BIT(17)
+ /* DAC Channel controls */
+--
+2.47.1
+
--- /dev/null
+From d9f9d96136cba8fedd647d2c024342ce090133c2 Mon Sep 17 00:00:00 2001
+From: Artem Sadovnikov <ancowi69@gmail.com>
+Date: Sat, 5 Oct 2024 10:06:57 +0000
+Subject: jfs: xattr: check invalid xattr size more strictly
+
+From: Artem Sadovnikov <ancowi69@gmail.com>
+
+commit d9f9d96136cba8fedd647d2c024342ce090133c2 upstream.
+
+Commit 7c55b78818cf ("jfs: xattr: fix buffer overflow for invalid xattr")
+also addresses this issue but it only fixes it for positive values, while
+ea_size is an integer type and can take negative values, e.g. in case of
+a corrupted filesystem. This still breaks validation and would overflow
+because of implicit conversion from int to size_t in print_hex_dump().
+
+Fix this issue by clamping the ea_size value instead.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Artem Sadovnikov <ancowi69@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/jfs/xattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/jfs/xattr.c
++++ b/fs/jfs/xattr.c
+@@ -559,7 +559,7 @@ static int ea_get(struct inode *inode, s
+
+ size_check:
+ if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
+- int size = min_t(int, EALIST_SIZE(ea_buf->xattr), ea_size);
++ int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
+
+ printk(KERN_ERR "ea_get: invalid extended attribute\n");
+ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
--- /dev/null
+From e735a5da64420a86be370b216c269b5dd8e830e2 Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oliver.upton@linux.dev>
+Date: Fri, 25 Oct 2024 20:31:03 +0000
+Subject: KVM: arm64: Don't retire aborted MMIO instruction
+
+From: Oliver Upton <oliver.upton@linux.dev>
+
+commit e735a5da64420a86be370b216c269b5dd8e830e2 upstream.
+
+Returning an abort to the guest for an unsupported MMIO access is a
+documented feature of the KVM UAPI. Nevertheless, it's clear that this
+plumbing has seen limited testing, since userspace can trivially cause a
+WARN in the MMIO return:
+
+ WARNING: CPU: 0 PID: 30558 at arch/arm64/include/asm/kvm_emulate.h:536 kvm_handle_mmio_return+0x46c/0x5c4 arch/arm64/include/asm/kvm_emulate.h:536
+ Call trace:
+ kvm_handle_mmio_return+0x46c/0x5c4 arch/arm64/include/asm/kvm_emulate.h:536
+ kvm_arch_vcpu_ioctl_run+0x98/0x15b4 arch/arm64/kvm/arm.c:1133
+ kvm_vcpu_ioctl+0x75c/0xa78 virt/kvm/kvm_main.c:4487
+ __do_sys_ioctl fs/ioctl.c:51 [inline]
+ __se_sys_ioctl fs/ioctl.c:893 [inline]
+ __arm64_sys_ioctl+0x14c/0x1c8 fs/ioctl.c:893
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49
+ el0_svc_common+0x1e0/0x23c arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
+ el0_svc+0x38/0x68 arch/arm64/kernel/entry-common.c:712
+ el0t_64_sync_handler+0x90/0xfc arch/arm64/kernel/entry-common.c:730
+ el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
+
+The splat is complaining that KVM is advancing PC while an exception is
+pending, i.e. that KVM is retiring the MMIO instruction despite a
+pending synchronous external abort. Womp womp.
+
+Fix the glaring UAPI bug by skipping over all the MMIO emulation in
+case there is a pending synchronous exception. Note that while userspace
+is capable of pending an asynchronous exception (SError, IRQ, or FIQ),
+it is still safe to retire the MMIO instruction in this case as (1) they
+are by definition asynchronous, and (2) KVM relies on hardware support
+for pending/delivering these exceptions instead of the software state
+machine for advancing PC.
+
+Cc: stable@vger.kernel.org
+Fixes: da345174ceca ("KVM: arm/arm64: Allow user injection of external data aborts")
+Reported-by: Alexander Potapenko <glider@google.com>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20241025203106.3529261-2-oliver.upton@linux.dev
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/mmio.c | 32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kvm/mmio.c
++++ b/arch/arm64/kvm/mmio.c
+@@ -72,6 +72,31 @@ unsigned long kvm_mmio_read_buf(const vo
+ return data;
+ }
+
++static bool kvm_pending_sync_exception(struct kvm_vcpu *vcpu)
++{
++ if (!vcpu_get_flag(vcpu, PENDING_EXCEPTION))
++ return false;
++
++ if (vcpu_el1_is_32bit(vcpu)) {
++ switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
++ case unpack_vcpu_flag(EXCEPT_AA32_UND):
++ case unpack_vcpu_flag(EXCEPT_AA32_IABT):
++ case unpack_vcpu_flag(EXCEPT_AA32_DABT):
++ return true;
++ default:
++ return false;
++ }
++ } else {
++ switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
++ case unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC):
++ case unpack_vcpu_flag(EXCEPT_AA64_EL2_SYNC):
++ return true;
++ default:
++ return false;
++ }
++ }
++}
++
+ /**
+ * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
+ * or in-kernel IO emulation
+@@ -84,8 +109,11 @@ int kvm_handle_mmio_return(struct kvm_vc
+ unsigned int len;
+ int mask;
+
+- /* Detect an already handled MMIO return */
+- if (unlikely(!vcpu->mmio_needed))
++ /*
++ * Detect if the MMIO return was already handled or if userspace aborted
++ * the MMIO access.
++ */
++ if (unlikely(!vcpu->mmio_needed || kvm_pending_sync_exception(vcpu)))
+ return 1;
+
+ vcpu->mmio_needed = 0;
--- /dev/null
+From 38d7aacca09230fdb98a34194fec2af597e8e20d Mon Sep 17 00:00:00 2001
+From: Raghavendra Rao Ananta <rananta@google.com>
+Date: Mon, 28 Oct 2024 23:45:33 +0000
+Subject: KVM: arm64: Get rid of userspace_irqchip_in_use
+
+From: Raghavendra Rao Ananta <rananta@google.com>
+
+commit 38d7aacca09230fdb98a34194fec2af597e8e20d upstream.
+
+Improper use of userspace_irqchip_in_use led to syzbot hitting the
+following WARN_ON() in kvm_timer_update_irq():
+
+WARNING: CPU: 0 PID: 3281 at arch/arm64/kvm/arch_timer.c:459
+kvm_timer_update_irq+0x21c/0x394
+Call trace:
+ kvm_timer_update_irq+0x21c/0x394 arch/arm64/kvm/arch_timer.c:459
+ kvm_timer_vcpu_reset+0x158/0x684 arch/arm64/kvm/arch_timer.c:968
+ kvm_reset_vcpu+0x3b4/0x560 arch/arm64/kvm/reset.c:264
+ kvm_vcpu_set_target arch/arm64/kvm/arm.c:1553 [inline]
+ kvm_arch_vcpu_ioctl_vcpu_init arch/arm64/kvm/arm.c:1573 [inline]
+ kvm_arch_vcpu_ioctl+0x112c/0x1b3c arch/arm64/kvm/arm.c:1695
+ kvm_vcpu_ioctl+0x4ec/0xf74 virt/kvm/kvm_main.c:4658
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:907 [inline]
+ __se_sys_ioctl fs/ioctl.c:893 [inline]
+ __arm64_sys_ioctl+0x108/0x184 fs/ioctl.c:893
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x78/0x1b8 arch/arm64/kernel/syscall.c:49
+ el0_svc_common+0xe8/0x1b0 arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x40/0x50 arch/arm64/kernel/syscall.c:151
+ el0_svc+0x54/0x14c arch/arm64/kernel/entry-common.c:712
+ el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
+ el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
+
+The following sequence led to the scenario:
+ - Userspace creates a VM and a vCPU.
+ - The vCPU is initialized with KVM_ARM_VCPU_PMU_V3 during
+ KVM_ARM_VCPU_INIT.
+ - Without any other setup, such as vGIC or vPMU, userspace issues
+ KVM_RUN on the vCPU. Since the vPMU is requested, but not setup,
+ kvm_arm_pmu_v3_enable() fails in kvm_arch_vcpu_run_pid_change().
+ As a result, KVM_RUN returns after enabling the timer, but before
+ incrementing 'userspace_irqchip_in_use':
+ kvm_arch_vcpu_run_pid_change()
+ ret = kvm_arm_pmu_v3_enable()
+ if (!vcpu->arch.pmu.created)
+ return -EINVAL;
+ if (ret)
+ return ret;
+ [...]
+ if (!irqchip_in_kernel(kvm))
+ static_branch_inc(&userspace_irqchip_in_use);
+ - Userspace ignores the error and issues KVM_ARM_VCPU_INIT again.
+ Since the timer is already enabled, control moves through the
+ following flow, ultimately hitting the WARN_ON():
+ kvm_timer_vcpu_reset()
+ if (timer->enabled)
+ kvm_timer_update_irq()
+ if (!userspace_irqchip())
+ ret = kvm_vgic_inject_irq()
+ ret = vgic_lazy_init()
+ if (unlikely(!vgic_initialized(kvm)))
+ if (kvm->arch.vgic.vgic_model !=
+ KVM_DEV_TYPE_ARM_VGIC_V2)
+ return -EBUSY;
+ WARN_ON(ret);
+
+Theoretically, since userspace_irqchip_in_use's functionality can be
+simply replaced by '!irqchip_in_kernel()', get rid of the static key
+to avoid the mismanagement, which also helps with the syzbot issue.
+
+Cc: <stable@vger.kernel.org>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Suggested-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/kvm_host.h | 2 --
+ arch/arm64/kvm/arch_timer.c | 3 +--
+ arch/arm64/kvm/arm.c | 18 +++---------------
+ 3 files changed, 4 insertions(+), 19 deletions(-)
+
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -73,8 +73,6 @@ enum kvm_mode kvm_get_mode(void);
+ static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
+ #endif
+
+-DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
+-
+ extern unsigned int __ro_after_init kvm_sve_max_vl;
+ extern unsigned int __ro_after_init kvm_host_sve_max_vl;
+ int __init kvm_arm_init_sve(void);
+--- a/arch/arm64/kvm/arch_timer.c
++++ b/arch/arm64/kvm/arch_timer.c
+@@ -206,8 +206,7 @@ void get_timer_map(struct kvm_vcpu *vcpu
+
+ static inline bool userspace_irqchip(struct kvm *kvm)
+ {
+- return static_branch_unlikely(&userspace_irqchip_in_use) &&
+- unlikely(!irqchip_in_kernel(kvm));
++ return unlikely(!irqchip_in_kernel(kvm));
+ }
+
+ static void soft_timer_start(struct hrtimer *hrt, u64 ns)
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -67,7 +67,6 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_
+ static bool vgic_present, kvm_arm_initialised;
+
+ static DEFINE_PER_CPU(unsigned char, kvm_hyp_initialized);
+-DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
+
+ bool is_kvm_arm_initialised(void)
+ {
+@@ -500,9 +499,6 @@ void kvm_arch_vcpu_postcreate(struct kvm
+
+ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
+ {
+- if (vcpu_has_run_once(vcpu) && unlikely(!irqchip_in_kernel(vcpu->kvm)))
+- static_branch_dec(&userspace_irqchip_in_use);
+-
+ kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+ kvm_timer_vcpu_terminate(vcpu);
+ kvm_pmu_vcpu_destroy(vcpu);
+@@ -847,14 +843,6 @@ int kvm_arch_vcpu_run_pid_change(struct
+ return ret;
+ }
+
+- if (!irqchip_in_kernel(kvm)) {
+- /*
+- * Tell the rest of the code that there are userspace irqchip
+- * VMs in the wild.
+- */
+- static_branch_inc(&userspace_irqchip_in_use);
+- }
+-
+ /*
+ * Initialize traps for protected VMs.
+ * NOTE: Move to run in EL2 directly, rather than via a hypercall, once
+@@ -1074,7 +1062,7 @@ static bool kvm_vcpu_exit_request(struct
+ * state gets updated in kvm_timer_update_run and
+ * kvm_pmu_update_run below).
+ */
+- if (static_branch_unlikely(&userspace_irqchip_in_use)) {
++ if (unlikely(!irqchip_in_kernel(vcpu->kvm))) {
+ if (kvm_timer_should_notify_user(vcpu) ||
+ kvm_pmu_should_notify_user(vcpu)) {
+ *ret = -EINTR;
+@@ -1196,7 +1184,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
+ vcpu->mode = OUTSIDE_GUEST_MODE;
+ isb(); /* Ensure work in x_flush_hwstate is committed */
+ kvm_pmu_sync_hwstate(vcpu);
+- if (static_branch_unlikely(&userspace_irqchip_in_use))
++ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
+ kvm_timer_sync_user(vcpu);
+ kvm_vgic_sync_hwstate(vcpu);
+ local_irq_enable();
+@@ -1242,7 +1230,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
+ * we don't want vtimer interrupts to race with syncing the
+ * timer virtual interrupt state.
+ */
+- if (static_branch_unlikely(&userspace_irqchip_in_use))
++ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
+ kvm_timer_sync_user(vcpu);
+
+ kvm_arch_vcpu_ctxsync_fp(vcpu);
--- /dev/null
+From 54bbee190d42166209185d89070c58a343bf514b Mon Sep 17 00:00:00 2001
+From: Raghavendra Rao Ananta <rananta@google.com>
+Date: Tue, 19 Nov 2024 16:52:29 -0800
+Subject: KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status
+
+From: Raghavendra Rao Ananta <rananta@google.com>
+
+commit 54bbee190d42166209185d89070c58a343bf514b upstream.
+
+DDI0487K.a D13.3.1 describes the PMU overflow condition, which evaluates
+to true if any counter's global enable (PMCR_EL0.E), overflow flag
+(PMOVSSET_EL0[n]), and interrupt enable (PMINTENSET_EL1[n]) are all 1.
+Of note, this does not require a counter to be enabled
+(i.e. PMCNTENSET_EL0[n] = 1) to generate an overflow.
+
+Align kvm_pmu_overflow_status() with the reality of the architecture
+and stop using PMCNTENSET_EL0 as part of the overflow condition. The
+bug was discovered while running an SBSA PMU test [*], which only sets
+PMCR.E, PMOVSSET<0>, PMINTENSET<0>, and expects an overflow interrupt.
+
+Cc: stable@vger.kernel.org
+Fixes: 76d883c4e640 ("arm64: KVM: Add access handler for PMOVSSET and PMOVSCLR register")
+Link: https://github.com/ARM-software/sbsa-acs/blob/master/test_pool/pmu/operating_system/test_pmu001.c
+Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
+[ oliver: massaged changelog ]
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20241120005230.2335682-2-oliver.upton@linux.dev
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/pmu-emul.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -342,7 +342,6 @@ static u64 kvm_pmu_overflow_status(struc
+
+ if ((kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E)) {
+ reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
+- reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0);
+ reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
+ }
+
--- /dev/null
+From 7fe28d7e68f92cc3d0668b8f2fbdf5c303ac3022 Mon Sep 17 00:00:00 2001
+From: Jing Zhang <jingzhangos@google.com>
+Date: Thu, 7 Nov 2024 13:41:34 -0800
+Subject: KVM: arm64: vgic-its: Add a data length check in vgic_its_save_*
+
+From: Jing Zhang <jingzhangos@google.com>
+
+commit 7fe28d7e68f92cc3d0668b8f2fbdf5c303ac3022 upstream.
+
+In all the vgic_its_save_*() functinos, they do not check whether
+the data length is 8 bytes before calling vgic_write_guest_lock.
+This patch adds the check. To prevent the kernel from being blown up
+when the fault occurs, KVM_BUG_ON() is used. And the other BUG_ON()s
+are replaced together.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
+[Jing: Update with the new entry read/write helpers]
+Signed-off-by: Jing Zhang <jingzhangos@google.com>
+Link: https://lore.kernel.org/r/20241107214137.428439-4-jingzhangos@google.com
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic-its.c | 20 ++++++++------------
+ arch/arm64/kvm/vgic/vgic.h | 23 +++++++++++++++++++++++
+ 2 files changed, 31 insertions(+), 12 deletions(-)
+
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -2090,7 +2090,6 @@ static int scan_its_table(struct vgic_it
+ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
+ struct its_ite *ite, gpa_t gpa, int ite_esz)
+ {
+- struct kvm *kvm = its->dev->kvm;
+ u32 next_offset;
+ u64 val;
+
+@@ -2099,7 +2098,8 @@ static int vgic_its_save_ite(struct vgic
+ ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) |
+ ite->collection->collection_id;
+ val = cpu_to_le64(val);
+- return vgic_write_guest_lock(kvm, gpa, &val, ite_esz);
++
++ return vgic_its_write_entry_lock(its, gpa, val, ite_esz);
+ }
+
+ /**
+@@ -2243,7 +2243,6 @@ static int vgic_its_restore_itt(struct v
+ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
+ gpa_t ptr, int dte_esz)
+ {
+- struct kvm *kvm = its->dev->kvm;
+ u64 val, itt_addr_field;
+ u32 next_offset;
+
+@@ -2254,7 +2253,8 @@ static int vgic_its_save_dte(struct vgic
+ (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
+ (dev->num_eventid_bits - 1));
+ val = cpu_to_le64(val);
+- return vgic_write_guest_lock(kvm, ptr, &val, dte_esz);
++
++ return vgic_its_write_entry_lock(its, ptr, val, dte_esz);
+ }
+
+ /**
+@@ -2441,7 +2441,8 @@ static int vgic_its_save_cte(struct vgic
+ ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) |
+ collection->collection_id);
+ val = cpu_to_le64(val);
+- return vgic_write_guest_lock(its->dev->kvm, gpa, &val, esz);
++
++ return vgic_its_write_entry_lock(its, gpa, val, esz);
+ }
+
+ /*
+@@ -2457,8 +2458,7 @@ static int vgic_its_restore_cte(struct v
+ u64 val;
+ int ret;
+
+- BUG_ON(esz > sizeof(val));
+- ret = kvm_read_guest_lock(kvm, gpa, &val, esz);
++ ret = vgic_its_read_entry_lock(its, gpa, &val, esz);
+ if (ret)
+ return ret;
+ val = le64_to_cpu(val);
+@@ -2496,7 +2496,6 @@ static int vgic_its_save_collection_tabl
+ u64 baser = its->baser_coll_table;
+ gpa_t gpa = GITS_BASER_ADDR_48_to_52(baser);
+ struct its_collection *collection;
+- u64 val;
+ size_t max_size, filled = 0;
+ int ret, cte_esz = abi->cte_esz;
+
+@@ -2520,10 +2519,7 @@ static int vgic_its_save_collection_tabl
+ * table is not fully filled, add a last dummy element
+ * with valid bit unset
+ */
+- val = 0;
+- BUG_ON(cte_esz > sizeof(val));
+- ret = vgic_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
+- return ret;
++ return vgic_its_write_entry_lock(its, gpa, 0, cte_esz);
+ }
+
+ /*
+--- a/arch/arm64/kvm/vgic/vgic.h
++++ b/arch/arm64/kvm/vgic/vgic.h
+@@ -146,6 +146,29 @@ static inline int vgic_write_guest_lock(
+ return ret;
+ }
+
++static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr,
++ u64 *eval, unsigned long esize)
++{
++ struct kvm *kvm = its->dev->kvm;
++
++ if (KVM_BUG_ON(esize != sizeof(*eval), kvm))
++ return -EINVAL;
++
++ return kvm_read_guest_lock(kvm, eaddr, eval, esize);
++
++}
++
++static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr,
++ u64 eval, unsigned long esize)
++{
++ struct kvm *kvm = its->dev->kvm;
++
++ if (KVM_BUG_ON(esize != sizeof(eval), kvm))
++ return -EINVAL;
++
++ return vgic_write_guest_lock(kvm, eaddr, &eval, esize);
++}
++
+ /*
+ * This struct provides an intermediate representation of the fields contained
+ * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
--- /dev/null
+From e9649129d33dca561305fc590a7c4ba8c3e5675a Mon Sep 17 00:00:00 2001
+From: Kunkun Jiang <jiangkunkun@huawei.com>
+Date: Thu, 7 Nov 2024 13:41:36 -0800
+Subject: KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device
+
+From: Kunkun Jiang <jiangkunkun@huawei.com>
+
+commit e9649129d33dca561305fc590a7c4ba8c3e5675a upstream.
+
+vgic_its_save_device_tables will traverse its->device_list to
+save DTE for each device. vgic_its_restore_device_tables will
+traverse each entry of device table and check if it is valid.
+Restore if valid.
+
+But when MAPD unmaps a device, it does not invalidate the
+corresponding DTE. In the scenario of continuous saves
+and restores, there may be a situation where a device's DTE
+is not saved but is restored. This is unreasonable and may
+cause restore to fail. This patch clears the corresponding
+DTE when MAPD unmaps a device.
+
+Cc: stable@vger.kernel.org
+Fixes: 57a9a117154c ("KVM: arm64: vgic-its: Device table save/restore")
+Co-developed-by: Shusen Li <lishusen2@huawei.com>
+Signed-off-by: Shusen Li <lishusen2@huawei.com>
+Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
+[Jing: Update with entry write helper]
+Signed-off-by: Jing Zhang <jingzhangos@google.com>
+Link: https://lore.kernel.org/r/20241107214137.428439-5-jingzhangos@google.com
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic-its.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -1143,9 +1143,11 @@ static int vgic_its_cmd_handle_mapd(stru
+ bool valid = its_cmd_get_validbit(its_cmd);
+ u8 num_eventid_bits = its_cmd_get_size(its_cmd);
+ gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd);
++ int dte_esz = vgic_its_get_abi(its)->dte_esz;
+ struct its_device *device;
++ gpa_t gpa;
+
+- if (!vgic_its_check_id(its, its->baser_device_table, device_id, NULL))
++ if (!vgic_its_check_id(its, its->baser_device_table, device_id, &gpa))
+ return E_ITS_MAPD_DEVICE_OOR;
+
+ if (valid && num_eventid_bits > VITS_TYPER_IDBITS)
+@@ -1166,7 +1168,7 @@ static int vgic_its_cmd_handle_mapd(stru
+ * is an error, so we are done in any case.
+ */
+ if (!valid)
+- return 0;
++ return vgic_its_write_entry_lock(its, gpa, 0, dte_esz);
+
+ device = vgic_its_alloc_device(its, device_id, itt_addr,
+ num_eventid_bits);
--- /dev/null
+From 7602ffd1d5e8927fadd5187cb4aed2fdc9c47143 Mon Sep 17 00:00:00 2001
+From: Kunkun Jiang <jiangkunkun@huawei.com>
+Date: Thu, 7 Nov 2024 13:41:37 -0800
+Subject: KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE
+
+From: Kunkun Jiang <jiangkunkun@huawei.com>
+
+commit 7602ffd1d5e8927fadd5187cb4aed2fdc9c47143 upstream.
+
+When DISCARD frees an ITE, it does not invalidate the
+corresponding ITE. In the scenario of continuous saves and
+restores, there may be a situation where an ITE is not saved
+but is restored. This is unreasonable and may cause restore
+to fail. This patch clears the corresponding ITE when DISCARD
+frees an ITE.
+
+Cc: stable@vger.kernel.org
+Fixes: eff484e0298d ("KVM: arm64: vgic-its: ITT save and restore")
+Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
+[Jing: Update with entry write helper]
+Signed-off-by: Jing Zhang <jingzhangos@google.com>
+Link: https://lore.kernel.org/r/20241107214137.428439-6-jingzhangos@google.com
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic-its.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -782,6 +782,9 @@ static int vgic_its_cmd_handle_discard(s
+
+ ite = find_ite(its, device_id, event_id);
+ if (ite && its_is_collection_mapped(ite->collection)) {
++ struct its_device *device = find_its_device(its, device_id);
++ int ite_esz = vgic_its_get_abi(its)->ite_esz;
++ gpa_t gpa = device->itt_addr + ite->event_id * ite_esz;
+ /*
+ * Though the spec talks about removing the pending state, we
+ * don't bother here since we clear the ITTE anyway and the
+@@ -790,7 +793,8 @@ static int vgic_its_cmd_handle_discard(s
+ vgic_its_invalidate_cache(its);
+
+ its_free_ite(kvm, ite);
+- return 0;
++
++ return vgic_its_write_entry_lock(its, gpa, 0, ite_esz);
+ }
+
+ return E_ITS_DISCARD_UNMAPPED_INTERRUPT;
--- /dev/null
+From d561491ba927cb5634094ff311795e9d618e9b86 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Sun, 17 Nov 2024 16:57:54 +0000
+Subject: KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit d561491ba927cb5634094ff311795e9d618e9b86 upstream.
+
+Make sure we filter out non-LPI invalidation when handling writes
+to GICR_INVLPIR.
+
+Fixes: 4645d11f4a553 ("KVM: arm64: vgic-v3: Implement MMIO-based LPI invalidation")
+Reported-by: Alexander Potapenko <glider@google.com>
+Tested-by: Alexander Potapenko <glider@google.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20241117165757.247686-2-maz@kernel.org
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic-mmio-v3.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+@@ -530,6 +530,7 @@ static void vgic_mmio_write_invlpi(struc
+ unsigned long val)
+ {
+ struct vgic_irq *irq;
++ u32 intid;
+
+ /*
+ * If the guest wrote only to the upper 32bit part of the
+@@ -541,9 +542,13 @@ static void vgic_mmio_write_invlpi(struc
+ if ((addr & 4) || !vgic_lpis_enabled(vcpu))
+ return;
+
++ intid = lower_32_bits(val);
++ if (intid < VGIC_MIN_LPI)
++ return;
++
+ vgic_set_rdist_busy(vcpu, true);
+
+- irq = vgic_get_irq(vcpu->kvm, NULL, lower_32_bits(val));
++ irq = vgic_get_irq(vcpu->kvm, NULL, intid);
+ if (irq) {
+ vgic_its_inv_lpi(vcpu->kvm, irq);
+ vgic_put_irq(vcpu->kvm, irq);
--- /dev/null
+From 2867eb782cf7f64c2ac427596133b6f9c3f64b7a Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Thu, 10 Oct 2024 11:23:06 -0700
+Subject: KVM: x86/mmu: Skip the "try unsync" path iff the old SPTE was a leaf SPTE
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 2867eb782cf7f64c2ac427596133b6f9c3f64b7a upstream.
+
+Apply make_spte()'s optimization to skip trying to unsync shadow pages if
+and only if the old SPTE was a leaf SPTE, as non-leaf SPTEs in direct MMUs
+are always writable, i.e. could trigger a false positive and incorrectly
+lead to KVM creating a SPTE without write-protecting or marking shadow
+pages unsync.
+
+This bug only affects the TDP MMU, as the shadow MMU only overwrites a
+shadow-present SPTE when synchronizing SPTEs (and only 4KiB SPTEs can be
+unsync). Specifically, mmu_set_spte() drops any non-leaf SPTEs *before*
+calling make_spte(), whereas the TDP MMU can do a direct replacement of a
+page table with the leaf SPTE.
+
+Opportunistically update the comment to explain why skipping the unsync
+stuff is safe, as opposed to simply saying "it's someone else's problem".
+
+Cc: stable@vger.kernel.org
+Tested-by: Alex Bennée <alex.bennee@linaro.org>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-ID: <20241010182427.1434605-5-seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/mmu/spte.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/kvm/mmu/spte.c
++++ b/arch/x86/kvm/mmu/spte.c
+@@ -226,12 +226,20 @@ bool make_spte(struct kvm_vcpu *vcpu, st
+ spte |= PT_WRITABLE_MASK | shadow_mmu_writable_mask;
+
+ /*
+- * Optimization: for pte sync, if spte was writable the hash
+- * lookup is unnecessary (and expensive). Write protection
+- * is responsibility of kvm_mmu_get_page / kvm_mmu_sync_roots.
+- * Same reasoning can be applied to dirty page accounting.
++ * When overwriting an existing leaf SPTE, and the old SPTE was
++ * writable, skip trying to unsync shadow pages as any relevant
++ * shadow pages must already be unsync, i.e. the hash lookup is
++ * unnecessary (and expensive).
++ *
++ * The same reasoning applies to dirty page/folio accounting;
++ * KVM will mark the folio dirty using the old SPTE, thus
++ * there's no need to immediately mark the new SPTE as dirty.
++ *
++ * Note, both cases rely on KVM not changing PFNs without first
++ * zapping the old SPTE, which is guaranteed by both the shadow
++ * MMU and the TDP MMU.
+ */
+- if (is_writable_pte(old_spte))
++ if (is_last_spte(old_spte, level) && is_writable_pte(old_spte))
+ goto out;
+
+ /*
--- /dev/null
+From d96c77bd4eeba469bddbbb14323d2191684da82a Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 8 Nov 2024 04:56:31 -0500
+Subject: KVM: x86: switch hugepage recovery thread to vhost_task
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit d96c77bd4eeba469bddbbb14323d2191684da82a upstream.
+
+kvm_vm_create_worker_thread() is meant to be used for kthreads that
+can consume significant amounts of CPU time on behalf of a VM or in
+response to how the VM behaves (for example how it accesses its memory).
+Therefore it wants to charge the CPU time consumed by that work to
+the VM's container.
+
+However, because of these threads, cgroups which have kvm instances
+inside never complete freezing. This can be trivially reproduced:
+
+ root@test ~# mkdir /sys/fs/cgroup/test
+ root@test ~# echo $$ > /sys/fs/cgroup/test/cgroup.procs
+ root@test ~# qemu-system-x86_64 -nographic -enable-kvm
+
+and in another terminal:
+
+ root@test ~# echo 1 > /sys/fs/cgroup/test/cgroup.freeze
+ root@test ~# cat /sys/fs/cgroup/test/cgroup.events
+ populated 1
+ frozen 0
+
+The cgroup freezing happens in the signal delivery path but
+kvm_nx_huge_page_recovery_worker, while joining non-root cgroups, never
+calls into the signal delivery path and thus never gets frozen. Because
+the cgroup freezer determines whether a given cgroup is frozen by
+comparing the number of frozen threads to the total number of threads
+in the cgroup, the cgroup never becomes frozen and users waiting for
+the state transition may hang indefinitely.
+
+Since the worker kthread is tied to a user process, it's better if
+it behaves similarly to user tasks as much as possible, including
+being able to send SIGSTOP and SIGCONT. In fact, vhost_task is all
+that kvm_vm_create_worker_thread() wanted to be and more: not only it
+inherits the userspace process's cgroups, it has other niceties like
+being parented properly in the process tree. Use it instead of the
+homegrown alternative.
+
+Incidentally, the new code is also better behaved when you flip recovery
+back and forth to disabled and back to enabled. If your recovery period
+is 1 minute, it will run the next recovery after 1 minute independent
+of how many times you flipped the parameter.
+
+(Commit message based on emails from Tejun).
+
+Reported-by: Tejun Heo <tj@kernel.org>
+Reported-by: Luca Boccassi <bluca@debian.org>
+Acked-by: Tejun Heo <tj@kernel.org>
+Tested-by: Luca Boccassi <bluca@debian.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/kvm_host.h | 4 +
+ arch/x86/kvm/Kconfig | 1
+ arch/x86/kvm/mmu/mmu.c | 68 ++++++++++++--------------
+ include/linux/kvm_host.h | 6 --
+ virt/kvm/kvm_main.c | 103 ----------------------------------------
+ 5 files changed, 35 insertions(+), 147 deletions(-)
+
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -26,6 +26,7 @@
+ #include <linux/irqbypass.h>
+ #include <linux/hyperv.h>
+ #include <linux/kfifo.h>
++#include <linux/sched/vhost_task.h>
+
+ #include <asm/apic.h>
+ #include <asm/pvclock-abi.h>
+@@ -1445,7 +1446,8 @@ struct kvm_arch {
+ bool sgx_provisioning_allowed;
+
+ struct kvm_x86_pmu_event_filter __rcu *pmu_event_filter;
+- struct task_struct *nx_huge_page_recovery_thread;
++ struct vhost_task *nx_huge_page_recovery_thread;
++ u64 nx_huge_page_last;
+
+ #ifdef CONFIG_X86_64
+ /* The number of TDP MMU pages across all roots. */
+--- a/arch/x86/kvm/Kconfig
++++ b/arch/x86/kvm/Kconfig
+@@ -29,6 +29,7 @@ config KVM
+ select HAVE_KVM_IRQ_BYPASS
+ select HAVE_KVM_IRQ_ROUTING
+ select HAVE_KVM_READONLY_MEM
++ select VHOST_TASK
+ select KVM_ASYNC_PF
+ select USER_RETURN_NOTIFIER
+ select KVM_MMIO
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -7160,7 +7160,7 @@ static int set_nx_huge_pages(const char
+ kvm_mmu_zap_all_fast(kvm);
+ mutex_unlock(&kvm->slots_lock);
+
+- wake_up_process(kvm->arch.nx_huge_page_recovery_thread);
++ vhost_task_wake(kvm->arch.nx_huge_page_recovery_thread);
+ }
+ mutex_unlock(&kvm_lock);
+ }
+@@ -7306,7 +7306,7 @@ static int set_nx_huge_pages_recovery_pa
+ mutex_lock(&kvm_lock);
+
+ list_for_each_entry(kvm, &vm_list, vm_list)
+- wake_up_process(kvm->arch.nx_huge_page_recovery_thread);
++ vhost_task_wake(kvm->arch.nx_huge_page_recovery_thread);
+
+ mutex_unlock(&kvm_lock);
+ }
+@@ -7409,62 +7409,56 @@ static void kvm_recover_nx_huge_pages(st
+ srcu_read_unlock(&kvm->srcu, rcu_idx);
+ }
+
+-static long get_nx_huge_page_recovery_timeout(u64 start_time)
++static void kvm_nx_huge_page_recovery_worker_kill(void *data)
+ {
+- bool enabled;
+- uint period;
+-
+- enabled = calc_nx_huge_pages_recovery_period(&period);
+-
+- return enabled ? start_time + msecs_to_jiffies(period) - get_jiffies_64()
+- : MAX_SCHEDULE_TIMEOUT;
+ }
+
+-static int kvm_nx_huge_page_recovery_worker(struct kvm *kvm, uintptr_t data)
++static bool kvm_nx_huge_page_recovery_worker(void *data)
+ {
+- u64 start_time;
++ struct kvm *kvm = data;
++ bool enabled;
++ uint period;
+ long remaining_time;
+
+- while (true) {
+- start_time = get_jiffies_64();
+- remaining_time = get_nx_huge_page_recovery_timeout(start_time);
+-
+- set_current_state(TASK_INTERRUPTIBLE);
+- while (!kthread_should_stop() && remaining_time > 0) {
+- schedule_timeout(remaining_time);
+- remaining_time = get_nx_huge_page_recovery_timeout(start_time);
+- set_current_state(TASK_INTERRUPTIBLE);
+- }
+-
+- set_current_state(TASK_RUNNING);
+-
+- if (kthread_should_stop())
+- return 0;
++ enabled = calc_nx_huge_pages_recovery_period(&period);
++ if (!enabled)
++ return false;
+
+- kvm_recover_nx_huge_pages(kvm);
++ remaining_time = kvm->arch.nx_huge_page_last + msecs_to_jiffies(period)
++ - get_jiffies_64();
++ if (remaining_time > 0) {
++ schedule_timeout(remaining_time);
++ /* check for signals and come back */
++ return true;
+ }
++
++ __set_current_state(TASK_RUNNING);
++ kvm_recover_nx_huge_pages(kvm);
++ kvm->arch.nx_huge_page_last = get_jiffies_64();
++ return true;
+ }
+
+ int kvm_mmu_post_init_vm(struct kvm *kvm)
+ {
+- int err;
+-
+ if (nx_hugepage_mitigation_hard_disabled)
+ return 0;
+
+- err = kvm_vm_create_worker_thread(kvm, kvm_nx_huge_page_recovery_worker, 0,
+- "kvm-nx-lpage-recovery",
+- &kvm->arch.nx_huge_page_recovery_thread);
+- if (!err)
+- kthread_unpark(kvm->arch.nx_huge_page_recovery_thread);
++ kvm->arch.nx_huge_page_last = get_jiffies_64();
++ kvm->arch.nx_huge_page_recovery_thread = vhost_task_create(
++ kvm_nx_huge_page_recovery_worker, kvm_nx_huge_page_recovery_worker_kill,
++ kvm, "kvm-nx-lpage-recovery");
+
+- return err;
++ if (!kvm->arch.nx_huge_page_recovery_thread)
++ return -ENOMEM;
++
++ vhost_task_start(kvm->arch.nx_huge_page_recovery_thread);
++ return 0;
+ }
+
+ void kvm_mmu_pre_destroy_vm(struct kvm *kvm)
+ {
+ if (kvm->arch.nx_huge_page_recovery_thread)
+- kthread_stop(kvm->arch.nx_huge_page_recovery_thread);
++ vhost_task_stop(kvm->arch.nx_huge_page_recovery_thread);
+ }
+
+ #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -2370,12 +2370,6 @@ static inline int kvm_arch_vcpu_run_pid_
+ }
+ #endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */
+
+-typedef int (*kvm_vm_thread_fn_t)(struct kvm *kvm, uintptr_t data);
+-
+-int kvm_vm_create_worker_thread(struct kvm *kvm, kvm_vm_thread_fn_t thread_fn,
+- uintptr_t data, const char *name,
+- struct task_struct **thread_ptr);
+-
+ #ifdef CONFIG_KVM_XFER_TO_GUEST_WORK
+ static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
+ {
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -6573,106 +6573,3 @@ void kvm_exit(void)
+ kvm_irqfd_exit();
+ }
+ EXPORT_SYMBOL_GPL(kvm_exit);
+-
+-struct kvm_vm_worker_thread_context {
+- struct kvm *kvm;
+- struct task_struct *parent;
+- struct completion init_done;
+- kvm_vm_thread_fn_t thread_fn;
+- uintptr_t data;
+- int err;
+-};
+-
+-static int kvm_vm_worker_thread(void *context)
+-{
+- /*
+- * The init_context is allocated on the stack of the parent thread, so
+- * we have to locally copy anything that is needed beyond initialization
+- */
+- struct kvm_vm_worker_thread_context *init_context = context;
+- struct task_struct *parent;
+- struct kvm *kvm = init_context->kvm;
+- kvm_vm_thread_fn_t thread_fn = init_context->thread_fn;
+- uintptr_t data = init_context->data;
+- int err;
+-
+- err = kthread_park(current);
+- /* kthread_park(current) is never supposed to return an error */
+- WARN_ON(err != 0);
+- if (err)
+- goto init_complete;
+-
+- err = cgroup_attach_task_all(init_context->parent, current);
+- if (err) {
+- kvm_err("%s: cgroup_attach_task_all failed with err %d\n",
+- __func__, err);
+- goto init_complete;
+- }
+-
+- set_user_nice(current, task_nice(init_context->parent));
+-
+-init_complete:
+- init_context->err = err;
+- complete(&init_context->init_done);
+- init_context = NULL;
+-
+- if (err)
+- goto out;
+-
+- /* Wait to be woken up by the spawner before proceeding. */
+- kthread_parkme();
+-
+- if (!kthread_should_stop())
+- err = thread_fn(kvm, data);
+-
+-out:
+- /*
+- * Move kthread back to its original cgroup to prevent it lingering in
+- * the cgroup of the VM process, after the latter finishes its
+- * execution.
+- *
+- * kthread_stop() waits on the 'exited' completion condition which is
+- * set in exit_mm(), via mm_release(), in do_exit(). However, the
+- * kthread is removed from the cgroup in the cgroup_exit() which is
+- * called after the exit_mm(). This causes the kthread_stop() to return
+- * before the kthread actually quits the cgroup.
+- */
+- rcu_read_lock();
+- parent = rcu_dereference(current->real_parent);
+- get_task_struct(parent);
+- rcu_read_unlock();
+- cgroup_attach_task_all(parent, current);
+- put_task_struct(parent);
+-
+- return err;
+-}
+-
+-int kvm_vm_create_worker_thread(struct kvm *kvm, kvm_vm_thread_fn_t thread_fn,
+- uintptr_t data, const char *name,
+- struct task_struct **thread_ptr)
+-{
+- struct kvm_vm_worker_thread_context init_context = {};
+- struct task_struct *thread;
+-
+- *thread_ptr = NULL;
+- init_context.kvm = kvm;
+- init_context.parent = current;
+- init_context.thread_fn = thread_fn;
+- init_context.data = data;
+- init_completion(&init_context.init_done);
+-
+- thread = kthread_run(kvm_vm_worker_thread, &init_context,
+- "%s-%d", name, task_pid_nr(current));
+- if (IS_ERR(thread))
+- return PTR_ERR(thread);
+-
+- /* kthread_run is never supposed to return NULL */
+- WARN_ON(thread == NULL);
+-
+- wait_for_completion(&init_context.init_done);
+-
+- if (!init_context.err)
+- *thread_ptr = thread;
+-
+- return init_context.err;
+-}
--- /dev/null
+From d7fe143cb115076fed0126ad8cf5ba6c3e575e43 Mon Sep 17 00:00:00 2001
+From: Ahmed Ehab <bottaawesome633@gmail.com>
+Date: Sun, 25 Aug 2024 01:10:30 +0300
+Subject: locking/lockdep: Avoid creating new name string literals in lockdep_set_subclass()
+
+From: Ahmed Ehab <bottaawesome633@gmail.com>
+
+commit d7fe143cb115076fed0126ad8cf5ba6c3e575e43 upstream.
+
+Syzbot reports a problem that a warning will be triggered while
+searching a lock class in look_up_lock_class().
+
+The cause of the issue is that a new name is created and used by
+lockdep_set_subclass() instead of using the existing one. This results
+in a lock instance has a different name pointer than previous registered
+one stored in lock class, and WARN_ONCE() is triggered because of that
+in look_up_lock_class().
+
+To fix this, change lockdep_set_subclass() to use the existing name
+instead of a new one. Hence, no new name will be created by
+lockdep_set_subclass(). Hence, the warning is avoided.
+
+[boqun: Reword the commit log to state the correct issue]
+
+Reported-by: <syzbot+7f4a6f7f7051474e40ad@syzkaller.appspotmail.com>
+Fixes: de8f5e4f2dc1f ("lockdep: Introduce wait-type checks")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ahmed Ehab <bottaawesome633@gmail.com>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Link: https://lore.kernel.org/lkml/20240824221031.7751-1-bottaawesome633@gmail.com/
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/lockdep.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -173,7 +173,7 @@ static inline void lockdep_init_map(stru
+ (lock)->dep_map.lock_type)
+
+ #define lockdep_set_subclass(lock, sub) \
+- lockdep_init_map_type(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\
++ lockdep_init_map_type(&(lock)->dep_map, (lock)->dep_map.name, (lock)->dep_map.key, sub,\
+ (lock)->dep_map.wait_type_inner, \
+ (lock)->dep_map.wait_type_outer, \
+ (lock)->dep_map.lock_type)
--- /dev/null
+From e67e0eb6a98b261caf45048f9eb95fd7609289c0 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Fri, 22 Nov 2024 15:47:47 +0800
+Subject: LoongArch: Explicitly specify code model in Makefile
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit e67e0eb6a98b261caf45048f9eb95fd7609289c0 upstream.
+
+LoongArch's toolchain may change the default code model from normal to
+medium. This is unnecessary for kernel, and generates some relocations
+which cannot be handled by the module loader. So explicitly specify the
+code model to normal in Makefile (for Rust 'normal' is 'small').
+
+Cc: stable@vger.kernel.org
+Tested-by: Haiyong Sun <sunhaiyong@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/loongarch/Makefile
++++ b/arch/loongarch/Makefile
+@@ -59,7 +59,7 @@ endif
+
+ ifdef CONFIG_64BIT
+ ld-emul = $(64bit-emul)
+-cflags-y += -mabi=lp64s
++cflags-y += -mabi=lp64s -mcmodel=normal
+ endif
+
+ cflags-y += -pipe $(CC_FLAGS_NO_FPU)
+@@ -104,7 +104,7 @@ ifdef CONFIG_OBJTOOL
+ KBUILD_CFLAGS += -fno-jump-tables
+ endif
+
+-KBUILD_RUSTFLAGS += --target=loongarch64-unknown-none-softfloat
++KBUILD_RUSTFLAGS += --target=loongarch64-unknown-none-softfloat -Ccode-model=small
+ KBUILD_RUSTFLAGS_KERNEL += -Zdirect-access-external-data=yes
+ KBUILD_RUSTFLAGS_MODULE += -Zdirect-access-external-data=no
+
--- /dev/null
+From c7acef99642b763ba585f4a43af999fcdbcc3dc4 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 10 Oct 2024 19:10:34 +0200
+Subject: PCI: Fix use-after-free of slot->bus on hot remove
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit c7acef99642b763ba585f4a43af999fcdbcc3dc4 upstream.
+
+Dennis reports a boot crash on recent Lenovo laptops with a USB4 dock.
+
+Since commit 0fc70886569c ("thunderbolt: Reset USB4 v2 host router") and
+commit 59a54c5f3dbd ("thunderbolt: Reset topology created by the boot
+firmware"), USB4 v2 and v1 Host Routers are reset on probe of the
+thunderbolt driver.
+
+The reset clears the Presence Detect State and Data Link Layer Link Active
+bits at the USB4 Host Router's Root Port and thus causes hot removal of the
+dock.
+
+The crash occurs when pciehp is unbound from one of the dock's Downstream
+Ports: pciehp creates a pci_slot on bind and destroys it on unbind. The
+pci_slot contains a pointer to the pci_bus below the Downstream Port, but
+a reference on that pci_bus is never acquired. The pci_bus is destroyed
+before the pci_slot, so a use-after-free ensues when pci_slot_release()
+accesses slot->bus.
+
+In principle this should not happen because pci_stop_bus_device() unbinds
+pciehp (and therefore destroys the pci_slot) before the pci_bus is
+destroyed by pci_remove_bus_device().
+
+However the stacktrace provided by Dennis shows that pciehp is unbound from
+pci_remove_bus_device() instead of pci_stop_bus_device(). To understand
+the significance of this, one needs to know that the PCI core uses a two
+step process to remove a portion of the hierarchy: It first unbinds all
+drivers in the sub-hierarchy in pci_stop_bus_device() and then actually
+removes the devices in pci_remove_bus_device(). There is no precaution to
+prevent driver binding in-between pci_stop_bus_device() and
+pci_remove_bus_device().
+
+In Dennis' case, it seems removal of the hierarchy by pciehp races with
+driver binding by pci_bus_add_devices(). pciehp is bound to the
+Downstream Port after pci_stop_bus_device() has run, so it is unbound by
+pci_remove_bus_device() instead of pci_stop_bus_device(). Because the
+pci_bus has already been destroyed at that point, accesses to it result in
+a use-after-free.
+
+One might conclude that driver binding needs to be prevented after
+pci_stop_bus_device() has run. However it seems risky that pci_slot points
+to pci_bus without holding a reference. Solely relying on correct ordering
+of driver unbind versus pci_bus destruction is certainly not defensive
+programming.
+
+If pci_slot has a need to access data in pci_bus, it ought to acquire a
+reference. Amend pci_create_slot() accordingly. Dennis reports that the
+crash is not reproducible with this change.
+
+Abridged stacktrace:
+
+ pcieport 0000:00:07.0: PME: Signaling with IRQ 156
+ pcieport 0000:00:07.0: pciehp: Slot #12 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+
+ pci_bus 0000:20: dev 00, created physical slot 12
+ pcieport 0000:00:07.0: pciehp: Slot(12): Card not present
+ ...
+ pcieport 0000:21:02.0: pciehp: pcie_disable_notification: SLOTCTRL d8 write cmd 0
+ Oops: general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b6b: 0000 [#1] PREEMPT SMP NOPTI
+ CPU: 13 UID: 0 PID: 134 Comm: irq/156-pciehp Not tainted 6.11.0-devel+ #1
+ RIP: 0010:dev_driver_string+0x12/0x40
+ pci_destroy_slot
+ pciehp_remove
+ pcie_port_remove_service
+ device_release_driver_internal
+ bus_remove_device
+ device_del
+ device_unregister
+ remove_iter
+ device_for_each_child
+ pcie_portdrv_remove
+ pci_device_remove
+ device_release_driver_internal
+ bus_remove_device
+ device_del
+ pci_remove_bus_device (recursive invocation)
+ pci_remove_bus_device
+ pciehp_unconfigure_device
+ pciehp_disable_slot
+ pciehp_handle_presence_or_link_change
+ pciehp_ist
+
+Link: https://lore.kernel.org/r/4bfd4c0e976c1776cd08e76603903b338cf25729.1728579288.git.lukas@wunner.de
+Reported-by: Dennis Wassenberg <Dennis.Wassenberg@secunet.com>
+Closes: https://lore.kernel.org/r/6de4b45ff2b32dd91a805ec02ec8ec73ef411bf6.camel@secunet.com/
+Tested-by: Dennis Wassenberg <Dennis.Wassenberg@secunet.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/slot.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/slot.c
++++ b/drivers/pci/slot.c
+@@ -79,6 +79,7 @@ static void pci_slot_release(struct kobj
+ up_read(&pci_bus_sem);
+
+ list_del(&slot->list);
++ pci_bus_put(slot->bus);
+
+ kfree(slot);
+ }
+@@ -261,7 +262,7 @@ placeholder:
+ goto err;
+ }
+
+- slot->bus = parent;
++ slot->bus = pci_bus_get(parent);
+ slot->number = slot_nr;
+
+ slot->kobj.kset = pci_slots_kset;
+@@ -269,6 +270,7 @@ placeholder:
+ slot_name = make_slot_name(name);
+ if (!slot_name) {
+ err = -ENOMEM;
++ pci_bus_put(slot->bus);
+ kfree(slot);
+ goto err;
+ }
--- /dev/null
+From 5b590160d2cf776b304eb054afafea2bd55e3620 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Tue, 22 Oct 2024 18:59:07 +0300
+Subject: perf/x86/intel/pt: Fix buffer full but size is 0 case
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 5b590160d2cf776b304eb054afafea2bd55e3620 upstream.
+
+If the trace data buffer becomes full, a truncated flag [T] is reported
+in PERF_RECORD_AUX. In some cases, the size reported is 0, even though
+data must have been added to make the buffer full.
+
+That happens when the buffer fills up from empty to full before the
+Intel PT driver has updated the buffer position. Then the driver
+calculates the new buffer position before calculating the data size.
+If the old and new positions are the same, the data size is reported
+as 0, even though it is really the whole buffer size.
+
+Fix by detecting when the buffer position is wrapped, and adjust the
+data size calculation accordingly.
+
+Example
+
+ Use a very small buffer size (8K) and observe the size of truncated [T]
+ data. Before the fix, it is possible to see records of 0 size.
+
+ Before:
+
+ $ perf record -m,8K -e intel_pt// uname
+ Linux
+ [ perf record: Woken up 2 times to write data ]
+ [ perf record: Captured and wrote 0.105 MB perf.data ]
+ $ perf script -D --no-itrace | grep AUX | grep -F '[T]'
+ Warning:
+ AUX data lost 2 times out of 3!
+
+ 5 19462712368111 0x19710 [0x40]: PERF_RECORD_AUX offset: 0 size: 0 flags: 0x1 [T]
+ 5 19462712700046 0x19ba8 [0x40]: PERF_RECORD_AUX offset: 0x170 size: 0xe90 flags: 0x1 [T]
+
+ After:
+
+ $ perf record -m,8K -e intel_pt// uname
+ Linux
+ [ perf record: Woken up 3 times to write data ]
+ [ perf record: Captured and wrote 0.040 MB perf.data ]
+ $ perf script -D --no-itrace | grep AUX | grep -F '[T]'
+ Warning:
+ AUX data lost 2 times out of 3!
+
+ 1 113720802995 0x4948 [0x40]: PERF_RECORD_AUX offset: 0 size: 0x2000 flags: 0x1 [T]
+ 1 113720979812 0x6b10 [0x40]: PERF_RECORD_AUX offset: 0x2000 size: 0x2000 flags: 0x1 [T]
+
+Fixes: 52ca9ced3f70 ("perf/x86/intel/pt: Add Intel PT PMU driver")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20241022155920.17511-2-adrian.hunter@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/events/intel/pt.c | 11 ++++++++---
+ arch/x86/events/intel/pt.h | 2 ++
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/events/intel/pt.c
++++ b/arch/x86/events/intel/pt.c
+@@ -828,11 +828,13 @@ static void pt_buffer_advance(struct pt_
+ buf->cur_idx++;
+
+ if (buf->cur_idx == buf->cur->last) {
+- if (buf->cur == buf->last)
++ if (buf->cur == buf->last) {
+ buf->cur = buf->first;
+- else
++ buf->wrapped = true;
++ } else {
+ buf->cur = list_entry(buf->cur->list.next, struct topa,
+ list);
++ }
+ buf->cur_idx = 0;
+ }
+ }
+@@ -846,8 +848,11 @@ static void pt_buffer_advance(struct pt_
+ static void pt_update_head(struct pt *pt)
+ {
+ struct pt_buffer *buf = perf_get_aux(&pt->handle);
++ bool wrapped = buf->wrapped;
+ u64 topa_idx, base, old;
+
++ buf->wrapped = false;
++
+ if (buf->single) {
+ local_set(&buf->data_size, buf->output_off);
+ return;
+@@ -865,7 +870,7 @@ static void pt_update_head(struct pt *pt
+ } else {
+ old = (local64_xchg(&buf->head, base) &
+ ((buf->nr_pages << PAGE_SHIFT) - 1));
+- if (base < old)
++ if (base < old || (base == old && wrapped))
+ base += buf->nr_pages << PAGE_SHIFT;
+
+ local_add(base - old, &buf->data_size);
+--- a/arch/x86/events/intel/pt.h
++++ b/arch/x86/events/intel/pt.h
+@@ -65,6 +65,7 @@ struct pt_pmu {
+ * @head: logical write offset inside the buffer
+ * @snapshot: if this is for a snapshot/overwrite counter
+ * @single: use Single Range Output instead of ToPA
++ * @wrapped: buffer advance wrapped back to the first topa table
+ * @stop_pos: STOP topa entry index
+ * @intr_pos: INT topa entry index
+ * @stop_te: STOP topa entry pointer
+@@ -82,6 +83,7 @@ struct pt_buffer {
+ local64_t head;
+ bool snapshot;
+ bool single;
++ bool wrapped;
+ long stop_pos, intr_pos;
+ struct topa_entry *stop_te, *intr_te;
+ void **data_pages;
--- /dev/null
+From 6bc0ebfb1d920f13c522545f114cdabb49e9408a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Fri, 25 Oct 2024 14:16:22 +0200
+Subject: pinctrl: qcom: spmi: fix debugfs drive strength
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit 6bc0ebfb1d920f13c522545f114cdabb49e9408a upstream.
+
+Commit 723e8462a4fe ("pinctrl: qcom: spmi-gpio: Fix the GPIO strength
+mapping") fixed a long-standing issue in the Qualcomm SPMI PMIC gpio
+driver which had the 'low' and 'high' drive strength settings switched
+but failed to update the debugfs interface which still gets this wrong.
+
+Fix the debugfs code so that the exported values match the hardware
+settings.
+
+Note that this probably means that most devicetrees that try to describe
+the firmware settings got this wrong if the settings were derived from
+debugfs. Before the above mentioned commit the settings would have
+actually matched the firmware settings even if they were described
+incorrectly, but now they are inverted.
+
+Fixes: 723e8462a4fe ("pinctrl: qcom: spmi-gpio: Fix the GPIO strength mapping")
+Fixes: eadff3024472 ("pinctrl: Qualcomm SPMI PMIC GPIO pin controller driver")
+Cc: Anjelique Melendez <quic_amelende@quicinc.com>
+Cc: stable@vger.kernel.org # 3.19
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/20241025121622.1496-1-johan+linaro@kernel.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
++++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+@@ -667,7 +667,7 @@ static void pmic_gpio_config_dbg_show(st
+ "push-pull", "open-drain", "open-source"
+ };
+ static const char *const strengths[] = {
+- "no", "high", "medium", "low"
++ "no", "low", "medium", "high"
+ };
+
+ pad = pctldev->desc->pins[pin].drv_data;
--- /dev/null
+From 44e5d21e6d3fd2a1fed7f0327cf72e99397e2eaf Mon Sep 17 00:00:00 2001
+From: Gautam Menghani <gautam@linux.ibm.com>
+Date: Fri, 8 Nov 2024 15:18:37 +0530
+Subject: powerpc/pseries: Fix KVM guest detection for disabling hardlockup detector
+
+From: Gautam Menghani <gautam@linux.ibm.com>
+
+commit 44e5d21e6d3fd2a1fed7f0327cf72e99397e2eaf upstream.
+
+As per the kernel documentation[1], hardlockup detector should
+be disabled in KVM guests as it may give false positives. On
+PPC, hardlockup detector is enabled inside KVM guests because
+disable_hardlockup_detector() is marked as early_initcall and it
+relies on kvm_guest static key (is_kvm_guest()) which is initialized
+later during boot by check_kvm_guest(), which is a core_initcall.
+check_kvm_guest() is also called in pSeries_smp_probe(), which is called
+before initcalls, but it is skipped if KVM guest does not have doorbell
+support or if the guest is launched with SMT=1.
+
+Call check_kvm_guest() in disable_hardlockup_detector() so that
+is_kvm_guest() check goes through fine and hardlockup detector can be
+disabled inside the KVM guest.
+
+[1]: Documentation/admin-guide/sysctl/kernel.rst
+
+Fixes: 633c8e9800f3 ("powerpc/pseries: Enable hardlockup watchdog for PowerVM partitions")
+Cc: stable@vger.kernel.org # v5.14+
+Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://patch.msgid.link/20241108094839.33084-1-gautam@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kernel/setup_64.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -920,6 +920,7 @@ static int __init disable_hardlockup_det
+ hardlockup_detector_disable();
+ #else
+ if (firmware_has_feature(FW_FEATURE_LPAR)) {
++ check_kvm_guest();
+ if (is_kvm_guest())
+ hardlockup_detector_disable();
+ }
asoc-intel-sst-fix-used-of-uninitialized-ctx-to-log-an-error.patch
soc-qcom-socinfo-fix-revision-check-in-qcom_socinfo_probe.patch
irqdomain-always-associate-interrupts-for-legacy-domains.patch
+ext4-supress-data-race-warnings-in-ext4_free_inodes_-count-set.patch
+ext4-fix-fs_ioc_getfsmap-handling.patch
+jfs-xattr-check-invalid-xattr-size-more-strictly.patch
+asoc-amd-yc-add-a-quirk-for-microfone-on-lenovo-thinkpad-p14s-gen-5-21mes00b00.patch
+asoc-codecs-fix-atomicity-violation-in-snd_soc_component_get_drvdata.patch
+asoc-da7213-populate-max_register-to-regmap_config.patch
+perf-x86-intel-pt-fix-buffer-full-but-size-is-0-case.patch
+crypto-x86-aegis128-access-32-bit-arguments-as-32-bit.patch
+kvm-x86-switch-hugepage-recovery-thread-to-vhost_task.patch
+kvm-x86-mmu-skip-the-try-unsync-path-iff-the-old-spte-was-a-leaf-spte.patch
+powerpc-pseries-fix-kvm-guest-detection-for-disabling-hardlockup-detector.patch
+kvm-arm64-vgic-v3-sanitise-guest-writes-to-gicr_invlpir.patch
+kvm-arm64-ignore-pmcntenset_el0-while-checking-for-overflow-status.patch
+kvm-arm64-don-t-retire-aborted-mmio-instruction.patch
+kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch
+kvm-arm64-get-rid-of-userspace_irqchip_in_use.patch
+kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch
+kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch
+compiler-attributes-disable-__counted_by-for-clang-19.1.3.patch
+pci-fix-use-after-free-of-slot-bus-on-hot-remove.patch
+loongarch-explicitly-specify-code-model-in-makefile.patch
+clk-clk-loongson2-fix-memory-corruption-bug-in-struct-loongson2_clk_provider.patch
+clk-clk-loongson2-fix-potential-buffer-overflow-in-flexible-array-member-access.patch
+fsnotify-fix-sending-inotify-event-with-unexpected-filename.patch
+fsnotify-fix-ordering-of-iput-and-watched_objects-decrement.patch
+comedi-flush-partial-mappings-in-error-case.patch
+apparmor-test-fix-memory-leak-for-aa_unpack_strdup.patch
+iio-dac-adi-axi-dac-fix-wrong-register-bitfield.patch
+tty-ldsic-fix-tty_ldisc_autoload-sysctl-s-proc_handler.patch
+locking-lockdep-avoid-creating-new-name-string-literals-in-lockdep_set_subclass.patch
+tools-nolibc-s390-include-std.h.patch
+pinctrl-qcom-spmi-fix-debugfs-drive-strength.patch
+dt-bindings-pinctrl-samsung-fix-interrupt-constraint-for-variants-with-fallbacks.patch
+dt-bindings-iio-dac-ad3552r-fix-maximum-spi-speed.patch
+exfat-fix-uninit-value-in-__exfat_get_dentry_set.patch
+exfat-fix-out-of-bounds-access-of-directory-entries.patch
+xhci-fix-control-transfer-error-on-etron-xhci-host.patch
+xhci-combine-two-if-statements-for-etron-xhci-host.patch
+xhci-don-t-perform-soft-retry-for-etron-xhci-host.patch
+xhci-don-t-issue-reset-device-command-to-etron-xhci-host.patch
+bluetooth-fix-type-of-len-in-rfcomm_sock_getsockopt-_old.patch
--- /dev/null
+From 711b5875814b2a0e9a5aaf7a85ba7c80f5a389b1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas.weissschuh@linutronix.de>
+Date: Fri, 27 Sep 2024 18:45:38 +0200
+Subject: tools/nolibc: s390: include std.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+
+commit 711b5875814b2a0e9a5aaf7a85ba7c80f5a389b1 upstream.
+
+arch-s390.h uses types from std.h, but does not include it.
+Depending on the inclusion order the compilation can fail.
+Include std.h explicitly to avoid these errors.
+
+Fixes: 404fa87c0eaf ("tools/nolibc: s390: provide custom implementation for sys_fork")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Link: https://lore.kernel.org/r/20240927-nolibc-s390-std-h-v1-1-30442339a6b9@linutronix.de
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/include/nolibc/arch-s390.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/tools/include/nolibc/arch-s390.h
++++ b/tools/include/nolibc/arch-s390.h
+@@ -10,6 +10,7 @@
+
+ #include "compiler.h"
+ #include "crt.h"
++#include "std.h"
+
+ /* Syscalls for s390:
+ * - registers are 64-bit
--- /dev/null
+From 635a9fca54f4f4148be1ae1c7c6bd37af80f5773 Mon Sep 17 00:00:00 2001
+From: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+Date: Tue, 12 Nov 2024 14:13:31 +0100
+Subject: tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler
+
+From: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+
+commit 635a9fca54f4f4148be1ae1c7c6bd37af80f5773 upstream.
+
+Commit 7c0cca7c847e ("tty: ldisc: add sysctl to prevent autoloading of
+ldiscs") introduces the tty_ldisc_autoload sysctl with the wrong
+proc_handler. .extra1 and .extra2 parameters are set to avoid other values
+thant SYSCTL_ZERO or SYSCTL_ONE to be set but proc_dointvec do not uses
+them.
+
+This commit fixes this by using proc_dointvec_minmax instead of
+proc_dointvec.
+
+Fixes: 7c0cca7c847e ("tty: ldisc: add sysctl to prevent autoloading of ldiscs")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+Reviewed-by: Lin Feng <linf@wangsu.com>
+Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20241112131357.49582-4-nicolas.bouchinet@clip-os.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/tty_io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -3631,7 +3631,7 @@ static struct ctl_table tty_table[] = {
+ .data = &tty_ldisc_autoload,
+ .maxlen = sizeof(tty_ldisc_autoload),
+ .mode = 0644,
+- .proc_handler = proc_dointvec,
++ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
--- /dev/null
+From d7b11fe5790203fcc0db182249d7bfd945e44ccb Mon Sep 17 00:00:00 2001
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+Date: Wed, 6 Nov 2024 12:14:43 +0200
+Subject: xhci: Combine two if statements for Etron xHCI host
+
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+
+commit d7b11fe5790203fcc0db182249d7bfd945e44ccb upstream.
+
+Combine two if statements, because these hosts have the same
+quirk flags applied.
+
+[Mathias: has stable tag because other fixes in series depend on this]
+
+Fixes: 91f7a1524a92 ("xhci: Apply broken streams quirk to Etron EJ188 xHCI host")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kuangyi Chiang <ki.chiang65@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241106101459.775897-18-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -401,12 +401,8 @@ static void xhci_pci_quirks(struct devic
+ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+
+ if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+- pdev->device == PCI_DEVICE_ID_EJ168) {
+- xhci->quirks |= XHCI_RESET_ON_RESUME;
+- xhci->quirks |= XHCI_BROKEN_STREAMS;
+- }
+- if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+- pdev->device == PCI_DEVICE_ID_EJ188) {
++ (pdev->device == PCI_DEVICE_ID_EJ168 ||
++ pdev->device == PCI_DEVICE_ID_EJ188)) {
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+ xhci->quirks |= XHCI_BROKEN_STREAMS;
+ }
--- /dev/null
+From 76d98856b1c6d06ce18f32c20527a4f9d283e660 Mon Sep 17 00:00:00 2001
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+Date: Wed, 6 Nov 2024 12:14:44 +0200
+Subject: xhci: Don't issue Reset Device command to Etron xHCI host
+
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+
+commit 76d98856b1c6d06ce18f32c20527a4f9d283e660 upstream.
+
+Sometimes the hub driver does not recognize the USB device connected
+to the external USB2.0 hub when the system resumes from S4.
+
+After the SetPortFeature(PORT_RESET) request is completed, the hub
+driver calls the HCD reset_device callback, which will issue a Reset
+Device command and free all structures associated with endpoints
+that were disabled.
+
+This happens when the xHCI driver issue a Reset Device command to
+inform the Etron xHCI host that the USB device associated with a
+device slot has been reset. Seems that the Etron xHCI host can not
+perform this command correctly, affecting the USB device.
+
+To work around this, the xHCI driver should obtain a new device slot
+with reference to commit 651aaf36a7d7 ("usb: xhci: Handle USB transaction
+error on address command"), which is another way to inform the Etron
+xHCI host that the USB device has been reset.
+
+Add a new XHCI_ETRON_HOST quirk flag to invoke the workaround in
+xhci_discover_or_reset_device().
+
+Fixes: 2a8f82c4ceaf ("USB: xhci: Notify the xHC when a device is reset.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kuangyi Chiang <ki.chiang65@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241106101459.775897-19-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci.c | 1 +
+ drivers/usb/host/xhci.c | 19 +++++++++++++++++++
+ drivers/usb/host/xhci.h | 1 +
+ 3 files changed, 21 insertions(+)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -403,6 +403,7 @@ static void xhci_pci_quirks(struct devic
+ if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+ (pdev->device == PCI_DEVICE_ID_EJ168 ||
+ pdev->device == PCI_DEVICE_ID_EJ188)) {
++ xhci->quirks |= XHCI_ETRON_HOST;
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+ xhci->quirks |= XHCI_BROKEN_STREAMS;
+ xhci->quirks |= XHCI_NO_SOFT_RETRY;
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3692,6 +3692,8 @@ void xhci_free_device_endpoint_resources
+ xhci->num_active_eps);
+ }
+
++static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
++
+ /*
+ * This submits a Reset Device Command, which will set the device state to 0,
+ * set the device address to 0, and disable all the endpoints except the default
+@@ -3762,6 +3764,23 @@ static int xhci_discover_or_reset_device
+ SLOT_STATE_DISABLED)
+ return 0;
+
++ if (xhci->quirks & XHCI_ETRON_HOST) {
++ /*
++ * Obtaining a new device slot to inform the xHCI host that
++ * the USB device has been reset.
++ */
++ ret = xhci_disable_slot(xhci, udev->slot_id);
++ xhci_free_virt_device(xhci, udev->slot_id);
++ if (!ret) {
++ ret = xhci_alloc_dev(hcd, udev);
++ if (ret == 1)
++ ret = 0;
++ else
++ ret = -EINVAL;
++ }
++ return ret;
++ }
++
+ trace_xhci_discover_or_reset_device(slot_ctx);
+
+ xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1629,6 +1629,7 @@ struct xhci_hcd {
+ #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
+ #define XHCI_WRITE_64_HI_LO BIT_ULL(47)
+ #define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48)
++#define XHCI_ETRON_HOST BIT_ULL(49)
+
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
--- /dev/null
+From e735e957f2b9cfe4be486e0304732ec36928591f Mon Sep 17 00:00:00 2001
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+Date: Wed, 6 Nov 2024 12:14:46 +0200
+Subject: xhci: Don't perform Soft Retry for Etron xHCI host
+
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+
+commit e735e957f2b9cfe4be486e0304732ec36928591f upstream.
+
+Since commit f8f80be501aa ("xhci: Use soft retry to recover faster from
+transaction errors"), unplugging USB device while enumeration results in
+errors like this:
+
+[ 364.855321] xhci_hcd 0000:0b:00.0: ERROR Transfer event for disabled endpoint slot 5 ep 2
+[ 364.864622] xhci_hcd 0000:0b:00.0: @0000002167656d70 67f03000 00000021 0c000000 05038001
+[ 374.934793] xhci_hcd 0000:0b:00.0: Abort failed to stop command ring: -110
+[ 374.958793] xhci_hcd 0000:0b:00.0: xHCI host controller not responding, assume dead
+[ 374.967590] xhci_hcd 0000:0b:00.0: HC died; cleaning up
+[ 374.973984] xhci_hcd 0000:0b:00.0: Timeout while waiting for configure endpoint command
+
+Seems that Etorn xHCI host can not perform Soft Retry correctly, apply
+XHCI_NO_SOFT_RETRY quirk to disable Soft Retry and then issue is gone.
+
+This patch depends on commit a4a251f8c235 ("usb: xhci: do not perform
+Soft Retry for some xHCI hosts").
+
+Fixes: f8f80be501aa ("xhci: Use soft retry to recover faster from transaction errors")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kuangyi Chiang <ki.chiang65@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241106101459.775897-21-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -405,6 +405,7 @@ static void xhci_pci_quirks(struct devic
+ pdev->device == PCI_DEVICE_ID_EJ188)) {
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+ xhci->quirks |= XHCI_BROKEN_STREAMS;
++ xhci->quirks |= XHCI_NO_SOFT_RETRY;
+ }
+
+ if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
--- /dev/null
+From 5e1c67abc9301d05130b7e267c204e7005503b33 Mon Sep 17 00:00:00 2001
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+Date: Wed, 6 Nov 2024 12:14:45 +0200
+Subject: xhci: Fix control transfer error on Etron xHCI host
+
+From: Kuangyi Chiang <ki.chiang65@gmail.com>
+
+commit 5e1c67abc9301d05130b7e267c204e7005503b33 upstream.
+
+Performing a stability stress test on a USB3.0 2.5G ethernet adapter
+results in errors like this:
+
+[ 91.441469] r8152 2-3:1.0 eth3: get_registers -71
+[ 91.458659] r8152 2-3:1.0 eth3: get_registers -71
+[ 91.475911] r8152 2-3:1.0 eth3: get_registers -71
+[ 91.493203] r8152 2-3:1.0 eth3: get_registers -71
+[ 91.510421] r8152 2-3:1.0 eth3: get_registers -71
+
+The r8152 driver will periodically issue lots of control-IN requests
+to access the status of ethernet adapter hardware registers during
+the test.
+
+This happens when the xHCI driver enqueue a control TD (which cross
+over the Link TRB between two ring segments, as shown) in the endpoint
+zero's transfer ring. Seems the Etron xHCI host can not perform this
+TD correctly, causing the USB transfer error occurred, maybe the upper
+driver retry that control-IN request can solve problem, but not all
+drivers do this.
+
+| |
+-------
+| TRB | Setup Stage
+-------
+| TRB | Link
+-------
+-------
+| TRB | Data Stage
+-------
+| TRB | Status Stage
+-------
+| |
+
+To work around this, the xHCI driver should enqueue a No Op TRB if
+next available TRB is the Link TRB in the ring segment, this can
+prevent the Setup and Data Stage TRB to be breaked by the Link TRB.
+
+Check if the XHCI_ETRON_HOST quirk flag is set before invoking the
+workaround in xhci_queue_ctrl_tx().
+
+Fixes: d0e96f5a71a0 ("USB: xhci: Control transfer support.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kuangyi Chiang <ki.chiang65@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241106101459.775897-20-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-ring.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3741,6 +3741,20 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ if (!urb->setup_packet)
+ return -EINVAL;
+
++ if ((xhci->quirks & XHCI_ETRON_HOST) &&
++ urb->dev->speed >= USB_SPEED_SUPER) {
++ /*
++ * If next available TRB is the Link TRB in the ring segment then
++ * enqueue a No Op TRB, this can prevent the Setup and Data Stage
++ * TRB to be breaked by the Link TRB.
++ */
++ if (trb_is_link(ep_ring->enqueue + 1)) {
++ field = TRB_TYPE(TRB_TR_NOOP) | ep_ring->cycle_state;
++ queue_trb(xhci, ep_ring, false, 0, 0,
++ TRB_INTR_TARGET(0), field);
++ }
++ }
++
+ /* 1 TRB for setup, 1 for status */
+ num_trbs = 2;
+ /*