--- /dev/null
+From 57054fe516d59d03a7bcf1888e82479ccc244f87 Mon Sep 17 00:00:00 2001
+From: "Shawn.Shao" <shawn.shao@jaguarmicro.com>
+Date: Thu, 12 Jan 2023 13:58:02 +0800
+Subject: Add exception protection processing for vd in axi_chan_handle_err function
+
+From: Shawn.Shao <shawn.shao@jaguarmicro.com>
+
+commit 57054fe516d59d03a7bcf1888e82479ccc244f87 upstream.
+
+Since there is no protection for vd, a kernel panic will be
+triggered here in exceptional cases.
+
+You can refer to the processing of axi_chan_block_xfer_complete function
+
+The triggered kernel panic is as follows:
+
+[ 67.848444] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000060
+[ 67.848447] Mem abort info:
+[ 67.848449] ESR = 0x96000004
+[ 67.848451] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 67.848454] SET = 0, FnV = 0
+[ 67.848456] EA = 0, S1PTW = 0
+[ 67.848458] Data abort info:
+[ 67.848460] ISV = 0, ISS = 0x00000004
+[ 67.848462] CM = 0, WnR = 0
+[ 67.848465] user pgtable: 4k pages, 48-bit VAs, pgdp=00000800c4c0b000
+[ 67.848468] [0000000000000060] pgd=0000000000000000, p4d=0000000000000000
+[ 67.848472] Internal error: Oops: 96000004 [#1] SMP
+[ 67.848475] Modules linked in: dmatest
+[ 67.848479] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.100-emu_x2rc+ #11
+[ 67.848483] pstate: 62000085 (nZCv daIf -PAN -UAO +TCO BTYPE=--)
+[ 67.848487] pc : axi_chan_handle_err+0xc4/0x230
+[ 67.848491] lr : axi_chan_handle_err+0x30/0x230
+[ 67.848493] sp : ffff0803fe55ae50
+[ 67.848495] x29: ffff0803fe55ae50 x28: ffff800011212200
+[ 67.848500] x27: ffff0800c42c0080 x26: ffff0800c097c080
+[ 67.848504] x25: ffff800010d33880 x24: ffff80001139d850
+[ 67.848508] x23: ffff0800c097c168 x22: 0000000000000000
+[ 67.848512] x21: 0000000000000080 x20: 0000000000002000
+[ 67.848517] x19: ffff0800c097c080 x18: 0000000000000000
+[ 67.848521] x17: 0000000000000000 x16: 0000000000000000
+[ 67.848525] x15: 0000000000000000 x14: 0000000000000000
+[ 67.848529] x13: 0000000000000000 x12: 0000000000000040
+[ 67.848533] x11: ffff0800c0400248 x10: ffff0800c040024a
+[ 67.848538] x9 : ffff800010576cd4 x8 : ffff0800c0400270
+[ 67.848542] x7 : 0000000000000000 x6 : ffff0800c04003e0
+[ 67.848546] x5 : ffff0800c0400248 x4 : ffff0800c4294480
+[ 67.848550] x3 : dead000000000100 x2 : dead000000000122
+[ 67.848555] x1 : 0000000000000100 x0 : ffff0800c097c168
+[ 67.848559] Call trace:
+[ 67.848562] axi_chan_handle_err+0xc4/0x230
+[ 67.848566] dw_axi_dma_interrupt+0xf4/0x590
+[ 67.848569] __handle_irq_event_percpu+0x60/0x220
+[ 67.848573] handle_irq_event+0x64/0x120
+[ 67.848576] handle_fasteoi_irq+0xc4/0x220
+[ 67.848580] __handle_domain_irq+0x80/0xe0
+[ 67.848583] gic_handle_irq+0xc0/0x138
+[ 67.848585] el1_irq+0xc8/0x180
+[ 67.848588] arch_cpu_idle+0x14/0x2c
+[ 67.848591] default_idle_call+0x40/0x16c
+[ 67.848594] do_idle+0x1f0/0x250
+[ 67.848597] cpu_startup_entry+0x2c/0x60
+[ 67.848600] rest_init+0xc0/0xcc
+[ 67.848603] arch_call_rest_init+0x14/0x1c
+[ 67.848606] start_kernel+0x4cc/0x500
+[ 67.848610] Code: eb0002ff 9a9f12d6 f2fbd5a2 f2fbd5a3 (a94602c1)
+[ 67.848613] ---[ end trace 585a97036f88203a ]---
+
+Signed-off-by: Shawn.Shao <shawn.shao@jaguarmicro.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230112055802.1764-1-shawn.shao@jaguarmicro.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -1018,6 +1018,11 @@ static noinline void axi_chan_handle_err
+
+ /* The bad descriptor currently is in the head of vc list */
+ vd = vchan_next_desc(&chan->vc);
++ if (!vd) {
++ dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n",
++ axi_chan_name(chan));
++ goto out;
++ }
+ /* Remove the completed descriptor from issued list */
+ list_del(&vd->node);
+
+@@ -1032,6 +1037,7 @@ static noinline void axi_chan_handle_err
+ /* Try to restart the controller */
+ axi_chan_start_first_queued(chan);
+
++out:
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
+ }
+
--- /dev/null
+From 272970be3dabd24cbe50e393ffee8f04aec3b9a8 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Thu, 29 Dec 2022 11:28:29 +0100
+Subject: Bluetooth: hci_qca: Fix driver shutdown on closed serdev
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+commit 272970be3dabd24cbe50e393ffee8f04aec3b9a8 upstream.
+
+The driver shutdown callback (which sends EDL_SOC_RESET to the device
+over serdev) should not be invoked when HCI device is not open (e.g. if
+hci_dev_open_sync() failed), because the serdev and its TTY are not open
+either. Also skip this step if device is powered off
+(qca_power_shutdown()).
+
+The shutdown callback causes use-after-free during system reboot with
+Qualcomm Atheros Bluetooth:
+
+ Unable to handle kernel paging request at virtual address
+ 0072662f67726fd7
+ ...
+ CPU: 6 PID: 1 Comm: systemd-shutdow Tainted: G W
+ 6.1.0-rt5-00325-g8a5f56bcfcca #8
+ Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
+ Call trace:
+ tty_driver_flush_buffer+0x4/0x30
+ serdev_device_write_flush+0x24/0x34
+ qca_serdev_shutdown+0x80/0x130 [hci_uart]
+ device_shutdown+0x15c/0x260
+ kernel_restart+0x48/0xac
+
+KASAN report:
+
+ BUG: KASAN: use-after-free in tty_driver_flush_buffer+0x1c/0x50
+ Read of size 8 at addr ffff16270c2e0018 by task systemd-shutdow/1
+
+ CPU: 7 PID: 1 Comm: systemd-shutdow Not tainted
+ 6.1.0-next-20221220-00014-gb85aaf97fb01-dirty #28
+ Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
+ Call trace:
+ dump_backtrace.part.0+0xdc/0xf0
+ show_stack+0x18/0x30
+ dump_stack_lvl+0x68/0x84
+ print_report+0x188/0x488
+ kasan_report+0xa4/0xf0
+ __asan_load8+0x80/0xac
+ tty_driver_flush_buffer+0x1c/0x50
+ ttyport_write_flush+0x34/0x44
+ serdev_device_write_flush+0x48/0x60
+ qca_serdev_shutdown+0x124/0x274
+ device_shutdown+0x1e8/0x350
+ kernel_restart+0x48/0xb0
+ __do_sys_reboot+0x244/0x2d0
+ __arm64_sys_reboot+0x54/0x70
+ invoke_syscall+0x60/0x190
+ el0_svc_common.constprop.0+0x7c/0x160
+ do_el0_svc+0x44/0xf0
+ el0_svc+0x2c/0x6c
+ el0t_64_sync_handler+0xbc/0x140
+ el0t_64_sync+0x190/0x194
+
+Fixes: 7e7bbddd029b ("Bluetooth: hci_qca: Fix qca6390 enable failure after warm reboot")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_qca.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -2157,10 +2157,17 @@ static void qca_serdev_shutdown(struct d
+ int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
+ struct serdev_device *serdev = to_serdev_device(dev);
+ struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
++ struct hci_uart *hu = &qcadev->serdev_hu;
++ struct hci_dev *hdev = hu->hdev;
++ struct qca_data *qca = hu->priv;
+ const u8 ibs_wake_cmd[] = { 0xFD };
+ const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
+
+ if (qcadev->btsoc_type == QCA_QCA6390) {
++ if (test_bit(QCA_BT_OFF, &qca->flags) ||
++ !test_bit(HCI_RUNNING, &hdev->flags))
++ return;
++
+ serdev_device_write_flush(serdev);
+ ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
+ sizeof(ibs_wake_cmd));
--- /dev/null
+From 3a4d29b6d631bb00236a98887e1039bbfc1b6ab5 Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Date: Mon, 19 Dec 2022 13:32:51 -0800
+Subject: Bluetooth: hci_sync: Fix use HCI_OP_LE_READ_BUFFER_SIZE_V2
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+commit 3a4d29b6d631bb00236a98887e1039bbfc1b6ab5 upstream.
+
+Don't try to use HCI_OP_LE_READ_BUFFER_SIZE_V2 if controller don't
+support ISO channels, but in order to check if ISO channels are
+supported HCI_OP_LE_READ_LOCAL_FEATURES needs to be done earlier so the
+features bits can be checked on hci_le_read_buffer_size_sync.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216817
+Fixes: c1631dbc00c1 ("Bluetooth: hci_sync: Fix hci_read_buffer_size_sync")
+Cc: stable@vger.kernel.org # 6.1
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hci_sync.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3554,7 +3554,7 @@ static const struct hci_init_stage hci_i
+ static int hci_le_read_buffer_size_sync(struct hci_dev *hdev)
+ {
+ /* Use Read LE Buffer Size V2 if supported */
+- if (hdev->commands[41] & 0x20)
++ if (iso_capable(hdev) && hdev->commands[41] & 0x20)
+ return __hci_cmd_sync_status(hdev,
+ HCI_OP_LE_READ_BUFFER_SIZE_V2,
+ 0, NULL, HCI_CMD_TIMEOUT);
+@@ -3579,10 +3579,10 @@ static int hci_le_read_supported_states_
+
+ /* LE Controller init stage 2 command sequence */
+ static const struct hci_init_stage le_init2[] = {
+- /* HCI_OP_LE_READ_BUFFER_SIZE */
+- HCI_INIT(hci_le_read_buffer_size_sync),
+ /* HCI_OP_LE_READ_LOCAL_FEATURES */
+ HCI_INIT(hci_le_read_local_features_sync),
++ /* HCI_OP_LE_READ_BUFFER_SIZE */
++ HCI_INIT(hci_le_read_buffer_size_sync),
+ /* HCI_OP_LE_READ_SUPPORTED_STATES */
+ HCI_INIT(hci_le_read_supported_states_sync),
+ {}
--- /dev/null
+From b30c14cd61025eeea2f2e8569606cd167ba9ad2d Mon Sep 17 00:00:00 2001
+From: James Houghton <jthoughton@google.com>
+Date: Wed, 4 Jan 2023 23:19:10 +0000
+Subject: hugetlb: unshare some PMDs when splitting VMAs
+
+From: James Houghton <jthoughton@google.com>
+
+commit b30c14cd61025eeea2f2e8569606cd167ba9ad2d upstream.
+
+PMD sharing can only be done in PUD_SIZE-aligned pieces of VMAs; however,
+it is possible that HugeTLB VMAs are split without unsharing the PMDs
+first.
+
+Without this fix, it is possible to hit the uffd-wp-related WARN_ON_ONCE
+in hugetlb_change_protection [1]. The key there is that
+hugetlb_unshare_all_pmds will not attempt to unshare PMDs in
+non-PUD_SIZE-aligned sections of the VMA.
+
+It might seem ideal to unshare in hugetlb_vm_op_open, but we need to
+unshare in both the new and old VMAs, so unsharing in hugetlb_vm_op_split
+seems natural.
+
+[1]: https://lore.kernel.org/linux-mm/CADrL8HVeOkj0QH5VZZbRzybNE8CG-tEGFshnA+bG9nMgcWtBSg@mail.gmail.com/
+
+Link: https://lkml.kernel.org/r/20230104231910.1464197-1-jthoughton@google.com
+Fixes: 6dfeaff93be1 ("hugetlb/userfaultfd: unshare all pmds for hugetlbfs when register wp")
+Signed-off-by: James Houghton <jthoughton@google.com>
+Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
+Acked-by: Peter Xu <peterx@redhat.com>
+Cc: Axel Rasmussen <axelrasmussen@google.com>
+Cc: Muchun Song <songmuchun@bytedance.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/hugetlb.c | 44 +++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 35 insertions(+), 9 deletions(-)
+
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -94,6 +94,8 @@ static int hugetlb_acct_memory(struct hs
+ static void hugetlb_vma_lock_free(struct vm_area_struct *vma);
+ static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma);
+ static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma);
++static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
++ unsigned long start, unsigned long end);
+
+ static inline bool subpool_is_free(struct hugepage_subpool *spool)
+ {
+@@ -4825,6 +4827,25 @@ static int hugetlb_vm_op_split(struct vm
+ {
+ if (addr & ~(huge_page_mask(hstate_vma(vma))))
+ return -EINVAL;
++
++ /*
++ * PMD sharing is only possible for PUD_SIZE-aligned address ranges
++ * in HugeTLB VMAs. If we will lose PUD_SIZE alignment due to this
++ * split, unshare PMDs in the PUD_SIZE interval surrounding addr now.
++ */
++ if (addr & ~PUD_MASK) {
++ /*
++ * hugetlb_vm_op_split is called right before we attempt to
++ * split the VMA. We will need to unshare PMDs in the old and
++ * new VMAs, so let's unshare before we split.
++ */
++ unsigned long floor = addr & PUD_MASK;
++ unsigned long ceil = floor + PUD_SIZE;
++
++ if (floor >= vma->vm_start && ceil <= vma->vm_end)
++ hugetlb_unshare_pmds(vma, floor, ceil);
++ }
++
+ return 0;
+ }
+
+@@ -7386,26 +7407,21 @@ void move_hugetlb_state(struct page *old
+ }
+ }
+
+-/*
+- * This function will unconditionally remove all the shared pmd pgtable entries
+- * within the specific vma for a hugetlbfs memory range.
+- */
+-void hugetlb_unshare_all_pmds(struct vm_area_struct *vma)
++static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
++ unsigned long start,
++ unsigned long end)
+ {
+ struct hstate *h = hstate_vma(vma);
+ unsigned long sz = huge_page_size(h);
+ struct mm_struct *mm = vma->vm_mm;
+ struct mmu_notifier_range range;
+- unsigned long address, start, end;
++ unsigned long address;
+ spinlock_t *ptl;
+ pte_t *ptep;
+
+ if (!(vma->vm_flags & VM_MAYSHARE))
+ return;
+
+- start = ALIGN(vma->vm_start, PUD_SIZE);
+- end = ALIGN_DOWN(vma->vm_end, PUD_SIZE);
+-
+ if (start >= end)
+ return;
+
+@@ -7437,6 +7453,16 @@ void hugetlb_unshare_all_pmds(struct vm_
+ mmu_notifier_invalidate_range_end(&range);
+ }
+
++/*
++ * This function will unconditionally remove all the shared pmd pgtable entries
++ * within the specific vma for a hugetlbfs memory range.
++ */
++void hugetlb_unshare_all_pmds(struct vm_area_struct *vma)
++{
++ hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE),
++ ALIGN_DOWN(vma->vm_end, PUD_SIZE));
++}
++
+ #ifdef CONFIG_CMA
+ static bool cma_reserve_called __initdata;
+
--- /dev/null
+From d52fec86a465355b379e839fa372ead0334d62e6 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Tue, 17 Jan 2023 11:42:16 +0800
+Subject: LoongArch: Add HWCAP_LOONGARCH_CPUCFG to elf_hwcap
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit d52fec86a465355b379e839fa372ead0334d62e6 upstream.
+
+HWCAP_LOONGARCH_CPUCFG is missing in elf_hwcap, so add it for glibc's
+later use.
+
+Cc: stable@vger.kernel.org
+Reported-by: Yinyu Cai <caiyinyu@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kernel/cpu-probe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/loongarch/kernel/cpu-probe.c
++++ b/arch/loongarch/kernel/cpu-probe.c
+@@ -94,7 +94,7 @@ static void cpu_probe_common(struct cpui
+ c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
+ LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
+
+- elf_hwcap |= HWCAP_LOONGARCH_CRC32;
++ elf_hwcap = HWCAP_LOONGARCH_CPUCFG | HWCAP_LOONGARCH_CRC32;
+
+ config = read_cpucfg(LOONGARCH_CPUCFG1);
+ if (config & CPUCFG1_UAL) {
--- /dev/null
+From ab0c3f1251b4670978fde0bd54161795a139b060 Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Thu, 22 Dec 2022 12:41:50 -0800
+Subject: mm/khugepaged: fix collapse_pte_mapped_thp() to allow anon_vma
+
+From: Hugh Dickins <hughd@google.com>
+
+commit ab0c3f1251b4670978fde0bd54161795a139b060 upstream.
+
+uprobe_write_opcode() uses collapse_pte_mapped_thp() to restore huge pmd,
+when removing a breakpoint from hugepage text: vma->anon_vma is always set
+in that case, so undo the prohibition. And MADV_COLLAPSE ought to be able
+to collapse some page tables in a vma which happens to have anon_vma set
+from CoWing elsewhere.
+
+Is anon_vma lock required? Almost not: if any page other than expected
+subpage of the non-anon huge page is found in the page table, collapse is
+aborted without making any change. However, it is possible that an anon
+page was CoWed from this extent in another mm or vma, in which case a
+concurrent lookup might look here: so keep it away while clearing pmd (but
+perhaps we shall go back to using pmd_lock() there in future).
+
+Note that collapse_pte_mapped_thp() is exceptional in freeing a page table
+without having cleared its ptes: I'm uneasy about that, and had thought
+pte_clear()ing appropriate; but exclusive i_mmap lock does fix the
+problem, and we would have to move the mmu_notification if clearing those
+ptes.
+
+What this fixes is not a dangerous instability. But I suggest Cc stable
+because uprobes "healing" has regressed in that way, so this should follow
+8d3c106e19e8 into those stable releases where it was backported (and may
+want adjustment there - I'll supply backports as needed).
+
+Link: https://lkml.kernel.org/r/b740c9fb-edba-92ba-59fb-7a5592e5dfc@google.com
+Fixes: 8d3c106e19e8 ("mm/khugepaged: take the right locks for page table retraction")
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: Jann Horn <jannh@google.com>
+Cc: Yang Shi <shy828301@gmail.com>
+Cc: Zach O'Keefe <zokeefe@google.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: <stable@vger.kernel.org> [5.4+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/khugepaged.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1467,14 +1467,6 @@ int collapse_pte_mapped_thp(struct mm_st
+ if (!hugepage_vma_check(vma, vma->vm_flags, false, false, false))
+ return SCAN_VMA_CHECK;
+
+- /*
+- * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings
+- * that got written to. Without this, we'd have to also lock the
+- * anon_vma if one exists.
+- */
+- if (vma->anon_vma)
+- return SCAN_VMA_CHECK;
+-
+ /* Keep pmd pgtable for uffd-wp; see comment in retract_page_tables() */
+ if (userfaultfd_wp(vma))
+ return SCAN_PTE_UFFD_WP;
+@@ -1574,8 +1566,14 @@ int collapse_pte_mapped_thp(struct mm_st
+ }
+
+ /* step 4: remove pte entries */
++ /* we make no change to anon, but protect concurrent anon page lookup */
++ if (vma->anon_vma)
++ anon_vma_lock_write(vma->anon_vma);
++
+ collapse_and_free_pmd(mm, vma, haddr, pmd);
+
++ if (vma->anon_vma)
++ anon_vma_unlock_write(vma->anon_vma);
+ i_mmap_unlock_write(vma->vm_file->f_mapping);
+
+ maybe_install_pmd:
--- /dev/null
+From 3de0c269adc6c2fac0bb1fb11965f0de699dc32b Mon Sep 17 00:00:00 2001
+From: Zach O'Keefe <zokeefe@google.com>
+Date: Sat, 24 Dec 2022 00:20:35 -0800
+Subject: mm/shmem: restore SHMEM_HUGE_DENY precedence over MADV_COLLAPSE
+
+From: Zach O'Keefe <zokeefe@google.com>
+
+commit 3de0c269adc6c2fac0bb1fb11965f0de699dc32b upstream.
+
+SHMEM_HUGE_DENY is for emergency use by the admin, to disable allocation
+of shmem huge pages if, for example, a dangerous bug is found in their
+usage: see "deny" in Documentation/mm/transhuge.rst. An app using
+madvise(,,MADV_COLLAPSE) should not be allowed to override it: restore its
+precedence over shmem_huge_force.
+
+Restore SHMEM_HUGE_DENY precedence over MADV_COLLAPSE.
+
+Link: https://lkml.kernel.org/r/20221224082035.3197140-2-zokeefe@google.com
+Fixes: 7c6c6cc4d3a2 ("mm/shmem: add flag to enforce shmem THP in hugepage_vma_check()")
+Signed-off-by: Zach O'Keefe <zokeefe@google.com>
+Suggested-by: Hugh Dickins <hughd@google.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: Yang Shi <shy828301@gmail.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/shmem.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -472,12 +472,10 @@ bool shmem_is_huge(struct vm_area_struct
+ if (vma && ((vma->vm_flags & VM_NOHUGEPAGE) ||
+ test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags)))
+ return false;
+- if (shmem_huge_force)
+- return true;
+- if (shmem_huge == SHMEM_HUGE_FORCE)
+- return true;
+ if (shmem_huge == SHMEM_HUGE_DENY)
+ return false;
++ if (shmem_huge_force || shmem_huge == SHMEM_HUGE_FORCE)
++ return true;
+
+ switch (SHMEM_SB(inode->i_sb)->huge) {
+ case SHMEM_HUGE_ALWAYS:
--- /dev/null
+From 7633355e5c7f29c049a9048e461427d1d8ed3051 Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Thu, 5 Jan 2023 14:53:56 +0900
+Subject: nilfs2: fix general protection fault in nilfs_btree_insert()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit 7633355e5c7f29c049a9048e461427d1d8ed3051 upstream.
+
+If nilfs2 reads a corrupted disk image and tries to reads a b-tree node
+block by calling __nilfs_btree_get_block() against an invalid virtual
+block address, it returns -ENOENT because conversion of the virtual block
+address to a disk block address fails. However, this return value is the
+same as the internal code that b-tree lookup routines return to indicate
+that the block being searched does not exist, so functions that operate on
+that b-tree may misbehave.
+
+When nilfs_btree_insert() receives this spurious 'not found' code from
+nilfs_btree_do_lookup(), it misunderstands that the 'not found' check was
+successful and continues the insert operation using incomplete lookup path
+data, causing the following crash:
+
+ general protection fault, probably for non-canonical address
+ 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
+ ...
+ RIP: 0010:nilfs_btree_get_nonroot_node fs/nilfs2/btree.c:418 [inline]
+ RIP: 0010:nilfs_btree_prepare_insert fs/nilfs2/btree.c:1077 [inline]
+ RIP: 0010:nilfs_btree_insert+0x6d3/0x1c10 fs/nilfs2/btree.c:1238
+ Code: bc 24 80 00 00 00 4c 89 f8 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89
+ ff e8 4b 02 92 fe 4d 8b 3f 49 83 c7 28 4c 89 f8 48 c1 e8 03 <42> 80 3c
+ 28 00 74 08 4c 89 ff e8 2e 02 92 fe 4d 8b 3f 49 83 c7 02
+ ...
+ Call Trace:
+ <TASK>
+ nilfs_bmap_do_insert fs/nilfs2/bmap.c:121 [inline]
+ nilfs_bmap_insert+0x20d/0x360 fs/nilfs2/bmap.c:147
+ nilfs_get_block+0x414/0x8d0 fs/nilfs2/inode.c:101
+ __block_write_begin_int+0x54c/0x1a80 fs/buffer.c:1991
+ __block_write_begin fs/buffer.c:2041 [inline]
+ block_write_begin+0x93/0x1e0 fs/buffer.c:2102
+ nilfs_write_begin+0x9c/0x110 fs/nilfs2/inode.c:261
+ generic_perform_write+0x2e4/0x5e0 mm/filemap.c:3772
+ __generic_file_write_iter+0x176/0x400 mm/filemap.c:3900
+ generic_file_write_iter+0xab/0x310 mm/filemap.c:3932
+ call_write_iter include/linux/fs.h:2186 [inline]
+ new_sync_write fs/read_write.c:491 [inline]
+ vfs_write+0x7dc/0xc50 fs/read_write.c:584
+ ksys_write+0x177/0x2a0 fs/read_write.c:637
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ ...
+ </TASK>
+
+This patch fixes the root cause of this problem by replacing the error
+code that __nilfs_btree_get_block() returns on block address conversion
+failure from -ENOENT to another internal code -EINVAL which means that the
+b-tree metadata is corrupted.
+
+By returning -EINVAL, it propagates without glitches, and for all relevant
+b-tree operations, functions in the upper bmap layer output an error
+message indicating corrupted b-tree metadata via
+nilfs_bmap_convert_error(), and code -EIO will be eventually returned as
+it should be.
+
+Link: https://lkml.kernel.org/r/000000000000bd89e205f0e38355@google.com
+Link: https://lkml.kernel.org/r/20230105055356.8811-1-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+ede796cecd5296353515@syzkaller.appspotmail.com
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/btree.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -480,9 +480,18 @@ static int __nilfs_btree_get_block(const
+ ret = nilfs_btnode_submit_block(btnc, ptr, 0, REQ_OP_READ, &bh,
+ &submit_ptr);
+ if (ret) {
+- if (ret != -EEXIST)
+- return ret;
+- goto out_check;
++ if (likely(ret == -EEXIST))
++ goto out_check;
++ if (ret == -ENOENT) {
++ /*
++ * Block address translation failed due to invalid
++ * value of 'ptr'. In this case, return internal code
++ * -EINVAL (broken bmap) to notify bmap layer of fatal
++ * metadata corruption.
++ */
++ ret = -EINVAL;
++ }
++ return ret;
+ }
+
+ if (ra) {
--- /dev/null
+From 80be727ec87225797771a39f3e6801baf291faaf Mon Sep 17 00:00:00 2001
+From: Liam Howlett <liam.howlett@oracle.com>
+Date: Mon, 9 Jan 2023 20:57:21 +0000
+Subject: nommu: fix do_munmap() error path
+
+From: Liam Howlett <liam.howlett@oracle.com>
+
+commit 80be727ec87225797771a39f3e6801baf291faaf upstream.
+
+When removing a VMA from the tree fails due to no memory, do not free the
+VMA since a reference still exists.
+
+Link: https://lkml.kernel.org/r/20230109205708.956103-1-Liam.Howlett@oracle.com
+Fixes: 8220543df148 ("nommu: remove uses of VMA linked list")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Yu Zhao <yuzhao@google.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/nommu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mm/nommu.c b/mm/nommu.c
+index c8252f01d5db..844af5be7640 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -1509,7 +1509,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list
+ erase_whole_vma:
+ if (delete_vma_from_mm(vma))
+ ret = -ENOMEM;
+- delete_vma(mm, vma);
++ else
++ delete_vma(mm, vma);
+ return ret;
+ }
+
+--
+2.39.1
+
--- /dev/null
+From 7f31cced5724e6d414fe750aa1cd7e7b578ec22f Mon Sep 17 00:00:00 2001
+From: Liam Howlett <liam.howlett@oracle.com>
+Date: Mon, 9 Jan 2023 20:55:21 +0000
+Subject: nommu: fix memory leak in do_mmap() error path
+
+From: Liam Howlett <liam.howlett@oracle.com>
+
+commit 7f31cced5724e6d414fe750aa1cd7e7b578ec22f upstream.
+
+The preallocation of the maple tree nodes may leak if the error path to
+"error_just_free" is taken. Fix this by moving the freeing of the maple
+tree nodes to a shared location for all error paths.
+
+Link: https://lkml.kernel.org/r/20230109205507.955577-1-Liam.Howlett@oracle.com
+Fixes: 8220543df148 ("nommu: remove uses of VMA linked list")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Yu Zhao <yuzhao@google.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/nommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 214c70e1d059..c8252f01d5db 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -1240,6 +1240,7 @@ unsigned long do_mmap(struct file *file,
+ error_just_free:
+ up_write(&nommu_region_sem);
+ error:
++ mas_destroy(&mas);
+ if (region->vm_file)
+ fput(region->vm_file);
+ kmem_cache_free(vm_region_jar, region);
+@@ -1250,7 +1251,6 @@ unsigned long do_mmap(struct file *file,
+
+ sharing_violation:
+ up_write(&nommu_region_sem);
+- mas_destroy(&mas);
+ pr_warn("Attempt to share mismatched mappings\n");
+ ret = -EINVAL;
+ goto error;
+--
+2.39.1
+
--- /dev/null
+From fd9edbdbdcde6b489ce59f326755ef16a2ffadd7 Mon Sep 17 00:00:00 2001
+From: Liam Howlett <liam.howlett@oracle.com>
+Date: Mon, 9 Jan 2023 20:58:20 +0000
+Subject: nommu: fix split_vma() map_count error
+
+From: Liam Howlett <liam.howlett@oracle.com>
+
+commit fd9edbdbdcde6b489ce59f326755ef16a2ffadd7 upstream.
+
+During the maple tree conversion of nommu, an error in counting the VMAs
+was introduced by counting the existing VMA again. The counting used to
+be decremented by one and incremented by two, but now it only increments
+by two. Fix the counting error by moving the increment outside the
+setup_vma_to_mm() function to the callers.
+
+Link: https://lkml.kernel.org/r/20230109205809.956325-1-Liam.Howlett@oracle.com
+Fixes: 8220543df148 ("nommu: remove uses of VMA linked list")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Yu Zhao <yuzhao@google.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/nommu.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 844af5be7640..5b83938ecb67 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -559,7 +559,6 @@ void vma_mas_remove(struct vm_area_struct *vma, struct ma_state *mas)
+
+ static void setup_vma_to_mm(struct vm_area_struct *vma, struct mm_struct *mm)
+ {
+- mm->map_count++;
+ vma->vm_mm = mm;
+
+ /* add the VMA to the mapping */
+@@ -587,6 +586,7 @@ static void mas_add_vma_to_mm(struct ma_state *mas, struct mm_struct *mm,
+ BUG_ON(!vma->vm_region);
+
+ setup_vma_to_mm(vma, mm);
++ mm->map_count++;
+
+ /* add the VMA to the tree */
+ vma_mas_store(vma, mas);
+@@ -1347,6 +1347,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+ if (vma->vm_file)
+ return -ENOMEM;
+
++ mm = vma->vm_mm;
+ if (mm->map_count >= sysctl_max_map_count)
+ return -ENOMEM;
+
+@@ -1398,6 +1399,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+ mas_set_range(&mas, vma->vm_start, vma->vm_end - 1);
+ mas_store(&mas, vma);
+ vma_mas_store(new, &mas);
++ mm->map_count++;
+ return 0;
+
+ err_mas_preallocate:
+--
+2.39.1
+
--- /dev/null
+From 5316a017d093f644675a56523bcf5787ba8f4fef Mon Sep 17 00:00:00 2001
+From: Alexey Dobriyan <adobriyan@gmail.com>
+Date: Fri, 6 Jan 2023 22:30:14 +0300
+Subject: proc: fix PIE proc-empty-vm, proc-pid-vm tests
+
+From: Alexey Dobriyan <adobriyan@gmail.com>
+
+commit 5316a017d093f644675a56523bcf5787ba8f4fef upstream.
+
+vsyscall detection code uses direct call to the beginning of
+the vsyscall page:
+
+ asm ("call %P0" :: "i" (0xffffffffff600000))
+
+It generates "call rel32" instruction but it is not relocated if binary
+is PIE, so binary segfaults into random userspace address and vsyscall
+page status is detected incorrectly.
+
+Do more direct:
+
+ asm ("call *%rax")
+
+which doesn't do need any relocaltions.
+
+Mark g_vsyscall as volatile for a good measure, I didn't find instruction
+setting it to 0. Now the code is obviously correct:
+
+ xor eax, eax
+ mov rdi, rbp
+ mov rsi, rbp
+ mov DWORD PTR [rip+0x2d15], eax # g_vsyscall = 0
+ mov rax, 0xffffffffff600000
+ call rax
+ mov DWORD PTR [rip+0x2d02], 1 # g_vsyscall = 1
+ mov eax, DWORD PTR ds:0xffffffffff600000
+ mov DWORD PTR [rip+0x2cf1], 2 # g_vsyscall = 2
+ mov edi, [rip+0x2ceb] # exit(g_vsyscall)
+ call exit
+
+Note: fixed proc-empty-vm test oopses 5.19.0-28-generic kernel
+ but this is separate story.
+
+Link: https://lkml.kernel.org/r/Y7h2xvzKLg36DSq8@p183
+Fixes: 5bc73bb3451b9 ("proc: test how it holds up with mapping'less process")
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
+Tested-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/proc/proc-empty-vm.c | 12 +++++++-----
+ tools/testing/selftests/proc/proc-pid-vm.c | 9 +++++----
+ 2 files changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/tools/testing/selftests/proc/proc-empty-vm.c b/tools/testing/selftests/proc/proc-empty-vm.c
+index d95b1cb43d9d..7588428b8fcd 100644
+--- a/tools/testing/selftests/proc/proc-empty-vm.c
++++ b/tools/testing/selftests/proc/proc-empty-vm.c
+@@ -25,6 +25,7 @@
+ #undef NDEBUG
+ #include <assert.h>
+ #include <errno.h>
++#include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -41,7 +42,7 @@
+ * 1: vsyscall VMA is --xp vsyscall=xonly
+ * 2: vsyscall VMA is r-xp vsyscall=emulate
+ */
+-static int g_vsyscall;
++static volatile int g_vsyscall;
+ static const char *g_proc_pid_maps_vsyscall;
+ static const char *g_proc_pid_smaps_vsyscall;
+
+@@ -147,11 +148,12 @@ static void vsyscall(void)
+
+ g_vsyscall = 0;
+ /* gettimeofday(NULL, NULL); */
++ uint64_t rax = 0xffffffffff600000;
+ asm volatile (
+- "call %P0"
+- :
+- : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL)
+- : "rax", "rcx", "r11"
++ "call *%[rax]"
++ : [rax] "+a" (rax)
++ : "D" (NULL), "S" (NULL)
++ : "rcx", "r11"
+ );
+
+ g_vsyscall = 1;
+diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c
+index 69551bfa215c..cacbd2a4aec9 100644
+--- a/tools/testing/selftests/proc/proc-pid-vm.c
++++ b/tools/testing/selftests/proc/proc-pid-vm.c
+@@ -257,11 +257,12 @@ static void vsyscall(void)
+
+ g_vsyscall = 0;
+ /* gettimeofday(NULL, NULL); */
++ uint64_t rax = 0xffffffffff600000;
+ asm volatile (
+- "call %P0"
+- :
+- : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL)
+- : "rax", "rcx", "r11"
++ "call *%[rax]"
++ : [rax] "+a" (rax)
++ : "D" (NULL), "S" (NULL)
++ : "rcx", "r11"
+ );
+
+ g_vsyscall = 1;
+--
+2.39.1
+
perf-x86-rapl-add-support-for-intel-emerald-rapids.patch
of-fdt-honor-config_cmdline-even-without-chosen-node.patch
fbdev-omapfb-avoid-stack-overflow-warning.patch
+bluetooth-hci_sync-fix-use-hci_op_le_read_buffer_size_v2.patch
+bluetooth-hci_qca-fix-driver-shutdown-on-closed-serdev.patch
+wifi-brcmfmac-fix-regression-for-broadcom-pcie-wifi-devices.patch
+wifi-mac80211-fix-mlo-ap_vlan-check.patch
+wifi-mac80211-reset-multiple-bssid-options-in-stop_ap.patch
+wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch
+wifi-mac80211-fix-initialization-of-rx-link-and-rx-link_sta.patch
+nommu-fix-memory-leak-in-do_mmap-error-path.patch
+nommu-fix-do_munmap-error-path.patch
+nommu-fix-split_vma-map_count-error.patch
+proc-fix-pie-proc-empty-vm-proc-pid-vm-tests.patch
+add-exception-protection-processing-for-vd-in-axi_chan_handle_err-function.patch
+loongarch-add-hwcap_loongarch_cpucfg-to-elf_hwcap.patch
+zonefs-detect-append-writes-at-invalid-locations.patch
+nilfs2-fix-general-protection-fault-in-nilfs_btree_insert.patch
+mm-shmem-restore-shmem_huge_deny-precedence-over-madv_collapse.patch
+hugetlb-unshare-some-pmds-when-splitting-vmas.patch
+mm-khugepaged-fix-collapse_pte_mapped_thp-to-allow-anon_vma.patch
--- /dev/null
+From ed05cb177ae5cd7f02f1d6e7706ba627d30f1696 Mon Sep 17 00:00:00 2001
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Wed, 11 Jan 2023 12:24:19 +0100
+Subject: wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices
+
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+
+commit ed05cb177ae5cd7f02f1d6e7706ba627d30f1696 upstream.
+
+A sanity check was introduced considering maximum flowrings above
+256 as insane and effectively aborting the device probe. This
+resulted in regression for number of users as the value turns out
+to be sane after all.
+
+Fixes: 2aca4f3734bd ("brcmfmac: return error when getting invalid max_flowrings from dongle")
+Reported-by: chainofflowers <chainofflowers@posteo.net>
+Link: https://lore.kernel.org/all/4781984.GXAFRqVoOG@luna/
+Reported-by: Christian Marillat <marillat@debian.org>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216894
+Cc: stable@vger.kernel.org
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230111112419.24185-1-arend.vanspriel@broadcom.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -1218,7 +1218,7 @@ static int brcmf_pcie_init_ringbuffers(s
+ BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
+ }
+- if (max_flowrings > 256) {
++ if (max_flowrings > 512) {
+ brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
+ return -EIO;
+ }
--- /dev/null
+From e66b7920aa5ac5b1a1997a454004ba9246a3c005 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 30 Dec 2022 21:07:47 +0100
+Subject: wifi: mac80211: fix initialization of rx->link and rx->link_sta
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit e66b7920aa5ac5b1a1997a454004ba9246a3c005 upstream.
+
+There are some codepaths that do not initialize rx->link_sta properly. This
+causes a crash in places which assume that rx->link_sta is valid if rx->sta
+is valid.
+One known instance is triggered by __ieee80211_rx_h_amsdu being called from
+fast-rx. It results in a crash like this one:
+
+ BUG: kernel NULL pointer dereference, address: 00000000000000a8
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page PGD 0 P4D 0
+ Oops: 0002 [#1] PREEMPT SMP PTI
+ CPU: 1 PID: 506 Comm: mt76-usb-rx phy Tainted: G E 6.1.0-debian64x+1.7 #3
+ Hardware name: ZOTAC ZBOX-ID92/ZBOX-IQ01/ZBOX-ID92/ZBOX-IQ01, BIOS B220P007 05/21/2014
+ RIP: 0010:ieee80211_deliver_skb+0x62/0x1f0 [mac80211]
+ Code: 00 48 89 04 24 e8 9e a7 c3 df 89 c0 48 03 1c c5 a0 ea 39 a1 4c 01 6b 08 48 ff 03 48
+ 83 7d 28 00 74 11 48 8b 45 30 48 63 55 44 <48> 83 84 d0 a8 00 00 00 01 41 8b 86 c0
+ 11 00 00 8d 50 fd 83 fa 01
+ RSP: 0018:ffff999040803b10 EFLAGS: 00010286
+ RAX: 0000000000000000 RBX: ffffb9903f496480 RCX: 0000000000000000
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: ffff999040803ce0 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000000 R12: ffff8d21828ac900
+ R13: 000000000000004a R14: ffff8d2198ed89c0 R15: ffff8d2198ed8000
+ FS: 0000000000000000(0000) GS:ffff8d24afe80000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00000000000000a8 CR3: 0000000429810002 CR4: 00000000001706e0
+ Call Trace:
+ <TASK>
+ __ieee80211_rx_h_amsdu+0x1b5/0x240 [mac80211]
+ ? ieee80211_prepare_and_rx_handle+0xcdd/0x1320 [mac80211]
+ ? __local_bh_enable_ip+0x3b/0xa0
+ ieee80211_prepare_and_rx_handle+0xcdd/0x1320 [mac80211]
+ ? prepare_transfer+0x109/0x1a0 [xhci_hcd]
+ ieee80211_rx_list+0xa80/0xda0 [mac80211]
+ mt76_rx_complete+0x207/0x2e0 [mt76]
+ mt76_rx_poll_complete+0x357/0x5a0 [mt76]
+ mt76u_rx_worker+0x4f5/0x600 [mt76_usb]
+ ? mt76_get_min_avg_rssi+0x140/0x140 [mt76]
+ __mt76_worker_fn+0x50/0x80 [mt76]
+ kthread+0xed/0x120
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x22/0x30
+
+Since the initialization of rx->link and rx->link_sta is rather convoluted
+and duplicated in many places, clean it up by using a helper function to
+set it.
+
+Fixes: ccdde7c74ffd ("wifi: mac80211: properly implement MLO key handling")
+Fixes: b320d6c456ff ("wifi: mac80211: use correct rx link_sta instead of default")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://lore.kernel.org/r/20221230200747.19040-1-nbd@nbd.name
+[remove unnecessary rx->sta->sta.mlo check]
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/rx.c | 222 ++++++++++++++++++++++++------------------------------
+ 1 file changed, 99 insertions(+), 123 deletions(-)
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -4070,6 +4070,58 @@ static void ieee80211_invoke_rx_handlers
+ #undef CALL_RXH
+ }
+
++static bool
++ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id)
++{
++ if (!sta->mlo)
++ return false;
++
++ return !!(sta->valid_links & BIT(link_id));
++}
++
++static bool ieee80211_rx_data_set_link(struct ieee80211_rx_data *rx,
++ u8 link_id)
++{
++ rx->link_id = link_id;
++ rx->link = rcu_dereference(rx->sdata->link[link_id]);
++
++ if (!rx->sta)
++ return rx->link;
++
++ if (!ieee80211_rx_is_valid_sta_link_id(&rx->sta->sta, link_id))
++ return false;
++
++ rx->link_sta = rcu_dereference(rx->sta->link[link_id]);
++
++ return rx->link && rx->link_sta;
++}
++
++static bool ieee80211_rx_data_set_sta(struct ieee80211_rx_data *rx,
++ struct ieee80211_sta *pubsta,
++ int link_id)
++{
++ struct sta_info *sta;
++
++ sta = container_of(pubsta, struct sta_info, sta);
++
++ rx->link_id = link_id;
++ rx->sta = sta;
++
++ if (sta) {
++ rx->local = sta->sdata->local;
++ if (!rx->sdata)
++ rx->sdata = sta->sdata;
++ rx->link_sta = &sta->deflink;
++ }
++
++ if (link_id < 0)
++ rx->link = &rx->sdata->deflink;
++ else if (!ieee80211_rx_data_set_link(rx, link_id))
++ return false;
++
++ return true;
++}
++
+ /*
+ * This function makes calls into the RX path, therefore
+ * it has to be invoked under RCU read lock.
+@@ -4078,16 +4130,19 @@ void ieee80211_release_reorder_timeout(s
+ {
+ struct sk_buff_head frames;
+ struct ieee80211_rx_data rx = {
+- .sta = sta,
+- .sdata = sta->sdata,
+- .local = sta->local,
+ /* This is OK -- must be QoS data frame */
+ .security_idx = tid,
+ .seqno_idx = tid,
+- .link_id = -1,
+ };
+ struct tid_ampdu_rx *tid_agg_rx;
+- u8 link_id;
++ int link_id = -1;
++
++ /* FIXME: statistics won't be right with this */
++ if (sta->sta.valid_links)
++ link_id = ffs(sta->sta.valid_links) - 1;
++
++ if (!ieee80211_rx_data_set_sta(&rx, &sta->sta, link_id))
++ return;
+
+ tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
+ if (!tid_agg_rx)
+@@ -4107,10 +4162,6 @@ void ieee80211_release_reorder_timeout(s
+ };
+ drv_event_callback(rx.local, rx.sdata, &event);
+ }
+- /* FIXME: statistics won't be right with this */
+- link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0;
+- rx.link = rcu_dereference(sta->sdata->link[link_id]);
+- rx.link_sta = rcu_dereference(sta->link[link_id]);
+
+ ieee80211_rx_handlers(&rx, &frames);
+ }
+@@ -4126,7 +4177,6 @@ void ieee80211_mark_rx_ba_filtered_frame
+ /* This is OK -- must be QoS data frame */
+ .security_idx = tid,
+ .seqno_idx = tid,
+- .link_id = -1,
+ };
+ int i, diff;
+
+@@ -4137,10 +4187,8 @@ void ieee80211_mark_rx_ba_filtered_frame
+
+ sta = container_of(pubsta, struct sta_info, sta);
+
+- rx.sta = sta;
+- rx.sdata = sta->sdata;
+- rx.link = &rx.sdata->deflink;
+- rx.local = sta->local;
++ if (!ieee80211_rx_data_set_sta(&rx, pubsta, -1))
++ return;
+
+ rcu_read_lock();
+ tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
+@@ -4527,15 +4575,6 @@ void ieee80211_check_fast_rx_iface(struc
+ mutex_unlock(&local->sta_mtx);
+ }
+
+-static bool
+-ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id)
+-{
+- if (!sta->mlo)
+- return false;
+-
+- return !!(sta->valid_links & BIT(link_id));
+-}
+-
+ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
+ struct ieee80211_fast_rx *fast_rx,
+ int orig_len)
+@@ -4646,7 +4685,6 @@ static bool ieee80211_invoke_fast_rx(str
+ struct sk_buff *skb = rx->skb;
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+- struct sta_info *sta = rx->sta;
+ int orig_len = skb->len;
+ int hdrlen = ieee80211_hdrlen(hdr->frame_control);
+ int snap_offs = hdrlen;
+@@ -4658,7 +4696,6 @@ static bool ieee80211_invoke_fast_rx(str
+ u8 da[ETH_ALEN];
+ u8 sa[ETH_ALEN];
+ } addrs __aligned(2);
+- struct link_sta_info *link_sta;
+ struct ieee80211_sta_rx_stats *stats;
+
+ /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
+@@ -4761,18 +4798,10 @@ static bool ieee80211_invoke_fast_rx(str
+ drop:
+ dev_kfree_skb(skb);
+
+- if (rx->link_id >= 0) {
+- link_sta = rcu_dereference(sta->link[rx->link_id]);
+- if (!link_sta)
+- return true;
+- } else {
+- link_sta = &sta->deflink;
+- }
+-
+ if (fast_rx->uses_rss)
+- stats = this_cpu_ptr(link_sta->pcpu_rx_stats);
++ stats = this_cpu_ptr(rx->link_sta->pcpu_rx_stats);
+ else
+- stats = &link_sta->rx_stats;
++ stats = &rx->link_sta->rx_stats;
+
+ stats->dropped++;
+ return true;
+@@ -4790,8 +4819,8 @@ static bool ieee80211_prepare_and_rx_han
+ struct ieee80211_local *local = rx->local;
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+- struct link_sta_info *link_sta = NULL;
+- struct ieee80211_link_data *link;
++ struct link_sta_info *link_sta = rx->link_sta;
++ struct ieee80211_link_data *link = rx->link;
+
+ rx->skb = skb;
+
+@@ -4813,35 +4842,6 @@ static bool ieee80211_prepare_and_rx_han
+ if (!ieee80211_accept_frame(rx))
+ return false;
+
+- if (rx->link_id >= 0) {
+- link = rcu_dereference(rx->sdata->link[rx->link_id]);
+-
+- /* we might race link removal */
+- if (!link)
+- return true;
+- rx->link = link;
+-
+- if (rx->sta) {
+- rx->link_sta =
+- rcu_dereference(rx->sta->link[rx->link_id]);
+- if (!rx->link_sta)
+- return true;
+- }
+- } else {
+- if (rx->sta)
+- rx->link_sta = &rx->sta->deflink;
+-
+- rx->link = &sdata->deflink;
+- }
+-
+- if (unlikely(!is_multicast_ether_addr(hdr->addr1) &&
+- rx->link_id >= 0 && rx->sta && rx->sta->sta.mlo)) {
+- link_sta = rcu_dereference(rx->sta->link[rx->link_id]);
+-
+- if (WARN_ON_ONCE(!link_sta))
+- return true;
+- }
+-
+ if (!consume) {
+ struct skb_shared_hwtstamps *shwt;
+
+@@ -4861,7 +4861,7 @@ static bool ieee80211_prepare_and_rx_han
+ shwt->hwtstamp = skb_hwtstamps(skb)->hwtstamp;
+ }
+
+- if (unlikely(link_sta)) {
++ if (unlikely(rx->sta && rx->sta->sta.mlo)) {
+ /* translate to MLD addresses */
+ if (ether_addr_equal(link->conf->addr, hdr->addr1))
+ ether_addr_copy(hdr->addr1, rx->sdata->vif.addr);
+@@ -4891,6 +4891,7 @@ static void __ieee80211_rx_handle_8023(s
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ struct ieee80211_fast_rx *fast_rx;
+ struct ieee80211_rx_data rx;
++ int link_id = -1;
+
+ memset(&rx, 0, sizeof(rx));
+ rx.skb = skb;
+@@ -4907,12 +4908,8 @@ static void __ieee80211_rx_handle_8023(s
+ if (!pubsta)
+ goto drop;
+
+- rx.sta = container_of(pubsta, struct sta_info, sta);
+- rx.sdata = rx.sta->sdata;
+-
+- if (status->link_valid &&
+- !ieee80211_rx_is_valid_sta_link_id(pubsta, status->link_id))
+- goto drop;
++ if (status->link_valid)
++ link_id = status->link_id;
+
+ /*
+ * TODO: Should the frame be dropped if the right link_id is not
+@@ -4921,19 +4918,8 @@ static void __ieee80211_rx_handle_8023(s
+ * link_id is used only for stats purpose and updating the stats on
+ * the deflink is fine?
+ */
+- if (status->link_valid)
+- rx.link_id = status->link_id;
+-
+- if (rx.link_id >= 0) {
+- struct ieee80211_link_data *link;
+-
+- link = rcu_dereference(rx.sdata->link[rx.link_id]);
+- if (!link)
+- goto drop;
+- rx.link = link;
+- } else {
+- rx.link = &rx.sdata->deflink;
+- }
++ if (!ieee80211_rx_data_set_sta(&rx, pubsta, link_id))
++ goto drop;
+
+ fast_rx = rcu_dereference(rx.sta->fast_rx);
+ if (!fast_rx)
+@@ -4951,6 +4937,8 @@ static bool ieee80211_rx_for_interface(s
+ {
+ struct link_sta_info *link_sta;
+ struct ieee80211_hdr *hdr = (void *)skb->data;
++ struct sta_info *sta;
++ int link_id = -1;
+
+ /*
+ * Look up link station first, in case there's a
+@@ -4960,24 +4948,19 @@ static bool ieee80211_rx_for_interface(s
+ */
+ link_sta = link_sta_info_get_bss(rx->sdata, hdr->addr2);
+ if (link_sta) {
+- rx->sta = link_sta->sta;
+- rx->link_id = link_sta->link_id;
++ sta = link_sta->sta;
++ link_id = link_sta->link_id;
+ } else {
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+
+- rx->sta = sta_info_get_bss(rx->sdata, hdr->addr2);
+- if (rx->sta) {
+- if (status->link_valid &&
+- !ieee80211_rx_is_valid_sta_link_id(&rx->sta->sta,
+- status->link_id))
+- return false;
+-
+- rx->link_id = status->link_valid ? status->link_id : -1;
+- } else {
+- rx->link_id = -1;
+- }
++ sta = sta_info_get_bss(rx->sdata, hdr->addr2);
++ if (status->link_valid)
++ link_id = status->link_id;
+ }
+
++ if (!ieee80211_rx_data_set_sta(rx, &sta->sta, link_id))
++ return false;
++
+ return ieee80211_prepare_and_rx_handle(rx, skb, consume);
+ }
+
+@@ -5036,19 +5019,15 @@ static void __ieee80211_rx_handle_packet
+
+ if (ieee80211_is_data(fc)) {
+ struct sta_info *sta, *prev_sta;
+- u8 link_id = status->link_id;
++ int link_id = -1;
+
+- if (pubsta) {
+- rx.sta = container_of(pubsta, struct sta_info, sta);
+- rx.sdata = rx.sta->sdata;
++ if (status->link_valid)
++ link_id = status->link_id;
+
+- if (status->link_valid &&
+- !ieee80211_rx_is_valid_sta_link_id(pubsta, link_id))
++ if (pubsta) {
++ if (!ieee80211_rx_data_set_sta(&rx, pubsta, link_id))
+ goto out;
+
+- if (status->link_valid)
+- rx.link_id = status->link_id;
+-
+ /*
+ * In MLO connection, fetch the link_id using addr2
+ * when the driver does not pass link_id in status.
+@@ -5066,7 +5045,7 @@ static void __ieee80211_rx_handle_packet
+ if (!link_sta)
+ goto out;
+
+- rx.link_id = link_sta->link_id;
++ ieee80211_rx_data_set_link(&rx, link_sta->link_id);
+ }
+
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
+@@ -5082,30 +5061,27 @@ static void __ieee80211_rx_handle_packet
+ continue;
+ }
+
+- if ((status->link_valid &&
+- !ieee80211_rx_is_valid_sta_link_id(&prev_sta->sta,
+- link_id)) ||
+- (!status->link_valid && prev_sta->sta.mlo))
++ rx.sdata = prev_sta->sdata;
++ if (!ieee80211_rx_data_set_sta(&rx, &prev_sta->sta,
++ link_id))
++ goto out;
++
++ if (!status->link_valid && prev_sta->sta.mlo)
+ continue;
+
+- rx.link_id = status->link_valid ? link_id : -1;
+- rx.sta = prev_sta;
+- rx.sdata = prev_sta->sdata;
+ ieee80211_prepare_and_rx_handle(&rx, skb, false);
+
+ prev_sta = sta;
+ }
+
+ if (prev_sta) {
+- if ((status->link_valid &&
+- !ieee80211_rx_is_valid_sta_link_id(&prev_sta->sta,
+- link_id)) ||
+- (!status->link_valid && prev_sta->sta.mlo))
++ rx.sdata = prev_sta->sdata;
++ if (!ieee80211_rx_data_set_sta(&rx, &prev_sta->sta,
++ link_id))
+ goto out;
+
+- rx.link_id = status->link_valid ? link_id : -1;
+- rx.sta = prev_sta;
+- rx.sdata = prev_sta->sdata;
++ if (!status->link_valid && prev_sta->sta.mlo)
++ goto out;
+
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
+ return;
--- /dev/null
+From f216033d770f7ca0eda491fe01a9f02e7af59576 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 14 Dec 2022 14:03:26 +0100
+Subject: wifi: mac80211: fix MLO + AP_VLAN check
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit f216033d770f7ca0eda491fe01a9f02e7af59576 upstream.
+
+Instead of preventing adding AP_VLAN to MLO enabled APs, this check was
+preventing adding more than one 4-addr AP_VLAN regardless of the MLO status.
+Fix this by adding missing extra checks.
+
+Fixes: ae960ee90bb1 ("wifi: mac80211: prevent VLANs on MLDs")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://lore.kernel.org/r/20221214130326.37756-1-nbd@nbd.name
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/iface.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index d49a5906a943..e20c3fe9a0b1 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -364,7 +364,9 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
+
+ /* No support for VLAN with MLO yet */
+ if (iftype == NL80211_IFTYPE_AP_VLAN &&
+- nsdata->wdev.use_4addr)
++ sdata->wdev.use_4addr &&
++ nsdata->vif.type == NL80211_IFTYPE_AP &&
++ nsdata->vif.valid_links)
+ return -EOPNOTSUPP;
+
+ /*
+--
+2.39.1
+
--- /dev/null
+From 0eb38842ada035d71bb06fb9116f26f24ee0f998 Mon Sep 17 00:00:00 2001
+From: Aloka Dixit <quic_alokad@quicinc.com>
+Date: Wed, 21 Dec 2022 10:56:16 -0800
+Subject: wifi: mac80211: reset multiple BSSID options in stop_ap()
+
+From: Aloka Dixit <quic_alokad@quicinc.com>
+
+commit 0eb38842ada035d71bb06fb9116f26f24ee0f998 upstream.
+
+Reset multiple BSSID options when all AP related configurations are
+reset in ieee80211_stop_ap().
+
+Stale values result in HWSIM test failures (e.g. p2p_group_cli_invalid),
+if run after 'he_ap_ema'.
+
+Reported-by: Jouni Malinen <j@w1.fi>
+Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
+Link: https://lore.kernel.org/r/20221221185616.11514-1-quic_alokad@quicinc.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/cfg.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -147,6 +147,7 @@ static int ieee80211_set_ap_mbssid_optio
+ link_conf->bssid_index = 0;
+ link_conf->nontransmitted = false;
+ link_conf->ema_ap = false;
++ link_conf->bssid_indicator = 0;
+
+ if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev)
+ return -EINVAL;
+@@ -1511,6 +1512,12 @@ static int ieee80211_stop_ap(struct wiph
+ kfree(link_conf->ftmr_params);
+ link_conf->ftmr_params = NULL;
+
++ sdata->vif.mbssid_tx_vif = NULL;
++ link_conf->bssid_index = 0;
++ link_conf->nontransmitted = false;
++ link_conf->ema_ap = false;
++ link_conf->bssid_indicator = 0;
++
+ __sta_info_flush(sdata, true);
+ ieee80211_free_keys(sdata, true);
+
--- /dev/null
+From 69403bad97aa0162e3d7911b27e25abe774093df Mon Sep 17 00:00:00 2001
+From: Alexander Wetzel <alexander@wetzel-home.de>
+Date: Fri, 30 Dec 2022 13:18:50 +0100
+Subject: wifi: mac80211: sdata can be NULL during AMPDU start
+
+From: Alexander Wetzel <alexander@wetzel-home.de>
+
+commit 69403bad97aa0162e3d7911b27e25abe774093df upstream.
+
+ieee80211_tx_ba_session_handle_start() may get NULL for sdata when a
+deauthentication is ongoing.
+
+Here a trace triggering the race with the hostapd test
+multi_ap_fronthaul_on_ap:
+
+(gdb) list *drv_ampdu_action+0x46
+0x8b16 is in drv_ampdu_action (net/mac80211/driver-ops.c:396).
+391 int ret = -EOPNOTSUPP;
+392
+393 might_sleep();
+394
+395 sdata = get_bss_sdata(sdata);
+396 if (!check_sdata_in_driver(sdata))
+397 return -EIO;
+398
+399 trace_drv_ampdu_action(local, sdata, params);
+400
+
+wlan0: moving STA 02:00:00:00:03:00 to state 3
+wlan0: associated
+wlan0: deauthenticating from 02:00:00:00:03:00 by local choice (Reason: 3=DEAUTH_LEAVING)
+wlan3.sta1: Open BA session requested for 02:00:00:00:00:00 tid 0
+wlan3.sta1: dropped frame to 02:00:00:00:00:00 (unauthorized port)
+wlan0: moving STA 02:00:00:00:03:00 to state 2
+wlan0: moving STA 02:00:00:00:03:00 to state 1
+wlan0: Removed STA 02:00:00:00:03:00
+wlan0: Destroyed STA 02:00:00:00:03:00
+BUG: unable to handle page fault for address: fffffffffffffb48
+PGD 11814067 P4D 11814067 PUD 11816067 PMD 0
+Oops: 0000 [#1] PREEMPT SMP PTI
+CPU: 2 PID: 133397 Comm: kworker/u16:1 Tainted: G W 6.1.0-rc8-wt+ #59
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-20220807_005459-localhost 04/01/2014
+Workqueue: phy3 ieee80211_ba_session_work [mac80211]
+RIP: 0010:drv_ampdu_action+0x46/0x280 [mac80211]
+Code: 53 48 89 f3 be 89 01 00 00 e8 d6 43 bf ef e8 21 46 81 f0 83 bb a0 1b 00 00 04 75 0e 48 8b 9b 28 0d 00 00 48 81 eb 10 0e 00 00 <8b> 93 58 09 00 00 f6 c2 20 0f 84 3b 01 00 00 8b 05 dd 1c 0f 00 85
+RSP: 0018:ffffc900025ebd20 EFLAGS: 00010287
+RAX: 0000000000000000 RBX: fffffffffffff1f0 RCX: ffff888102228240
+RDX: 0000000080000000 RSI: ffffffff918c5de0 RDI: ffff888102228b40
+RBP: ffffc900025ebd40 R08: 0000000000000001 R09: 0000000000000001
+R10: 0000000000000001 R11: 0000000000000000 R12: ffff888118c18ec0
+R13: 0000000000000000 R14: ffffc900025ebd60 R15: ffff888018b7efb8
+FS: 0000000000000000(0000) GS:ffff88817a600000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: fffffffffffffb48 CR3: 0000000105228006 CR4: 0000000000170ee0
+Call Trace:
+ <TASK>
+ ieee80211_tx_ba_session_handle_start+0xd0/0x190 [mac80211]
+ ieee80211_ba_session_work+0xff/0x2e0 [mac80211]
+ process_one_work+0x29f/0x620
+ worker_thread+0x4d/0x3d0
+ ? process_one_work+0x620/0x620
+ kthread+0xfb/0x120
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x22/0x30
+ </TASK>
+
+Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
+Link: https://lore.kernel.org/r/20221230121850.218810-2-alexander@wetzel-home.de
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/agg-tx.c | 6 +++++-
+ net/mac80211/driver-ops.c | 3 +++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -491,7 +491,7 @@ void ieee80211_tx_ba_session_handle_star
+ {
+ struct tid_ampdu_tx *tid_tx;
+ struct ieee80211_local *local = sta->local;
+- struct ieee80211_sub_if_data *sdata = sta->sdata;
++ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_ampdu_params params = {
+ .sta = &sta->sta,
+ .action = IEEE80211_AMPDU_TX_START,
+@@ -521,6 +521,7 @@ void ieee80211_tx_ba_session_handle_star
+ */
+ synchronize_net();
+
++ sdata = sta->sdata;
+ params.ssn = sta->tid_seq[tid] >> 4;
+ ret = drv_ampdu_action(local, sdata, ¶ms);
+ tid_tx->ssn = params.ssn;
+@@ -534,6 +535,9 @@ void ieee80211_tx_ba_session_handle_star
+ */
+ set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state);
+ } else if (ret) {
++ if (!sdata)
++ return;
++
+ ht_dbg(sdata,
+ "BA request denied - HW unavailable for %pM tid %d\n",
+ sta->sta.addr, tid);
+--- a/net/mac80211/driver-ops.c
++++ b/net/mac80211/driver-ops.c
+@@ -391,6 +391,9 @@ int drv_ampdu_action(struct ieee80211_lo
+
+ might_sleep();
+
++ if (!sdata)
++ return -EIO;
++
+ sdata = get_bss_sdata(sdata);
+ if (!check_sdata_in_driver(sdata))
+ return -EIO;
--- /dev/null
+From a608da3bd730d718f2d3ebec1c26f9865f8f17ce Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Date: Fri, 6 Jan 2023 17:43:06 +0900
+Subject: zonefs: Detect append writes at invalid locations
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+commit a608da3bd730d718f2d3ebec1c26f9865f8f17ce upstream.
+
+Using REQ_OP_ZONE_APPEND operations for synchronous writes to sequential
+files succeeds regardless of the zone write pointer position, as long as
+the target zone is not full. This means that if an external (buggy)
+application writes to the zone of a sequential file underneath the file
+system, subsequent file write() operation will succeed but the file size
+will not be correct and the file will contain invalid data written by
+another application.
+
+Modify zonefs_file_dio_append() to check the written sector of an append
+write (returned in bio->bi_iter.bi_sector) and return -EIO if there is a
+mismatch with the file zone wp offset field. This change triggers a call
+to zonefs_io_error() and a zone check. Modify zonefs_io_error_cb() to
+not expose the unexpected data after the current inode size when the
+errors=remount-ro mode is used. Other error modes are correctly handled
+already.
+
+Fixes: 02ef12a663c7 ("zonefs: use REQ_OP_ZONE_APPEND for sync DIO")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/zonefs/super.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -442,6 +442,10 @@ static int zonefs_io_error_cb(struct blk
+ data_size = zonefs_check_zone_condition(inode, zone,
+ false, false);
+ }
++ } else if (sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_RO &&
++ data_size > isize) {
++ /* Do not expose garbage data */
++ data_size = isize;
+ }
+
+ /*
+@@ -805,6 +809,24 @@ static ssize_t zonefs_file_dio_append(st
+
+ ret = submit_bio_wait(bio);
+
++ /*
++ * If the file zone was written underneath the file system, the zone
++ * write pointer may not be where we expect it to be, but the zone
++ * append write can still succeed. So check manually that we wrote where
++ * we intended to, that is, at zi->i_wpoffset.
++ */
++ if (!ret) {
++ sector_t wpsector =
++ zi->i_zsector + (zi->i_wpoffset >> SECTOR_SHIFT);
++
++ if (bio->bi_iter.bi_sector != wpsector) {
++ zonefs_warn(inode->i_sb,
++ "Corrupted write pointer %llu for zone at %llu\n",
++ wpsector, zi->i_zsector);
++ ret = -EIO;
++ }
++ }
++
+ zonefs_file_write_dio_end_io(iocb, size, ret, 0);
+ trace_zonefs_file_dio_append(inode, size, ret);
+