--- /dev/null
+From stable+bounces-256826-greg=kroah.com@vger.kernel.org Sat May 30 01:40:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 19:38:33 -0400
+Subject: ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP 16 Piston OmniBook X
+To: stable@vger.kernel.org
+Cc: Zhang Heng <zhangheng@kylinos.cn>, Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529233833.1909329-2-sashal@kernel.org>
+
+From: Zhang Heng <zhangheng@kylinos.cn>
+
+[ Upstream commit 9e5fb6098d21e1f9be9982b46c3e5b8329d4e7d2 ]
+
+The ALC245 sound card on this machine requires the quirk
+`ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX` to fix the mic and mute LED.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221509
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
+Link: https://patch.msgid.link/20260519015535.891156-1-zhangheng@kylinos.cn
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/realtek/alc269.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/hda/codecs/realtek/alc269.c
++++ b/sound/hda/codecs/realtek/alc269.c
+@@ -7182,7 +7182,7 @@ static const struct hda_quirk alc269_fix
+ SND_PCI_QUIRK(0x103c, 0x8da0, "HP 16 Clipper OmniBook 7(X360)", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8da1, "HP 16 Clipper OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8da7, "HP 14 Enstrom OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
+- SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
++ SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX),
+ SND_PCI_QUIRK(0x103c, 0x8dc9, "HP Laptop 15-fc0xxx", ALC236_FIXUP_HP_DMIC),
+ SND_PCI_QUIRK(0x103c, 0x8dd4, "HP EliteStudio 8 AIO", ALC274_FIXUP_HP_AIO_BIND_DACS),
+ SND_PCI_QUIRK(0x103c, 0x8dd7, "HP Laptop 15-fd0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
--- /dev/null
+From stable+bounces-256825-greg=kroah.com@vger.kernel.org Sat May 30 01:44:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 19:38:32 -0400
+Subject: ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP Envy X360 15-fh0xxx
+To: stable@vger.kernel.org
+Cc: Fernando Antunez Antonio <fer.antunez24antonio@gmail.com>, Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529233833.1909329-1-sashal@kernel.org>
+
+From: Fernando Antunez Antonio <fer.antunez24antonio@gmail.com>
+
+[ Upstream commit dc1e0172be54e742bccb28d5f14c0c395e28c098 ]
+
+This enables the mute and mic-mute LEDs on the HP Envy X360 15-fh0xxx
+2-in-1 laptops.
+The quirk 'ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX' has been created and
+is now enabled for this device.
+
+This is my first patch, and I'm still getting to grips with the code,
+so there's probably a better way to implement this fix.
+I apologize for any inconvenience caused by the constant release of
+new versions of this patch.
+
+Signed-off-by: Fernando Antunez Antonio <fer.antunez24antonio@gmail.com>
+Link: https://patch.msgid.link/20260504-hpenvy-muteled-fix-v3-1-5567fd9b3d25@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 9e5fb6098d21 ("ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP 16 Piston OmniBook X")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/realtek/alc269.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/sound/hda/codecs/realtek/alc269.c
++++ b/sound/hda/codecs/realtek/alc269.c
+@@ -4132,6 +4132,7 @@ enum {
+ ALC245_FIXUP_ACER_MICMUTE_LED,
+ ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED,
+ ALC236_FIXUP_HP_DMIC,
++ ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX,
+ };
+
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -6678,6 +6679,12 @@ static const struct hda_fixup alc269_fix
+ { 0x12, 0x90a60160 }, /* use as internal mic */
+ { }
+ },
++ },
++ [ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = cs35l41_fixup_i2c_two,
++ .chained = true,
++ .chain_id = ALC245_FIXUP_HP_X360_MUTE_LEDS
+ }
+ };
+
+@@ -7096,7 +7103,7 @@ static const struct hda_quirk alc269_fix
+ SND_PCI_QUIRK(0x103c, 0x8be6, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8be7, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8be8, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
+- SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
++ SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy x360 2-in-1 Laptop 15-fh0xxx", ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX),
+ SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8c15, "HP Spectre x360 2-in-1 Laptop 14-eu0xxx", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
+ SND_PCI_QUIRK(0x103c, 0x8c16, "HP Spectre x360 2-in-1 Laptop 16-aa0xxx", ALC245_FIXUP_HP_SPECTRE_X360_16_AA0XXX),
--- /dev/null
+From stable+bounces-259315-greg=kroah.com@vger.kernel.org Sun May 31 02:24:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 20:23:54 -0400
+Subject: arm64: tlb: Flush walk cache when unsharing PMD tables
+To: stable@vger.kernel.org
+Cc: Zeng Heng <zengheng4@huawei.com>, Catalin Marinas <catalin.marinas@arm.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260531002354.3659423-1-sashal@kernel.org>
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit c2ff4764e03e7a8d758352f4aceb8fe1be6ac971 ]
+
+When huge_pmd_unshare() is called to unshare a PMD table, the
+tlb_unshare_pmd_ptdesc() function sets tlb->unshared_tables=true
+but the aarch64 tlb_flush() only checked tlb->freed_tables to
+determine whether to use TLBF_NONE (vae1is, invalidates walk
+cache) or TLBF_NOWALKCACHE (vale1is, leaf-only).
+
+This caused the stale PMD page table entry to remain in the walk cache
+after unshare, potentially leading to incorrect page table walks.
+
+Fix by including unshared_tables in the check, so that when
+unsharing tables, TLBF_NONE is used and the walk cache is properly
+invalidated.
+
+Here is the detailed distinction between vae1is and vale1is:
+
+| Instruction Combination | Actual Invalidation Scope |
+| ------------------------ | --------------------------------------------------|
+| `VAE1IS` + TTL=`0` | All entries at all levels (full invalidation) |
+| `VAE1IS` + TTL=`2` (L2) | Non-leaf at Level 0/1 + leaf at Level 2 |
+| `VALE1IS` + TTL=`0` | Leaf entries at all levels (non-leaf not cleared) |
+| `VALE1IS` + TTL=`2` (L2) | Leaf entry at Level 2 only |
+
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/tlb.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/tlb.h
++++ b/arch/arm64/include/asm/tlb.h
+@@ -53,7 +53,7 @@ static inline int tlb_get_level(struct m
+ static inline void tlb_flush(struct mmu_gather *tlb)
+ {
+ struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
+- bool last_level = !tlb->freed_tables;
++ bool last_level = !(tlb->freed_tables || tlb->unshared_tables);
+ unsigned long stride = tlb_get_unmap_size(tlb);
+ int tlb_level = tlb_get_level(tlb);
+
--- /dev/null
+From stable+bounces-259547-greg=kroah.com@vger.kernel.org Mon Jun 1 14:47:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Jun 2026 08:37:12 -0400
+Subject: hwmon: (pmbus) Add support for guarded PMBus lock
+To: stable@vger.kernel.org
+Cc: Guenter Roeck <linux@roeck-us.net>, Sanman Pradhan <psanman@juniper.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601123713.718815-1-sashal@kernel.org>
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 1814f4d3ff358277a5b6957e7f133c2812dc80ec ]
+
+Add support for guard(pmbus_lock)() and scoped_guard(pmbus_lock)()
+to be able to simplify the PMBus code.
+
+Also introduce pmbus_lock() as pre-requisite for supporting
+guard().
+
+Reviewed-by: Sanman Pradhan <psanman@juniper.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Stable-dep-of: 4e4af55aaca7 ("hwmon: (pmbus/adm1266) serialize sequencer_state debugfs read with pmbus_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwmon/pmbus/pmbus.h | 5 +++++
+ drivers/hwmon/pmbus/pmbus_core.c | 8 ++++++++
+ 2 files changed, 13 insertions(+)
+
+--- a/drivers/hwmon/pmbus/pmbus.h
++++ b/drivers/hwmon/pmbus/pmbus.h
+@@ -10,6 +10,7 @@
+ #define PMBUS_H
+
+ #include <linux/bitops.h>
++#include <linux/cleanup.h>
+ #include <linux/regulator/driver.h>
+
+ /*
+@@ -563,7 +564,11 @@ int pmbus_get_fan_rate_device(struct i2c
+ int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id,
+ enum pmbus_fan_mode mode);
+ int pmbus_lock_interruptible(struct i2c_client *client);
++void pmbus_lock(struct i2c_client *client);
+ void pmbus_unlock(struct i2c_client *client);
++
++DEFINE_GUARD(pmbus_lock, struct i2c_client *, pmbus_lock(_T), pmbus_unlock(_T))
++
+ int pmbus_update_fan(struct i2c_client *client, int page, int id,
+ u8 config, u8 mask, u16 command);
+ struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client);
+--- a/drivers/hwmon/pmbus/pmbus_core.c
++++ b/drivers/hwmon/pmbus/pmbus_core.c
+@@ -3871,6 +3871,14 @@ struct dentry *pmbus_get_debugfs_dir(str
+ }
+ EXPORT_SYMBOL_NS_GPL(pmbus_get_debugfs_dir, "PMBUS");
+
++void pmbus_lock(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++
++ mutex_lock(&data->update_lock);
++}
++EXPORT_SYMBOL_NS_GPL(pmbus_lock, "PMBUS");
++
+ int pmbus_lock_interruptible(struct i2c_client *client)
+ {
+ struct pmbus_data *data = i2c_get_clientdata(client);
--- /dev/null
+From stable+bounces-259561-greg=kroah.com@vger.kernel.org Mon Jun 1 15:41:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Jun 2026 09:36:11 -0400
+Subject: hwmon: (pmbus/adm1266) serialize GPIO PMBus accesses with pmbus_lock
+To: stable@vger.kernel.org
+Cc: Abdurrahman Hussain <abdurrahman@nexthop.ai>, Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>, Guenter Roeck <linux@roeck-us.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601133611.789541-2-sashal@kernel.org>
+
+From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+
+[ Upstream commit bab8c6fb5af8df7e753d196c1262cb78e92ca872 ]
+
+adm1266_gpio_get(), adm1266_gpio_get_multiple(), and
+adm1266_gpio_dbg_show() all issue PMBus reads against the device but
+none of them take pmbus_lock. The pmbus_core framework holds
+pmbus_lock around its own multi-transaction sequences (notably the
+"set PAGE, then read paged register" pattern used by hwmon
+attributes), so an unlocked GPIO accessor can land between a PAGE
+write and the subsequent paged read in another thread and corrupt
+either side's view of the device state machine.
+
+Take pmbus_lock at the top of each of the three accessors via the
+scope-based guard(). The lock is uncontended in the common case and
+adds only a single mutex round-trip per call.
+
+Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-6-e425e4f88139@nexthop.ai
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwmon/pmbus/adm1266.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/hwmon/pmbus/adm1266.c
++++ b/drivers/hwmon/pmbus/adm1266.c
+@@ -173,6 +173,8 @@ static int adm1266_gpio_get(struct gpio_
+ else
+ pmbus_cmd = ADM1266_PDIO_STATUS;
+
++ guard(pmbus_lock)(data->client);
++
+ ret = i2c_smbus_read_block_data(data->client, pmbus_cmd, read_buf);
+ if (ret < 0)
+ return ret;
+@@ -195,6 +197,8 @@ static int adm1266_gpio_get_multiple(str
+ unsigned int gpio_nr;
+ int ret;
+
++ guard(pmbus_lock)(data->client);
++
+ ret = i2c_smbus_read_block_data(data->client, ADM1266_GPIO_STATUS, read_buf);
+ if (ret < 0)
+ return ret;
+@@ -236,6 +240,8 @@ static void adm1266_gpio_dbg_show(struct
+ int ret;
+ int i;
+
++ guard(pmbus_lock)(data->client);
++
+ for (i = 0; i < ADM1266_GPIO_NR; i++) {
+ write_cmd = adm1266_gpio_mapping[i][1];
+ ret = adm1266_pmbus_block_xfer(data, ADM1266_GPIO_CONFIG, 1, &write_cmd, read_buf);
--- /dev/null
+From stable+bounces-259548-greg=kroah.com@vger.kernel.org Mon Jun 1 14:39:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Jun 2026 08:37:13 -0400
+Subject: hwmon: (pmbus/adm1266) serialize sequencer_state debugfs read with pmbus_lock
+To: stable@vger.kernel.org
+Cc: Abdurrahman Hussain <abdurrahman@nexthop.ai>, Guenter Roeck <linux@roeck-us.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601123713.718815-2-sashal@kernel.org>
+
+From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+
+[ Upstream commit 4e4af55aaca7f6d7673d5f9889ad0529db86a048 ]
+
+adm1266_state_read() backs the sequencer_state debugfs entry and
+issues an i2c_smbus_read_word_data(client, ADM1266_READ_STATE)
+against the device without taking pmbus_lock. pmbus_core holds
+pmbus_lock around its own multi-transaction sequences (notably the
+"set PAGE, then read paged register" pattern used by hwmon
+attributes), so an unlocked debugfs reader can land between a PAGE
+write and the subsequent paged read in another thread. READ_STATE
+itself is not paged, so it cannot corrupt PAGE in flight, but the
+same defensive serialisation that applies to the GPIO accessors
+applies here: any direct device access from outside pmbus_core
+should be ordered with respect to pmbus_core's own.
+
+Take pmbus_lock at the top of adm1266_state_read() via the
+scope-based guard().
+
+Fixes: ed1ff457e187 ("hwmon: (pmbus/adm1266) add debugfs for states")
+Cc: stable@vger.kernel.org
+Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+Link: https://lore.kernel.org/r/20260518-adm1266-gpio-fixes-v3-8-e425e4f88139@nexthop.ai
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwmon/pmbus/adm1266.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/hwmon/pmbus/adm1266.c
++++ b/drivers/hwmon/pmbus/adm1266.c
+@@ -328,6 +328,7 @@ static int adm1266_state_read(struct seq
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret;
+
++ guard(pmbus_lock)(client);
+ ret = i2c_smbus_read_word_data(client, ADM1266_READ_STATE);
+ if (ret < 0)
+ return ret;
--- /dev/null
+From stable+bounces-259391-greg=kroah.com@vger.kernel.org Mon Jun 1 02:40:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 May 2026 20:38:43 -0400
+Subject: i2c: tegra: make tegra_i2c_mutex_unlock() return void
+To: stable@vger.kernel.org
+Cc: Saurav Sachidanand <sauravsc@amazon.com>, Jon Hunter <jonathanh@nvidia.com>, Thierry Reding <treding@nvidia.com>, Andi Shyti <andi.shyti@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601003844.82662-1-sashal@kernel.org>
+
+From: Saurav Sachidanand <sauravsc@amazon.com>
+
+[ Upstream commit 30792d12842901f5276f466a960962d5bfa15cc8 ]
+
+tegra_i2c_mutex_unlock() returning an error that overwrites the transfer
+result causes silent loss of I2C transfer errors. If the transfer failed
+but the unlock succeeded, the error was lost and the function incorrectly
+reported success.
+
+Rather than propagating the unlock error (which is not actionable by the
+caller - the I2C message may have been sent regardless), convert the
+function to return void and WARN on the unexpected condition. If the
+unlock fails, subsequent lock attempts will fail anyway, making the error
+visible on the next transfer.
+
+Fixes: 6077cfd716fb ("i2c: tegra: Add support for SW mutex register")
+Signed-off-by: Saurav Sachidanand <sauravsc@amazon.com>
+Cc: <stable@vger.kernel.org> # v7.0+
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20260507221145.62183-3-sauravsc@amazon.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-tegra.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -445,25 +445,22 @@ static int tegra_i2c_mutex_lock(struct t
+ return ret;
+ }
+
+-static int tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev)
++static void tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev)
+ {
+ unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX);
+ u32 val, id;
+
+ if (!i2c_dev->hw->has_mutex)
+- return 0;
++ return;
+
+ val = readl(i2c_dev->base + reg);
+
+ id = FIELD_GET(I2C_SW_MUTEX_GRANT, val);
+- if (id && id != I2C_SW_MUTEX_ID_CCPLEX) {
+- dev_warn(i2c_dev->dev, "unable to unlock mutex, mutex is owned by: %u\n", id);
+- return -EPERM;
+- }
++ if (WARN(id && id != I2C_SW_MUTEX_ID_CCPLEX,
++ "unable to unlock mutex, mutex is owned by: %u\n", id))
++ return;
+
+ writel(0, i2c_dev->base + reg);
+-
+- return 0;
+ }
+
+ static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
+@@ -1556,7 +1553,7 @@ static int tegra_i2c_xfer(struct i2c_ada
+ break;
+ }
+
+- ret = tegra_i2c_mutex_unlock(i2c_dev);
++ tegra_i2c_mutex_unlock(i2c_dev);
+ pm_runtime_put(i2c_dev->dev);
+
+ return ret ?: i;
--- /dev/null
+From stable+bounces-256662-greg=kroah.com@vger.kernel.org Fri May 29 19:24:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 12:51:40 -0400
+Subject: platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery
+To: stable@vger.kernel.org
+Cc: "Lukas Wunner" <lukas@wunner.de>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529165140.1230013-3-sashal@kernel.org>
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 348ccc754d8939e21ca5956ff45720b81d6e407f ]
+
+After a PCIe Uncorrectable Error has been reported by a device with
+Intel Vendor Specific Extended Capabilities and has been recovered
+through a Secondary Bus Reset, its driver calls intel_vsec_pci_probe()
+to rescan and reinitialize VSECs.
+
+intel_vsec_pci_probe() invokes pcim_enable_device() and thereby adds
+another devm action which calls pcim_disable_device() on driver unbind.
+
+So once the driver unbinds, pcim_disable_device() will be called as many
+times as an Uncorrectable Error occurred, plus one. This will lead to
+an enable_cnt imbalance on driver unbind.
+
+Additionally, since commit dc957ab6aa05 ("platform/x86/intel/vsec: Add
+private data for per-device data"), a devm_kzalloc() allocation is
+leaked on every Uncorrectable Error.
+
+Avoid by splitting the VSEC rescan out of intel_vsec_pci_probe() into a
+separate helper and calling that on PCIe error recovery.
+
+Fixes: 936874b77dd0 ("platform/x86/intel/vsec: Add PCI error recovery support to Intel PMT")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v6.0+
+Link: https://patch.msgid.link/bd594d09fa866dc51dddc9a447c3b23f9b1402cc.1778736835.git.lukas@wunner.de
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c | 54 +++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 24 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -620,29 +620,13 @@ static void intel_vsec_skip_missing_depe
+ }
+ }
+
+-static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
++static int intel_vsec_pci_init(struct pci_dev *pdev)
+ {
+- const struct intel_vsec_platform_info *info;
+- struct vsec_priv *priv;
+- int num_caps, ret;
++ struct vsec_priv *priv = pci_get_drvdata(pdev);
++ const struct intel_vsec_platform_info *info = priv->info;
+ int run_once = 0;
+ bool found_any = false;
+-
+- ret = pcim_enable_device(pdev);
+- if (ret)
+- return ret;
+-
+- pci_save_state(pdev);
+- info = (const struct intel_vsec_platform_info *)id->driver_data;
+- if (!info)
+- return -EINVAL;
+-
+- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- priv->info = info;
+- pci_set_drvdata(pdev, priv);
++ int num_caps;
+
+ num_caps = hweight_long(info->caps);
+ while (num_caps--) {
+@@ -663,6 +647,31 @@ static int intel_vsec_pci_probe(struct p
+ return 0;
+ }
+
++static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
++{
++ const struct intel_vsec_platform_info *info;
++ struct vsec_priv *priv;
++ int ret;
++
++ ret = pcim_enable_device(pdev);
++ if (ret)
++ return ret;
++
++ pci_save_state(pdev);
++ info = (const struct intel_vsec_platform_info *)id->driver_data;
++ if (!info)
++ return -EINVAL;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->info = info;
++ pci_set_drvdata(pdev, priv);
++
++ return intel_vsec_pci_init(pdev);
++}
++
+ int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
+ struct intel_vsec_device *vsec_dev)
+ {
+@@ -800,7 +809,6 @@ static pci_ers_result_t intel_vsec_pci_s
+ {
+ struct intel_vsec_device *intel_vsec_dev;
+ pci_ers_result_t status = PCI_ERS_RESULT_DISCONNECT;
+- const struct pci_device_id *pci_dev_id;
+ unsigned long index;
+
+ dev_info(&pdev->dev, "Resetting PCI slot\n");
+@@ -821,10 +829,8 @@ static pci_ers_result_t intel_vsec_pci_s
+ devm_release_action(&pdev->dev, intel_vsec_remove_aux,
+ &intel_vsec_dev->auxdev);
+ }
+- pci_disable_device(pdev);
+ pci_restore_state(pdev);
+- pci_dev_id = pci_match_id(intel_vsec_pci_ids, pdev);
+- intel_vsec_pci_probe(pdev, pci_dev_id);
++ intel_vsec_pci_init(pdev);
+
+ out:
+ return status;
--- /dev/null
+From stable+bounces-256660-greg=kroah.com@vger.kernel.org Fri May 29 19:22:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 12:51:39 -0400
+Subject: platform/x86/intel/vsec: Make driver_data info const
+To: stable@vger.kernel.org
+Cc: "David E. Box" <david.e.box@linux.intel.com>, "Michael J. Ruhl" <michael.j.ruhl@intel.com>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529165140.1230013-2-sashal@kernel.org>
+
+From: "David E. Box" <david.e.box@linux.intel.com>
+
+[ Upstream commit 9577c74c96f88d807d1ba005adbf5952e7127e55 ]
+
+Treat PCI id->driver_data (intel_vsec_platform_info) as read-only by making
+vsec_priv->info a const pointer and updating all function signatures to
+accept const intel_vsec_platform_info *.
+
+This improves const-correctness and clarifies that the platform info data
+from the driver_data table is not meant to be modified at runtime.
+
+No functional changes intended.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Link: https://patch.msgid.link/20260313015202.3660072-3-david.e.box@linux.intel.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Stable-dep-of: 348ccc754d89 ("platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c | 20 ++++++++++----------
+ include/linux/intel_vsec.h | 4 ++--
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -42,7 +42,7 @@ enum vsec_device_state {
+ };
+
+ struct vsec_priv {
+- struct intel_vsec_platform_info *info;
++ const struct intel_vsec_platform_info *info;
+ struct device *suppliers[VSEC_FEATURE_COUNT];
+ struct oobmsm_plat_info plat_info;
+ enum vsec_device_state state[VSEC_FEATURE_COUNT];
+@@ -270,7 +270,7 @@ cleanup_aux:
+ EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC");
+
+ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
+- struct intel_vsec_platform_info *info,
++ const struct intel_vsec_platform_info *info,
+ unsigned long cap_id, u64 base_addr)
+ {
+ struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
+@@ -406,7 +406,7 @@ static int get_cap_id(u32 header_id, uns
+
+ static int intel_vsec_register_device(struct pci_dev *pdev,
+ struct intel_vsec_header *header,
+- struct intel_vsec_platform_info *info,
++ const struct intel_vsec_platform_info *info,
+ u64 base_addr)
+ {
+ const struct vsec_feature_dependency *consumer_deps;
+@@ -452,7 +452,7 @@ static int intel_vsec_register_device(st
+ }
+
+ static bool intel_vsec_walk_header(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info)
++ const struct intel_vsec_platform_info *info)
+ {
+ struct intel_vsec_header **header = info->headers;
+ bool have_devices = false;
+@@ -468,7 +468,7 @@ static bool intel_vsec_walk_header(struc
+ }
+
+ static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info)
++ const struct intel_vsec_platform_info *info)
+ {
+ bool have_devices = false;
+ int pos = 0;
+@@ -519,7 +519,7 @@ static bool intel_vsec_walk_dvsec(struct
+ }
+
+ static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info)
++ const struct intel_vsec_platform_info *info)
+ {
+ bool have_devices = false;
+ int pos = 0;
+@@ -565,7 +565,7 @@ static bool intel_vsec_walk_vsec(struct
+ }
+
+ int intel_vsec_register(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info)
++ const struct intel_vsec_platform_info *info)
+ {
+ if (!pdev || !info || !info->headers)
+ return -EINVAL;
+@@ -578,7 +578,7 @@ int intel_vsec_register(struct pci_dev *
+ EXPORT_SYMBOL_NS_GPL(intel_vsec_register, "INTEL_VSEC");
+
+ static bool intel_vsec_get_features(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info)
++ const struct intel_vsec_platform_info *info)
+ {
+ bool found = false;
+
+@@ -622,7 +622,7 @@ static void intel_vsec_skip_missing_depe
+
+ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+- struct intel_vsec_platform_info *info;
++ const struct intel_vsec_platform_info *info;
+ struct vsec_priv *priv;
+ int num_caps, ret;
+ int run_once = 0;
+@@ -633,7 +633,7 @@ static int intel_vsec_pci_probe(struct p
+ return ret;
+
+ pci_save_state(pdev);
+- info = (struct intel_vsec_platform_info *)id->driver_data;
++ info = (const struct intel_vsec_platform_info *)id->driver_data;
+ if (!info)
+ return -EINVAL;
+
+--- a/include/linux/intel_vsec.h
++++ b/include/linux/intel_vsec.h
+@@ -200,13 +200,13 @@ static inline struct intel_vsec_device *
+
+ #if IS_ENABLED(CONFIG_INTEL_VSEC)
+ int intel_vsec_register(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info);
++ const struct intel_vsec_platform_info *info);
+ int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
+ struct intel_vsec_device *vsec_dev);
+ struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev);
+ #else
+ static inline int intel_vsec_register(struct pci_dev *pdev,
+- struct intel_vsec_platform_info *info)
++ const struct intel_vsec_platform_info *info)
+ {
+ return -ENODEV;
+ }
--- /dev/null
+From stable+bounces-256661-greg=kroah.com@vger.kernel.org Fri May 29 19:22:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 12:51:38 -0400
+Subject: platform/x86/intel/vsec: Refactor base_addr handling
+To: stable@vger.kernel.org
+Cc: "David E. Box" <david.e.box@linux.intel.com>, "Michael J. Ruhl" <michael.j.ruhl@intel.com>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529165140.1230013-1-sashal@kernel.org>
+
+From: "David E. Box" <david.e.box@linux.intel.com>
+
+[ Upstream commit 904b333fc51cc045941df9656302449a0fc9978e ]
+
+The base_addr field in intel_vsec_platform_info was originally added to
+support devices that emulate PCI VSEC capabilities in MMIO. Previously,
+the code would check at registration time whether base_addr was set,
+falling back to the PCI BAR if not.
+
+Refactor this by making base_addr an explicit function parameter. This
+clarifies ownership of the value and removes conditional logic from
+intel_vsec_add_dev(). It also enables making intel_vsec_platform_info
+const in a later patch, since the function no longer needs to write to
+info->base_addr.
+
+No functional change intended.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Link: https://patch.msgid.link/20260313015202.3660072-2-david.e.box@linux.intel.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Stable-dep-of: 348ccc754d89 ("platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -271,14 +271,13 @@ EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux,
+
+ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
+ struct intel_vsec_platform_info *info,
+- unsigned long cap_id)
++ unsigned long cap_id, u64 base_addr)
+ {
+ struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
+ struct resource __free(kfree) *res = NULL;
+ struct resource *tmp;
+ struct device *parent;
+ unsigned long quirks = info->quirks;
+- u64 base_addr;
+ int i;
+
+ if (info->parent)
+@@ -310,11 +309,6 @@ static int intel_vsec_add_dev(struct pci
+ if (quirks & VSEC_QUIRK_TABLE_SHIFT)
+ header->offset >>= TABLE_OFFSET_SHIFT;
+
+- if (info->base_addr)
+- base_addr = info->base_addr;
+- else
+- base_addr = pdev->resource[header->tbir].start;
+-
+ /*
+ * The DVSEC/VSEC contains the starting offset and count for a block of
+ * discovery tables. Create a resource array of these tables to the
+@@ -412,7 +406,8 @@ static int get_cap_id(u32 header_id, uns
+
+ static int intel_vsec_register_device(struct pci_dev *pdev,
+ struct intel_vsec_header *header,
+- struct intel_vsec_platform_info *info)
++ struct intel_vsec_platform_info *info,
++ u64 base_addr)
+ {
+ const struct vsec_feature_dependency *consumer_deps;
+ struct vsec_priv *priv;
+@@ -428,7 +423,7 @@ static int intel_vsec_register_device(st
+ * For others using the exported APIs, add the device directly.
+ */
+ if (!pci_match_id(intel_vsec_pci_ids, pdev))
+- return intel_vsec_add_dev(pdev, header, info, cap_id);
++ return intel_vsec_add_dev(pdev, header, info, cap_id, base_addr);
+
+ priv = pci_get_drvdata(pdev);
+ if (priv->state[cap_id] == STATE_REGISTERED ||
+@@ -444,7 +439,7 @@ static int intel_vsec_register_device(st
+
+ consumer_deps = get_consumer_dependencies(priv, cap_id);
+ if (!consumer_deps || suppliers_ready(priv, consumer_deps, cap_id)) {
+- ret = intel_vsec_add_dev(pdev, header, info, cap_id);
++ ret = intel_vsec_add_dev(pdev, header, info, cap_id, base_addr);
+ if (ret)
+ priv->state[cap_id] = STATE_SKIP;
+ else
+@@ -464,7 +459,7 @@ static bool intel_vsec_walk_header(struc
+ int ret;
+
+ for ( ; *header; header++) {
+- ret = intel_vsec_register_device(pdev, *header, info);
++ ret = intel_vsec_register_device(pdev, *header, info, info->base_addr);
+ if (!ret)
+ have_devices = true;
+ }
+@@ -512,7 +507,8 @@ static bool intel_vsec_walk_dvsec(struct
+ pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr);
+ header.id = PCI_DVSEC_HEADER2_ID(hdr);
+
+- ret = intel_vsec_register_device(pdev, &header, info);
++ ret = intel_vsec_register_device(pdev, &header, info,
++ pci_resource_start(pdev, header.tbir));
+ if (ret)
+ continue;
+
+@@ -557,7 +553,8 @@ static bool intel_vsec_walk_vsec(struct
+ header.tbir = INTEL_DVSEC_TABLE_BAR(table);
+ header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
+
+- ret = intel_vsec_register_device(pdev, &header, info);
++ ret = intel_vsec_register_device(pdev, &header, info,
++ pci_resource_start(pdev, header.tbir));
+ if (ret)
+ continue;
+
--- /dev/null
+From 83f9efcce93f8574be2279090ee2aec58b86cda7 Mon Sep 17 00:00:00 2001
+From: Lorenzo Stoakes <ljs@kernel.org>
+Date: Tue, 12 May 2026 17:06:43 +0100
+Subject: Revert "mm/hugetlbfs: update hugetlbfs to use mmap_prepare"
+
+From: Lorenzo Stoakes <ljs@kernel.org>
+
+commit 83f9efcce93f8574be2279090ee2aec58b86cda7 upstream.
+
+This reverts commit ea52cb24cd3f ("mm/hugetlbfs: update hugetlbfs to use
+mmap_prepare") with conflict resolution to account for changes in commit
+ea52cb24cd3f ("mm/hugetlbfs: update hugetlbfs to use mmap_prepare").
+
+The patch incorrectly handled hugetlb VMA lock allocation at the
+mmap_prepare stage, where a failed allocation occurring after mmap_prepare
+is called might result in the lock leaking.
+
+There is no risk of a merge causing a similar issues, as
+VMA_DONTEXPAND_BIT is set for hugetlb mappings.
+
+As a first step in addressing this issue, simply revert the change so we
+can rework how we do this having corrected the underlying issues.
+
+We maintain the VMA flags changes as best we can, accounting for the fact
+that we were working with a VMA descriptor previously and propagating
+like-for-like changes for this.
+
+Note that we invoke vma_set_flags() and do not call vma_start_write() as
+vm_flags_set() does. This is OK as it's being done in an .mmap hook where
+the VMA is not yet linked into the tree so nobody else can be accessing
+it.
+
+Link: https://lore.kernel.org/20260512160643.266960-1-ljs@kernel.org
+Fixes: ea52cb24cd3f ("mm/hugetlbfs: update hugetlbfs to use mmap_prepare")
+Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>
+Reported-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Closes: https://lore.kernel.org/linux-mm/20260425070700.562229-1-25181214217@stu.xidian.edu.cn/
+Acked-by: Muchun Song <muchun.song@linux.dev>
+Acked-by: Oscar Salvador <osalvador@suse.de>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Pedro Falcato <pfalcato@suse.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hugetlbfs/inode.c | 46 +++++++-------------------
+ include/linux/hugetlb.h | 8 ----
+ include/linux/hugetlb_inline.h | 12 ------
+ mm/hugetlb.c | 71 ++++++++++++++++-------------------------
+ 4 files changed, 44 insertions(+), 93 deletions(-)
+
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -96,15 +96,8 @@ static const struct fs_parameter_spec hu
+ #define PGOFF_LOFFT_MAX \
+ (((1UL << (PAGE_SHIFT + 1)) - 1) << (BITS_PER_LONG - (PAGE_SHIFT + 1)))
+
+-static int hugetlb_file_mmap_prepare_success(const struct vm_area_struct *vma)
++static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+- /* Unfortunate we have to reassign vma->vm_private_data. */
+- return hugetlb_vma_lock_alloc((struct vm_area_struct *)vma);
+-}
+-
+-static int hugetlbfs_file_mmap_prepare(struct vm_area_desc *desc)
+-{
+- struct file *file = desc->file;
+ struct inode *inode = file_inode(file);
+ loff_t len, vma_len;
+ int ret;
+@@ -119,8 +112,8 @@ static int hugetlbfs_file_mmap_prepare(s
+ * way when do_mmap unwinds (may be important on powerpc
+ * and ia64).
+ */
+- vma_desc_set_flags(desc, VMA_HUGETLB_BIT, VMA_DONTEXPAND_BIT);
+- desc->vm_ops = &hugetlb_vm_ops;
++ vma_set_flags(vma, VMA_HUGETLB_BIT, VMA_DONTEXPAND_BIT);
++ vma->vm_ops = &hugetlb_vm_ops;
+
+ /*
+ * page based offset in vm_pgoff could be sufficiently large to
+@@ -129,16 +122,16 @@ static int hugetlbfs_file_mmap_prepare(s
+ * sizeof(unsigned long). So, only check in those instances.
+ */
+ if (sizeof(unsigned long) == sizeof(loff_t)) {
+- if (desc->pgoff & PGOFF_LOFFT_MAX)
++ if (vma->vm_pgoff & PGOFF_LOFFT_MAX)
+ return -EINVAL;
+ }
+
+ /* must be huge page aligned */
+- if (desc->pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
++ if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
+ return -EINVAL;
+
+- vma_len = (loff_t)vma_desc_size(desc);
+- len = vma_len + ((loff_t)desc->pgoff << PAGE_SHIFT);
++ vma_len = (loff_t)(vma->vm_end - vma->vm_start);
++ len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+ /* check for overflow */
+ if (len < vma_len)
+ return -EINVAL;
+@@ -148,7 +141,7 @@ static int hugetlbfs_file_mmap_prepare(s
+
+ ret = -ENOMEM;
+
+- vma_flags = desc->vma_flags;
++ vma_flags = vma->flags;
+ /*
+ * for SHM_HUGETLB, the pages are reserved in the shmget() call so skip
+ * reserving here. Note: only for SHM hugetlbfs file, the inode
+@@ -158,30 +151,17 @@ static int hugetlbfs_file_mmap_prepare(s
+ vma_flags_set(&vma_flags, VMA_NORESERVE_BIT);
+
+ if (hugetlb_reserve_pages(inode,
+- desc->pgoff >> huge_page_order(h),
+- len >> huge_page_shift(h), desc,
+- vma_flags) < 0)
++ vma->vm_pgoff >> huge_page_order(h),
++ len >> huge_page_shift(h), vma,
++ vma_flags) < 0)
+ goto out;
+
+ ret = 0;
+- if (vma_desc_test_flags(desc, VMA_WRITE_BIT) && inode->i_size < len)
++ if (vma_flags_test(&vma->flags, VMA_WRITE_BIT) && inode->i_size < len)
+ i_size_write(inode, len);
+ out:
+ inode_unlock(inode);
+
+- if (!ret) {
+- /* Allocate the VMA lock after we set it up. */
+- desc->action.success_hook = hugetlb_file_mmap_prepare_success;
+- /*
+- * We cannot permit the rmap finding this VMA in the time
+- * between the VMA being inserted into the VMA tree and the
+- * completion/success hook being invoked.
+- *
+- * This is because we establish a per-VMA hugetlb lock which can
+- * be raced by rmap.
+- */
+- desc->action.hide_from_rmap_until_complete = true;
+- }
+ return ret;
+ }
+
+@@ -1238,7 +1218,7 @@ static void init_once(void *foo)
+
+ static const struct file_operations hugetlbfs_file_operations = {
+ .read_iter = hugetlbfs_read_iter,
+- .mmap_prepare = hugetlbfs_file_mmap_prepare,
++ .mmap = hugetlbfs_file_mmap,
+ .fsync = noop_fsync,
+ .get_unmapped_area = hugetlb_get_unmapped_area,
+ .llseek = default_llseek,
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -148,7 +148,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_
+ struct folio **foliop);
+ #endif /* CONFIG_USERFAULTFD */
+ long hugetlb_reserve_pages(struct inode *inode, long from, long to,
+- struct vm_area_desc *desc, vma_flags_t vma_flags);
++ struct vm_area_struct *vma, vma_flags_t vma_flags);
+ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
+ long freed);
+ bool folio_isolate_hugetlb(struct folio *folio, struct list_head *list);
+@@ -276,7 +276,6 @@ long hugetlb_change_protection(struct vm
+ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma);
+ void fixup_hugetlb_reservations(struct vm_area_struct *vma);
+ void hugetlb_split(struct vm_area_struct *vma, unsigned long addr);
+-int hugetlb_vma_lock_alloc(struct vm_area_struct *vma);
+
+ unsigned int arch_hugetlb_cma_order(void);
+
+@@ -469,11 +468,6 @@ static inline void fixup_hugetlb_reserva
+
+ static inline void hugetlb_split(struct vm_area_struct *vma, unsigned long addr) {}
+
+-static inline int hugetlb_vma_lock_alloc(struct vm_area_struct *vma)
+-{
+- return 0;
+-}
+-
+ #endif /* !CONFIG_HUGETLB_PAGE */
+
+ #ifndef pgd_write
+--- a/include/linux/hugetlb_inline.h
++++ b/include/linux/hugetlb_inline.h
+@@ -6,11 +6,6 @@
+
+ #ifdef CONFIG_HUGETLB_PAGE
+
+-static inline bool is_vm_hugetlb_flags(vm_flags_t vm_flags)
+-{
+- return !!(vm_flags & VM_HUGETLB);
+-}
+-
+ static inline bool is_vma_hugetlb_flags(const vma_flags_t *flags)
+ {
+ return vma_flags_test(flags, VMA_HUGETLB_BIT);
+@@ -18,11 +13,6 @@ static inline bool is_vma_hugetlb_flags(
+
+ #else
+
+-static inline bool is_vm_hugetlb_flags(vm_flags_t vm_flags)
+-{
+- return false;
+-}
+-
+ static inline bool is_vma_hugetlb_flags(const vma_flags_t *flags)
+ {
+ return false;
+@@ -32,7 +22,7 @@ static inline bool is_vma_hugetlb_flags(
+
+ static inline bool is_vm_hugetlb_page(const struct vm_area_struct *vma)
+ {
+- return is_vm_hugetlb_flags(vma->vm_flags);
++ return is_vma_hugetlb_flags(&vma->flags);
+ }
+
+ #endif
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -116,6 +116,7 @@ struct mutex *hugetlb_fault_mutex_table
+ /* Forward declaration */
+ static int hugetlb_acct_memory(struct hstate *h, long delta);
+ static void hugetlb_vma_lock_free(struct vm_area_struct *vma);
++static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma);
+ static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma);
+ static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end, bool take_locks);
+@@ -413,21 +414,17 @@ static void hugetlb_vma_lock_free(struct
+ }
+ }
+
+-/*
+- * vma specific semaphore used for pmd sharing and fault/truncation
+- * synchronization
+- */
+-int hugetlb_vma_lock_alloc(struct vm_area_struct *vma)
++static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma)
+ {
+ struct hugetlb_vma_lock *vma_lock;
+
+ /* Only establish in (flags) sharable vmas */
+ if (!vma || !(vma->vm_flags & VM_MAYSHARE))
+- return 0;
++ return;
+
+ /* Should never get here with non-NULL vm_private_data */
+ if (vma->vm_private_data)
+- return -EINVAL;
++ return;
+
+ vma_lock = kmalloc_obj(*vma_lock);
+ if (!vma_lock) {
+@@ -442,15 +439,13 @@ int hugetlb_vma_lock_alloc(struct vm_are
+ * allocation failure.
+ */
+ pr_warn_once("HugeTLB: unable to allocate vma specific lock\n");
+- return -EINVAL;
++ return;
+ }
+
+ kref_init(&vma_lock->refs);
+ init_rwsem(&vma_lock->rw_sema);
+ vma_lock->vma = vma;
+ vma->vm_private_data = vma_lock;
+-
+- return 0;
+ }
+
+ /* Helper that removes a struct file_region from the resv_map cache and returns
+@@ -1183,28 +1178,20 @@ static struct resv_map *vma_resv_map(str
+ }
+ }
+
+-static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags)
++static void set_vma_resv_map(struct vm_area_struct *vma, struct resv_map *map)
+ {
+ VM_WARN_ON_ONCE_VMA(!is_vm_hugetlb_page(vma), vma);
+- VM_WARN_ON_ONCE_VMA(vma->vm_flags & VM_MAYSHARE, vma);
++ VM_WARN_ON_ONCE_VMA(vma_flags_test(&vma->flags, VMA_MAYSHARE_BIT), vma);
+
+- set_vma_private_data(vma, get_vma_private_data(vma) | flags);
++ set_vma_private_data(vma, (unsigned long)map);
+ }
+
+-static void set_vma_desc_resv_map(struct vm_area_desc *desc, struct resv_map *map)
+-{
+- VM_WARN_ON_ONCE(!is_vma_hugetlb_flags(&desc->vma_flags));
+- VM_WARN_ON_ONCE(vma_desc_test_flags(desc, VMA_MAYSHARE_BIT));
+-
+- desc->private_data = map;
+-}
+-
+-static void set_vma_desc_resv_flags(struct vm_area_desc *desc, unsigned long flags)
++static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags)
+ {
+- VM_WARN_ON_ONCE(!is_vma_hugetlb_flags(&desc->vma_flags));
+- VM_WARN_ON_ONCE(vma_desc_test_flags(desc, VMA_MAYSHARE_BIT));
++ VM_WARN_ON_ONCE_VMA(!is_vm_hugetlb_page(vma), vma);
++ VM_WARN_ON_ONCE_VMA(vma_flags_test(&vma->flags, VMA_MAYSHARE_BIT), vma);
+
+- desc->private_data = (void *)((unsigned long)desc->private_data | flags);
++ set_vma_private_data(vma, get_vma_private_data(vma) | flags);
+ }
+
+ static int is_vma_resv_set(struct vm_area_struct *vma, unsigned long flag)
+@@ -1214,13 +1201,6 @@ static int is_vma_resv_set(struct vm_are
+ return (get_vma_private_data(vma) & flag) != 0;
+ }
+
+-static bool is_vma_desc_resv_set(struct vm_area_desc *desc, unsigned long flag)
+-{
+- VM_WARN_ON_ONCE(!is_vma_hugetlb_flags(&desc->vma_flags));
+-
+- return ((unsigned long)desc->private_data) & flag;
+-}
+-
+ bool __vma_private_lock(struct vm_area_struct *vma)
+ {
+ return !(vma->vm_flags & VM_MAYSHARE) &&
+@@ -6572,7 +6552,7 @@ next:
+
+ long hugetlb_reserve_pages(struct inode *inode,
+ long from, long to,
+- struct vm_area_desc *desc,
++ struct vm_area_struct *vma,
+ vma_flags_t vma_flags)
+ {
+ long chg = -1, add = -1, spool_resv, gbl_resv;
+@@ -6590,6 +6570,12 @@ long hugetlb_reserve_pages(struct inode
+ }
+
+ /*
++ * vma specific semaphore used for pmd sharing and fault/truncation
++ * synchronization
++ */
++ hugetlb_vma_lock_alloc(vma);
++
++ /*
+ * Only apply hugepage reservation if asked. At fault time, an
+ * attempt will be made for VM_NORESERVE to allocate a page
+ * without using reserves
+@@ -6601,9 +6587,9 @@ long hugetlb_reserve_pages(struct inode
+ * Shared mappings base their reservation on the number of pages that
+ * are already allocated on behalf of the file. Private mappings need
+ * to reserve the full area even if read-only as mprotect() may be
+- * called to make the mapping read-write. Assume !desc is a shm mapping
++ * called to make the mapping read-write. Assume !vma is a shm mapping
+ */
+- if (!desc || vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)) {
++ if (!vma || vma_flags_test(&vma->flags, VMA_MAYSHARE_BIT)) {
+ /*
+ * resv_map can not be NULL as hugetlb_reserve_pages is only
+ * called for inodes for which resv_maps were created (see
+@@ -6622,8 +6608,8 @@ long hugetlb_reserve_pages(struct inode
+
+ chg = to - from;
+
+- set_vma_desc_resv_map(desc, resv_map);
+- set_vma_desc_resv_flags(desc, HPAGE_RESV_OWNER);
++ set_vma_resv_map(vma, resv_map);
++ set_vma_resv_flags(vma, HPAGE_RESV_OWNER);
+ }
+
+ if (chg < 0) {
+@@ -6637,7 +6623,7 @@ long hugetlb_reserve_pages(struct inode
+ if (err < 0)
+ goto out_err;
+
+- if (desc && !vma_desc_test_flags(desc, VMA_MAYSHARE_BIT) && h_cg) {
++ if (vma && !vma_flags_test(&vma->flags, VMA_MAYSHARE_BIT) && h_cg) {
+ /* For private mappings, the hugetlb_cgroup uncharge info hangs
+ * of the resv_map.
+ */
+@@ -6674,7 +6660,7 @@ long hugetlb_reserve_pages(struct inode
+ * consumed reservations are stored in the map. Hence, nothing
+ * else has to be done for private mappings here
+ */
+- if (!desc || vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)) {
++ if (!vma || vma_flags_test(&vma->flags, VMA_MAYSHARE_BIT)) {
+ add = region_add(resv_map, from, to, regions_needed, h, h_cg);
+
+ if (unlikely(add < 0)) {
+@@ -6738,15 +6724,16 @@ out_uncharge_cgroup:
+ hugetlb_cgroup_uncharge_cgroup_rsvd(hstate_index(h),
+ chg * pages_per_huge_page(h), h_cg);
+ out_err:
+- if (!desc || vma_desc_test_flags(desc, VMA_MAYSHARE_BIT))
++ hugetlb_vma_lock_free(vma);
++ if (!vma || vma_flags_test(&vma->flags, VMA_MAYSHARE_BIT))
+ /* Only call region_abort if the region_chg succeeded but the
+ * region_add failed or didn't run.
+ */
+ if (chg >= 0 && add < 0)
+ region_abort(resv_map, from, to, regions_needed);
+- if (desc && is_vma_desc_resv_set(desc, HPAGE_RESV_OWNER)) {
++ if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) {
+ kref_put(&resv_map->refs, resv_map_release);
+- set_vma_desc_resv_map(desc, NULL);
++ set_vma_resv_map(vma, NULL);
+ }
+ return err;
+ }
--- /dev/null
+From stable+bounces-256685-greg=kroah.com@vger.kernel.org Fri May 29 20:02:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:50:22 -0400
+Subject: rxrpc: Fix RESPONSE packet verification to extract skb to a linear buffer
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Hyunwoo Kim <imv4bel@gmail.com>, Simon Horman <horms@kernel.org>, Jiayuan Chen <jiayuan.chen@linux.dev>, linux-afs@lists.infradead.org, stable@kernel.org, Jeffrey Altman <jaltman@auristor.com>, Marc Dionne <marc.dionne@auristor.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529175022.1450013-3-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 8bfab4b6ffc2fe92da86300728fc8c3c7ebffb56 ]
+
+This improves the fix for CVE-2026-43500.
+
+Fix the verification of RESPONSE packets to avoid the problem of
+overwriting a RESPONSE packet sent via splice to a local address by
+extracting the contents of the UDP packet into a kmalloc'd linear buffer
+rather than decrypting the data in place in the sk_buff (which may corrupt
+the original buffer).
+
+Fixes: 24481a7f5733 ("rxrpc: Fix conn-level packet handling to unshare RESPONSE packets")
+Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
+Closes: https://lore.kernel.org/r/afKV2zGR6rrelPC7@v4bel/
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Simon Horman <horms@kernel.org>
+cc: Jiayuan Chen <jiayuan.chen@linux.dev>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+Tested-by: Marc Dionne <marc.dionne@auristor.com>
+Link: https://patch.msgid.link/20260515230516.2718212-4-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/ar-internal.h | 7 ++-
+ net/rxrpc/conn_event.c | 30 ++++++---------
+ net/rxrpc/insecure.c | 5 +-
+ net/rxrpc/rxgk.c | 96 +++++++++++++++---------------------------------
+ net/rxrpc/rxgk_app.c | 46 +++++++++--------------
+ net/rxrpc/rxgk_common.h | 92 +---------------------------------------------
+ net/rxrpc/rxkad.c | 29 +++++---------
+ 7 files changed, 81 insertions(+), 224 deletions(-)
+
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -307,15 +307,16 @@ struct rxrpc_security {
+ struct sk_buff *challenge);
+
+ /* verify a response */
+- int (*verify_response)(struct rxrpc_connection *,
+- struct sk_buff *);
++ int (*verify_response)(struct rxrpc_connection *conn,
++ struct sk_buff *response_skb,
++ void *response, unsigned int len);
+
+ /* clear connection security */
+ void (*clear)(struct rxrpc_connection *);
+
+ /* Default ticket -> key decoder */
+ int (*default_decode_ticket)(struct rxrpc_connection *conn, struct sk_buff *skb,
+- unsigned int ticket_offset, unsigned int ticket_len,
++ void *ticket, unsigned int ticket_len,
+ struct key **_key);
+ };
+
+--- a/net/rxrpc/conn_event.c
++++ b/net/rxrpc/conn_event.c
+@@ -243,28 +243,22 @@ static void rxrpc_call_is_secure(struct
+ static int rxrpc_verify_response(struct rxrpc_connection *conn,
+ struct sk_buff *skb)
+ {
++ unsigned int len = skb->len - sizeof(struct rxrpc_wire_header);
++ void *buffer;
+ int ret;
+
+- if (skb_cloned(skb) || skb_has_frag_list(skb) ||
+- skb_has_shared_frag(skb)) {
+- /* Copy the packet if shared so that we can do in-place
+- * decryption.
+- */
+- struct sk_buff *nskb = skb_copy(skb, GFP_NOFS);
++ buffer = kmalloc(len, GFP_NOFS);
++ if (!buffer)
++ return -ENOMEM;
+
+- if (nskb) {
+- rxrpc_new_skb(nskb, rxrpc_skb_new_unshared);
+- ret = conn->security->verify_response(conn, nskb);
+- rxrpc_free_skb(nskb, rxrpc_skb_put_response_copy);
+- } else {
+- /* OOM - Drop the packet. */
+- rxrpc_see_skb(skb, rxrpc_skb_see_unshare_nomem);
+- ret = -ENOMEM;
+- }
+- } else {
+- ret = conn->security->verify_response(conn, skb);
+- }
++ ret = skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), buffer, len);
++ if (ret < 0)
++ goto out;
+
++ ret = conn->security->verify_response(conn, skb, buffer, len);
++
++out:
++ kfree(buffer);
+ return ret;
+ }
+
+--- a/net/rxrpc/insecure.c
++++ b/net/rxrpc/insecure.c
+@@ -54,9 +54,10 @@ static int none_sendmsg_respond_to_chall
+ }
+
+ static int none_verify_response(struct rxrpc_connection *conn,
+- struct sk_buff *skb)
++ struct sk_buff *response_skb,
++ void *response, unsigned int len)
+ {
+- return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO,
++ return rxrpc_abort_conn(conn, response_skb, RX_PROTOCOL_ERROR, -EPROTO,
+ rxrpc_eproto_rxnull_response);
+ }
+
+--- a/net/rxrpc/rxgk.c
++++ b/net/rxrpc/rxgk.c
+@@ -1084,11 +1084,12 @@ static int rxgk_sendmsg_respond_to_chall
+ * unsigned int call_numbers<>;
+ * };
+ */
+-static int rxgk_do_verify_authenticator(struct rxrpc_connection *conn,
+- const struct krb5_enctype *krb5,
+- struct sk_buff *skb,
+- __be32 *p, __be32 *end)
++static int rxgk_verify_authenticator(struct rxrpc_connection *conn,
++ const struct krb5_enctype *krb5,
++ struct sk_buff *skb,
++ void *auth, unsigned int auth_len)
+ {
++ __be32 *p = auth, *end = auth + auth_len;
+ u32 app_len, call_count, level, epoch, cid, i;
+
+ _enter("");
+@@ -1152,37 +1153,6 @@ static int rxgk_do_verify_authenticator(
+ }
+
+ /*
+- * Extract the authenticator and verify it.
+- */
+-static int rxgk_verify_authenticator(struct rxrpc_connection *conn,
+- const struct krb5_enctype *krb5,
+- struct sk_buff *skb,
+- unsigned int auth_offset, unsigned int auth_len)
+-{
+- void *auth;
+- __be32 *p;
+- int ret;
+-
+- auth = kmalloc(auth_len, GFP_NOFS);
+- if (!auth)
+- return -ENOMEM;
+-
+- ret = skb_copy_bits(skb, auth_offset, auth, auth_len);
+- if (ret < 0) {
+- ret = rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO,
+- rxgk_abort_resp_short_auth);
+- goto error;
+- }
+-
+- p = auth;
+- ret = rxgk_do_verify_authenticator(conn, krb5, skb, p,
+- p + auth_len / sizeof(*p));
+-error:
+- kfree(auth);
+- return ret;
+-}
+-
+-/*
+ * Verify a response.
+ *
+ * struct RXGK_Response {
+@@ -1192,49 +1162,45 @@ error:
+ * };
+ */
+ static int rxgk_verify_response(struct rxrpc_connection *conn,
+- struct sk_buff *skb)
++ struct sk_buff *skb,
++ void *buffer, unsigned int len)
+ {
+ const struct krb5_enctype *krb5;
+ struct rxrpc_key_token *token;
+ struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+- struct rxgk_response rhdr;
++ struct rxgk_response *rhdr;
+ struct rxgk_context *gk;
+ struct key *key = NULL;
+- unsigned int offset = sizeof(struct rxrpc_wire_header);
+- unsigned int len = skb->len - sizeof(struct rxrpc_wire_header);
+- unsigned int token_offset, token_len;
+- unsigned int auth_offset, auth_len;
++ unsigned int resp_token_len, auth_len;
++ void *resp_token, *auth;
+ __be32 xauth_len;
+ int ret, ec;
+
+ _enter("{%d}", conn->debug_id);
+
+ /* Parse the RXGK_Response object */
+- if (sizeof(rhdr) + sizeof(__be32) > len)
++ if (len < sizeof(*rhdr) + sizeof(__be32))
+ goto short_packet;
+-
+- if (skb_copy_bits(skb, offset, &rhdr, sizeof(rhdr)) < 0)
+- goto short_packet;
+- offset += sizeof(rhdr);
+- len -= sizeof(rhdr);
+-
+- token_offset = offset;
+- token_len = ntohl(rhdr.token_len);
+- if (token_len > len ||
+- xdr_round_up(token_len) + sizeof(__be32) > len)
++ rhdr = buffer;
++ buffer += sizeof(*rhdr);
++ len -= sizeof(*rhdr);
++
++ resp_token = buffer;
++ resp_token_len = ntohl(rhdr->token_len);
++ if (resp_token_len > len ||
++ xdr_round_up(resp_token_len) + sizeof(__be32) > len)
+ goto short_packet;
+
+- trace_rxrpc_rx_response(conn, sp->hdr.serial, 0, sp->hdr.cksum, token_len);
++ trace_rxrpc_rx_response(conn, sp->hdr.serial, 0, sp->hdr.cksum, resp_token_len);
+
+- offset += xdr_round_up(token_len);
+- len -= xdr_round_up(token_len);
++ buffer += xdr_round_up(resp_token_len);
++ len -= xdr_round_up(resp_token_len);
+
+- if (skb_copy_bits(skb, offset, &xauth_len, sizeof(xauth_len)) < 0)
+- goto short_packet;
+- offset += sizeof(xauth_len);
++ xauth_len = *(__be32 *)buffer;
++ buffer += sizeof(xauth_len);
+ len -= sizeof(xauth_len);
+
+- auth_offset = offset;
++ auth = buffer;
+ auth_len = ntohl(xauth_len);
+ if (auth_len > len)
+ goto short_packet;
+@@ -1249,7 +1215,7 @@ static int rxgk_verify_response(struct r
+ * to the app to deal with - which might mean a round trip to
+ * userspace.
+ */
+- ret = rxgk_extract_token(conn, skb, token_offset, token_len, &key);
++ ret = rxgk_extract_token(conn, skb, resp_token, resp_token_len, &key);
+ if (ret < 0)
+ goto out;
+
+@@ -1263,7 +1229,7 @@ static int rxgk_verify_response(struct r
+ */
+ token = key->payload.data[0];
+ conn->security_level = token->rxgk->level;
+- conn->rxgk.start_time = __be64_to_cpu(rhdr.start_time);
++ conn->rxgk.start_time = __be64_to_cpu(rhdr->start_time);
+
+ gk = rxgk_generate_transport_key(conn, token->rxgk, sp->hdr.cksum, GFP_NOFS);
+ if (IS_ERR(gk)) {
+@@ -1273,18 +1239,18 @@ static int rxgk_verify_response(struct r
+
+ krb5 = gk->krb5;
+
+- trace_rxrpc_rx_response(conn, sp->hdr.serial, krb5->etype, sp->hdr.cksum, token_len);
++ trace_rxrpc_rx_response(conn, sp->hdr.serial, krb5->etype, sp->hdr.cksum,
++ resp_token_len);
+
+ /* Decrypt, parse and verify the authenticator. */
+- ret = rxgk_decrypt_skb(krb5, gk->resp_enc, skb,
+- &auth_offset, &auth_len, &ec);
++ ret = rxgk_decrypt(krb5, gk->resp_enc, &auth, &auth_len, &ec);
+ if (ret < 0) {
+ rxrpc_abort_conn(conn, skb, RXGK_SEALEDINCON, ret,
+ rxgk_abort_resp_auth_dec);
+ goto out_gk;
+ }
+
+- ret = rxgk_verify_authenticator(conn, krb5, skb, auth_offset, auth_len);
++ ret = rxgk_verify_authenticator(conn, krb5, skb, auth, auth_len);
+ if (ret < 0)
+ goto out_gk;
+
+--- a/net/rxrpc/rxgk_app.c
++++ b/net/rxrpc/rxgk_app.c
+@@ -40,7 +40,7 @@
+ * };
+ */
+ int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb,
+- unsigned int ticket_offset, unsigned int ticket_len,
++ void *buffer, unsigned int ticket_len,
+ struct key **_key)
+ {
+ struct rxrpc_key_token *token;
+@@ -49,7 +49,7 @@ int rxgk_yfs_decode_ticket(struct rxrpc_
+ size_t pre_ticket_len, payload_len;
+ unsigned int klen, enctype;
+ void *payload, *ticket;
+- __be32 *t, *p, *q, tmp[2];
++ __be32 *t, *p, *q, *tmp;
+ int ret;
+
+ _enter("");
+@@ -59,10 +59,7 @@ int rxgk_yfs_decode_ticket(struct rxrpc_
+ rxgk_abort_resp_short_yfs_tkt);
+
+ /* Get the session key length */
+- ret = skb_copy_bits(skb, ticket_offset, tmp, sizeof(tmp));
+- if (ret < 0)
+- return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
+- rxgk_abort_resp_short_yfs_klen);
++ tmp = buffer;
+ enctype = ntohl(tmp[0]);
+ klen = ntohl(tmp[1]);
+
+@@ -84,12 +81,7 @@ int rxgk_yfs_decode_ticket(struct rxrpc_
+ * it.
+ */
+ ticket = payload + pre_ticket_len;
+- ret = skb_copy_bits(skb, ticket_offset, ticket, ticket_len);
+- if (ret < 0) {
+- ret = rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
+- rxgk_abort_resp_short_yfs_tkt);
+- goto error;
+- }
++ memcpy(ticket, buffer, ticket_len);
+
+ /* Fill out the form header. */
+ p = payload;
+@@ -131,7 +123,7 @@ int rxgk_yfs_decode_ticket(struct rxrpc_
+ goto error;
+ }
+
+- /* Ticket read in with skb_copy_bits above */
++ /* Ticket appended above. */
+ q += xdr_round_up(ticket_len) / 4;
+ if (WARN_ON((unsigned long)q - (unsigned long)payload != payload_len)) {
+ ret = -EIO;
+@@ -182,14 +174,15 @@ error:
+ * [tools.ietf.org/html/draft-wilkinson-afs3-rxgk-afs-08 sec 6.1]
+ */
+ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
+- unsigned int token_offset, unsigned int token_len,
++ void *token, unsigned int token_len,
+ struct key **_key)
+ {
+ const struct krb5_enctype *krb5;
+ const struct krb5_buffer *server_secret;
+ struct crypto_aead *token_enc = NULL;
+ struct key *server_key;
+- unsigned int ticket_offset, ticket_len;
++ unsigned int ticket_len;
++ void *ticket;
+ u32 kvno, enctype;
+ int ret, ec = 0;
+
+@@ -197,24 +190,23 @@ int rxgk_extract_token(struct rxrpc_conn
+ __be32 kvno;
+ __be32 enctype;
+ __be32 token_len;
+- } container;
++ } *container;
+
+- if (token_len < sizeof(container))
++ if (token_len < sizeof(*container))
+ goto short_packet;
+
+ /* Decode the RXGK_TokenContainer object. This tells us which server
+ * key we should be using. We can then fetch the key, get the secret
+ * and set up the crypto to extract the token.
+ */
+- if (skb_copy_bits(skb, token_offset, &container, sizeof(container)) < 0)
+- goto short_packet;
++ container = token;
++ token += sizeof(*container);
+
+- kvno = ntohl(container.kvno);
+- enctype = ntohl(container.enctype);
+- ticket_len = ntohl(container.token_len);
+- ticket_offset = token_offset + sizeof(container);
++ kvno = ntohl(container->kvno);
++ enctype = ntohl(container->enctype);
++ ticket_len = ntohl(container->token_len);
+
+- if (ticket_len > xdr_round_down(token_len - sizeof(container)))
++ if (ticket_len > xdr_round_down(token_len - sizeof(*container)))
+ goto short_packet;
+
+ _debug("KVNO %u", kvno);
+@@ -237,8 +229,8 @@ int rxgk_extract_token(struct rxrpc_conn
+ * gain access to K0, from which we can derive the transport key and
+ * thence decode the authenticator.
+ */
+- ret = rxgk_decrypt_skb(krb5, token_enc, skb,
+- &ticket_offset, &ticket_len, &ec);
++ ticket = token;
++ ret = rxgk_decrypt(krb5, token_enc, &ticket, &ticket_len, &ec);
+ crypto_free_aead(token_enc);
+ token_enc = NULL;
+ if (ret < 0) {
+@@ -248,7 +240,7 @@ int rxgk_extract_token(struct rxrpc_conn
+ return ret;
+ }
+
+- ret = conn->security->default_decode_ticket(conn, skb, ticket_offset,
++ ret = conn->security->default_decode_ticket(conn, skb, ticket,
+ ticket_len, _key);
+ if (ret < 0)
+ goto cant_get_token;
+--- a/net/rxrpc/rxgk_common.h
++++ b/net/rxrpc/rxgk_common.h
+@@ -41,10 +41,10 @@ struct rxgk_context {
+ * rxgk_app.c
+ */
+ int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb,
+- unsigned int ticket_offset, unsigned int ticket_len,
++ void *ticket, unsigned int ticket_len,
+ struct key **_key);
+ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
+- unsigned int token_offset, unsigned int token_len,
++ void *token, unsigned int token_len,
+ struct key **_key);
+
+ /*
+@@ -62,50 +62,6 @@ int rxgk_set_up_token_cipher(const struc
+ gfp_t gfp);
+
+ /*
+- * Apply decryption and checksumming functions to part of an skbuff. The
+- * offset and length are updated to reflect the actual content of the encrypted
+- * region.
+- */
+-static inline
+-int rxgk_decrypt_skb(const struct krb5_enctype *krb5,
+- struct crypto_aead *aead,
+- struct sk_buff *skb,
+- unsigned int *_offset, unsigned int *_len,
+- int *_error_code)
+-{
+- struct scatterlist sg[16];
+- size_t offset = 0, len = *_len;
+- int nr_sg, ret;
+-
+- sg_init_table(sg, ARRAY_SIZE(sg));
+- nr_sg = skb_to_sgvec(skb, sg, *_offset, len);
+- if (unlikely(nr_sg < 0))
+- return nr_sg;
+-
+- ret = crypto_krb5_decrypt(krb5, aead, sg, nr_sg,
+- &offset, &len);
+- switch (ret) {
+- case 0:
+- *_offset += offset;
+- *_len = len;
+- break;
+- case -EBADMSG: /* Checksum mismatch. */
+- case -EPROTO:
+- *_error_code = RXGK_SEALEDINCON;
+- break;
+- case -EMSGSIZE:
+- *_error_code = RXGK_PACKETSHORT;
+- break;
+- case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */
+- default:
+- *_error_code = RXGK_INCONSISTENCY;
+- break;
+- }
+-
+- return ret;
+-}
+-
+-/*
+ * Apply decryption and checksumming functions a flat data buffer. The data
+ * point and length are updated to reflect the actual content of the encrypted
+ * region.
+@@ -136,50 +92,6 @@ static inline int rxgk_decrypt(const str
+ case -EPROTO:
+ *_error_code = RXGK_SEALEDINCON;
+ break;
+- case -EMSGSIZE:
+- *_error_code = RXGK_PACKETSHORT;
+- break;
+- case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */
+- default:
+- *_error_code = RXGK_INCONSISTENCY;
+- break;
+- }
+-
+- return ret;
+-}
+-
+-/*
+- * Check the MIC on a region of an skbuff. The offset and length are updated
+- * to reflect the actual content of the secure region.
+- */
+-static inline
+-int rxgk_verify_mic_skb(const struct krb5_enctype *krb5,
+- struct crypto_shash *shash,
+- const struct krb5_buffer *metadata,
+- struct sk_buff *skb,
+- unsigned int *_offset, unsigned int *_len,
+- u32 *_error_code)
+-{
+- struct scatterlist sg[16];
+- size_t offset = 0, len = *_len;
+- int nr_sg, ret;
+-
+- sg_init_table(sg, ARRAY_SIZE(sg));
+- nr_sg = skb_to_sgvec(skb, sg, *_offset, len);
+- if (unlikely(nr_sg < 0))
+- return nr_sg;
+-
+- ret = crypto_krb5_verify_mic(krb5, shash, metadata, sg, nr_sg,
+- &offset, &len);
+- switch (ret) {
+- case 0:
+- *_offset += offset;
+- *_len = len;
+- break;
+- case -EBADMSG: /* Checksum mismatch */
+- case -EPROTO:
+- *_error_code = RXGK_SEALEDINCON;
+- break;
+ case -EMSGSIZE:
+ *_error_code = RXGK_PACKETSHORT;
+ break;
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -963,7 +963,6 @@ static int rxkad_decrypt_ticket(struct r
+ *_expiry = 0;
+
+ ASSERT(server_key->payload.data[0] != NULL);
+- ASSERTCMP((unsigned long) ticket & 7UL, ==, 0);
+
+ memcpy(&iv, &server_key->payload.data[2], sizeof(iv));
+
+@@ -1112,14 +1111,15 @@ unlock:
+ * verify a response
+ */
+ static int rxkad_verify_response(struct rxrpc_connection *conn,
+- struct sk_buff *skb)
++ struct sk_buff *skb,
++ void *buffer, unsigned int len)
+ {
+ struct rxkad_response *response;
+ struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+ struct rxrpc_crypt session_key;
+ struct key *server_key;
+ time64_t expiry;
+- void *ticket = NULL;
++ void *ticket;
+ u32 version, kvno, ticket_len, level;
+ __be32 csum;
+ int ret, i;
+@@ -1142,13 +1142,8 @@ static int rxkad_verify_response(struct
+ }
+ }
+
+- ret = -ENOMEM;
+- response = kzalloc_obj(struct rxkad_response, GFP_NOFS);
+- if (!response)
+- goto error;
+-
+- if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
+- response, sizeof(*response)) < 0) {
++ response = buffer;
++ if (len < sizeof(*response)) {
+ ret = rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+ rxkad_abort_resp_short);
+ goto error;
+@@ -1160,6 +1155,9 @@ static int rxkad_verify_response(struct
+
+ trace_rxrpc_rx_response(conn, sp->hdr.serial, version, kvno, ticket_len);
+
++ buffer += sizeof(*response);
++ len -= sizeof(*response);
++
+ if (version != RXKAD_VERSION) {
+ ret = rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO,
+ rxkad_abort_resp_version);
+@@ -1179,13 +1177,8 @@ static int rxkad_verify_response(struct
+ }
+
+ /* extract the kerberos ticket and decrypt and decode it */
+- ret = -ENOMEM;
+- ticket = kmalloc(ticket_len, GFP_NOFS);
+- if (!ticket)
+- goto error;
+-
+- if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header) + sizeof(*response),
+- ticket, ticket_len) < 0) {
++ ticket = buffer;
++ if (ticket_len > len) {
+ ret = rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+ rxkad_abort_resp_short_tkt);
+ goto error;
+@@ -1265,8 +1258,6 @@ static int rxkad_verify_response(struct
+ ret = rxrpc_get_server_data_key(conn, &session_key, expiry, kvno);
+
+ error:
+- kfree(ticket);
+- kfree(response);
+ key_put(server_key);
+ _leave(" = %d", ret);
+ return ret;
serial-core-introduce-guard-uart_port_lock_check_sysrq_irqsave.patch
serial-8250-dispatch-sysrq-character-in-serial8250_handle_irq.patch
serial-8250_dw-dispatch-sysrq-character-in-dw8250_handle_irq.patch
+revert-mm-hugetlbfs-update-hugetlbfs-to-use-mmap_prepare.patch
+platform-x86-intel-vsec-refactor-base_addr-handling.patch
+platform-x86-intel-vsec-make-driver_data-info-const.patch
+platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
+rxrpc-fix-response-packet-verification-to-extract-skb-to-a-linear-buffer.patch
+alsa-hda-realtek-fix-mute-and-mic-mute-leds-for-hp-envy-x360-15-fh0xxx.patch
+alsa-hda-realtek-fix-mute-and-mic-mute-leds-for-hp-16-piston-omnibook-x.patch
+arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
+i2c-tegra-make-tegra_i2c_mutex_unlock-return-void.patch
+hwmon-pmbus-add-support-for-guarded-pmbus-lock.patch
+hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch
+hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch