From 7f7b6f7311a7463b4917486a36303e530e8a0081 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 3 Feb 2026 17:40:49 +0100 Subject: [PATCH] 5.10-stable patches added patches: dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch driver-core-fix-potential-null-ptr-deref-in-device_add.patch iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch mei-trace-treat-reg-parameter-as-string.patch mm-pagewalk-add-walk_page_range_vma.patch net-sched-act_ife-convert-comma-to-semicolon.patch nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch nvme-fix-pcie-subsystem-reset-controller-state-transition.patch nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch w1-w1_therm-use-swap-to-make-code-cleaner.patch xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch --- ...-fix-device-leak-on-route-allocation.patch | 91 +++++++ ...ode-leak-on-route-allocation-failure.patch | 48 ++++ ...tential-null-ptr-deref-in-device_add.patch | 71 ++++++ ...adc-fix-of-populate-on-driver-rebind.patch | 69 ++++++ ...ver-holes-in-scan_get_next_rmap_item.patch | 230 ++++++++++++++++++ ...-trace-treat-reg-parameter-as-string.patch | 104 ++++++++ .../mm-pagewalk-add-walk_page_range_vma.patch | 77 ++++++ ...d-act_ife-convert-comma-to-semicolon.patch | 44 ++++ ..._ctrl-callback-to-match-name-pattern.patch | 47 ++++ ...em-reset-controller-state-transition.patch | 58 +++++ ...directly-handle-subsys-reset-fallout.patch | 205 ++++++++++++++++ ...ntial-memory-leak-in-scsiback_remove.patch | 40 +++ queue-5.10/series | 15 ++ ...-one-buffer-overflow-in-alarms_store.patch | 136 +++++++++++ ..._therm-use-swap-to-make-code-cleaner.patch | 50 ++++ ...parse-alloc-of-last-full-inode-chunk.patch | 85 +++++++ 16 files changed, 1370 insertions(+) create mode 100644 queue-5.10/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch create mode 100644 queue-5.10/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch create mode 100644 queue-5.10/driver-core-fix-potential-null-ptr-deref-in-device_add.patch create mode 100644 queue-5.10/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch create mode 100644 queue-5.10/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch create mode 100644 queue-5.10/mei-trace-treat-reg-parameter-as-string.patch create mode 100644 queue-5.10/mm-pagewalk-add-walk_page_range_vma.patch create mode 100644 queue-5.10/net-sched-act_ife-convert-comma-to-semicolon.patch create mode 100644 queue-5.10/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch create mode 100644 queue-5.10/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch create mode 100644 queue-5.10/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch create mode 100644 queue-5.10/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch create mode 100644 queue-5.10/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch create mode 100644 queue-5.10/w1-w1_therm-use-swap-to-make-code-cleaner.patch create mode 100644 queue-5.10/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch diff --git a/queue-5.10/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch b/queue-5.10/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch new file mode 100644 index 0000000000..164b604c0a --- /dev/null +++ b/queue-5.10/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch @@ -0,0 +1,91 @@ +From stable+bounces-210743-greg=kroah.com@vger.kernel.org Wed Jan 21 13:32:26 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:29:51 -0500 +Subject: dmaengine: stm32: dmamux: fix device leak on route allocation +To: stable@vger.kernel.org +Cc: Johan Hovold , Pierre-Yves MORDRET , Amelie Delaunay , Vinod Koul , Sasha Levin +Message-ID: <20260121122951.1531380-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit dd6e4943889fb354efa3f700e42739da9bddb6ef ] + +Make sure to drop the reference taken when looking up the DMA mux +platform device during route allocation. + +Note that holding a reference to a device does not prevent its driver +data from going away so there is no point in keeping the reference. + +Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") +Cc: stable@vger.kernel.org # 4.15 +Cc: Pierre-Yves MORDRET +Signed-off-by: Johan Hovold +Reviewed-by: Amelie Delaunay +Link: https://patch.msgid.link/20251117161258.10679-11-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/stm32-dmamux.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/dma/stm32-dmamux.c ++++ b/drivers/dma/stm32-dmamux.c +@@ -88,23 +88,25 @@ static void *stm32_dmamux_route_allocate + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev); + struct stm32_dmamux *mux; + u32 i, min, max; +- int ret; ++ int ret = -EINVAL; + unsigned long flags; + + if (dma_spec->args_count != 3) { + dev_err(&pdev->dev, "invalid number of dma mux args\n"); +- return ERR_PTR(-EINVAL); ++ goto err_put_pdev; + } + + if (dma_spec->args[0] > dmamux->dmamux_requests) { + dev_err(&pdev->dev, "invalid mux request number: %d\n", + dma_spec->args[0]); +- return ERR_PTR(-EINVAL); ++ goto err_put_pdev; + } + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); +- if (!mux) +- return ERR_PTR(-ENOMEM); ++ if (!mux) { ++ ret = -ENOMEM; ++ goto err_put_pdev; ++ } + + spin_lock_irqsave(&dmamux->lock, flags); + mux->chan_id = find_first_zero_bit(dmamux->dma_inuse, +@@ -131,7 +133,6 @@ static void *stm32_dmamux_route_allocate + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1); + if (!dma_spec->np) { + dev_err(&pdev->dev, "can't get dma master\n"); +- ret = -EINVAL; + goto error; + } + +@@ -158,6 +159,8 @@ static void *stm32_dmamux_route_allocate + dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n", + mux->request, mux->master, mux->chan_id); + ++ put_device(&pdev->dev); ++ + return mux; + + err_put_dma_spec_np: +@@ -167,6 +170,9 @@ error: + + error_chan_id: + kfree(mux); ++err_put_pdev: ++ put_device(&pdev->dev); ++ + return ERR_PTR(ret); + } + diff --git a/queue-5.10/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch b/queue-5.10/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch new file mode 100644 index 0000000000..71d76ade55 --- /dev/null +++ b/queue-5.10/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch @@ -0,0 +1,48 @@ +From stable+bounces-210746-greg=kroah.com@vger.kernel.org Wed Jan 21 13:54:56 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:40:36 -0500 +Subject: dmaengine: stm32: dmamux: fix OF node leak on route allocation failure +To: stable@vger.kernel.org +Cc: Johan Hovold , Pierre-Yves MORDRET , Amelie Delaunay , Vinod Koul , Sasha Levin +Message-ID: <20260121124036.1533446-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit b1b590a590af13ded598e70f0b72bc1e515787a1 ] + +Make sure to drop the reference taken to the DMA master OF node also on +late route allocation failures. + +Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") +Cc: stable@vger.kernel.org # 4.15 +Cc: Pierre-Yves MORDRET +Signed-off-by: Johan Hovold +Reviewed-by: Amelie Delaunay +Link: https://patch.msgid.link/20251117161258.10679-12-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/stm32-dmamux.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/dma/stm32-dmamux.c ++++ b/drivers/dma/stm32-dmamux.c +@@ -140,7 +140,7 @@ static void *stm32_dmamux_route_allocate + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + spin_unlock_irqrestore(&dmamux->lock, flags); +- goto error; ++ goto err_put_dma_spec_np; + } + spin_unlock_irqrestore(&dmamux->lock, flags); + +@@ -160,6 +160,8 @@ static void *stm32_dmamux_route_allocate + + return mux; + ++err_put_dma_spec_np: ++ of_node_put(dma_spec->np); + error: + clear_bit(mux->chan_id, dmamux->dma_inuse); + diff --git a/queue-5.10/driver-core-fix-potential-null-ptr-deref-in-device_add.patch b/queue-5.10/driver-core-fix-potential-null-ptr-deref-in-device_add.patch new file mode 100644 index 0000000000..eea9fcd5c4 --- /dev/null +++ b/queue-5.10/driver-core-fix-potential-null-ptr-deref-in-device_add.patch @@ -0,0 +1,71 @@ +From stable+bounces-211235-greg=kroah.com@vger.kernel.org Thu Jan 22 14:48:23 2026 +From: alvalan9@foxmail.com +Date: Thu, 22 Jan 2026 12:51:05 +0000 +Subject: driver core: fix potential null-ptr-deref in device_add() +To: stable@vger.kernel.org +Cc: Yang Yingliang , Greg Kroah-Hartman , Alva Lan +Message-ID: + +From: Yang Yingliang + +[ Upstream commit f6837f34a34973ef6600c08195ed300e24e97317 ] + +I got the following null-ptr-deref report while doing fault injection test: + +BUG: kernel NULL pointer dereference, address: 0000000000000058 +CPU: 2 PID: 278 Comm: 37-i2c-ds2482 Tainted: G B W N 6.1.0-rc3+ +RIP: 0010:klist_put+0x2d/0xd0 +Call Trace: + + klist_remove+0xf1/0x1c0 + device_release_driver_internal+0x196/0x210 + bus_remove_device+0x1bd/0x240 + device_add+0xd3d/0x1100 + w1_add_master_device+0x476/0x490 [wire] + ds2482_probe+0x303/0x3e0 [ds2482] + +This is how it happened: + +w1_alloc_dev() + // The dev->driver is set to w1_master_driver. + memcpy(&dev->dev, device, sizeof(struct device)); + device_add() + bus_add_device() + dpm_sysfs_add() // It fails, calls bus_remove_device. + + // error path + bus_remove_device() + // The dev->driver is not null, but driver is not bound. + __device_release_driver() + klist_remove(&dev->p->knode_driver) <-- It causes null-ptr-deref. + + // normal path + bus_probe_device() // It's not called yet. + device_bind_driver() + +If dev->driver is set, in the error path after calling bus_add_device() +in device_add(), bus_remove_device() is called, then the device will be +detached from driver. But device_bind_driver() is not called yet, so it +causes null-ptr-deref while access the 'knode_driver'. To fix this, set +dev->driver to null in the error path before calling bus_remove_device(). + +Fixes: 57eee3d23e88 ("Driver core: Call device_pm_add() after bus_add_device() in device_add()") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20221205034904.2077765-1-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Alva Lan +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -3036,6 +3036,7 @@ done: + device_pm_remove(dev); + dpm_sysfs_remove(dev); + DPMError: ++ dev->driver = NULL; + bus_remove_device(dev); + BusError: + device_remove_attrs(dev); diff --git a/queue-5.10/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch b/queue-5.10/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch new file mode 100644 index 0000000000..d1d3bb256e --- /dev/null +++ b/queue-5.10/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch @@ -0,0 +1,69 @@ +From stable+bounces-212649-greg=kroah.com@vger.kernel.org Wed Jan 28 18:46:37 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 12:42:23 -0500 +Subject: iio: adc: exynos_adc: fix OF populate on driver rebind +To: stable@vger.kernel.org +Cc: Johan Hovold , Krzysztof Kozlowski , Jonathan Cameron , Sasha Levin +Message-ID: <20260128174223.2597131-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit ea6b4feba85e996e840e0b661bc42793df6eb701 ] + +Since commit c6e126de43e7 ("of: Keep track of populated platform +devices") child devices will not be created by of_platform_populate() +if the devices had previously been deregistered individually so that the +OF_POPULATED flag is still set in the corresponding OF nodes. + +Switch to using of_platform_depopulate() instead of open coding so that +the child devices are created if the driver is rebound. + +Fixes: c6e126de43e7 ("of: Keep track of populated platform devices") +Cc: stable@vger.kernel.org # 3.16 +Signed-off-by: Johan Hovold +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Jonathan Cameron +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/exynos_adc.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/iio/adc/exynos_adc.c ++++ b/drivers/iio/adc/exynos_adc.c +@@ -718,14 +718,7 @@ static const struct iio_chan_spec exynos + ADC_CHANNEL(9, "adc9"), + }; + +-static int exynos_adc_remove_devices(struct device *dev, void *c) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- +- platform_device_unregister(pdev); + +- return 0; +-} + + static int exynos_adc_ts_open(struct input_dev *dev) + { +@@ -924,8 +917,7 @@ static int exynos_adc_probe(struct platf + return 0; + + err_of_populate: +- device_for_each_child(&indio_dev->dev, NULL, +- exynos_adc_remove_devices); ++ of_platform_depopulate(&indio_dev->dev); + if (has_ts) { + input_unregister_device(info->input); + free_irq(info->tsirq, info); +@@ -954,8 +946,7 @@ static int exynos_adc_remove(struct plat + free_irq(info->tsirq, info); + input_unregister_device(info->input); + } +- device_for_each_child(&indio_dev->dev, NULL, +- exynos_adc_remove_devices); ++ of_platform_depopulate(&indio_dev->dev); + iio_device_unregister(indio_dev); + free_irq(info->irq, info); + if (info->data->exit_hw) diff --git a/queue-5.10/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch b/queue-5.10/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch new file mode 100644 index 0000000000..0bf8248caa --- /dev/null +++ b/queue-5.10/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch @@ -0,0 +1,230 @@ +From stable+bounces-210188-greg=kroah.com@vger.kernel.org Sun Jan 18 00:38:31 2026 +From: Pedro Demarchi Gomes +Date: Sat, 17 Jan 2026 20:38:01 -0300 +Subject: ksm: use range-walk function to jump over holes in scan_get_next_rmap_item +To: stable@vger.kernel.org +Cc: Zhi.Yang@windriver.com, Pedro Demarchi Gomes , David Hildenbrand , craftfever , Chengming Zhou , xu xin , Andrew Morton +Message-ID: <20260117233801.339606-2-pedrodemargomes@gmail.com> + +From: Pedro Demarchi Gomes + +[ Upstream commit f5548c318d6520d4fa3c5ed6003eeb710763cbc5 ] + +Currently, scan_get_next_rmap_item() walks every page address in a VMA to +locate mergeable pages. This becomes highly inefficient when scanning +large virtual memory areas that contain mostly unmapped regions, causing +ksmd to use large amount of cpu without deduplicating much pages. + +This patch replaces the per-address lookup with a range walk using +walk_page_range(). The range walker allows KSM to skip over entire +unmapped holes in a VMA, avoiding unnecessary lookups. This problem was +previously discussed in [1]. + +Consider the following test program which creates a 32 TiB mapping in the +virtual address space but only populates a single page: + +/* 32 TiB */ +const size_t size = 32ul * 1024 * 1024 * 1024 * 1024; + +int main() { + char *area = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0); + + if (area == MAP_FAILED) { + perror("mmap() failed\n"); + return -1; + } + + /* Populate a single page such that we get an anon_vma. */ + *area = 0; + + /* Enable KSM. */ + madvise(area, size, MADV_MERGEABLE); + pause(); + return 0; +} + +$ ./ksm-sparse & +$ echo 1 > /sys/kernel/mm/ksm/run + +Without this patch ksmd uses 100% of the cpu for a long time (more then 1 +hour in my test machine) scanning all the 32 TiB virtual address space +that contain only one mapped page. This makes ksmd essentially deadlocked +not able to deduplicate anything of value. With this patch ksmd walks +only the one mapped page and skips the rest of the 32 TiB virtual address +space, making the scan fast using little cpu. + +Link: https://lkml.kernel.org/r/20251023035841.41406-1-pedrodemargomes@gmail.com +Link: https://lkml.kernel.org/r/20251022153059.22763-1-pedrodemargomes@gmail.com +Link: https://lore.kernel.org/linux-mm/423de7a3-1c62-4e72-8e79-19a6413e420c@redhat.com/ [1] +Fixes: 31dbd01f3143 ("ksm: Kernel SamePage Merging") +Signed-off-by: Pedro Demarchi Gomes +Co-developed-by: David Hildenbrand +Signed-off-by: David Hildenbrand +Reported-by: craftfever +Closes: https://lkml.kernel.org/r/020cf8de6e773bb78ba7614ef250129f11a63781@murena.io +Suggested-by: David Hildenbrand +Acked-by: David Hildenbrand +Cc: Chengming Zhou +Cc: xu xin +Cc: +Signed-off-by: Andrew Morton +[ change folio to page, replace pmdp_get_lockless with pmd_read_atomic and pmdp_get with + READ_ONCE(*pmdp) ] +Signed-off-by: Pedro Demarchi Gomes +Signed-off-by: Greg Kroah-Hartman +--- + mm/ksm.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 105 insertions(+), 10 deletions(-) + +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #include + #include "internal.h" +@@ -2223,6 +2224,89 @@ static struct rmap_item *get_next_rmap_i + return rmap_item; + } + ++struct ksm_next_page_arg { ++ struct page *page; ++ unsigned long addr; ++}; ++ ++static int ksm_next_page_pmd_entry(pmd_t *pmdp, unsigned long addr, unsigned long end, ++ struct mm_walk *walk) ++{ ++ struct ksm_next_page_arg *private = walk->private; ++ struct vm_area_struct *vma = walk->vma; ++ pte_t *start_ptep = NULL, *ptep, pte; ++ struct mm_struct *mm = walk->mm; ++ struct page *page; ++ spinlock_t *ptl; ++ pmd_t pmd; ++ ++ if (ksm_test_exit(mm)) ++ return 0; ++ ++ cond_resched(); ++ ++ pmd = pmd_read_atomic(pmdp); ++ if (!pmd_present(pmd)) ++ return 0; ++ ++ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pmd_leaf(pmd)) { ++ ptl = pmd_lock(mm, pmdp); ++ pmd = READ_ONCE(*pmdp); ++ ++ if (!pmd_present(pmd)) { ++ goto not_found_unlock; ++ } else if (pmd_leaf(pmd)) { ++ page = vm_normal_page_pmd(vma, addr, pmd); ++ if (!page) ++ goto not_found_unlock; ++ ++ if (is_zone_device_page(page) || !PageAnon(page)) ++ goto not_found_unlock; ++ ++ page += ((addr & (PMD_SIZE - 1)) >> PAGE_SHIFT); ++ goto found_unlock; ++ } ++ spin_unlock(ptl); ++ } ++ ++ start_ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); ++ if (!start_ptep) ++ return 0; ++ ++ for (ptep = start_ptep; addr < end; ptep++, addr += PAGE_SIZE) { ++ pte = ptep_get(ptep); ++ ++ if (!pte_present(pte)) ++ continue; ++ ++ page = vm_normal_page(vma, addr, pte); ++ if (!page) ++ continue; ++ ++ if (is_zone_device_page(page) || !PageAnon(page)) ++ continue; ++ goto found_unlock; ++ } ++ ++not_found_unlock: ++ spin_unlock(ptl); ++ if (start_ptep) ++ pte_unmap(start_ptep); ++ return 0; ++found_unlock: ++ get_page(page); ++ spin_unlock(ptl); ++ if (start_ptep) ++ pte_unmap(start_ptep); ++ private->page = page; ++ private->addr = addr; ++ return 1; ++} ++ ++static struct mm_walk_ops ksm_next_page_ops = { ++ .pmd_entry = ksm_next_page_pmd_entry, ++}; ++ + static struct rmap_item *scan_get_next_rmap_item(struct page **page) + { + struct mm_struct *mm; +@@ -2302,29 +2386,40 @@ next_mm: + ksm_scan.address = vma->vm_end; + + while (ksm_scan.address < vma->vm_end) { ++ struct ksm_next_page_arg ksm_next_page_arg; ++ struct page *tmp_page = NULL; ++ int found; ++ + if (ksm_test_exit(mm)) + break; +- *page = follow_page(vma, ksm_scan.address, FOLL_GET); +- if (IS_ERR_OR_NULL(*page)) { +- ksm_scan.address += PAGE_SIZE; +- cond_resched(); +- continue; ++ ++ found = walk_page_range_vma(vma, ksm_scan.address, ++ vma->vm_end, ++ &ksm_next_page_ops, ++ &ksm_next_page_arg); ++ ++ if (found > 0) { ++ tmp_page = ksm_next_page_arg.page; ++ ksm_scan.address = ksm_next_page_arg.addr; ++ } else { ++ VM_WARN_ON_ONCE(found < 0); ++ ksm_scan.address = vma->vm_end - PAGE_SIZE; + } +- if (PageAnon(*page)) { +- flush_anon_page(vma, *page, ksm_scan.address); +- flush_dcache_page(*page); ++ if (tmp_page) { ++ flush_anon_page(vma, tmp_page, ksm_scan.address); ++ flush_dcache_page(tmp_page); + rmap_item = get_next_rmap_item(slot, + ksm_scan.rmap_list, ksm_scan.address); + if (rmap_item) { + ksm_scan.rmap_list = + &rmap_item->rmap_list; + ksm_scan.address += PAGE_SIZE; ++ *page = tmp_page; + } else +- put_page(*page); ++ put_page(tmp_page); + mmap_read_unlock(mm); + return rmap_item; + } +- put_page(*page); + ksm_scan.address += PAGE_SIZE; + cond_resched(); + } diff --git a/queue-5.10/mei-trace-treat-reg-parameter-as-string.patch b/queue-5.10/mei-trace-treat-reg-parameter-as-string.patch new file mode 100644 index 0000000000..caa6d0ea08 --- /dev/null +++ b/queue-5.10/mei-trace-treat-reg-parameter-as-string.patch @@ -0,0 +1,104 @@ +From stable+bounces-212713-greg=kroah.com@vger.kernel.org Thu Jan 29 01:09:44 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 19:09:29 -0500 +Subject: mei: trace: treat reg parameter as string +To: stable@vger.kernel.org +Cc: Alexander Usyskin , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260129000930.2930326-1-sashal@kernel.org> + +From: Alexander Usyskin + +[ Upstream commit 06d5a7afe1d0b47102936d8fba568572c2b4b941 ] + +The commit +afd2627f727b ("tracing: Check "%s" dereference via the field and not the TP_printk format") +forbids to emit event with a plain char* without a wrapper. + +The reg parameter always passed as static string and wrapper +is not strictly required, contrary to dev parameter. +Use the string wrapper anyway to check sanity of the reg parameters, +store it value independently and prevent internal kernel data leaks. + +Since some code refactoring has taken place, explicit backporting may +be needed for kernels older than 6.10. + +Cc: stable@vger.kernel.org # v6.11+ +Fixes: a0a927d06d79 ("mei: me: add io register tracing") +Signed-off-by: Alexander Usyskin +Link: https://patch.msgid.link/20260111145125.1754912-1-alexander.usyskin@intel.com +Signed-off-by: Greg Kroah-Hartman +[ adapted single-argument __assign_str() calls to two-argument form ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/mei-trace.h | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/misc/mei/mei-trace.h ++++ b/drivers/misc/mei/mei-trace.h +@@ -21,18 +21,18 @@ TRACE_EVENT(mei_reg_read, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)) +- __entry->reg = reg; ++ __assign_str(reg, reg) + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] read %s:[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + TRACE_EVENT(mei_reg_write, +@@ -40,18 +40,18 @@ TRACE_EVENT(mei_reg_write, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)) +- __entry->reg = reg; ++ __assign_str(reg, reg) + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] write %s[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + TRACE_EVENT(mei_pci_cfg_read, +@@ -59,18 +59,18 @@ TRACE_EVENT(mei_pci_cfg_read, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)) +- __entry->reg = reg; ++ __assign_str(reg, reg) + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] pci cfg read %s:[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + #endif /* _MEI_TRACE_H_ */ diff --git a/queue-5.10/mm-pagewalk-add-walk_page_range_vma.patch b/queue-5.10/mm-pagewalk-add-walk_page_range_vma.patch new file mode 100644 index 0000000000..393023f1c2 --- /dev/null +++ b/queue-5.10/mm-pagewalk-add-walk_page_range_vma.patch @@ -0,0 +1,77 @@ +From stable+bounces-210187-greg=kroah.com@vger.kernel.org Sun Jan 18 00:38:26 2026 +From: Pedro Demarchi Gomes +Date: Sat, 17 Jan 2026 20:38:00 -0300 +Subject: mm/pagewalk: add walk_page_range_vma() +To: stable@vger.kernel.org +Cc: Zhi.Yang@windriver.com, David Hildenbrand , Andrea Arcangeli , Hugh Dickins , Jason Gunthorpe , John Hubbard , "Matthew Wilcox (Oracle)" , Peter Xu , Shuah Khan , Vlastimil Babka , Andrew Morton , Pedro Demarchi Gomes +Message-ID: <20260117233801.339606-1-pedrodemargomes@gmail.com> + +From: David Hildenbrand + +[ Upstream commit e07cda5f232fac4de0925d8a4c92e51e41fa2f6e ] + +Let's add walk_page_range_vma(), which is similar to walk_page_vma(), +however, is only interested in a subset of the VMA range. + +To be used in KSM code to stop using follow_page() next. + +Link: https://lkml.kernel.org/r/20221021101141.84170-8-david@redhat.com +Signed-off-by: David Hildenbrand +Cc: Andrea Arcangeli +Cc: Hugh Dickins +Cc: Jason Gunthorpe +Cc: John Hubbard +Cc: Matthew Wilcox (Oracle) +Cc: Peter Xu +Cc: Shuah Khan +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Stable-dep-of: f5548c318d6 ("ksm: use range-walk function to jump over holes in scan_get_next_rmap_item") +Signed-off-by: Pedro Demarchi Gomes +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/pagewalk.h | 3 +++ + mm/pagewalk.c | 20 ++++++++++++++++++++ + 2 files changed, 23 insertions(+) + +--- a/include/linux/pagewalk.h ++++ b/include/linux/pagewalk.h +@@ -99,6 +99,9 @@ int walk_page_range_novma(struct mm_stru + unsigned long end, const struct mm_walk_ops *ops, + pgd_t *pgd, + void *private); ++int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, ++ unsigned long end, const struct mm_walk_ops *ops, ++ void *private); + int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops, + void *private); + int walk_page_mapping(struct address_space *mapping, pgoff_t first_index, +--- a/mm/pagewalk.c ++++ b/mm/pagewalk.c +@@ -461,6 +461,26 @@ int walk_page_range_novma(struct mm_stru + return walk_pgd_range(start, end, &walk); + } + ++int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, ++ unsigned long end, const struct mm_walk_ops *ops, ++ void *private) ++{ ++ struct mm_walk walk = { ++ .ops = ops, ++ .mm = vma->vm_mm, ++ .vma = vma, ++ .private = private, ++ }; ++ ++ if (start >= end || !walk.mm) ++ return -EINVAL; ++ if (start < vma->vm_start || end > vma->vm_end) ++ return -EINVAL; ++ ++ mmap_assert_locked(walk.mm); ++ return __walk_page_range(start, end, &walk); ++} ++ + int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops, + void *private) + { diff --git a/queue-5.10/net-sched-act_ife-convert-comma-to-semicolon.patch b/queue-5.10/net-sched-act_ife-convert-comma-to-semicolon.patch new file mode 100644 index 0000000000..c5e271e1fa --- /dev/null +++ b/queue-5.10/net-sched-act_ife-convert-comma-to-semicolon.patch @@ -0,0 +1,44 @@ +From 205305c028ad986d0649b8b100bab6032dcd1bb5 Mon Sep 17 00:00:00 2001 +From: Chen Ni +Date: Wed, 12 Nov 2025 15:27:09 +0800 +Subject: net/sched: act_ife: convert comma to semicolon + +From: Chen Ni + +commit 205305c028ad986d0649b8b100bab6032dcd1bb5 upstream. + +Replace comma between expressions with semicolons. + +Using a ',' in place of a ';' can have unintended side effects. +Although that is not the case here, it is seems best to use ';' +unless ',' is intended. + +Found by inspection. +No functional change intended. +Compile tested only. + +Signed-off-by: Chen Ni +Reviewed-by: Jamal Hadi Salim +Link: https://patch.msgid.link/20251112072709.73755-1-nichen@iscas.ac.cn +Signed-off-by: Jakub Kicinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/act_ife.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/sched/act_ife.c ++++ b/net/sched/act_ife.c +@@ -648,9 +648,9 @@ static int tcf_ife_dump(struct sk_buff * + + memset(&opt, 0, sizeof(opt)); + +- opt.index = ife->tcf_index, +- opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref, +- opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind, ++ opt.index = ife->tcf_index; ++ opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref; ++ opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind; + + spin_lock_bh(&ife->tcf_lock); + opt.action = ife->tcf_action; diff --git a/queue-5.10/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch b/queue-5.10/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch new file mode 100644 index 0000000000..b906b80e56 --- /dev/null +++ b/queue-5.10/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch @@ -0,0 +1,47 @@ +From stable+bounces-210669-greg=kroah.com@vger.kernel.org Wed Jan 21 04:06:29 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 22:06:17 -0500 +Subject: nvme-fc: rename free_ctrl callback to match name pattern +To: stable@vger.kernel.org +Cc: Daniel Wagner , Christoph Hellwig , Sagi Grimberg , Hannes Reinecke , Keith Busch , Sasha Levin +Message-ID: <20260121030619.1172509-1-sashal@kernel.org> + +From: Daniel Wagner + +[ Upstream commit 205fb5fa6fde1b5b426015eb1ff69f2ff25ef5bb ] + +Rename nvme_fc_nvme_ctrl_freed to nvme_fc_free_ctrl to match the name +pattern for the callback. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -2409,7 +2409,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ct + * controller. Called after last nvme_put_ctrl() call + */ + static void +-nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl) ++nvme_fc_free_ctrl(struct nvme_ctrl *nctrl) + { + struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); + +@@ -3350,7 +3350,7 @@ static const struct nvme_ctrl_ops nvme_f + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, +- .free_ctrl = nvme_fc_nvme_ctrl_freed, ++ .free_ctrl = nvme_fc_free_ctrl, + .submit_async_event = nvme_fc_submit_async_event, + .delete_ctrl = nvme_fc_delete_ctrl, + .get_address = nvmf_get_address, diff --git a/queue-5.10/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch b/queue-5.10/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch new file mode 100644 index 0000000000..2335ac199a --- /dev/null +++ b/queue-5.10/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch @@ -0,0 +1,58 @@ +From stable+bounces-210671-greg=kroah.com@vger.kernel.org Wed Jan 21 04:06:34 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 22:06:19 -0500 +Subject: nvme: fix PCIe subsystem reset controller state transition +To: stable@vger.kernel.org +Cc: Nilay Shroff , Daniel Wagner , Keith Busch , Sasha Levin +Message-ID: <20260121030619.1172509-3-sashal@kernel.org> + +From: Nilay Shroff + +[ Upstream commit 0edb475ac0a7d153318a24d4dca175a270a5cc4f ] + +The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING +state”) disallows controller state transitions directly from RESETTING +to LIVE. However, the NVMe PCIe subsystem reset path relies on this +transition to recover the controller on PowerPC (PPC) systems. + +On PPC systems, issuing a subsystem reset causes a temporary loss of +communication with the NVMe adapter. A subsequent PCIe MMIO read then +triggers EEH recovery, which restores the PCIe link and brings the +controller back online. For EEH recovery to proceed correctly, the +controller must transition back to the LIVE state. + +Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow +entering LIVE from CONNECTING state”), the controller can no longer +transition directly from RESETTING to LIVE. As a result, EEH recovery +exits prematurely, leaving the controller stuck in the RESETTING state. + +Fix this by explicitly transitioning the controller state from RESETTING +to CONNECTING and then to LIVE. This satisfies the updated state +transition rules and allows the controller to be successfully recovered +on PPC systems following a PCIe subsystem reset. + +Cc: stable@vger.kernel.org +Fixes: d2fe192348f9 ("nvme: only allow entering LIVE from CONNECTING state") +Reviewed-by: Daniel Wagner +Signed-off-by: Nilay Shroff +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/pci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1146,7 +1146,10 @@ static int nvme_pci_subsystem_reset(stru + } + + writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); +- nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); ++ ++ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) || ++ !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) ++ goto unlock; + + /* + * Read controller status to flush the previous write and trigger a diff --git a/queue-5.10/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch b/queue-5.10/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch new file mode 100644 index 0000000000..7eb2a1a6f9 --- /dev/null +++ b/queue-5.10/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch @@ -0,0 +1,205 @@ +From stable+bounces-210670-greg=kroah.com@vger.kernel.org Wed Jan 21 04:06:31 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 22:06:18 -0500 +Subject: nvme-pci: do not directly handle subsys reset fallout +To: stable@vger.kernel.org +Cc: Keith Busch , Nilay Shroff , Christoph Hellwig , Sasha Levin +Message-ID: <20260121030619.1172509-2-sashal@kernel.org> + +From: Keith Busch + +[ Upstream commit 210b1f6576e8b367907e7ff51ef425062e1468e4 ] + +Scheduling reset_work after a nvme subsystem reset is expected to fail +on pcie, but this also prevents potential handling the platform's pcie +services may provide that might successfully recovering the link without +re-enumeration. Such examples include AER, DPC, and power's EEH. + +Provide a pci specific operation that safely initiates a subsystem +reset, and instead of scheduling reset work, read back the status +register to trigger a pcie read error. + +Since this only affects pci, the other fabrics drivers subscribe to a +generic nvmf subsystem reset that is exactly the same as before. The +loop fabric doesn't use it because nvmet doesn't support setting that +property anyway. + +And since we're using the magic NSSR value in two places now, provide a +symbolic define for it. + +Reported-by: Nilay Shroff +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fabrics.c | 15 +++++++++++++++ + drivers/nvme/host/fabrics.h | 1 + + drivers/nvme/host/fc.c | 1 + + drivers/nvme/host/nvme.h | 14 +++----------- + drivers/nvme/host/pci.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/nvme/host/rdma.c | 1 + + drivers/nvme/host/tcp.c | 1 + + include/linux/nvme.h | 3 +++ + 8 files changed, 61 insertions(+), 11 deletions(-) + +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -253,6 +253,21 @@ int nvmf_reg_write32(struct nvme_ctrl *c + } + EXPORT_SYMBOL_GPL(nvmf_reg_write32); + ++int nvmf_subsystem_reset(struct nvme_ctrl *ctrl) ++{ ++ int ret; ++ ++ if (!nvme_wait_reset(ctrl)) ++ return -EBUSY; ++ ++ ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, NVME_SUBSYS_RESET); ++ if (ret) ++ return ret; ++ ++ return nvme_try_sched_reset(ctrl); ++} ++EXPORT_SYMBOL_GPL(nvmf_subsystem_reset); ++ + /** + * nvmf_log_connect_error() - Error-parsing-diagnostic print + * out function for connect() errors. +--- a/drivers/nvme/host/fabrics.h ++++ b/drivers/nvme/host/fabrics.h +@@ -166,6 +166,7 @@ nvmf_ctlr_matches_baseopts(struct nvme_c + int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val); + int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val); + int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val); ++int nvmf_subsystem_reset(struct nvme_ctrl *ctrl); + int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl); + int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid, bool poll); + int nvmf_register_transport(struct nvmf_transport_ops *ops); +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -3350,6 +3350,7 @@ static const struct nvme_ctrl_ops nvme_f + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_fc_free_ctrl, + .submit_async_event = nvme_fc_submit_async_event, + .delete_ctrl = nvme_fc_delete_ctrl, +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -485,6 +485,7 @@ struct nvme_ctrl_ops { + int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val); + void (*free_ctrl)(struct nvme_ctrl *ctrl); + void (*submit_async_event)(struct nvme_ctrl *ctrl); ++ int (*subsystem_reset)(struct nvme_ctrl *ctrl); + void (*delete_ctrl)(struct nvme_ctrl *ctrl); + void (*stop_ctrl)(struct nvme_ctrl *ctrl); + int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); +@@ -554,18 +555,9 @@ int nvme_try_sched_reset(struct nvme_ctr + + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) + { +- int ret; +- +- if (!ctrl->subsystem) ++ if (!ctrl->subsystem || !ctrl->ops->subsystem_reset) + return -ENOTTY; +- if (!nvme_wait_reset(ctrl)) +- return -EBUSY; +- +- ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); +- if (ret) +- return ret; +- +- return nvme_try_sched_reset(ctrl); ++ return ctrl->ops->subsystem_reset(ctrl); + } + + /* +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1123,6 +1123,41 @@ static void nvme_pci_submit_async_event( + spin_unlock(&nvmeq->sq_lock); + } + ++static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl) ++{ ++ struct nvme_dev *dev = to_nvme_dev(ctrl); ++ int ret = 0; ++ ++ /* ++ * Taking the shutdown_lock ensures the BAR mapping is not being ++ * altered by reset_work. Holding this lock before the RESETTING state ++ * change, if successful, also ensures nvme_remove won't be able to ++ * proceed to iounmap until we're done. ++ */ ++ mutex_lock(&dev->shutdown_lock); ++ if (!dev->bar_mapped_size) { ++ ret = -ENODEV; ++ goto unlock; ++ } ++ ++ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) { ++ ret = -EBUSY; ++ goto unlock; ++ } ++ ++ writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); ++ nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); ++ ++ /* ++ * Read controller status to flush the previous write and trigger a ++ * pcie read error. ++ */ ++ readl(dev->bar + NVME_REG_CSTS); ++unlock: ++ mutex_unlock(&dev->shutdown_lock); ++ return ret; ++} ++ + static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) + { + struct nvme_command c; +@@ -2844,6 +2879,7 @@ static const struct nvme_ctrl_ops nvme_p + .reg_read64 = nvme_pci_reg_read64, + .free_ctrl = nvme_pci_free_ctrl, + .submit_async_event = nvme_pci_submit_async_event, ++ .subsystem_reset = nvme_pci_subsystem_reset, + .get_address = nvme_pci_get_address, + }; + +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -2293,6 +2293,7 @@ static const struct nvme_ctrl_ops nvme_r + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_rdma_free_ctrl, + .submit_async_event = nvme_rdma_submit_async_event, + .delete_ctrl = nvme_rdma_delete_ctrl, +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -2530,6 +2530,7 @@ static const struct nvme_ctrl_ops nvme_t + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_tcp_free_ctrl, + .submit_async_event = nvme_tcp_submit_async_event, + .delete_ctrl = nvme_tcp_delete_ctrl, +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -27,6 +27,9 @@ + + #define NVME_NSID_ALL 0xffffffff + ++/* Special NSSR value, 'NVMe' */ ++#define NVME_SUBSYS_RESET 0x4E564D65 ++ + enum nvme_subsys_type { + NVME_NQN_DISC = 1, /* Discovery type target subsystem */ + NVME_NQN_NVME = 2, /* NVME type target subsystem */ diff --git a/queue-5.10/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch b/queue-5.10/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch new file mode 100644 index 0000000000..f16654a62b --- /dev/null +++ b/queue-5.10/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch @@ -0,0 +1,40 @@ +From stable+bounces-211668-greg=kroah.com@vger.kernel.org Mon Jan 26 18:47:01 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 12:46:54 -0500 +Subject: scsi: xen: scsiback: Fix potential memory leak in scsiback_remove() +To: stable@vger.kernel.org +Cc: Abdun Nihaal , Juergen Gross , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260126174654.3437191-1-sashal@kernel.org> + +From: Abdun Nihaal + +[ Upstream commit 901a5f309daba412e2a30364d7ec1492fa11c32c ] + +Memory allocated for struct vscsiblk_info in scsiback_probe() is not +freed in scsiback_remove() leading to potential memory leaks on remove, +as well as in the scsiback_probe() error paths. Fix that by freeing it +in scsiback_remove(). + +Cc: stable@vger.kernel.org +Fixes: d9d660f6e562 ("xen-scsiback: Add Xen PV SCSI backend driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20251223063012.119035-1-nihaal@cse.iitm.ac.in +Signed-off-by: Martin K. Petersen +[ adapted void scsiback_remove() to int return type with return 0 statement ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/xen-scsiback.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/xen/xen-scsiback.c ++++ b/drivers/xen/xen-scsiback.c +@@ -1202,6 +1202,7 @@ static int scsiback_remove(struct xenbus + gnttab_page_cache_shrink(&info->free_pages, 0); + + dev_set_drvdata(&dev->dev, NULL); ++ kfree(info); + + return 0; + } diff --git a/queue-5.10/series b/queue-5.10/series index 8365cc8a45..bd51e9d82d 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -133,3 +133,18 @@ net-bridge-fix-static-key-check.patch scsi-firewire-sbp-target-fix-overflow-in-sbp_make_tp.patch dma-pool-distinguish-between-missing-and-exhausted-a.patch scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch +net-sched-act_ife-convert-comma-to-semicolon.patch +nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch +nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch +nvme-fix-pcie-subsystem-reset-controller-state-transition.patch +xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch +dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch +dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch +scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch +w1-w1_therm-use-swap-to-make-code-cleaner.patch +w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch +iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch +mei-trace-treat-reg-parameter-as-string.patch +driver-core-fix-potential-null-ptr-deref-in-device_add.patch +mm-pagewalk-add-walk_page_range_vma.patch +ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch diff --git a/queue-5.10/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch b/queue-5.10/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch new file mode 100644 index 0000000000..53b2ee598e --- /dev/null +++ b/queue-5.10/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch @@ -0,0 +1,136 @@ +From stable+bounces-211645-greg=kroah.com@vger.kernel.org Mon Jan 26 16:59:34 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 10:59:29 -0500 +Subject: w1: therm: Fix off-by-one buffer overflow in alarms_store +To: stable@vger.kernel.org +Cc: Thorsten Blum , Krzysztof Kozlowski , Sasha Levin +Message-ID: <20260126155929.3332297-2-sashal@kernel.org> + +From: Thorsten Blum + +[ Upstream commit 761fcf46a1bd797bd32d23f3ea0141ffd437668a ] + +The sysfs buffer passed to alarms_store() is allocated with 'size + 1' +bytes and a NUL terminator is appended. However, the 'size' argument +does not account for this extra byte. The original code then allocated +'size' bytes and used strcpy() to copy 'buf', which always writes one +byte past the allocated buffer since strcpy() copies until the NUL +terminator at index 'size'. + +Fix this by parsing the 'buf' parameter directly using simple_strtoll() +without allocating any intermediate memory or string copying. This +removes the overflow while simplifying the code. + +Cc: stable@vger.kernel.org +Fixes: e2c94d6f5720 ("w1_therm: adding alarm sysfs entry") +Signed-off-by: Thorsten Blum +Link: https://patch.msgid.link/20251216145007.44328-2-thorsten.blum@linux.dev +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_therm.c | 60 +++++++++++++------------------------------ + 1 file changed, 19 insertions(+), 41 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -1781,53 +1781,35 @@ static ssize_t alarms_store(struct devic + struct w1_slave *sl = dev_to_w1_slave(device); + struct therm_info info; + u8 new_config_register[3]; /* array of data to be written */ +- int temp, ret; +- char *token = NULL; ++ long long temp; ++ int ret = 0; + s8 tl, th; /* 1 byte per value + temp ring order */ +- char *p_args, *orig; ++ const char *p = buf; ++ char *endp; + +- p_args = orig = kmalloc(size, GFP_KERNEL); +- /* Safe string copys as buf is const */ +- if (!p_args) { +- dev_warn(device, +- "%s: error unable to allocate memory %d\n", +- __func__, -ENOMEM); +- return size; +- } +- strcpy(p_args, buf); +- +- /* Split string using space char */ +- token = strsep(&p_args, " "); +- +- if (!token) { +- dev_info(device, +- "%s: error parsing args %d\n", __func__, -EINVAL); +- goto free_m; +- } +- +- /* Convert 1st entry to int */ +- ret = kstrtoint (token, 10, &temp); ++ temp = simple_strtoll(p, &endp, 10); ++ if (p == endp || *endp != ' ') ++ ret = -EINVAL; ++ else if (temp < INT_MIN || temp > INT_MAX) ++ ret = -ERANGE; + if (ret) { + dev_info(device, + "%s: error parsing args %d\n", __func__, ret); +- goto free_m; ++ return size; + } + + tl = int_to_short(temp); + +- /* Split string using space char */ +- token = strsep(&p_args, " "); +- if (!token) { +- dev_info(device, +- "%s: error parsing args %d\n", __func__, -EINVAL); +- goto free_m; +- } +- /* Convert 2nd entry to int */ +- ret = kstrtoint (token, 10, &temp); ++ p = endp + 1; ++ temp = simple_strtoll(p, &endp, 10); ++ if (p == endp) ++ ret = -EINVAL; ++ else if (temp < INT_MIN || temp > INT_MAX) ++ ret = -ERANGE; + if (ret) { + dev_info(device, + "%s: error parsing args %d\n", __func__, ret); +- goto free_m; ++ return size; + } + + /* Prepare to cast to short by eliminating out of range values */ +@@ -1850,7 +1832,7 @@ static ssize_t alarms_store(struct devic + dev_info(device, + "%s: error reading from the slave device %d\n", + __func__, ret); +- goto free_m; ++ return size; + } + + /* Write data in the device RAM */ +@@ -1858,7 +1840,7 @@ static ssize_t alarms_store(struct devic + dev_info(device, + "%s: Device not supported by the driver %d\n", + __func__, -ENODEV); +- goto free_m; ++ return size; + } + + ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register); +@@ -1867,10 +1849,6 @@ static ssize_t alarms_store(struct devic + "%s: error writing to the slave device %d\n", + __func__, ret); + +-free_m: +- /* free allocated memory */ +- kfree(orig); +- + return size; + } + diff --git a/queue-5.10/w1-w1_therm-use-swap-to-make-code-cleaner.patch b/queue-5.10/w1-w1_therm-use-swap-to-make-code-cleaner.patch new file mode 100644 index 0000000000..3cba91c531 --- /dev/null +++ b/queue-5.10/w1-w1_therm-use-swap-to-make-code-cleaner.patch @@ -0,0 +1,50 @@ +From stable+bounces-211644-greg=kroah.com@vger.kernel.org Mon Jan 26 16:59:34 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 10:59:28 -0500 +Subject: w1: w1_therm: use swap() to make code cleaner +To: stable@vger.kernel.org +Cc: Yang Guang , Zeal Robot , David Yang , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260126155929.3332297-1-sashal@kernel.org> + +From: Yang Guang + +[ Upstream commit e233897b1f7a859092bd20b10bfd412013381a10 ] + +Use the macro 'swap()' defined in 'include/linux/minmax.h' to avoid +opencoding it. + +Reported-by: Zeal Robot +Signed-off-by: David Yang +Signed-off-by: Yang Guang +Link: https://lore.kernel.org/r/cb14f9e6e86cf8494ed2ddce6eec8ebd988908d9.1640077704.git.yang.guang5@zte.com.cn +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 761fcf46a1bd ("w1: therm: Fix off-by-one buffer overflow in alarms_store") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_therm.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -1783,7 +1783,7 @@ static ssize_t alarms_store(struct devic + u8 new_config_register[3]; /* array of data to be written */ + int temp, ret; + char *token = NULL; +- s8 tl, th, tt; /* 1 byte per value + temp ring order */ ++ s8 tl, th; /* 1 byte per value + temp ring order */ + char *p_args, *orig; + + p_args = orig = kmalloc(size, GFP_KERNEL); +@@ -1834,9 +1834,8 @@ static ssize_t alarms_store(struct devic + th = int_to_short(temp); + + /* Reorder if required th and tl */ +- if (tl > th) { +- tt = tl; tl = th; th = tt; +- } ++ if (tl > th) ++ swap(tl, th); + + /* + * Read the scratchpad to change only the required bits diff --git a/queue-5.10/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch b/queue-5.10/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch new file mode 100644 index 0000000000..aeea927528 --- /dev/null +++ b/queue-5.10/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch @@ -0,0 +1,85 @@ +From stable+bounces-210653-greg=kroah.com@vger.kernel.org Wed Jan 21 03:50:56 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:42:42 -0500 +Subject: xfs: set max_agbno to allow sparse alloc of last full inode chunk +To: stable@vger.kernel.org +Cc: Brian Foster , "Darrick J. Wong" , Carlos Maiolino , Sasha Levin +Message-ID: <20260121024242.1136177-1-sashal@kernel.org> + +From: Brian Foster + +[ Upstream commit c360004c0160dbe345870f59f24595519008926f ] + +Sparse inode cluster allocation sets min/max agbno values to avoid +allocating an inode cluster that might map to an invalid inode +chunk. For example, we can't have an inode record mapped to agbno 0 +or that extends past the end of a runt AG of misaligned size. + +The initial calculation of max_agbno is unnecessarily conservative, +however. This has triggered a corner case allocation failure where a +small runt AG (i.e. 2063 blocks) is mostly full save for an extent +to the EOFS boundary: [2050,13]. max_agbno is set to 2048 in this +case, which happens to be the offset of the last possible valid +inode chunk in the AG. In practice, we should be able to allocate +the 4-block cluster at agbno 2052 to map to the parent inode record +at agbno 2048, but the max_agbno value precludes it. + +Note that this can result in filesystem shutdown via dirty trans +cancel on stable kernels prior to commit 9eb775968b68 ("xfs: walk +all AGs if TRYLOCK passed to xfs_alloc_vextent_iterate_ags") because +the tail AG selection by the allocator sets t_highest_agno on the +transaction. If the inode allocator spins around and finds an inode +chunk with free inodes in an earlier AG, the subsequent dir name +creation path may still fail to allocate due to the AG restriction +and cancel. + +To avoid this problem, update the max_agbno calculation to the agbno +prior to the last chunk aligned agbno in the AG. This is not +necessarily the last valid allocation target for a sparse chunk, but +since inode chunks (i.e. records) are chunk aligned and sparse +allocs are cluster sized/aligned, this allows the sb_spino_align +alignment restriction to take over and round down the max effective +agbno to within the last valid inode chunk in the AG. + +Note that even though the allocator improvements in the +aforementioned commit seem to avoid this particular dirty trans +cancel situation, the max_agbno logic improvement still applies as +we should be able to allocate from an AG that has been appropriately +selected. The more important target for this patch however are +older/stable kernels prior to this allocator rework/improvement. + +Cc: stable@vger.kernel.org # v4.2 +Fixes: 56d1115c9bc7 ("xfs: allocate sparse inode chunks on full chunk allocation failure") +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +[ xfs_ag_block_count(args.mp, pag_agno(pag)) => args.mp->m_sb.sb_agblocks ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_ialloc.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/fs/xfs/libxfs/xfs_ialloc.c ++++ b/fs/xfs/libxfs/xfs_ialloc.c +@@ -777,14 +777,15 @@ sparse_alloc: + * invalid inode records, such as records that start at agbno 0 + * or extend beyond the AG. + * +- * Set min agbno to the first aligned, non-zero agbno and max to +- * the last aligned agbno that is at least one full chunk from +- * the end of the AG. ++ * Set min agbno to the first chunk aligned, non-zero agbno and ++ * max to one less than the last chunk aligned agbno from the ++ * end of the AG. We subtract 1 from max so that the cluster ++ * allocation alignment takes over and allows allocation within ++ * the last full inode chunk in the AG. + */ + args.min_agbno = args.mp->m_sb.sb_inoalignmt; + args.max_agbno = round_down(args.mp->m_sb.sb_agblocks, +- args.mp->m_sb.sb_inoalignmt) - +- igeo->ialloc_blks; ++ args.mp->m_sb.sb_inoalignmt) - 1; + + error = xfs_alloc_vextent(&args); + if (error) -- 2.47.3