]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Apr 2026 16:54:58 +0000 (10:54 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Apr 2026 16:54:58 +0000 (10:54 -0600)
added patches:
arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
device-property-make-modifications-of-fwnode-flags-thread-safe.patch
driver-core-don-t-let-a-device-probe-until-it-s-ready.patch
drm-nouveau-fix-nvkm_device-leak-on-aperture-removal-failure.patch
drm-nouveau-fix-u32-overflow-in-pushbuf-reloc-bounds-check.patch
firmware-google-framebuffer-do-not-mark-framebuffer-as-busy.patch
fs-afs-revert-mmap_prepare-change.patch
greybus-gb-beagleplay-bound-bootloader-receive-buffering.patch
greybus-gb-beagleplay-fix-sleep-in-atomic-context-in-hdlc_tx_frames.patch
ibmasm-fix-heap-over-read-in-ibmasm_send_i2o_message.patch
ibmasm-fix-oob-reads-in-command_file_write-due-to-missing-size-checks.patch
kbuild-rust-allow-clippy-uninlined_format_args.patch
leds-qcom-lpg-check-for-array-overflow-when-selecting-the-high-resolution.patch
loongarch-add-spectre-boundry-for-syscall-dispatch-table.patch
misc-ibmasm-fix-oob-mmio-read-in-ibmasm_handle_mouse_interrupt.patch
mm-migrate-requeue-destination-folio-on-deferred-split-queue.patch
rust-dma-remove-dma_attr_no_kernel_mapping-from-public-attrs.patch

18 files changed:
queue-6.18/arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch [new file with mode: 0644]
queue-6.18/device-property-make-modifications-of-fwnode-flags-thread-safe.patch [new file with mode: 0644]
queue-6.18/driver-core-don-t-let-a-device-probe-until-it-s-ready.patch [new file with mode: 0644]
queue-6.18/drm-nouveau-fix-nvkm_device-leak-on-aperture-removal-failure.patch [new file with mode: 0644]
queue-6.18/drm-nouveau-fix-u32-overflow-in-pushbuf-reloc-bounds-check.patch [new file with mode: 0644]
queue-6.18/firmware-google-framebuffer-do-not-mark-framebuffer-as-busy.patch [new file with mode: 0644]
queue-6.18/fs-afs-revert-mmap_prepare-change.patch [new file with mode: 0644]
queue-6.18/greybus-gb-beagleplay-bound-bootloader-receive-buffering.patch [new file with mode: 0644]
queue-6.18/greybus-gb-beagleplay-fix-sleep-in-atomic-context-in-hdlc_tx_frames.patch [new file with mode: 0644]
queue-6.18/ibmasm-fix-heap-over-read-in-ibmasm_send_i2o_message.patch [new file with mode: 0644]
queue-6.18/ibmasm-fix-oob-reads-in-command_file_write-due-to-missing-size-checks.patch [new file with mode: 0644]
queue-6.18/kbuild-rust-allow-clippy-uninlined_format_args.patch [new file with mode: 0644]
queue-6.18/leds-qcom-lpg-check-for-array-overflow-when-selecting-the-high-resolution.patch [new file with mode: 0644]
queue-6.18/loongarch-add-spectre-boundry-for-syscall-dispatch-table.patch [new file with mode: 0644]
queue-6.18/misc-ibmasm-fix-oob-mmio-read-in-ibmasm_handle_mouse_interrupt.patch [new file with mode: 0644]
queue-6.18/mm-migrate-requeue-destination-folio-on-deferred-split-queue.patch [new file with mode: 0644]
queue-6.18/rust-dma-remove-dma_attr_no_kernel_mapping-from-public-attrs.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch b/queue-6.18/arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
new file mode 100644 (file)
index 0000000..92ecfe4
--- /dev/null
@@ -0,0 +1,132 @@
+From 48478b9f791376b4b89018d7afdfd06865498f65 Mon Sep 17 00:00:00 2001
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+Date: Mon, 9 Mar 2026 02:57:24 +0000
+Subject: arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+commit 48478b9f791376b4b89018d7afdfd06865498f65 upstream.
+
+During a memory hot remove operation, both linear and vmemmap mappings for
+the memory range being removed, get unmapped via unmap_hotplug_range() but
+mapped pages get freed only for vmemmap mapping. This is just a sequential
+operation where each table entry gets cleared, followed by a leaf specific
+TLB flush, and then followed by memory free operation when applicable.
+
+This approach was simple and uniform both for vmemmap and linear mappings.
+But linear mapping might contain CONT marked block memory where it becomes
+necessary to first clear out all entire in the range before a TLB flush.
+This is as per the architecture requirement. Hence batch all TLB flushes
+during the table tear down walk and finally do it in unmap_hotplug_range().
+
+Prior to this fix, it was hypothetically possible for a speculative access
+to a higher address in the contiguous block to fill the TLB with shattered
+entries for the entire contiguous range after a lower address had already
+been cleared and invalidated. Due to the table entries being shattered, the
+subsequent TLB invalidation for the higher address would not then clear the
+TLB entries for the lower address, meaning stale TLB entries could persist.
+
+Besides it also helps in improving the performance via TLBI range operation
+along with reduced synchronization instructions. The time spent executing
+unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
+in KVM guest.
+
+This scheme is not applicable during vmemmap mapping tear down where memory
+needs to be freed and hence a TLB flush is required after clearing out page
+table entry.
+
+Cc: Will Deacon <will@kernel.org>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
+Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
+Cc: stable@vger.kernel.org
+Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
+Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/mm/mmu.c |   36 ++++++++++++++++++++----------------
+ 1 file changed, 20 insertions(+), 16 deletions(-)
+
+--- a/arch/arm64/mm/mmu.c
++++ b/arch/arm64/mm/mmu.c
+@@ -1465,10 +1465,14 @@ static void unmap_hotplug_pte_range(pmd_
+               WARN_ON(!pte_present(pte));
+               __pte_clear(&init_mm, addr, ptep);
+-              flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+-              if (free_mapped)
++              if (free_mapped) {
++                      /* CONT blocks are not supported in the vmemmap */
++                      WARN_ON(pte_cont(pte));
++                      flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+                       free_hotplug_page_range(pte_page(pte),
+                                               PAGE_SIZE, altmap);
++              }
++              /* unmap_hotplug_range() flushes TLB for !free_mapped */
+       } while (addr += PAGE_SIZE, addr < end);
+ }
+@@ -1489,15 +1493,14 @@ static void unmap_hotplug_pmd_range(pud_
+               WARN_ON(!pmd_present(pmd));
+               if (pmd_sect(pmd)) {
+                       pmd_clear(pmdp);
+-
+-                      /*
+-                       * One TLBI should be sufficient here as the PMD_SIZE
+-                       * range is mapped with a single block entry.
+-                       */
+-                      flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+-                      if (free_mapped)
++                      if (free_mapped) {
++                              /* CONT blocks are not supported in the vmemmap */
++                              WARN_ON(pmd_cont(pmd));
++                              flush_tlb_kernel_range(addr, addr + PMD_SIZE);
+                               free_hotplug_page_range(pmd_page(pmd),
+                                                       PMD_SIZE, altmap);
++                      }
++                      /* unmap_hotplug_range() flushes TLB for !free_mapped */
+                       continue;
+               }
+               WARN_ON(!pmd_table(pmd));
+@@ -1522,15 +1525,12 @@ static void unmap_hotplug_pud_range(p4d_
+               WARN_ON(!pud_present(pud));
+               if (pud_sect(pud)) {
+                       pud_clear(pudp);
+-
+-                      /*
+-                       * One TLBI should be sufficient here as the PUD_SIZE
+-                       * range is mapped with a single block entry.
+-                       */
+-                      flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+-                      if (free_mapped)
++                      if (free_mapped) {
++                              flush_tlb_kernel_range(addr, addr + PUD_SIZE);
+                               free_hotplug_page_range(pud_page(pud),
+                                                       PUD_SIZE, altmap);
++                      }
++                      /* unmap_hotplug_range() flushes TLB for !free_mapped */
+                       continue;
+               }
+               WARN_ON(!pud_table(pud));
+@@ -1560,6 +1560,7 @@ static void unmap_hotplug_p4d_range(pgd_
+ static void unmap_hotplug_range(unsigned long addr, unsigned long end,
+                               bool free_mapped, struct vmem_altmap *altmap)
+ {
++      unsigned long start = addr;
+       unsigned long next;
+       pgd_t *pgdp, pgd;
+@@ -1581,6 +1582,9 @@ static void unmap_hotplug_range(unsigned
+               WARN_ON(!pgd_present(pgd));
+               unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
+       } while (addr = next, addr < end);
++
++      if (!free_mapped)
++              flush_tlb_kernel_range(start, end);
+ }
+ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
diff --git a/queue-6.18/device-property-make-modifications-of-fwnode-flags-thread-safe.patch b/queue-6.18/device-property-make-modifications-of-fwnode-flags-thread-safe.patch
new file mode 100644 (file)
index 0000000..4efe655
--- /dev/null
@@ -0,0 +1,312 @@
+From f72e77c33e4b5657af35125e75bab249256030f3 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Tue, 17 Mar 2026 09:01:20 -0700
+Subject: device property: Make modifications of fwnode "flags" thread safe
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit f72e77c33e4b5657af35125e75bab249256030f3 upstream.
+
+In various places in the kernel, we modify the fwnode "flags" member
+by doing either:
+  fwnode->flags |= SOME_FLAG;
+  fwnode->flags &= ~SOME_FLAG;
+
+This type of modification is not thread-safe. If two threads are both
+mucking with the flags at the same time then one can clobber the
+other.
+
+While flags are often modified while under the "fwnode_link_lock",
+this is not universally true.
+
+Create some accessor functions for setting, clearing, and testing the
+FWNODE flags and move all users to these accessor functions. New
+accessor functions use set_bit() and clear_bit(), which are
+thread-safe.
+
+Cc: stable@vger.kernel.org
+Fixes: c2c724c868c4 ("driver core: Add fw_devlink_parse_fwtree()")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
+Reviewed-by: Saravana Kannan <saravanak@kernel.org>
+Link: https://patch.msgid.link/20260317090112.v2.1.I0a4d03104ecd5103df3d76f66c8d21b1d15a2e38@changeid
+[ Fix fwnode_clear_flag() argument alignment, restore dropped blank
+  line in fwnode_dev_initialized(), and remove unnecessary parentheses
+  around fwnode_test_flag() calls. - Danilo ]
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c                 |   24 +++++++++----------
+ drivers/bus/imx-weim.c              |    2 -
+ drivers/i2c/i2c-core-of.c           |    2 -
+ drivers/net/phy/mdio_bus_provider.c |    4 +--
+ drivers/of/base.c                   |    2 -
+ drivers/of/dynamic.c                |    2 -
+ drivers/of/platform.c               |    2 -
+ drivers/spi/spi.c                   |    2 -
+ include/linux/fwnode.h              |   44 +++++++++++++++++++++++++++---------
+ 9 files changed, 53 insertions(+), 31 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -182,7 +182,7 @@ void fw_devlink_purge_absent_suppliers(s
+       if (fwnode->dev)
+               return;
+-      fwnode->flags |= FWNODE_FLAG_NOT_DEVICE;
++      fwnode_set_flag(fwnode, FWNODE_FLAG_NOT_DEVICE);
+       fwnode_links_purge_consumers(fwnode);
+       fwnode_for_each_available_child_node(fwnode, child)
+@@ -228,7 +228,7 @@ static void __fw_devlink_pickup_dangling
+       if (fwnode->dev && fwnode->dev->bus)
+               return;
+-      fwnode->flags |= FWNODE_FLAG_NOT_DEVICE;
++      fwnode_set_flag(fwnode, FWNODE_FLAG_NOT_DEVICE);
+       __fwnode_links_move_consumers(fwnode, new_sup);
+       fwnode_for_each_available_child_node(fwnode, child)
+@@ -1012,7 +1012,7 @@ static void device_links_missing_supplie
+ static bool dev_is_best_effort(struct device *dev)
+ {
+       return (fw_devlink_best_effort && dev->can_match) ||
+-              (dev->fwnode && (dev->fwnode->flags & FWNODE_FLAG_BEST_EFFORT));
++              (dev->fwnode && fwnode_test_flag(dev->fwnode, FWNODE_FLAG_BEST_EFFORT));
+ }
+ static struct fwnode_handle *fwnode_links_check_suppliers(
+@@ -1723,11 +1723,11 @@ bool fw_devlink_is_strict(void)
+ static void fw_devlink_parse_fwnode(struct fwnode_handle *fwnode)
+ {
+-      if (fwnode->flags & FWNODE_FLAG_LINKS_ADDED)
++      if (fwnode_test_flag(fwnode, FWNODE_FLAG_LINKS_ADDED))
+               return;
+       fwnode_call_int_op(fwnode, add_links);
+-      fwnode->flags |= FWNODE_FLAG_LINKS_ADDED;
++      fwnode_set_flag(fwnode, FWNODE_FLAG_LINKS_ADDED);
+ }
+ static void fw_devlink_parse_fwtree(struct fwnode_handle *fwnode)
+@@ -1885,7 +1885,7 @@ static bool fwnode_init_without_drv(stru
+       struct device *dev;
+       bool ret;
+-      if (!(fwnode->flags & FWNODE_FLAG_INITIALIZED))
++      if (!fwnode_test_flag(fwnode, FWNODE_FLAG_INITIALIZED))
+               return false;
+       dev = get_dev_from_fwnode(fwnode);
+@@ -2001,10 +2001,10 @@ static bool __fw_devlink_relax_cycles(st
+        * We aren't trying to find all cycles. Just a cycle between con and
+        * sup_handle.
+        */
+-      if (sup_handle->flags & FWNODE_FLAG_VISITED)
++      if (fwnode_test_flag(sup_handle, FWNODE_FLAG_VISITED))
+               return false;
+-      sup_handle->flags |= FWNODE_FLAG_VISITED;
++      fwnode_set_flag(sup_handle, FWNODE_FLAG_VISITED);
+       /* Termination condition. */
+       if (sup_handle == con_handle) {
+@@ -2074,7 +2074,7 @@ static bool __fw_devlink_relax_cycles(st
+       }
+ out:
+-      sup_handle->flags &= ~FWNODE_FLAG_VISITED;
++      fwnode_clear_flag(sup_handle, FWNODE_FLAG_VISITED);
+       put_device(sup_dev);
+       put_device(con_dev);
+       put_device(par_dev);
+@@ -2127,7 +2127,7 @@ static int fw_devlink_create_devlink(str
+        * When such a flag is set, we can't create device links where P is the
+        * supplier of C as that would delay the probe of C.
+        */
+-      if (sup_handle->flags & FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD &&
++      if (fwnode_test_flag(sup_handle, FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD) &&
+           fwnode_is_ancestor_of(sup_handle, con->fwnode))
+               return -EINVAL;
+@@ -2150,7 +2150,7 @@ static int fw_devlink_create_devlink(str
+       else
+               flags = FW_DEVLINK_FLAGS_PERMISSIVE;
+-      if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE)
++      if (fwnode_test_flag(sup_handle, FWNODE_FLAG_NOT_DEVICE))
+               sup_dev = fwnode_get_next_parent_dev(sup_handle);
+       else
+               sup_dev = get_dev_from_fwnode(sup_handle);
+@@ -2162,7 +2162,7 @@ static int fw_devlink_create_devlink(str
+                * supplier device indefinitely.
+                */
+               if (sup_dev->links.status == DL_DEV_NO_DRIVER &&
+-                  sup_handle->flags & FWNODE_FLAG_INITIALIZED) {
++                  fwnode_test_flag(sup_handle, FWNODE_FLAG_INITIALIZED)) {
+                       dev_dbg(con,
+                               "Not linking %pfwf - dev might never probe\n",
+                               sup_handle);
+--- a/drivers/bus/imx-weim.c
++++ b/drivers/bus/imx-weim.c
+@@ -332,7 +332,7 @@ static int of_weim_notify(struct notifie
+                        * fw_devlink doesn't skip adding consumers to this
+                        * device.
+                        */
+-                      rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
++                      fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
+                       if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
+                               dev_err(&pdev->dev,
+                                       "Failed to create child device '%pOF'\n",
+--- a/drivers/i2c/i2c-core-of.c
++++ b/drivers/i2c/i2c-core-of.c
+@@ -180,7 +180,7 @@ static int of_i2c_notify(struct notifier
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+-              rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
++              fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
+               client = of_i2c_register_device(adap, rd->dn);
+               if (IS_ERR(client)) {
+                       dev_err(&adap->dev, "failed to create client for '%pOF'\n",
+--- a/drivers/net/phy/mdio_bus_provider.c
++++ b/drivers/net/phy/mdio_bus_provider.c
+@@ -299,8 +299,8 @@ int __mdiobus_register(struct mii_bus *b
+               return -EINVAL;
+       if (bus->parent && bus->parent->of_node)
+-              bus->parent->of_node->fwnode.flags |=
+-                                      FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD;
++              fwnode_set_flag(&bus->parent->of_node->fwnode,
++                              FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD);
+       WARN(bus->state != MDIOBUS_ALLOCATED &&
+            bus->state != MDIOBUS_UNREGISTERED,
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -1868,7 +1868,7 @@ void of_alias_scan(void * (*dt_alloc)(u6
+               if (name)
+                       of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
+               if (of_stdout)
+-                      of_stdout->fwnode.flags |= FWNODE_FLAG_BEST_EFFORT;
++                      fwnode_set_flag(&of_stdout->fwnode, FWNODE_FLAG_BEST_EFFORT);
+       }
+       if (!of_aliases)
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -225,7 +225,7 @@ static void __of_attach_node(struct devi
+       np->sibling = np->parent->child;
+       np->parent->child = np;
+       of_node_clear_flag(np, OF_DETACHED);
+-      np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
++      fwnode_set_flag(&np->fwnode, FWNODE_FLAG_NOT_DEVICE);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -743,7 +743,7 @@ static int of_platform_notify(struct not
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+-              rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
++              fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
+               /* pdev_parent may be NULL when no bus platform device */
+               pdev_parent = of_find_device_by_node(parent);
+               pdev = of_platform_device_create(rd->dn, NULL,
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -4801,7 +4801,7 @@ static int of_spi_notify(struct notifier
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+-              rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
++              fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
+               spi = of_register_spi_device(ctlr, rd->dn);
+               put_device(&ctlr->dev);
+--- a/include/linux/fwnode.h
++++ b/include/linux/fwnode.h
+@@ -15,6 +15,7 @@
+ #define _LINUX_FWNODE_H_
+ #include <linux/bits.h>
++#include <linux/bitops.h>
+ #include <linux/err.h>
+ #include <linux/list.h>
+ #include <linux/types.h>
+@@ -42,12 +43,12 @@ struct device;
+  *            suppliers. Only enforce ordering with suppliers that have
+  *            drivers.
+  */
+-#define FWNODE_FLAG_LINKS_ADDED                       BIT(0)
+-#define FWNODE_FLAG_NOT_DEVICE                        BIT(1)
+-#define FWNODE_FLAG_INITIALIZED                       BIT(2)
+-#define FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD  BIT(3)
+-#define FWNODE_FLAG_BEST_EFFORT                       BIT(4)
+-#define FWNODE_FLAG_VISITED                   BIT(5)
++#define FWNODE_FLAG_LINKS_ADDED                       0
++#define FWNODE_FLAG_NOT_DEVICE                        1
++#define FWNODE_FLAG_INITIALIZED                       2
++#define FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD  3
++#define FWNODE_FLAG_BEST_EFFORT                       4
++#define FWNODE_FLAG_VISITED                   5
+ struct fwnode_handle {
+       struct fwnode_handle *secondary;
+@@ -57,7 +58,7 @@ struct fwnode_handle {
+       struct device *dev;
+       struct list_head suppliers;
+       struct list_head consumers;
+-      u8 flags;
++      unsigned long flags;
+ };
+ /*
+@@ -212,16 +213,37 @@ static inline void fwnode_init(struct fw
+       INIT_LIST_HEAD(&fwnode->suppliers);
+ }
++static inline void fwnode_set_flag(struct fwnode_handle *fwnode,
++                                 unsigned int bit)
++{
++      set_bit(bit, &fwnode->flags);
++}
++
++static inline void fwnode_clear_flag(struct fwnode_handle *fwnode,
++                                   unsigned int bit)
++{
++      clear_bit(bit, &fwnode->flags);
++}
++
++static inline void fwnode_assign_flag(struct fwnode_handle *fwnode,
++                                    unsigned int bit, bool value)
++{
++      assign_bit(bit, &fwnode->flags, value);
++}
++
++static inline bool fwnode_test_flag(struct fwnode_handle *fwnode,
++                                  unsigned int bit)
++{
++      return test_bit(bit, &fwnode->flags);
++}
++
+ static inline void fwnode_dev_initialized(struct fwnode_handle *fwnode,
+                                         bool initialized)
+ {
+       if (IS_ERR_OR_NULL(fwnode))
+               return;
+-      if (initialized)
+-              fwnode->flags |= FWNODE_FLAG_INITIALIZED;
+-      else
+-              fwnode->flags &= ~FWNODE_FLAG_INITIALIZED;
++      fwnode_assign_flag(fwnode, FWNODE_FLAG_INITIALIZED, initialized);
+ }
+ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup,
diff --git a/queue-6.18/driver-core-don-t-let-a-device-probe-until-it-s-ready.patch b/queue-6.18/driver-core-don-t-let-a-device-probe-until-it-s-ready.patch
new file mode 100644 (file)
index 0000000..164a8c0
--- /dev/null
@@ -0,0 +1,214 @@
+From a2225b6e834a838ae3c93709760edc0a169eb2f2 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Mon, 6 Apr 2026 16:22:54 -0700
+Subject: driver core: Don't let a device probe until it's ready
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit a2225b6e834a838ae3c93709760edc0a169eb2f2 upstream.
+
+The moment we link a "struct device" into the list of devices for the
+bus, it's possible probe can happen. This is because another thread
+can load the driver at any time and that can cause the device to
+probe. This has been seen in practice with a stack crawl that looks
+like this [1]:
+
+  really_probe()
+  __driver_probe_device()
+  driver_probe_device()
+  __driver_attach()
+  bus_for_each_dev()
+  driver_attach()
+  bus_add_driver()
+  driver_register()
+  __platform_driver_register()
+  init_module() [some module]
+  do_one_initcall()
+  do_init_module()
+  load_module()
+  __arm64_sys_finit_module()
+  invoke_syscall()
+
+As a result of the above, it was seen that device_links_driver_bound()
+could be called for the device before "dev->fwnode->dev" was
+assigned. This prevented __fw_devlink_pickup_dangling_consumers() from
+being called which meant that other devices waiting on our driver's
+sub-nodes were stuck deferring forever.
+
+It's believed that this problem is showing up suddenly for two
+reasons:
+1. Android has recently (last ~1 year) implemented an optimization to
+   the order it loads modules [2]. When devices opt-in to this faster
+   loading, modules are loaded one-after-the-other very quickly. This
+   is unlike how other distributions do it. The reproduction of this
+   problem has only been seen on devices that opt-in to Android's
+   "parallel module loading".
+2. Android devices typically opt-in to fw_devlink, and the most
+   noticeable issue is the NULL "dev->fwnode->dev" in
+   device_links_driver_bound(). fw_devlink is somewhat new code and
+   also not in use by all Linux devices.
+
+Even though the specific symptom where "dev->fwnode->dev" wasn't
+assigned could be fixed by moving that assignment higher in
+device_add(), other parts of device_add() (like the call to
+device_pm_add()) are also important to run before probe. Only moving
+the "dev->fwnode->dev" assignment would likely fix the current
+symptoms but lead to difficult-to-debug problems in the future.
+
+Fix the problem by preventing probe until device_add() has run far
+enough that the device is ready to probe. If somehow we end up trying
+to probe before we're allowed, __driver_probe_device() will return
+-EPROBE_DEFER which will make certain the device is noticed.
+
+In the race condition that was seen with Android's faster module
+loading, we will temporarily add the device to the deferred list and
+then take it off immediately when device_add() probes the device.
+
+Instead of adding another flag to the bitfields already in "struct
+device", instead add a new "flags" field and use that. This allows us
+to freely change the bit from different thread without worrying about
+corrupting nearby bits (and means threads changing other bit won't
+corrupt us).
+
+[1] Captured on a machine running a downstream 6.6 kernel
+[2] https://cs.android.com/android/platform/superproject/main/+/main:system/core/libmodprobe/libmodprobe.cpp?q=LoadModulesParallel
+
+Cc: stable@vger.kernel.org
+Fixes: 2023c610dc54 ("Driver core: add new device to bus's list before probing")
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
+Reviewed-by: Danilo Krummrich <dakr@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patch.msgid.link/20260406162231.v5.1.Id750b0fbcc94f23ed04b7aecabcead688d0d8c17@changeid
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c    |   15 +++++++++++++++
+ drivers/base/dd.c      |   20 ++++++++++++++++++++
+ include/linux/device.h |   44 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 79 insertions(+)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -3688,6 +3688,21 @@ int device_add(struct device *dev)
+               fw_devlink_link_device(dev);
+       }
++      /*
++       * The moment the device was linked into the bus's "klist_devices" in
++       * bus_add_device() then it's possible that probe could have been
++       * attempted in a different thread via userspace loading a driver
++       * matching the device. "ready_to_probe" being unset would have
++       * blocked those attempts. Now that all of the above initialization has
++       * happened, unblock probe. If probe happens through another thread
++       * after this point but before bus_probe_device() runs then it's fine.
++       * bus_probe_device() -> device_initial_probe() -> __device_attach()
++       * will notice (under device_lock) that the device is already bound.
++       */
++      device_lock(dev);
++      dev_set_ready_to_probe(dev);
++      device_unlock(dev);
++
+       bus_probe_device(dev);
+       /*
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -846,6 +846,26 @@ static int __driver_probe_device(const s
+       if (dev->driver)
+               return -EBUSY;
++      /*
++       * In device_add(), the "struct device" gets linked into the subsystem's
++       * list of devices and broadcast to userspace (via uevent) before we're
++       * quite ready to probe. Those open pathways to driver probe before
++       * we've finished enough of device_add() to reliably support probe.
++       * Detect this and tell other pathways to try again later. device_add()
++       * itself will also try to probe immediately after setting
++       * "ready_to_probe".
++       */
++      if (!dev_ready_to_probe(dev))
++              return dev_err_probe(dev, -EPROBE_DEFER, "Device not ready to probe\n");
++
++      /*
++       * Set can_match = true after calling dev_ready_to_probe(), so
++       * driver_deferred_probe_add() won't actually add the device to the
++       * deferred probe list when dev_ready_to_probe() returns false.
++       *
++       * When dev_ready_to_probe() returns false, it means that device_add()
++       * will do another probe() attempt for us.
++       */
+       dev->can_match = true;
+       dev_dbg(dev, "bus: '%s': %s: matched device with driver %s\n",
+               drv->bus->name, __func__, drv->name);
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -478,6 +478,21 @@ struct device_physical_location {
+ };
+ /**
++ * enum struct_device_flags - Flags in struct device
++ *
++ * Each flag should have a set of accessor functions created via
++ * __create_dev_flag_accessors() for each access.
++ *
++ * @DEV_FLAG_READY_TO_PROBE: If set then device_add() has finished enough
++ *            initialization that probe could be called.
++ */
++enum struct_device_flags {
++      DEV_FLAG_READY_TO_PROBE = 0,
++
++      DEV_FLAG_COUNT
++};
++
++/**
+  * struct device - The basic device structure
+  * @parent:   The device's "parent" device, the device to which it is attached.
+  *            In most cases, a parent device is some sort of bus or host
+@@ -572,6 +587,7 @@ struct device_physical_location {
+  * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers.
+  * @dma_iommu: Device is using default IOMMU implementation for DMA and
+  *            doesn't rely on dma_ops structure.
++ * @flags:    DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
+  *
+  * At the lowest level, every device in a Linux system is represented by an
+  * instance of struct device. The device structure contains the information
+@@ -694,8 +710,36 @@ struct device {
+ #ifdef CONFIG_IOMMU_DMA
+       bool                    dma_iommu:1;
+ #endif
++
++      DECLARE_BITMAP(flags, DEV_FLAG_COUNT);
+ };
++#define __create_dev_flag_accessors(accessor_name, flag_name) \
++static inline bool dev_##accessor_name(const struct device *dev) \
++{ \
++      return test_bit(flag_name, dev->flags); \
++} \
++static inline void dev_set_##accessor_name(struct device *dev) \
++{ \
++      set_bit(flag_name, dev->flags); \
++} \
++static inline void dev_clear_##accessor_name(struct device *dev) \
++{ \
++      clear_bit(flag_name, dev->flags); \
++} \
++static inline void dev_assign_##accessor_name(struct device *dev, bool value) \
++{ \
++      assign_bit(flag_name, dev->flags, value); \
++} \
++static inline bool dev_test_and_set_##accessor_name(struct device *dev) \
++{ \
++      return test_and_set_bit(flag_name, dev->flags); \
++}
++
++__create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE);
++
++#undef __create_dev_flag_accessors
++
+ /**
+  * struct device_link - Device link representation.
+  * @supplier: The device on the supplier end of the link.
diff --git a/queue-6.18/drm-nouveau-fix-nvkm_device-leak-on-aperture-removal-failure.patch b/queue-6.18/drm-nouveau-fix-nvkm_device-leak-on-aperture-removal-failure.patch
new file mode 100644 (file)
index 0000000..7b2e7d8
--- /dev/null
@@ -0,0 +1,40 @@
+From 6597ff1d8de3f583be169587efeafd8af134e138 Mon Sep 17 00:00:00 2001
+From: David Carlier <devnexen@gmail.com>
+Date: Sat, 11 Apr 2026 07:29:38 +0100
+Subject: drm/nouveau: fix nvkm_device leak on aperture removal failure
+
+From: David Carlier <devnexen@gmail.com>
+
+commit 6597ff1d8de3f583be169587efeafd8af134e138 upstream.
+
+When aperture_remove_conflicting_pci_devices() fails during probe, the
+error path returns directly without unwinding the nvkm_device that was
+just allocated by nvkm_device_pci_new(). This leaks both the device
+wrapper and the pci_enable_device() reference taken inside it.
+
+Jump to the existing fail_nvkm label so nvkm_device_del() runs and
+balances both. The leak was introduced when the intermediate
+nvkm_device_del() between detection and aperture removal was dropped
+in favor of creating the pci device once.
+
+Fixes: c0bfe34330b5 ("drm/nouveau: create pci device once")
+Cc: stable@vger.kernel.org
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Link: https://patch.msgid.link/20260411062938.22925-1-devnexen@gmail.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/nouveau_drm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
+@@ -874,7 +874,7 @@ static int nouveau_drm_probe(struct pci_
+       /* Remove conflicting drivers (vesafb, efifb etc). */
+       ret = aperture_remove_conflicting_pci_devices(pdev, driver_pci.name);
+       if (ret)
+-              return ret;
++              goto fail_nvkm;
+       pci_set_master(pdev);
diff --git a/queue-6.18/drm-nouveau-fix-u32-overflow-in-pushbuf-reloc-bounds-check.patch b/queue-6.18/drm-nouveau-fix-u32-overflow-in-pushbuf-reloc-bounds-check.patch
new file mode 100644 (file)
index 0000000..dbff604
--- /dev/null
@@ -0,0 +1,49 @@
+From 2fc87d37be1b730a149b035f9375fdb8cc5333a5 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Mon, 20 Apr 2026 21:16:09 +0200
+Subject: drm/nouveau: fix u32 overflow in pushbuf reloc bounds check
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 2fc87d37be1b730a149b035f9375fdb8cc5333a5 upstream.
+
+nouveau_gem_pushbuf_reloc_apply() validates each relocation with
+
+    if (r->reloc_bo_offset + 4 > nvbo->bo.base.size)
+
+but reloc_bo_offset is __u32 (uapi/drm/nouveau_drm.h) and the integer
+literal 4 promotes to unsigned int, so the addition is performed in 32
+bits and wraps before the comparison against the size_t bo size.
+
+Cast to u64 so the addition happens in 64-bit arithmetic.
+
+Cc: Lyude Paul <lyude@redhat.com>
+Cc: Danilo Krummrich <dakr@kernel.org>
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: Maxime Ripard <mripard@kernel.org>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: David Airlie <airlied@gmail.com>
+Cc: Simona Vetter <simona@ffwll.ch>
+Reported-by: Anthropic
+Cc: stable <stable@kernel.org>
+Assisted-by: gkh_clanker_t1000
+Fixes: a1606a9596e5 ("drm/nouveau: new gem pushbuf interface, bump to 0.0.16")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ Add Fixes: tag. - Danilo ]
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/nouveau_gem.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
+@@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct n
+               }
+               nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
+-              if (unlikely(r->reloc_bo_offset + 4 >
++              if (unlikely((u64)r->reloc_bo_offset + 4 >
+                            nvbo->bo.base.size)) {
+                       NV_PRINTK(err, cli, "reloc outside of bo\n");
+                       ret = -EINVAL;
diff --git a/queue-6.18/firmware-google-framebuffer-do-not-mark-framebuffer-as-busy.patch b/queue-6.18/firmware-google-framebuffer-do-not-mark-framebuffer-as-busy.patch
new file mode 100644 (file)
index 0000000..b2bc47b
--- /dev/null
@@ -0,0 +1,47 @@
+From f3850d399de3b6142b02315227ef9e772ed0c302 Mon Sep 17 00:00:00 2001
+From: Thomas Zimmermann <tzimmermann@suse.de>
+Date: Tue, 17 Feb 2026 16:56:12 +0100
+Subject: firmware: google: framebuffer: Do not mark framebuffer as busy
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+commit f3850d399de3b6142b02315227ef9e772ed0c302 upstream.
+
+Remove the flag IORESOURCE_BUSY flag from coreboot's framebuffer
+resource. It prevents simpledrm from successfully requesting the
+range for its own use; resulting in errors such as
+
+[    2.775430] simple-framebuffer simple-framebuffer.0: [drm] could not acquire memory region [mem 0x80000000-0x80407fff flags 0x80000200]
+
+As with other uses of simple-framebuffer, the simple-framebuffer
+device should only declare it's I/O resources, but not actively use
+them.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: 851b4c14532d ("firmware: coreboot: Add coreboot framebuffer driver")
+Acked-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Acked-by: Julius Werner <jwerner@chromium.org>
+Cc: Samuel Holland <samuel@sholland.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Tzung-Bi Shih <tzungbi@kernel.org>
+Cc: Brian Norris <briannorris@chromium.org>
+Cc: Julius Werner <jwerner@chromium.org>
+Cc: chrome-platform@lists.linux.dev
+Cc: <stable@vger.kernel.org> # v4.18+
+Link: https://patch.msgid.link/20260217155836.96267-3-tzimmermann@suse.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/google/framebuffer-coreboot.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/firmware/google/framebuffer-coreboot.c
++++ b/drivers/firmware/google/framebuffer-coreboot.c
+@@ -67,7 +67,7 @@ static int framebuffer_probe(struct core
+               return -ENODEV;
+       memset(&res, 0, sizeof(res));
+-      res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++      res.flags = IORESOURCE_MEM;
+       res.name = "Coreboot Framebuffer";
+       res.start = fb->physical_address;
+       length = PAGE_ALIGN(fb->y_resolution * fb->bytes_per_line);
diff --git a/queue-6.18/fs-afs-revert-mmap_prepare-change.patch b/queue-6.18/fs-afs-revert-mmap_prepare-change.patch
new file mode 100644 (file)
index 0000000..68710dd
--- /dev/null
@@ -0,0 +1,107 @@
+From fbfc6578eaca12daa0c09df1e9ba7f2c657b49da Mon Sep 17 00:00:00 2001
+From: "Lorenzo Stoakes (Oracle)" <ljs@kernel.org>
+Date: Fri, 20 Mar 2026 22:39:35 +0000
+Subject: fs: afs: revert mmap_prepare() change
+
+From: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+
+commit fbfc6578eaca12daa0c09df1e9ba7f2c657b49da upstream.
+
+Partially reverts commit 9d5403b1036c ("fs: convert most other
+generic_file_*mmap() users to .mmap_prepare()").
+
+This is because the .mmap invocation establishes a refcount, but
+.mmap_prepare is called at a point where a merge or an allocation failure
+might happen after the call, which would leak the refcount increment.
+
+Functionality is being added to permit the use of .mmap_prepare in this
+case, but in the interim, we need to fix this.
+
+Link: https://lkml.kernel.org/r/08804c94e39d9102a3a8fbd12385e8aa079ba1d3.1774045440.git.ljs@kernel.org
+Fixes: 9d5403b1036c ("fs: convert most other generic_file_*mmap() users to .mmap_prepare()")
+Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Bodo Stroesser <bostroesser@gmail.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Clemens Ladisch <clemens@ladisch.de>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: David Howells <dhowells@redhat.com>
+Cc: Dexuan Cui <decui@microsoft.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Jann Horn <jannh@google.com>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Long Li <longli@microsoft.com>
+Cc: Marc Dionne <marc.dionne@auristor.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Pedro Falcato <pfalcato@suse.de>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Cc: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Cc: Wei Liu <wei.liu@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/afs/file.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/afs/file.c b/fs/afs/file.c
+index f609366fd2ac..74d04af51ff4 100644
+--- a/fs/afs/file.c
++++ b/fs/afs/file.c
+@@ -19,7 +19,7 @@
+ #include <trace/events/netfs.h>
+ #include "internal.h"
+-static int afs_file_mmap_prepare(struct vm_area_desc *desc);
++static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
+ static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
+ static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
+@@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
+       .llseek         = generic_file_llseek,
+       .read_iter      = afs_file_read_iter,
+       .write_iter     = netfs_file_write_iter,
+-      .mmap_prepare   = afs_file_mmap_prepare,
++      .mmap           = afs_file_mmap,
+       .splice_read    = afs_file_splice_read,
+       .splice_write   = iter_file_splice_write,
+       .fsync          = afs_fsync,
+@@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
+ /*
+  * Handle setting up a memory mapping on an AFS file.
+  */
+-static int afs_file_mmap_prepare(struct vm_area_desc *desc)
++static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+-      struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
++      struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
+       int ret;
+       afs_add_open_mmap(vnode);
+-      ret = generic_file_mmap_prepare(desc);
++      ret = generic_file_mmap(file, vma);
+       if (ret == 0)
+-              desc->vm_ops = &afs_vm_ops;
++              vma->vm_ops = &afs_vm_ops;
+       else
+               afs_drop_open_mmap(vnode);
+       return ret;
+-- 
+2.54.0
+
diff --git a/queue-6.18/greybus-gb-beagleplay-bound-bootloader-receive-buffering.patch b/queue-6.18/greybus-gb-beagleplay-bound-bootloader-receive-buffering.patch
new file mode 100644 (file)
index 0000000..0a041fb
--- /dev/null
@@ -0,0 +1,44 @@
+From 1214bf28965ceaf584fb20d357731264dd2e10e1 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Thu, 2 Apr 2026 13:40:16 +0800
+Subject: greybus: gb-beagleplay: bound bootloader receive buffering
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 1214bf28965ceaf584fb20d357731264dd2e10e1 upstream.
+
+cc1352_bootloader_rx() appends each serdev chunk into the fixed
+rx_buffer before parsing bootloader packets. The helper can keep
+leftover bytes between callbacks and may receive multiple packets in one
+callback, so a single count value is not constrained by one packet
+length.
+
+Check that the incoming chunk fits in the remaining receive buffer space
+before memcpy(). If it does not, drop the staged data and consume the
+bytes instead of overflowing rx_buffer.
+
+Fixes: 0cf7befa3ea2 ("greybus: gb-beagleplay: Add firmware upload API")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Link: https://patch.msgid.link/20260402054016.38587-1-pengpeng@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/greybus/gb-beagleplay.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/greybus/gb-beagleplay.c
++++ b/drivers/greybus/gb-beagleplay.c
+@@ -535,6 +535,13 @@ static size_t cc1352_bootloader_rx(struc
+       int ret;
+       size_t off = 0;
++      if (count > sizeof(bg->rx_buffer) - bg->rx_buffer_len) {
++              dev_warn(&bg->sd->dev,
++                       "dropping oversized bootloader receive chunk");
++              bg->rx_buffer_len = 0;
++              return count;
++      }
++
+       memcpy(bg->rx_buffer + bg->rx_buffer_len, data, count);
+       bg->rx_buffer_len += count;
diff --git a/queue-6.18/greybus-gb-beagleplay-fix-sleep-in-atomic-context-in-hdlc_tx_frames.patch b/queue-6.18/greybus-gb-beagleplay-fix-sleep-in-atomic-context-in-hdlc_tx_frames.patch
new file mode 100644 (file)
index 0000000..d37d9f9
--- /dev/null
@@ -0,0 +1,180 @@
+From 6b526dca0966f2370835765019a54319b78fca8d Mon Sep 17 00:00:00 2001
+From: Weigang He <geoffreyhe2@gmail.com>
+Date: Mon, 30 Mar 2026 12:08:00 +0000
+Subject: greybus: gb-beagleplay: fix sleep in atomic context in hdlc_tx_frames()
+
+From: Weigang He <geoffreyhe2@gmail.com>
+
+commit 6b526dca0966f2370835765019a54319b78fca8d upstream.
+
+hdlc_append() calls usleep_range() to wait for circular buffer space,
+but it is called with tx_producer_lock (a spinlock) held via
+hdlc_tx_frames() -> hdlc_append_tx_frame()/hdlc_append_tx_u8()/etc.
+Sleeping while holding a spinlock is illegal and can trigger
+"BUG: scheduling while atomic".
+
+Fix this by moving the buffer-space wait out of hdlc_append() and into
+hdlc_tx_frames(), before the spinlock is acquired.  The new flow:
+
+ 1. Pre-calculate the worst-case encoded frame length.
+ 2. Wait (with sleep) outside the lock until enough space is available,
+    kicking the TX consumer work to drain the buffer.
+ 3. Acquire the spinlock, re-verify space, and write the entire frame
+    atomically.
+
+This ensures that sleeping only happens without any lock held, and
+that frames are either fully enqueued or not written at all.
+
+This bug is found by CodeQL static analysis tool (interprocedural
+sleep-in-atomic query) and my code review.
+
+Fixes: ec558bbfea67 ("greybus: Add BeaglePlay Linux Driver")
+Cc: stable <stable@kernel.org>
+Cc: Ayush Singh <ayushdevel1325@gmail.com>
+Cc: Johan Hovold <johan@kernel.org>
+Cc: Alex Elder <elder@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
+Link: https://patch.msgid.link/20260330120801.981506-1-geoffreyhe2@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/greybus/gb-beagleplay.c |  107 +++++++++++++++++++++++++++++++++-------
+ 1 file changed, 90 insertions(+), 17 deletions(-)
+
+--- a/drivers/greybus/gb-beagleplay.c
++++ b/drivers/greybus/gb-beagleplay.c
+@@ -242,30 +242,26 @@ static void hdlc_write(struct gb_beaglep
+ }
+ /**
+- * hdlc_append() - Queue HDLC data for sending.
++ * hdlc_append() - Queue a single HDLC byte for sending.
+  * @bg: beagleplay greybus driver
+  * @value: hdlc byte to transmit
+  *
+- * Assumes that producer lock as been acquired.
++ * Caller must hold tx_producer_lock and must have ensured sufficient
++ * space in the circular buffer before calling (see hdlc_tx_frames()).
+  */
+ static void hdlc_append(struct gb_beagleplay *bg, u8 value)
+ {
+-      int tail, head = bg->tx_circ_buf.head;
++      int head = bg->tx_circ_buf.head;
++      int tail = READ_ONCE(bg->tx_circ_buf.tail);
+-      while (true) {
+-              tail = READ_ONCE(bg->tx_circ_buf.tail);
+-
+-              if (CIRC_SPACE(head, tail, TX_CIRC_BUF_SIZE) >= 1) {
+-                      bg->tx_circ_buf.buf[head] = value;
+-
+-                      /* Finish producing HDLC byte */
+-                      smp_store_release(&bg->tx_circ_buf.head,
+-                                        (head + 1) & (TX_CIRC_BUF_SIZE - 1));
+-                      return;
+-              }
+-              dev_warn(&bg->sd->dev, "Tx circ buf full");
+-              usleep_range(3000, 5000);
+-      }
++      lockdep_assert_held(&bg->tx_producer_lock);
++      if (WARN_ON_ONCE(CIRC_SPACE(head, tail, TX_CIRC_BUF_SIZE) < 1))
++              return;
++
++      bg->tx_circ_buf.buf[head] = value;
++      /* Ensure buffer write is visible before advancing head. */
++      smp_store_release(&bg->tx_circ_buf.head,
++                        (head + 1) & (TX_CIRC_BUF_SIZE - 1));
+ }
+ static void hdlc_append_escaped(struct gb_beagleplay *bg, u8 value)
+@@ -313,13 +309,90 @@ static void hdlc_transmit(struct work_st
+       spin_unlock_bh(&bg->tx_consumer_lock);
+ }
++/**
++ * hdlc_encoded_length() - Calculate worst-case encoded length of an HDLC frame.
++ * @payloads: array of payload buffers
++ * @count: number of payloads
++ *
++ * Returns the maximum number of bytes needed in the circular buffer.
++ */
++static size_t hdlc_encoded_length(const struct hdlc_payload payloads[],
++                                size_t count)
++{
++      size_t i, payload_len = 0;
++
++      for (i = 0; i < count; i++)
++              payload_len += payloads[i].len;
++
++      /*
++       * Worst case: every data byte needs escaping (doubles in size).
++       * data bytes = address(1) + control(1) + payload + crc(2)
++       * framing    = opening flag(1) + closing flag(1)
++       */
++      return 2 + (1 + 1 + payload_len + 2) * 2;
++}
++
++#define HDLC_TX_BUF_WAIT_RETRIES      500
++#define HDLC_TX_BUF_WAIT_US_MIN       3000
++#define HDLC_TX_BUF_WAIT_US_MAX       5000
++
++/**
++ * hdlc_tx_frames() - Encode and queue an HDLC frame for transmission.
++ * @bg: beagleplay greybus driver
++ * @address: HDLC address field
++ * @control: HDLC control field
++ * @payloads: array of payload buffers
++ * @count: number of payloads
++ *
++ * Sleeps outside the spinlock until enough circular-buffer space is
++ * available, then verifies space under the lock and writes the entire
++ * frame atomically.  Either a complete frame is enqueued or nothing is
++ * written, avoiding both sleeping in atomic context and partial frames.
++ */
+ static void hdlc_tx_frames(struct gb_beagleplay *bg, u8 address, u8 control,
+                          const struct hdlc_payload payloads[], size_t count)
+ {
++      size_t needed = hdlc_encoded_length(payloads, count);
++      int retries = HDLC_TX_BUF_WAIT_RETRIES;
+       size_t i;
++      int head, tail;
++
++      /* Wait outside the lock for sufficient buffer space. */
++      while (retries--) {
++              /* Pairs with smp_store_release() in hdlc_append(). */
++              head = smp_load_acquire(&bg->tx_circ_buf.head);
++              tail = READ_ONCE(bg->tx_circ_buf.tail);
++
++              if (CIRC_SPACE(head, tail, TX_CIRC_BUF_SIZE) >= needed)
++                      break;
++
++              /* Kick the consumer and sleep â€” no lock held. */
++              schedule_work(&bg->tx_work);
++              usleep_range(HDLC_TX_BUF_WAIT_US_MIN, HDLC_TX_BUF_WAIT_US_MAX);
++      }
++
++      if (retries < 0) {
++              dev_warn_ratelimited(&bg->sd->dev,
++                                   "Tx circ buf full, dropping frame\n");
++              return;
++      }
+       spin_lock(&bg->tx_producer_lock);
++      /*
++       * Re-check under the lock.  Should not fail since
++       * tx_producer_lock serialises all producers and the
++       * consumer only frees space, but guard against it.
++       */
++      head = bg->tx_circ_buf.head;
++      tail = READ_ONCE(bg->tx_circ_buf.tail);
++      if (unlikely(CIRC_SPACE(head, tail, TX_CIRC_BUF_SIZE) < needed)) {
++              spin_unlock(&bg->tx_producer_lock);
++              dev_warn_ratelimited(&bg->sd->dev,
++                                   "Tx circ buf space lost, dropping frame\n");
++              return;
++      }
++
+       hdlc_append_tx_frame(bg);
+       hdlc_append_tx_u8(bg, address);
+       hdlc_append_tx_u8(bg, control);
diff --git a/queue-6.18/ibmasm-fix-heap-over-read-in-ibmasm_send_i2o_message.patch b/queue-6.18/ibmasm-fix-heap-over-read-in-ibmasm_send_i2o_message.patch
new file mode 100644 (file)
index 0000000..5cd0f2d
--- /dev/null
@@ -0,0 +1,72 @@
+From 9aad71144fa3682cca3837a06c8623016790e7ec Mon Sep 17 00:00:00 2001
+From: Tyllis Xu <livelycarpet87@gmail.com>
+Date: Sat, 14 Mar 2026 11:58:05 -0500
+Subject: ibmasm: fix heap over-read in ibmasm_send_i2o_message()
+
+From: Tyllis Xu <livelycarpet87@gmail.com>
+
+commit 9aad71144fa3682cca3837a06c8623016790e7ec upstream.
+
+The ibmasm_send_i2o_message() function uses get_dot_command_size() to
+compute the byte count for memcpy_toio(), but this value is derived from
+user-controlled fields in the dot_command_header (command_size: u8,
+data_size: u16) and is never validated against the actual allocation size.
+A root user can write a small buffer with inflated header fields, causing
+memcpy_toio() to read up to ~65 KB past the end of the allocation into
+adjacent kernel heap, which is then forwarded to the service processor
+over MMIO.
+
+Silently clamping the copy size is not sufficient: if the header fields
+claim a larger size than the buffer, the SP receives a dot command whose
+own header is inconsistent with the I2O message length, which can cause
+the SP to desynchronize. Reject such commands outright by returning
+failure.
+
+Validate command_size before calling get_mfa_inbound() to avoid leaking
+an I2O message frame: reading INBOUND_QUEUE_PORT dequeues a hardware
+frame from the controller's free pool, and returning without a
+corresponding set_mfa_inbound() call would permanently exhaust it.
+
+Additionally, clamp command_size to I2O_COMMAND_SIZE before the
+memcpy_toio() so the MMIO write stays within the I2O message frame,
+consistent with the clamping already performed by outgoing_message_size()
+for the header field.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
+Link: https://patch.msgid.link/20260314165805.548293-1-LivelyCarpet87@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/ibmasm/lowlevel.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/misc/ibmasm/lowlevel.c
++++ b/drivers/misc/ibmasm/lowlevel.c
+@@ -19,17 +19,21 @@ static struct i2o_header header = I2O_HE
+ int ibmasm_send_i2o_message(struct service_processor *sp)
+ {
+       u32 mfa;
+-      unsigned int command_size;
++      size_t command_size;
+       struct i2o_message *message;
+       struct command *command = sp->current_command;
++      command_size = get_dot_command_size(command->buffer);
++      if (command_size > command->buffer_size)
++              return 1;
++      if (command_size > I2O_COMMAND_SIZE)
++              command_size = I2O_COMMAND_SIZE;
++
+       mfa = get_mfa_inbound(sp->base_address);
+       if (!mfa)
+               return 1;
+-      command_size = get_dot_command_size(command->buffer);
+-      header.message_size = outgoing_message_size(command_size);
+-
++      header.message_size = outgoing_message_size((unsigned int)command_size);
+       message = get_i2o_message(sp->base_address, mfa);
+       memcpy_toio(&message->header, &header, sizeof(struct i2o_header));
diff --git a/queue-6.18/ibmasm-fix-oob-reads-in-command_file_write-due-to-missing-size-checks.patch b/queue-6.18/ibmasm-fix-oob-reads-in-command_file_write-due-to-missing-size-checks.patch
new file mode 100644 (file)
index 0000000..fdf6a0b
--- /dev/null
@@ -0,0 +1,59 @@
+From 0eb09f737428e482a32a2e31e5e223f2b35a71d3 Mon Sep 17 00:00:00 2001
+From: Tyllis Xu <livelycarpet87@gmail.com>
+Date: Sat, 14 Mar 2026 11:53:54 -0500
+Subject: ibmasm: fix OOB reads in command_file_write due to missing size checks
+
+From: Tyllis Xu <livelycarpet87@gmail.com>
+
+commit 0eb09f737428e482a32a2e31e5e223f2b35a71d3 upstream.
+
+The command_file_write() handler allocates a kernel buffer of exactly
+count bytes and copies user data into it, but does not validate the
+buffer against the dot command protocol before passing it to
+get_dot_command_size() and get_dot_command_timeout().
+
+Since both the allocation size (count) and the header fields (command_size,
+data_size) are independently user-controlled, an attacker can cause
+get_dot_command_size() to return a value exceeding the allocation,
+triggering OOB reads in get_dot_command_timeout() and an out-of-bounds
+memcpy_toio() that leaks kernel heap memory to the service processor.
+
+Fix with two guards: reject writes smaller than sizeof(struct
+dot_command_header) before allocation, then after copying user data
+reject commands where the buffer is smaller than the total size declared
+by the header (sizeof(header) + command_size + data_size). This ensures
+all subsequent header and payload field accesses stay within the buffer.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
+Link: https://patch.msgid.link/20260314165355.548119-1-LivelyCarpet87@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/ibmasm/ibmasmfs.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/misc/ibmasm/ibmasmfs.c
++++ b/drivers/misc/ibmasm/ibmasmfs.c
+@@ -303,6 +303,8 @@ static ssize_t command_file_write(struct
+               return -EINVAL;
+       if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
+               return 0;
++      if (count < sizeof(struct dot_command_header))
++              return -EINVAL;
+       if (*offset != 0)
+               return 0;
+@@ -319,6 +321,11 @@ static ssize_t command_file_write(struct
+               return -EFAULT;
+       }
++      if (count < get_dot_command_size(cmd->buffer)) {
++              command_put(cmd);
++              return -EINVAL;
++      }
++
+       spin_lock_irqsave(&command_data->sp->lock, flags);
+       if (command_data->command) {
+               spin_unlock_irqrestore(&command_data->sp->lock, flags);
diff --git a/queue-6.18/kbuild-rust-allow-clippy-uninlined_format_args.patch b/queue-6.18/kbuild-rust-allow-clippy-uninlined_format_args.patch
new file mode 100644 (file)
index 0000000..92fe4d4
--- /dev/null
@@ -0,0 +1,72 @@
+From 10eea3c147141c90cf409b8df56d245c9d7f88d9 Mon Sep 17 00:00:00 2001
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Tue, 31 Mar 2026 22:58:48 +0200
+Subject: kbuild: rust: allow `clippy::uninlined_format_args`
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+commit 10eea3c147141c90cf409b8df56d245c9d7f88d9 upstream.
+
+Clippy in Rust 1.88.0 (only) reports [1]:
+
+    warning: variables can be used directly in the `format!` string
+       --> rust/macros/module.rs:112:23
+        |
+    112 |         let content = format!("{param}:{content}", param = param, content = content);
+        |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        |
+        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
+        = note: `-W clippy::uninlined-format-args` implied by `-W clippy::all`
+        = help: to override `-W clippy::all` add `#[allow(clippy::uninlined_format_args)]`
+    help: change this to
+        |
+    112 -         let content = format!("{param}:{content}", param = param, content = content);
+    112 +         let content = format!("{param}:{content}");
+
+    warning: variables can be used directly in the `format!` string
+       --> rust/macros/module.rs:198:14
+        |
+    198 |         t => panic!("Unsupported parameter type {}", t),
+        |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        |
+        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
+        = note: `-W clippy::uninlined-format-args` implied by `-W clippy::all`
+        = help: to override `-W clippy::all` add `#[allow(clippy::uninlined_format_args)]`
+    help: change this to
+        |
+    198 -         t => panic!("Unsupported parameter type {}", t),
+    198 +         t => panic!("Unsupported parameter type {t}"),
+        |
+
+The reason it only triggers in that version is that the lint was moved
+from `pedantic` to `style` in Rust 1.88.0 and then back to `pedantic`
+in Rust 1.89.0 [2][3].
+
+In the first case, the suggestion is fair and a pure simplification, thus
+we will clean it up separately.
+
+To keep the behavior the same across all versions, and since the lint
+does not work for all macros (e.g. custom ones like `pr_info!`), disable
+it globally.
+
+Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
+Link: https://lore.kernel.org/rust-for-linux/CANiq72=drAtf3y_DZ-2o4jb6Az9J3Yj4QYwWnbRui4sm4AJD3Q@mail.gmail.com/ [1]
+Link: https://github.com/rust-lang/rust-clippy/pull/15287 [2]
+Link: https://github.com/rust-lang/rust-clippy/issues/15151 [3]
+Link: https://patch.msgid.link/20260331205849.498295-1-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Makefile |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Makefile
++++ b/Makefile
+@@ -492,6 +492,7 @@ export rust_common_flags := --edition=20
+                           -Wclippy::ptr_cast_constness \
+                           -Wclippy::ref_as_ptr \
+                           -Wclippy::undocumented_unsafe_blocks \
++                          -Aclippy::uninlined_format_args \
+                           -Wclippy::unnecessary_safety_comment \
+                           -Wclippy::unnecessary_safety_doc \
+                           -Wrustdoc::missing_crate_level_docs \
diff --git a/queue-6.18/leds-qcom-lpg-check-for-array-overflow-when-selecting-the-high-resolution.patch b/queue-6.18/leds-qcom-lpg-check-for-array-overflow-when-selecting-the-high-resolution.patch
new file mode 100644 (file)
index 0000000..ac32b2d
--- /dev/null
@@ -0,0 +1,40 @@
+From d45963a93c1495e9f1338fde91d0ebba8fd22474 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Thu, 19 Feb 2026 15:34:35 +0100
+Subject: leds: qcom-lpg: Check for array overflow when selecting the high resolution
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit d45963a93c1495e9f1338fde91d0ebba8fd22474 upstream.
+
+When selecting the high resolution values from the array, FIELD_GET() is
+used to pull from a 3 bit register, yet the array being indexed has only
+5 values in it.  Odds are the hardware is sane, but just to be safe,
+properly check before just overflowing and reading random data and then
+setting up chip values based on that.
+
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/2026021934-nearby-playroom-036b@gregkh
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/rgb/leds-qcom-lpg.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/leds/rgb/leds-qcom-lpg.c
++++ b/drivers/leds/rgb/leds-qcom-lpg.c
+@@ -1273,7 +1273,12 @@ static int lpg_pwm_get_state(struct pwm_
+               return ret;
+       if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) {
+-              refclk = lpg_clk_rates_hi_res[FIELD_GET(PWM_CLK_SELECT_HI_RES_MASK, val)];
++              unsigned int clk_idx = FIELD_GET(PWM_CLK_SELECT_HI_RES_MASK, val);
++
++              if (clk_idx >= ARRAY_SIZE(lpg_clk_rates_hi_res))
++                      return -EINVAL;
++
++              refclk = lpg_clk_rates_hi_res[clk_idx];
+               resolution = lpg_pwm_resolution_hi_res[FIELD_GET(PWM_SIZE_HI_RES_MASK, val)];
+       } else {
+               refclk = lpg_clk_rates[FIELD_GET(PWM_CLK_SELECT_MASK, val)];
diff --git a/queue-6.18/loongarch-add-spectre-boundry-for-syscall-dispatch-table.patch b/queue-6.18/loongarch-add-spectre-boundry-for-syscall-dispatch-table.patch
new file mode 100644 (file)
index 0000000..dc52319
--- /dev/null
@@ -0,0 +1,41 @@
+From 0c965d2784fbbd7f8e3b96d875c9cfdf7c00da3d Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Wed, 22 Apr 2026 15:45:12 +0800
+Subject: LoongArch: Add spectre boundry for syscall dispatch table
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 0c965d2784fbbd7f8e3b96d875c9cfdf7c00da3d upstream.
+
+The LoongArch syscall number is directly controlled by userspace, but
+does not have a array_index_nospec() boundry to prevent access past the
+syscall function pointer tables.
+
+Cc: stable@vger.kernel.org
+Assisted-by: gkh_clanker_2000
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kernel/syscall.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/loongarch/kernel/syscall.c
++++ b/arch/loongarch/kernel/syscall.c
+@@ -9,6 +9,7 @@
+ #include <linux/entry-common.h>
+ #include <linux/errno.h>
+ #include <linux/linkage.h>
++#include <linux/nospec.h>
+ #include <linux/objtool.h>
+ #include <linux/randomize_kstack.h>
+ #include <linux/syscalls.h>
+@@ -61,7 +62,7 @@ void noinstr __no_stack_protector do_sys
+       add_random_kstack_offset();
+       if (nr < NR_syscalls) {
+-              syscall_fn = sys_call_table[nr];
++              syscall_fn = sys_call_table[array_index_nospec(nr, NR_syscalls)];
+               regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6],
+                                          regs->regs[7], regs->regs[8], regs->regs[9]);
+       }
diff --git a/queue-6.18/misc-ibmasm-fix-oob-mmio-read-in-ibmasm_handle_mouse_interrupt.patch b/queue-6.18/misc-ibmasm-fix-oob-mmio-read-in-ibmasm_handle_mouse_interrupt.patch
new file mode 100644 (file)
index 0000000..e612ad0
--- /dev/null
@@ -0,0 +1,62 @@
+From 4b6e6ead556734bdc14024c5f837132b1e7a4b84 Mon Sep 17 00:00:00 2001
+From: Tyllis Xu <livelycarpet87@gmail.com>
+Date: Sun, 8 Mar 2026 00:21:08 -0600
+Subject: misc: ibmasm: fix OOB MMIO read in ibmasm_handle_mouse_interrupt()
+
+From: Tyllis Xu <livelycarpet87@gmail.com>
+
+commit 4b6e6ead556734bdc14024c5f837132b1e7a4b84 upstream.
+
+ibmasm_handle_mouse_interrupt() performs an out-of-bounds MMIO read
+when the queue reader or writer index from hardware exceeds
+REMOTE_QUEUE_SIZE (60).
+
+A compromised service processor can trigger this by writing an
+out-of-range value to the reader or writer MMIO register before
+asserting an interrupt. Since writer is re-read from hardware on
+every loop iteration, it can also be set to an out-of-range value
+after the loop has already started.
+
+The root cause is that get_queue_reader() and get_queue_writer() return
+raw readl() values that are passed directly into get_queue_entry(),
+which computes:
+
+  queue_begin + reader * sizeof(struct remote_input)
+
+with no bounds check. This unchecked MMIO address is then passed to
+memcpy_fromio(), reading 8 bytes from unintended device registers.
+For sufficiently large values the address falls outside the PCI BAR
+mapping entirely, triggering a machine check exception.
+
+Fix by checking both indices against REMOTE_QUEUE_SIZE at the top of
+the loop body, before any call to get_queue_entry(). On an out-of-range
+value, reset the reader register to 0 via set_queue_reader() before
+breaking, so that normal queue operation can resume if the corrupted
+hardware state is transient.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Fixes: 278d72ae8803 ("[PATCH] ibmasm driver: redesign handling of remote control events")
+Cc: stable@vger.kernel.org
+Cc: ychen@northwestern.edu
+Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
+Link: https://patch.msgid.link/20260308062108.258940-1-LivelyCarpet87@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/ibmasm/remote.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/misc/ibmasm/remote.c
++++ b/drivers/misc/ibmasm/remote.c
+@@ -177,6 +177,11 @@ void ibmasm_handle_mouse_interrupt(struc
+       writer = get_queue_writer(sp);
+       while (reader != writer) {
++              if (reader >= REMOTE_QUEUE_SIZE || writer >= REMOTE_QUEUE_SIZE) {
++                      set_queue_reader(sp, 0);
++                      break;
++              }
++
+               memcpy_fromio(&input, get_queue_entry(sp, reader),
+                               sizeof(struct remote_input));
diff --git a/queue-6.18/mm-migrate-requeue-destination-folio-on-deferred-split-queue.patch b/queue-6.18/mm-migrate-requeue-destination-folio-on-deferred-split-queue.patch
new file mode 100644 (file)
index 0000000..3b785b0
--- /dev/null
@@ -0,0 +1,97 @@
+From a2e0c0668a3486f96b86c50e02872c8e94fd4f9c Mon Sep 17 00:00:00 2001
+From: Usama Arif <usama.arif@linux.dev>
+Date: Thu, 12 Mar 2026 03:47:23 -0700
+Subject: mm: migrate: requeue destination folio on deferred split queue
+
+From: Usama Arif <usama.arif@linux.dev>
+
+commit a2e0c0668a3486f96b86c50e02872c8e94fd4f9c upstream.
+
+During folio migration, __folio_migrate_mapping() removes the source folio
+from the deferred split queue, but the destination folio is never
+re-queued.  This causes underutilized THPs to escape the shrinker after
+NUMA migration, since they silently drop off the deferred split list.
+
+Fix this by recording whether the source folio was on the deferred split
+queue and its partially mapped state before move_to_new_folio() unqueues
+it, and re-queuing the destination folio after a successful migration if
+it was.
+
+By the time migrate_folio_move() runs, partially mapped folios without a
+pin have already been split by migrate_pages_batch().  So only two cases
+remain on the deferred list at this point:
+  1. Partially mapped folios with a pin (split failed).
+  2. Fully mapped but potentially underused folios.  The recorded
+     partially_mapped state is forwarded to deferred_split_folio() so that
+     the destination folio is correctly re-queued in both cases.
+
+Because THPs are removed from the deferred_list, THP shinker cannot
+split the underutilized THPs in time.  As a result, users will show
+less free memory than before.
+
+Link: https://lkml.kernel.org/r/20260312104723.1351321-1-usama.arif@linux.dev
+Fixes: dafff3f4c850 ("mm: split underused THPs")
+Signed-off-by: Usama Arif <usama.arif@linux.dev>
+Reported-by: Johannes Weiner <hannes@cmpxchg.org>
+Acked-by: Johannes Weiner <hannes@cmpxchg.org>
+Acked-by: Zi Yan <ziy@nvidia.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Acked-by: SeongJae Park <sj@kernel.org>
+Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Byungchul Park <byungchul@sk.com>
+Cc: Gregory Price <gourry@gourry.net>
+Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
+Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Nico Pache <npache@redhat.com>
+Cc: Rakie Kim <rakie.kim@sk.com>
+Cc: Ying Huang <ying.huang@linux.alibaba.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/migrate.c |   17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -1349,6 +1349,8 @@ static int migrate_folio_move(free_folio
+       int rc;
+       int old_page_state = 0;
+       struct anon_vma *anon_vma = NULL;
++      bool src_deferred_split = false;
++      bool src_partially_mapped = false;
+       struct list_head *prev;
+       __migrate_folio_extract(dst, &old_page_state, &anon_vma);
+@@ -1362,6 +1364,12 @@ static int migrate_folio_move(free_folio
+               goto out_unlock_both;
+       }
++      if (folio_order(src) > 1 &&
++          !data_race(list_empty(&src->_deferred_list))) {
++              src_deferred_split = true;
++              src_partially_mapped = folio_test_partially_mapped(src);
++      }
++
+       rc = move_to_new_folio(dst, src, mode);
+       if (rc)
+               goto out;
+@@ -1382,6 +1390,15 @@ static int migrate_folio_move(free_folio
+       if (old_page_state & PAGE_WAS_MAPPED)
+               remove_migration_ptes(src, dst, 0);
++      /*
++       * Requeue the destination folio on the deferred split queue if
++       * the source was on the queue.  The source is unqueued in
++       * __folio_migrate_mapping(), so we recorded the state from
++       * before move_to_new_folio().
++       */
++      if (src_deferred_split)
++              deferred_split_folio(dst, src_partially_mapped);
++
+ out_unlock_both:
+       folio_unlock(dst);
+       folio_set_owner_migrate_reason(dst, reason);
diff --git a/queue-6.18/rust-dma-remove-dma_attr_no_kernel_mapping-from-public-attrs.patch b/queue-6.18/rust-dma-remove-dma_attr_no_kernel_mapping-from-public-attrs.patch
new file mode 100644 (file)
index 0000000..42d249c
--- /dev/null
@@ -0,0 +1,50 @@
+From 18fb5f1f0289b8217c0c43d54d12bccc201dd640 Mon Sep 17 00:00:00 2001
+From: Danilo Krummrich <dakr@kernel.org>
+Date: Sat, 21 Mar 2026 18:27:46 +0100
+Subject: rust: dma: remove DMA_ATTR_NO_KERNEL_MAPPING from public attrs
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+commit 18fb5f1f0289b8217c0c43d54d12bccc201dd640 upstream.
+
+When DMA_ATTR_NO_KERNEL_MAPPING is passed to dma_alloc_attrs(), the
+returned CPU address is not a pointer to the allocated memory but an
+opaque handle (e.g. struct page *).
+
+Coherent<T> (or CoherentAllocation<T> respectively) stores this value as
+NonNull<T> and exposes methods that dereference it and even modify its
+contents.
+
+Remove the flag from the public attrs module such that drivers cannot
+pass it to Coherent<T> (or CoherentAllocation<T> respectively) in the
+first place.
+
+Instead DMA_ATTR_NO_KERNEL_MAPPING can be supported with an additional
+opaque type (e.g. CoherentHandle) which does not provide access to the
+allocated memory.
+
+Cc: stable@vger.kernel.org
+Fixes: ad2907b4e308 ("rust: add dma coherent allocator abstraction")
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://patch.msgid.link/20260321172749.592387-1-dakr@kernel.org
+Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ rust/kernel/dma.rs |    3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/rust/kernel/dma.rs
++++ b/rust/kernel/dma.rs
+@@ -232,9 +232,6 @@ pub mod attrs {
+     /// Specifies that writes to the mapping may be buffered to improve performance.
+     pub const DMA_ATTR_WRITE_COMBINE: Attrs = Attrs(bindings::DMA_ATTR_WRITE_COMBINE);
+-    /// Lets the platform to avoid creating a kernel virtual mapping for the allocated buffer.
+-    pub const DMA_ATTR_NO_KERNEL_MAPPING: Attrs = Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING);
+-
+     /// Allows platform code to skip synchronization of the CPU cache for the given buffer assuming
+     /// that it has been already transferred to 'device' domain.
+     pub const DMA_ATTR_SKIP_CPU_SYNC: Attrs = Attrs(bindings::DMA_ATTR_SKIP_CPU_SYNC);
index bf25601f849895b6fef49906fc7240f71ece4c4f..9738d7470a5fadcbf9ba2755c1d0d00e24872f66 100644 (file)
@@ -5,3 +5,20 @@ usb-xhci-make-usb_host_endpoint.hcpriv-survive-endpoint_disable.patch
 usb-chipidea-otg-not-wait-vbus-drop-if-use-role_switch.patch
 usb-chipidea-core-allow-ci_irq_handler-handle-both-id-and-vbus-change.patch
 alsa-usb-audio-evaluate-packsize-caps-at-the-right-place.patch
+loongarch-add-spectre-boundry-for-syscall-dispatch-table.patch
+drm-nouveau-fix-u32-overflow-in-pushbuf-reloc-bounds-check.patch
+leds-qcom-lpg-check-for-array-overflow-when-selecting-the-high-resolution.patch
+greybus-gb-beagleplay-bound-bootloader-receive-buffering.patch
+greybus-gb-beagleplay-fix-sleep-in-atomic-context-in-hdlc_tx_frames.patch
+misc-ibmasm-fix-oob-mmio-read-in-ibmasm_handle_mouse_interrupt.patch
+ibmasm-fix-oob-reads-in-command_file_write-due-to-missing-size-checks.patch
+ibmasm-fix-heap-over-read-in-ibmasm_send_i2o_message.patch
+driver-core-don-t-let-a-device-probe-until-it-s-ready.patch
+device-property-make-modifications-of-fwnode-flags-thread-safe.patch
+drm-nouveau-fix-nvkm_device-leak-on-aperture-removal-failure.patch
+rust-dma-remove-dma_attr_no_kernel_mapping-from-public-attrs.patch
+kbuild-rust-allow-clippy-uninlined_format_args.patch
+fs-afs-revert-mmap_prepare-change.patch
+firmware-google-framebuffer-do-not-mark-framebuffer-as-busy.patch
+arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
+mm-migrate-requeue-destination-folio-on-deferred-split-queue.patch