]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Dec 2024 12:23:34 +0000 (13:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Dec 2024 12:23:34 +0000 (13:23 +0100)
added patches:
arm64-smccc-remove-broken-support-for-smcccv1.3-sve-discard-hint.patch
arm64-sve-discard-stale-cpu-state-when-handling-sve-traps.patch
bluetooth-l2cap-fix-uaf-in-l2cap_connect.patch
crypto-hisilicon-qm-inject-error-before-stopping-queue.patch
fou-remove-warn-in-gue_gro_receive-on-unsupported-protocol.patch
gve-fixes-for-napi_poll-when-budget-is-0.patch
ima-fix-use-after-free-on-a-dentry-s-dname.name.patch
net-dsa-microchip-correct-ksz8795-static-mac-table-access.patch
revert-drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch
scsi-core-fix-scsi_mode_select-buffer-length-handling.patch
serial-sc16is7xx-change-efr-lock-to-operate-on-each-channels.patch
serial-sc16is7xx-improve-regmap-debugfs-by-using-one-regmap-per-port.patch
serial-sc16is7xx-remove-global-regmap-from-struct-sc16is7xx_port.patch
serial-sc16is7xx-remove-unused-line-structure-member.patch
serial-sc16is7xx-remove-wasteful-static-buffer-in-sc16is7xx_regmap_name.patch

16 files changed:
queue-5.15/arm64-smccc-remove-broken-support-for-smcccv1.3-sve-discard-hint.patch [new file with mode: 0644]
queue-5.15/arm64-sve-discard-stale-cpu-state-when-handling-sve-traps.patch [new file with mode: 0644]
queue-5.15/bluetooth-l2cap-fix-uaf-in-l2cap_connect.patch [new file with mode: 0644]
queue-5.15/crypto-hisilicon-qm-inject-error-before-stopping-queue.patch [new file with mode: 0644]
queue-5.15/fou-remove-warn-in-gue_gro_receive-on-unsupported-protocol.patch [new file with mode: 0644]
queue-5.15/gve-fixes-for-napi_poll-when-budget-is-0.patch [new file with mode: 0644]
queue-5.15/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch [new file with mode: 0644]
queue-5.15/net-dsa-microchip-correct-ksz8795-static-mac-table-access.patch [new file with mode: 0644]
queue-5.15/revert-drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch [new file with mode: 0644]
queue-5.15/scsi-core-fix-scsi_mode_select-buffer-length-handling.patch [new file with mode: 0644]
queue-5.15/serial-sc16is7xx-change-efr-lock-to-operate-on-each-channels.patch [new file with mode: 0644]
queue-5.15/serial-sc16is7xx-improve-regmap-debugfs-by-using-one-regmap-per-port.patch [new file with mode: 0644]
queue-5.15/serial-sc16is7xx-remove-global-regmap-from-struct-sc16is7xx_port.patch [new file with mode: 0644]
queue-5.15/serial-sc16is7xx-remove-unused-line-structure-member.patch [new file with mode: 0644]
queue-5.15/serial-sc16is7xx-remove-wasteful-static-buffer-in-sc16is7xx_regmap_name.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/arm64-smccc-remove-broken-support-for-smcccv1.3-sve-discard-hint.patch b/queue-5.15/arm64-smccc-remove-broken-support-for-smcccv1.3-sve-discard-hint.patch
new file mode 100644 (file)
index 0000000..25b6871
--- /dev/null
@@ -0,0 +1,224 @@
+From 8c462d56487e3abdbf8a61cedfe7c795a54f4a78 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Wed, 6 Nov 2024 16:04:48 +0000
+Subject: arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit 8c462d56487e3abdbf8a61cedfe7c795a54f4a78 upstream.
+
+SMCCCv1.3 added a hint bit which callers can set in an SMCCC function ID
+(AKA "FID") to indicate that it is acceptable for the SMCCC
+implementation to discard SVE and/or SME state over a specific SMCCC
+call. The kernel support for using this hint is broken and SMCCC calls
+may clobber the SVE and/or SME state of arbitrary tasks, though FPSIMD
+state is unaffected.
+
+The kernel support is intended to use the hint when there is no SVE or
+SME state to save, and to do this it checks whether TIF_FOREIGN_FPSTATE
+is set or TIF_SVE is clear in assembly code:
+
+|        ldr     <flags>, [<current_task>, #TSK_TI_FLAGS]
+|        tbnz    <flags>, #TIF_FOREIGN_FPSTATE, 1f   // Any live FP state?
+|        tbnz    <flags>, #TIF_SVE, 2f               // Does that state include SVE?
+|
+| 1:     orr     <fid>, <fid>, ARM_SMCCC_1_3_SVE_HINT
+| 2:
+|        << SMCCC call using FID >>
+
+This is not safe as-is:
+
+(1) SMCCC calls can be made in a preemptible context and preemption can
+    result in TIF_FOREIGN_FPSTATE being set or cleared at arbitrary
+    points in time. Thus checking for TIF_FOREIGN_FPSTATE provides no
+    guarantee.
+
+(2) TIF_FOREIGN_FPSTATE only indicates that the live FP/SVE/SME state in
+    the CPU does not belong to the current task, and does not indicate
+    that clobbering this state is acceptable.
+
+    When the live CPU state is clobbered it is necessary to update
+    fpsimd_last_state.st to ensure that a subsequent context switch will
+    reload FP/SVE/SME state from memory rather than consuming the
+    clobbered state. This and the SMCCC call itself must happen in a
+    critical section with preemption disabled to avoid races.
+
+(3) Live SVE/SME state can exist with TIF_SVE clear (e.g. with only
+    TIF_SME set), and checking TIF_SVE alone is insufficient.
+
+Remove the broken support for the SMCCCv1.3 SVE saving hint. This is
+effectively a revert of commits:
+
+* cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint")
+* a7c3acca5380 ("arm64: smccc: Save lr before calling __arm_smccc_sve_check()")
+
+... leaving behind the ARM_SMCCC_VERSION_1_3 and ARM_SMCCC_1_3_SVE_HINT
+definitions, since these are simply definitions from the SMCCC
+specification, and the latter is used in KVM via ARM_SMCCC_CALL_HINTS.
+
+If we want to bring this back in future, we'll probably want to handle
+this logic in C where we can use all the usual FPSIMD/SVE/SME helper
+functions, and that'll likely require some rework of the SMCCC code
+and/or its callers.
+
+Fixes: cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Ard Biesheuvel <ardb@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20241106160448.2712997-1-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+[ Mark: fix conflicts in <linux/arm-smccc.h> and drivers/firmware/smccc/smccc.c ]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/smccc-call.S |   35 +++--------------------------------
+ drivers/firmware/smccc/smccc.c |    4 ----
+ include/linux/arm-smccc.h      |   30 ++----------------------------
+ 3 files changed, 5 insertions(+), 64 deletions(-)
+
+--- a/arch/arm64/kernel/smccc-call.S
++++ b/arch/arm64/kernel/smccc-call.S
+@@ -7,48 +7,19 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/assembler.h>
+-#include <asm/thread_info.h>
+-
+-/*
+- * If we have SMCCC v1.3 and (as is likely) no SVE state in
+- * the registers then set the SMCCC hint bit to say there's no
+- * need to preserve it.  Do this by directly adjusting the SMCCC
+- * function value which is already stored in x0 ready to be called.
+- */
+-SYM_FUNC_START(__arm_smccc_sve_check)
+-
+-      ldr_l   x16, smccc_has_sve_hint
+-      cbz     x16, 2f
+-
+-      get_current_task x16
+-      ldr     x16, [x16, #TSK_TI_FLAGS]
+-      tbnz    x16, #TIF_FOREIGN_FPSTATE, 1f   // Any live FP state?
+-      tbnz    x16, #TIF_SVE, 2f               // Does that state include SVE?
+-
+-1:    orr     x0, x0, ARM_SMCCC_1_3_SVE_HINT
+-
+-2:    ret
+-SYM_FUNC_END(__arm_smccc_sve_check)
+-EXPORT_SYMBOL(__arm_smccc_sve_check)
+       .macro SMCCC instr
+-      stp     x29, x30, [sp, #-16]!
+-      mov     x29, sp
+-alternative_if ARM64_SVE
+-      bl      __arm_smccc_sve_check
+-alternative_else_nop_endif
+       \instr  #0
+-      ldr     x4, [sp, #16]
++      ldr     x4, [sp]
+       stp     x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
+       stp     x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
+-      ldr     x4, [sp, #24]
++      ldr     x4, [sp, #8]
+       cbz     x4, 1f /* no quirk structure */
+       ldr     x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
+       cmp     x9, #ARM_SMCCC_QUIRK_QCOM_A6
+       b.ne    1f
+       str     x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
+-1:    ldp     x29, x30, [sp], #16
+-      ret
++1:    ret
+       .endm
+ /*
+--- a/drivers/firmware/smccc/smccc.c
++++ b/drivers/firmware/smccc/smccc.c
+@@ -16,7 +16,6 @@ static u32 smccc_version = ARM_SMCCC_VER
+ static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
+ bool __ro_after_init smccc_trng_available = false;
+-u64 __ro_after_init smccc_has_sve_hint = false;
+ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
+ {
+@@ -24,9 +23,6 @@ void __init arm_smccc_version_init(u32 v
+       smccc_conduit = conduit;
+       smccc_trng_available = smccc_probe_trng();
+-      if (IS_ENABLED(CONFIG_ARM64_SVE) &&
+-          smccc_version >= ARM_SMCCC_VERSION_1_3)
+-              smccc_has_sve_hint = true;
+ }
+ enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
+--- a/include/linux/arm-smccc.h
++++ b/include/linux/arm-smccc.h
+@@ -224,8 +224,6 @@ u32 arm_smccc_get_version(void);
+ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
+-extern u64 smccc_has_sve_hint;
+-
+ /**
+  * struct arm_smccc_res - Result from SMC/HVC call
+  * @a0-a3 result values from registers 0 to 3
+@@ -306,15 +304,6 @@ struct arm_smccc_quirk {
+ };
+ /**
+- * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls
+- *
+- * Sets the SMCCC hint bit to indicate if there is live state in the SVE
+- * registers, this modifies x0 in place and should never be called from C
+- * code.
+- */
+-asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0);
+-
+-/**
+  * __arm_smccc_smc() - make SMC calls
+  * @a0-a7: arguments passed in registers 0 to 7
+  * @res: result values from registers 0 to 3
+@@ -381,20 +370,6 @@ asmlinkage void __arm_smccc_hvc(unsigned
+ #endif
+-/* nVHE hypervisor doesn't have a current thread so needs separate checks */
+-#if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__)
+-
+-#define SMCCC_SVE_CHECK ALTERNATIVE("nop \n",  "bl __arm_smccc_sve_check \n", \
+-                                  ARM64_SVE)
+-#define smccc_sve_clobbers "x16", "x30", "cc",
+-
+-#else
+-
+-#define SMCCC_SVE_CHECK
+-#define smccc_sve_clobbers
+-
+-#endif
+-
+ #define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
+ #define __count_args(...)                                             \
+@@ -462,7 +437,7 @@ asmlinkage void __arm_smccc_hvc(unsigned
+ #define ___constraints(count)                                         \
+       : __constraint_read_ ## count                                   \
+-      : smccc_sve_clobbers "memory"
++      : "memory"
+ #define __constraints(count)  ___constraints(count)
+ /*
+@@ -477,8 +452,7 @@ asmlinkage void __arm_smccc_hvc(unsigned
+               register unsigned long r2 asm("r2");                    \
+               register unsigned long r3 asm("r3");                    \
+               __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
+-              asm volatile(SMCCC_SVE_CHECK                            \
+-                           inst "\n" :                                \
++              asm volatile(inst "\n" :                                \
+                            "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
+                            __constraints(__count_args(__VA_ARGS__))); \
+               if (___res)                                             \
diff --git a/queue-5.15/arm64-sve-discard-stale-cpu-state-when-handling-sve-traps.patch b/queue-5.15/arm64-sve-discard-stale-cpu-state-when-handling-sve-traps.patch
new file mode 100644 (file)
index 0000000..714fb15
--- /dev/null
@@ -0,0 +1,91 @@
+From 751ecf6afd6568adc98f2a6052315552c0483d18 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Wed, 30 Oct 2024 20:23:50 +0000
+Subject: arm64/sve: Discard stale CPU state when handling SVE traps
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 751ecf6afd6568adc98f2a6052315552c0483d18 upstream.
+
+The logic for handling SVE traps manipulates saved FPSIMD/SVE state
+incorrectly, and a race with preemption can result in a task having
+TIF_SVE set and TIF_FOREIGN_FPSTATE clear even though the live CPU state
+is stale (e.g. with SVE traps enabled). This has been observed to result
+in warnings from do_sve_acc() where SVE traps are not expected while
+TIF_SVE is set:
+
+|         if (test_and_set_thread_flag(TIF_SVE))
+|                 WARN_ON(1); /* SVE access shouldn't have trapped */
+
+Warnings of this form have been reported intermittently, e.g.
+
+  https://lore.kernel.org/linux-arm-kernel/CA+G9fYtEGe_DhY2Ms7+L7NKsLYUomGsgqpdBj+QwDLeSg=JhGg@mail.gmail.com/
+  https://lore.kernel.org/linux-arm-kernel/000000000000511e9a060ce5a45c@google.com/
+
+The race can occur when the SVE trap handler is preempted before and
+after manipulating the saved FPSIMD/SVE state, starting and ending on
+the same CPU, e.g.
+
+| void do_sve_acc(unsigned long esr, struct pt_regs *regs)
+| {
+|         // Trap on CPU 0 with TIF_SVE clear, SVE traps enabled
+|         // task->fpsimd_cpu is 0.
+|         // per_cpu_ptr(&fpsimd_last_state, 0) is task.
+|
+|         ...
+|
+|         // Preempted; migrated from CPU 0 to CPU 1.
+|         // TIF_FOREIGN_FPSTATE is set.
+|
+|         get_cpu_fpsimd_context();
+|
+|         if (test_and_set_thread_flag(TIF_SVE))
+|                 WARN_ON(1); /* SVE access shouldn't have trapped */
+|
+|         sve_init_regs() {
+|                 if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+|                         ...
+|                 } else {
+|                         fpsimd_to_sve(current);
+|                         current->thread.fp_type = FP_STATE_SVE;
+|                 }
+|         }
+|
+|         put_cpu_fpsimd_context();
+|
+|         // Preempted; migrated from CPU 1 to CPU 0.
+|         // task->fpsimd_cpu is still 0
+|         // If per_cpu_ptr(&fpsimd_last_state, 0) is still task then:
+|         // - Stale HW state is reused (with SVE traps enabled)
+|         // - TIF_FOREIGN_FPSTATE is cleared
+|         // - A return to userspace skips HW state restore
+| }
+
+Fix the case where the state is not live and TIF_FOREIGN_FPSTATE is set
+by calling fpsimd_flush_task_state() to detach from the saved CPU
+state. This ensures that a subsequent context switch will not reuse the
+stale CPU state, and will instead set TIF_FOREIGN_FPSTATE, forcing the
+new state to be reloaded from memory prior to a return to userspace.
+
+Fixes: cccb78ce89c4 ("arm64/sve: Rework SVE access trap to convert state in registers")
+Reported-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Mark Rutland <mark.rutland@arm.com>
+Link: https://lore.kernel.org/r/20241030-arm64-fpsimd-foreign-flush-v1-1-bd7bd66905a2@kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/fpsimd.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -964,6 +964,7 @@ void do_sve_acc(unsigned long esr, struc
+               fpsimd_bind_task_to_cpu();
+       } else {
+               fpsimd_to_sve(current);
++              fpsimd_flush_task_state(current);
+       }
+       put_cpu_fpsimd_context();
diff --git a/queue-5.15/bluetooth-l2cap-fix-uaf-in-l2cap_connect.patch b/queue-5.15/bluetooth-l2cap-fix-uaf-in-l2cap_connect.patch
new file mode 100644 (file)
index 0000000..81f6f30
--- /dev/null
@@ -0,0 +1,123 @@
+From 333b4fd11e89b29c84c269123f871883a30be586 Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Date: Mon, 23 Sep 2024 12:47:39 -0400
+Subject: Bluetooth: L2CAP: Fix uaf in l2cap_connect
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+commit 333b4fd11e89b29c84c269123f871883a30be586 upstream.
+
+[Syzbot reported]
+BUG: KASAN: slab-use-after-free in l2cap_connect.constprop.0+0x10d8/0x1270 net/bluetooth/l2cap_core.c:3949
+Read of size 8 at addr ffff8880241e9800 by task kworker/u9:0/54
+
+CPU: 0 UID: 0 PID: 54 Comm: kworker/u9:0 Not tainted 6.11.0-rc6-syzkaller-00268-g788220eee30d #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024
+Workqueue: hci2 hci_rx_work
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:93 [inline]
+ dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:119
+ print_address_description mm/kasan/report.c:377 [inline]
+ print_report+0xc3/0x620 mm/kasan/report.c:488
+ kasan_report+0xd9/0x110 mm/kasan/report.c:601
+ l2cap_connect.constprop.0+0x10d8/0x1270 net/bluetooth/l2cap_core.c:3949
+ l2cap_connect_req net/bluetooth/l2cap_core.c:4080 [inline]
+ l2cap_bredr_sig_cmd net/bluetooth/l2cap_core.c:4772 [inline]
+ l2cap_sig_channel net/bluetooth/l2cap_core.c:5543 [inline]
+ l2cap_recv_frame+0xf0b/0x8eb0 net/bluetooth/l2cap_core.c:6825
+ l2cap_recv_acldata+0x9b4/0xb70 net/bluetooth/l2cap_core.c:7514
+ hci_acldata_packet net/bluetooth/hci_core.c:3791 [inline]
+ hci_rx_work+0xaab/0x1610 net/bluetooth/hci_core.c:4028
+ process_one_work+0x9c5/0x1b40 kernel/workqueue.c:3231
+ process_scheduled_works kernel/workqueue.c:3312 [inline]
+ worker_thread+0x6c8/0xed0 kernel/workqueue.c:3389
+ kthread+0x2c1/0x3a0 kernel/kthread.c:389
+ ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
+...
+
+Freed by task 5245:
+ kasan_save_stack+0x33/0x60 mm/kasan/common.c:47
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:68
+ kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:579
+ poison_slab_object+0xf7/0x160 mm/kasan/common.c:240
+ __kasan_slab_free+0x32/0x50 mm/kasan/common.c:256
+ kasan_slab_free include/linux/kasan.h:184 [inline]
+ slab_free_hook mm/slub.c:2256 [inline]
+ slab_free mm/slub.c:4477 [inline]
+ kfree+0x12a/0x3b0 mm/slub.c:4598
+ l2cap_conn_free net/bluetooth/l2cap_core.c:1810 [inline]
+ kref_put include/linux/kref.h:65 [inline]
+ l2cap_conn_put net/bluetooth/l2cap_core.c:1822 [inline]
+ l2cap_conn_del+0x59d/0x730 net/bluetooth/l2cap_core.c:1802
+ l2cap_connect_cfm+0x9e6/0xf80 net/bluetooth/l2cap_core.c:7241
+ hci_connect_cfm include/net/bluetooth/hci_core.h:1960 [inline]
+ hci_conn_failed+0x1c3/0x370 net/bluetooth/hci_conn.c:1265
+ hci_abort_conn_sync+0x75a/0xb50 net/bluetooth/hci_sync.c:5583
+ abort_conn_sync+0x197/0x360 net/bluetooth/hci_conn.c:2917
+ hci_cmd_sync_work+0x1a4/0x410 net/bluetooth/hci_sync.c:328
+ process_one_work+0x9c5/0x1b40 kernel/workqueue.c:3231
+ process_scheduled_works kernel/workqueue.c:3312 [inline]
+ worker_thread+0x6c8/0xed0 kernel/workqueue.c:3389
+ kthread+0x2c1/0x3a0 kernel/kthread.c:389
+ ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
+
+Reported-by: syzbot+c12e2f941af1feb5632c@syzkaller.appspotmail.com
+Tested-by: syzbot+c12e2f941af1feb5632c@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c12e2f941af1feb5632c
+Fixes: 7b064edae38d ("Bluetooth: Fix authentication if acl data comes before remote feature evt")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
+Signed-off-by: Guocai He <guocai.he.cn@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hci_core.c   |    2 ++
+ net/bluetooth/hci_event.c  |    2 +-
+ net/bluetooth/l2cap_core.c |    9 ---------
+ 3 files changed, 3 insertions(+), 10 deletions(-)
+
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4964,6 +4964,8 @@ static void hci_acldata_packet(struct hc
+       hci_dev_lock(hdev);
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
++      if (conn && hci_dev_test_flag(hdev, HCI_MGMT))
++              mgmt_device_connected(hdev, conn, NULL, 0);
+       hci_dev_unlock(hdev);
+       if (conn) {
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3338,7 +3338,7 @@ static void hci_remote_features_evt(stru
+               goto unlock;
+       }
+-      if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
++      if (!ev->status) {
+               struct hci_cp_remote_name_req cp;
+               memset(&cp, 0, sizeof(cp));
+               bacpy(&cp.bdaddr, &conn->dst);
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -4276,18 +4276,9 @@ sendresp:
+ static int l2cap_connect_req(struct l2cap_conn *conn,
+                            struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
+ {
+-      struct hci_dev *hdev = conn->hcon->hdev;
+-      struct hci_conn *hcon = conn->hcon;
+-
+       if (cmd_len < sizeof(struct l2cap_conn_req))
+               return -EPROTO;
+-      hci_dev_lock(hdev);
+-      if (hci_dev_test_flag(hdev, HCI_MGMT) &&
+-          !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
+-              mgmt_device_connected(hdev, hcon, NULL, 0);
+-      hci_dev_unlock(hdev);
+-
+       l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
+       return 0;
+ }
diff --git a/queue-5.15/crypto-hisilicon-qm-inject-error-before-stopping-queue.patch b/queue-5.15/crypto-hisilicon-qm-inject-error-before-stopping-queue.patch
new file mode 100644 (file)
index 0000000..968f474
--- /dev/null
@@ -0,0 +1,108 @@
+From b04f06fc0243600665b3b50253869533b7938468 Mon Sep 17 00:00:00 2001
+From: Weili Qian <qianweili@huawei.com>
+Date: Sat, 31 Aug 2024 19:48:31 +0800
+Subject: crypto: hisilicon/qm - inject error before stopping queue
+
+From: Weili Qian <qianweili@huawei.com>
+
+commit b04f06fc0243600665b3b50253869533b7938468 upstream.
+
+The master ooo cannot be completely closed when the
+accelerator core reports memory error. Therefore, the driver
+needs to inject the qm error to close the master ooo. Currently,
+the qm error is injected after stopping queue, memory may be
+released immediately after stopping queue, causing the device to
+access the released memory. Therefore, error is injected to close master
+ooo before stopping queue to ensure that the device does not access
+the released memory.
+
+Fixes: 6c6dd5802c2d ("crypto: hisilicon/qm - add controller reset interface")
+Signed-off-by: Weili Qian <qianweili@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
+---
+ drivers/crypto/hisilicon/qm.c |   51 +++++++++++++++++++-----------------------
+ 1 file changed, 24 insertions(+), 27 deletions(-)
+
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -4638,6 +4638,28 @@ static int qm_set_vf_mse(struct hisi_qm
+       return -ETIMEDOUT;
+ }
++static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
++{
++      u32 nfe_enb = 0;
++
++      /* Kunpeng930 hardware automatically close master ooo when NFE occurs */
++      if (qm->ver >= QM_HW_V3)
++              return;
++
++      if (!qm->err_status.is_dev_ecc_mbit &&
++          qm->err_status.is_qm_ecc_mbit &&
++          qm->err_ini->close_axi_master_ooo) {
++              qm->err_ini->close_axi_master_ooo(qm);
++      } else if (qm->err_status.is_dev_ecc_mbit &&
++                 !qm->err_status.is_qm_ecc_mbit &&
++                 !qm->err_ini->close_axi_master_ooo) {
++              nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
++              writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
++                     qm->io_base + QM_RAS_NFE_ENABLE);
++              writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
++      }
++}
++
+ static int qm_vf_reset_prepare(struct hisi_qm *qm,
+                              enum qm_stop_reason stop_reason)
+ {
+@@ -4742,6 +4764,8 @@ static int qm_controller_reset_prepare(s
+               return ret;
+       }
++      qm_dev_ecc_mbit_handle(qm);
++
+       /* PF obtains the information of VF by querying the register. */
+       qm_cmd_uninit(qm);
+@@ -4766,31 +4790,6 @@ static int qm_controller_reset_prepare(s
+       return 0;
+ }
+-static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
+-{
+-      u32 nfe_enb = 0;
+-
+-      /* Kunpeng930 hardware automatically close master ooo when NFE occurs */
+-      if (qm->ver >= QM_HW_V3)
+-              return;
+-
+-      if (!qm->err_status.is_dev_ecc_mbit &&
+-          qm->err_status.is_qm_ecc_mbit &&
+-          qm->err_ini->close_axi_master_ooo) {
+-
+-              qm->err_ini->close_axi_master_ooo(qm);
+-
+-      } else if (qm->err_status.is_dev_ecc_mbit &&
+-                 !qm->err_status.is_qm_ecc_mbit &&
+-                 !qm->err_ini->close_axi_master_ooo) {
+-
+-              nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
+-              writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
+-                     qm->io_base + QM_RAS_NFE_ENABLE);
+-              writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
+-      }
+-}
+-
+ static int qm_soft_reset(struct hisi_qm *qm)
+ {
+       struct pci_dev *pdev = qm->pdev;
+@@ -4816,8 +4815,6 @@ static int qm_soft_reset(struct hisi_qm
+               return ret;
+       }
+-      qm_dev_ecc_mbit_handle(qm);
+-
+       /* OOO register set and check */
+       writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
+              qm->io_base + ACC_MASTER_GLOBAL_CTRL);
diff --git a/queue-5.15/fou-remove-warn-in-gue_gro_receive-on-unsupported-protocol.patch b/queue-5.15/fou-remove-warn-in-gue_gro_receive-on-unsupported-protocol.patch
new file mode 100644 (file)
index 0000000..a1a3a92
--- /dev/null
@@ -0,0 +1,42 @@
+From dd89a81d850fa9a65f67b4527c0e420d15bf836c Mon Sep 17 00:00:00 2001
+From: Willem de Bruijn <willemb@google.com>
+Date: Fri, 14 Jun 2024 08:25:18 -0400
+Subject: fou: remove warn in gue_gro_receive on unsupported protocol
+
+From: Willem de Bruijn <willemb@google.com>
+
+commit dd89a81d850fa9a65f67b4527c0e420d15bf836c upstream.
+
+Drop the WARN_ON_ONCE inn gue_gro_receive if the encapsulated type is
+not known or does not have a GRO handler.
+
+Such a packet is easily constructed. Syzbot generates them and sets
+off this warning.
+
+Remove the warning as it is expected and not actionable.
+
+The warning was previously reduced from WARN_ON to WARN_ON_ONCE in
+commit 270136613bf7 ("fou: Do WARN_ON_ONCE in gue_gro_receive for bad
+proto callbacks").
+
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20240614122552.1649044-1-willemdebruijn.kernel@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
+---
+ net/ipv4/fou.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/fou.c
++++ b/net/ipv4/fou.c
+@@ -453,7 +453,7 @@ next_proto:
+       offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
+       ops = rcu_dereference(offloads[proto]);
+-      if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive))
++      if (!ops || !ops->callbacks.gro_receive)
+               goto out;
+       pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
diff --git a/queue-5.15/gve-fixes-for-napi_poll-when-budget-is-0.patch b/queue-5.15/gve-fixes-for-napi_poll-when-budget-is-0.patch
new file mode 100644 (file)
index 0000000..83aee3d
--- /dev/null
@@ -0,0 +1,78 @@
+From 278a370c1766060d2144d6cf0b06c101e1043b6d Mon Sep 17 00:00:00 2001
+From: Ziwei Xiao <ziweixiao@google.com>
+Date: Mon, 13 Nov 2023 16:41:44 -0800
+Subject: gve: Fixes for napi_poll when budget is 0
+
+From: Ziwei Xiao <ziweixiao@google.com>
+
+commit 278a370c1766060d2144d6cf0b06c101e1043b6d upstream.
+
+Netpoll will explicilty pass the polling call with a budget of 0 to
+indicate it's clearing the Tx path only. For the gve_rx_poll and
+gve_xdp_poll, they were mistakenly taking the 0 budget as the indication
+to do all the work. Add check to avoid the rx path and xdp path being
+called when budget is 0. And also avoid napi_complete_done being called
+when budget is 0 for netpoll.
+
+Fixes: f5cedc84a30d ("gve: Add transmit and receive support")
+Signed-off-by: Ziwei Xiao <ziweixiao@google.com>
+Link: https://lore.kernel.org/r/20231114004144.2022268-1-ziweixiao@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Praveen Kaligineedi <pkaligineedi@google.com>
+Signed-off-by: Praveen Kaligineedi <pkaligineedi@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/google/gve/gve_main.c |    7 +++++++
+ drivers/net/ethernet/google/gve/gve_rx.c   |    4 ----
+ drivers/net/ethernet/google/gve/gve_tx.c   |    4 ----
+ 3 files changed, 7 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/google/gve/gve_main.c
++++ b/drivers/net/ethernet/google/gve/gve_main.c
+@@ -201,6 +201,10 @@ static int gve_napi_poll(struct napi_str
+       if (block->tx)
+               reschedule |= gve_tx_poll(block, budget);
++
++      if (!budget)
++              return 0;
++
+       if (block->rx)
+               reschedule |= gve_rx_poll(block, budget);
+@@ -236,6 +240,9 @@ static int gve_napi_poll_dqo(struct napi
+       if (block->tx)
+               reschedule |= gve_tx_poll_dqo(block, /*do_clean=*/true);
++      if (!budget)
++              return 0;
++
+       if (block->rx) {
+               work_done = gve_rx_poll_dqo(block, budget);
+               reschedule |= work_done == budget;
+--- a/drivers/net/ethernet/google/gve/gve_rx.c
++++ b/drivers/net/ethernet/google/gve/gve_rx.c
+@@ -606,10 +606,6 @@ bool gve_rx_poll(struct gve_notify_block
+       feat = block->napi.dev->features;
+-      /* If budget is 0, do all the work */
+-      if (budget == 0)
+-              budget = INT_MAX;
+-
+       if (budget > 0)
+               repoll |= gve_clean_rx_done(rx, budget, feat);
+       else
+--- a/drivers/net/ethernet/google/gve/gve_tx.c
++++ b/drivers/net/ethernet/google/gve/gve_tx.c
+@@ -686,10 +686,6 @@ bool gve_tx_poll(struct gve_notify_block
+       u32 nic_done;
+       u32 to_do;
+-      /* If budget is 0, do all the work */
+-      if (budget == 0)
+-              budget = INT_MAX;
+-
+       /* Find out how much work there is to be done */
+       tx->last_nic_done = gve_tx_load_event_counter(priv, tx);
+       nic_done = be32_to_cpu(tx->last_nic_done);
diff --git a/queue-5.15/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch b/queue-5.15/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch
new file mode 100644 (file)
index 0000000..d72401d
--- /dev/null
@@ -0,0 +1,114 @@
+From be84f32bb2c981ca670922e047cdde1488b233de Mon Sep 17 00:00:00 2001
+From: Stefan Berger <stefanb@linux.ibm.com>
+Date: Fri, 22 Mar 2024 10:03:12 -0400
+Subject: ima: Fix use-after-free on a dentry's dname.name
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+commit be84f32bb2c981ca670922e047cdde1488b233de upstream.
+
+->d_name.name can change on rename and the earlier value can be freed;
+there are conditions sufficient to stabilize it (->d_lock on dentry,
+->d_lock on its parent, ->i_rwsem exclusive on the parent's inode,
+rename_lock), but none of those are met at any of the sites. Take a stable
+snapshot of the name instead.
+
+Link: https://lore.kernel.org/all/20240202182732.GE2087318@ZenIV/
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
+---
+ security/integrity/ima/ima_api.c          |   16 ++++++++++++----
+ security/integrity/ima/ima_template_lib.c |   17 ++++++++++++++---
+ 2 files changed, 26 insertions(+), 7 deletions(-)
+
+--- a/security/integrity/ima/ima_api.c
++++ b/security/integrity/ima/ima_api.c
+@@ -217,7 +217,7 @@ int ima_collect_measurement(struct integ
+       const char *audit_cause = "failed";
+       struct inode *inode = file_inode(file);
+       struct inode *real_inode = d_real_inode(file_dentry(file));
+-      const char *filename = file->f_path.dentry->d_name.name;
++      struct name_snapshot filename;
+       int result = 0;
+       int length;
+       void *tmpbuf;
+@@ -280,9 +280,13 @@ out:
+               if (file->f_flags & O_DIRECT)
+                       audit_cause = "failed(directio)";
++              take_dentry_name_snapshot(&filename, file->f_path.dentry);
++
+               integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
+-                                  filename, "collect_data", audit_cause,
+-                                  result, 0);
++                                  filename.name.name, "collect_data",
++                                  audit_cause, result, 0);
++
++              release_dentry_name_snapshot(&filename);
+       }
+       return result;
+ }
+@@ -395,6 +399,7 @@ out:
+  */
+ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
+ {
++      struct name_snapshot filename;
+       char *pathname = NULL;
+       *pathbuf = __getname();
+@@ -408,7 +413,10 @@ const char *ima_d_path(const struct path
+       }
+       if (!pathname) {
+-              strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX);
++              take_dentry_name_snapshot(&filename, path->dentry);
++              strscpy(namebuf, filename.name.name, NAME_MAX);
++              release_dentry_name_snapshot(&filename);
++
+               pathname = namebuf;
+       }
+--- a/security/integrity/ima/ima_template_lib.c
++++ b/security/integrity/ima/ima_template_lib.c
+@@ -426,7 +426,10 @@ static int ima_eventname_init_common(str
+                                    bool size_limit)
+ {
+       const char *cur_filename = NULL;
++      struct name_snapshot filename;
+       u32 cur_filename_len = 0;
++      bool snapshot = false;
++      int ret;
+       BUG_ON(event_data->filename == NULL && event_data->file == NULL);
+@@ -439,7 +442,10 @@ static int ima_eventname_init_common(str
+       }
+       if (event_data->file) {
+-              cur_filename = event_data->file->f_path.dentry->d_name.name;
++              take_dentry_name_snapshot(&filename,
++                                        event_data->file->f_path.dentry);
++              snapshot = true;
++              cur_filename = filename.name.name;
+               cur_filename_len = strlen(cur_filename);
+       } else
+               /*
+@@ -448,8 +454,13 @@ static int ima_eventname_init_common(str
+                */
+               cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
+ out:
+-      return ima_write_template_field_data(cur_filename, cur_filename_len,
+-                                           DATA_FMT_STRING, field_data);
++      ret = ima_write_template_field_data(cur_filename, cur_filename_len,
++                                          DATA_FMT_STRING, field_data);
++
++      if (snapshot)
++              release_dentry_name_snapshot(&filename);
++
++      return ret;
+ }
+ /*
diff --git a/queue-5.15/net-dsa-microchip-correct-ksz8795-static-mac-table-access.patch b/queue-5.15/net-dsa-microchip-correct-ksz8795-static-mac-table-access.patch
new file mode 100644 (file)
index 0000000..f747cc5
--- /dev/null
@@ -0,0 +1,75 @@
+From 4bdf79d686b49ac49373b36466acfb93972c7d7c Mon Sep 17 00:00:00 2001
+From: Tristram Ha <Tristram.Ha@microchip.com>
+Date: Thu, 13 Jul 2023 17:46:22 -0700
+Subject: net: dsa: microchip: correct KSZ8795 static MAC table access
+
+From: Tristram Ha <Tristram.Ha@microchip.com>
+
+commit 4bdf79d686b49ac49373b36466acfb93972c7d7c upstream.
+
+The KSZ8795 driver code was modified to use on KSZ8863/73, which has
+different register definitions.  Some of the new KSZ8795 register
+information are wrong compared to previous code.
+
+KSZ8795 also behaves differently in that the STATIC_MAC_TABLE_USE_FID
+and STATIC_MAC_TABLE_FID bits are off by 1 when doing MAC table reading
+than writing.  To compensate that a special code was added to shift the
+register value by 1 before applying those bits.  This is wrong when the
+code is running on KSZ8863, so this special code is only executed when
+KSZ8795 is detected.
+
+Fixes: 4b20a07e103f ("net: dsa: microchip: ksz8795: add support for ksz88xx chips")
+Signed-off-by: Tristram Ha <Tristram.Ha@microchip.com>
+Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Jörg Sommer <joerg@jo-so.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/microchip/ksz8795.c |   18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/dsa/microchip/ksz8795.c
++++ b/drivers/net/dsa/microchip/ksz8795.c
+@@ -25,6 +25,8 @@
+ #include "ksz8795_reg.h"
+ #include "ksz8.h"
++#define KSZ8795_CHIP_ID         0x09
++
+ static const u8 ksz8795_regs[] = {
+       [REG_IND_CTRL_0]                = 0x6E,
+       [REG_IND_DATA_8]                = 0x70,
+@@ -52,13 +54,13 @@ static const u32 ksz8795_masks[] = {
+       [STATIC_MAC_TABLE_VALID]        = BIT(21),
+       [STATIC_MAC_TABLE_USE_FID]      = BIT(23),
+       [STATIC_MAC_TABLE_FID]          = GENMASK(30, 24),
+-      [STATIC_MAC_TABLE_OVERRIDE]     = BIT(26),
+-      [STATIC_MAC_TABLE_FWD_PORTS]    = GENMASK(24, 20),
++      [STATIC_MAC_TABLE_OVERRIDE]     = BIT(22),
++      [STATIC_MAC_TABLE_FWD_PORTS]    = GENMASK(20, 16),
+       [DYNAMIC_MAC_TABLE_ENTRIES_H]   = GENMASK(6, 0),
+-      [DYNAMIC_MAC_TABLE_MAC_EMPTY]   = BIT(8),
++      [DYNAMIC_MAC_TABLE_MAC_EMPTY]   = BIT(7),
+       [DYNAMIC_MAC_TABLE_NOT_READY]   = BIT(7),
+       [DYNAMIC_MAC_TABLE_ENTRIES]     = GENMASK(31, 29),
+-      [DYNAMIC_MAC_TABLE_FID]         = GENMASK(26, 20),
++      [DYNAMIC_MAC_TABLE_FID]         = GENMASK(22, 16),
+       [DYNAMIC_MAC_TABLE_SRC_PORT]    = GENMASK(26, 24),
+       [DYNAMIC_MAC_TABLE_TIMESTAMP]   = GENMASK(28, 27),
+ };
+@@ -601,7 +603,13 @@ static int ksz8_r_sta_mac_table(struct k
+                               shifts[STATIC_MAC_FWD_PORTS];
+               alu->is_override =
+                       (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE]) ? 1 : 0;
+-              data_hi >>= 1;
++
++              /* KSZ8795 family switches have STATIC_MAC_TABLE_USE_FID and
++               * STATIC_MAC_TABLE_FID definitions off by 1 when doing read on the
++               * static MAC table compared to doing write.
++               */
++              if (dev->chip_id == KSZ8795_CHIP_ID)
++                      data_hi >>= 1;
+               alu->is_static = true;
+               alu->is_use_fid =
+                       (data_hi & masks[STATIC_MAC_TABLE_USE_FID]) ? 1 : 0;
diff --git a/queue-5.15/revert-drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch b/queue-5.15/revert-drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch
new file mode 100644 (file)
index 0000000..ebba14e
--- /dev/null
@@ -0,0 +1,34 @@
+From zhangzekun11@huawei.com  Thu Dec 12 12:45:23 2024
+From: Zhang Zekun <zhangzekun11@huawei.com>
+Date: Wed, 4 Dec 2024 16:26:27 +0800
+Subject: Revert "drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read()"
+To: <gregkh@linuxfoundation.org>
+Cc: <cve@kernel.org>, <stable@vger.kernel.org>, <kevinyang.wang@amd.com>, <alexander.deucher@amd.com>, <liuyongqiang13@huawei.com>, <zhangzekun11@huawei.com>
+Message-ID: <20241204082627.3756-1-zhangzekun11@huawei.com>
+
+From: Zhang Zekun <zhangzekun11@huawei.com>
+
+This reverts commit aaf6160a4b7f9ee3cd91aa5b3251f5dbe2170f42.
+
+The origin mainline patch fix a buffer overflow issue in
+amdgpu_debugfs_gprwave_read(), but it has not been introduced in kernel
+6.1 and older kernels. This patch add a check in a wrong function in the
+same file.
+
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+@@ -401,7 +401,7 @@ static ssize_t amdgpu_debugfs_regs_didt_
+       ssize_t result = 0;
+       int r;
+-      if (size > 4096 || size & 0x3 || *pos & 0x3)
++      if (size & 0x3 || *pos & 0x3)
+               return -EINVAL;
+       if (!adev->didt_wreg)
diff --git a/queue-5.15/scsi-core-fix-scsi_mode_select-buffer-length-handling.patch b/queue-5.15/scsi-core-fix-scsi_mode_select-buffer-length-handling.patch
new file mode 100644 (file)
index 0000000..0519ba3
--- /dev/null
@@ -0,0 +1,71 @@
+From a7d6840bed0c2b16ac3071b74b5fcf08fc488241 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <damien.lemoal@wdc.com>
+Date: Fri, 20 Aug 2021 16:02:54 +0900
+Subject: scsi: core: Fix scsi_mode_select() buffer length handling
+
+From: Damien Le Moal <damien.lemoal@wdc.com>
+
+commit a7d6840bed0c2b16ac3071b74b5fcf08fc488241 upstream.
+
+The MODE SELECT(6) command allows handling mode page buffers that are up to
+255 bytes, including the 4 byte header needed in front of the page
+buffer. For requests larger than this limit, automatically use the MODE
+SELECT(10) command.
+
+In both cases, since scsi_mode_select() adds the mode select page header,
+checks on the buffer length value must include this header size to avoid
+overflows of the command CDB allocation length field.
+
+While at it, use put_unaligned_be16() for setting the header block
+descriptor length and CDB allocation length when using MODE SELECT(10).
+
+[mkp: fix MODE SENSE vs. MODE SELECT confusion]
+
+Link: https://lore.kernel.org/r/20210820070255.682775-3-damien.lemoal@wdc.com
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/scsi_lib.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2044,8 +2044,15 @@ scsi_mode_select(struct scsi_device *sde
+       memset(cmd, 0, sizeof(cmd));
+       cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0);
+-      if (sdev->use_10_for_ms) {
+-              if (len > 65535)
++      /*
++       * Use MODE SELECT(10) if the device asked for it or if the mode page
++       * and the mode select header cannot fit within the maximumm 255 bytes
++       * of the MODE SELECT(6) command.
++       */
++      if (sdev->use_10_for_ms ||
++          len + 4 > 255 ||
++          data->block_descriptor_length > 255) {
++              if (len > 65535 - 8)
+                       return -EINVAL;
+               real_buffer = kmalloc(8 + len, GFP_KERNEL);
+               if (!real_buffer)
+@@ -2058,15 +2065,13 @@ scsi_mode_select(struct scsi_device *sde
+               real_buffer[3] = data->device_specific;
+               real_buffer[4] = data->longlba ? 0x01 : 0;
+               real_buffer[5] = 0;
+-              real_buffer[6] = data->block_descriptor_length >> 8;
+-              real_buffer[7] = data->block_descriptor_length;
++              put_unaligned_be16(data->block_descriptor_length,
++                                 &real_buffer[6]);
+               cmd[0] = MODE_SELECT_10;
+-              cmd[7] = len >> 8;
+-              cmd[8] = len;
++              put_unaligned_be16(len, &cmd[7]);
+       } else {
+-              if (len > 255 || data->block_descriptor_length > 255 ||
+-                  data->longlba)
++              if (data->longlba)
+                       return -EINVAL;
+               real_buffer = kmalloc(4 + len, GFP_KERNEL);
diff --git a/queue-5.15/serial-sc16is7xx-change-efr-lock-to-operate-on-each-channels.patch b/queue-5.15/serial-sc16is7xx-change-efr-lock-to-operate-on-each-channels.patch
new file mode 100644 (file)
index 0000000..0f4b7b1
--- /dev/null
@@ -0,0 +1,181 @@
+From 4409df5866b7ff7686ba27e449ca97a92ee063c9 Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Mon, 11 Dec 2023 12:13:51 -0500
+Subject: serial: sc16is7xx: change EFR lock to operate on each channels
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit 4409df5866b7ff7686ba27e449ca97a92ee063c9 upstream.
+
+Now that the driver has been converted to use one regmap per port, change
+efr locking to operate on a channel basis instead of on the whole IC.
+
+Fixes: 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
+Cc:  <stable@vger.kernel.org> # 6.1.x: 3837a03 serial: sc16is7xx: improve regmap debugfs by using one regmap per port
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231211171353.2901416-5-hugo@hugovil.com
+[Hui: fixed some conflict when backporting to 5.15.y]
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c |   41 +++++++++++++++++++++++------------------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -314,6 +314,7 @@ struct sc16is7xx_one_config {
+ struct sc16is7xx_one {
+       struct uart_port                port;
+       struct regmap                   *regmap;
++      struct mutex                    efr_lock; /* EFR registers access */
+       struct kthread_work             tx_work;
+       struct kthread_work             reg_work;
+       struct sc16is7xx_one_config     config;
+@@ -329,7 +330,6 @@ struct sc16is7xx_port {
+       unsigned char                   buf[SC16IS7XX_FIFO_SIZE];
+       struct kthread_worker           kworker;
+       struct task_struct              *kworker_task;
+-      struct mutex                    efr_lock;
+       struct sc16is7xx_one            p[];
+ };
+@@ -491,7 +491,6 @@ static bool sc16is7xx_regmap_noinc(struc
+  */
+ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
+ {
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+       struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       u8 lcr;
+       unsigned int prescaler = 1;
+@@ -515,7 +514,7 @@ static int sc16is7xx_set_baud(struct uar
+        * because the bulk of the interrupt processing is run as a workqueue
+        * job in thread context.
+        */
+-      mutex_lock(&s->efr_lock);
++      mutex_lock(&one->efr_lock);
+       lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
+@@ -532,7 +531,7 @@ static int sc16is7xx_set_baud(struct uar
+       /* Put LCR back to the normal mode */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
+-      mutex_unlock(&s->efr_lock);
++      mutex_unlock(&one->efr_lock);
+       /* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */
+       sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
+@@ -680,14 +679,20 @@ static void sc16is7xx_handle_tx(struct u
+ static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
+ {
++      bool rc = true;
+       struct uart_port *port = &s->p[portno].port;
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
++
++      mutex_lock(&one->efr_lock);
+       do {
+               unsigned int iir, rxlen;
+               iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG);
+-              if (iir & SC16IS7XX_IIR_NO_INT_BIT)
+-                      return false;
++              if (iir & SC16IS7XX_IIR_NO_INT_BIT) {
++                      rc = false;
++                      goto out_port_irq;
++              }
+               iir &= SC16IS7XX_IIR_ID_MASK;
+@@ -722,15 +727,17 @@ static bool sc16is7xx_port_irq(struct sc
+                       break;
+               }
+       } while (0);
+-      return true;
++
++out_port_irq:
++      mutex_unlock(&one->efr_lock);
++
++      return rc;
+ }
+ static irqreturn_t sc16is7xx_irq(int irq, void *dev_id)
+ {
+       struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id;
+-      mutex_lock(&s->efr_lock);
+-
+       while (1) {
+               bool keep_polling = false;
+               int i;
+@@ -741,23 +748,21 @@ static irqreturn_t sc16is7xx_irq(int irq
+                       break;
+       }
+-      mutex_unlock(&s->efr_lock);
+-
+       return IRQ_HANDLED;
+ }
+ static void sc16is7xx_tx_proc(struct kthread_work *ws)
+ {
+       struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port);
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       if ((port->rs485.flags & SER_RS485_ENABLED) &&
+           (port->rs485.delay_rts_before_send > 0))
+               msleep(port->rs485.delay_rts_before_send);
+-      mutex_lock(&s->efr_lock);
++      mutex_lock(&one->efr_lock);
+       sc16is7xx_handle_tx(port);
+-      mutex_unlock(&s->efr_lock);
++      mutex_unlock(&one->efr_lock);
+ }
+ static void sc16is7xx_reconf_rs485(struct uart_port *port)
+@@ -878,7 +883,6 @@ static void sc16is7xx_set_termios(struct
+                                 struct ktermios *termios,
+                                 struct ktermios *old)
+ {
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+       struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       unsigned int lcr, flow = 0;
+       int baud;
+@@ -934,7 +938,7 @@ static void sc16is7xx_set_termios(struct
+               port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK;
+       /* As above, claim the mutex while accessing the EFR. */
+-      mutex_lock(&s->efr_lock);
++      mutex_lock(&one->efr_lock);
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
+                            SC16IS7XX_LCR_CONF_MODE_B);
+@@ -957,7 +961,7 @@ static void sc16is7xx_set_termios(struct
+       /* Update LCR register */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
+-      mutex_unlock(&s->efr_lock);
++      mutex_unlock(&one->efr_lock);
+       /* Get baud rate generator configuration */
+       baud = uart_get_baud_rate(port, termios, old,
+@@ -1261,7 +1265,6 @@ static int sc16is7xx_probe(struct device
+       s->devtype = devtype;
+       dev_set_drvdata(dev, s);
+-      mutex_init(&s->efr_lock);
+       kthread_init_worker(&s->kworker);
+       s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker,
+@@ -1302,6 +1305,8 @@ static int sc16is7xx_probe(struct device
+                       goto out_ports;
+               }
++              mutex_init(&s->p[i].efr_lock);
++
+               /* Disable all interrupts */
+               sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_IER_REG, 0);
+               /* Disable TX/RX */
diff --git a/queue-5.15/serial-sc16is7xx-improve-regmap-debugfs-by-using-one-regmap-per-port.patch b/queue-5.15/serial-sc16is7xx-improve-regmap-debugfs-by-using-one-regmap-per-port.patch
new file mode 100644 (file)
index 0000000..f49b300
--- /dev/null
@@ -0,0 +1,432 @@
+From 3837a0379533aabb9e4483677077479f7c6aa910 Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Mon, 30 Oct 2023 17:14:47 -0400
+Subject: serial: sc16is7xx: improve regmap debugfs by using one regmap per port
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit 3837a0379533aabb9e4483677077479f7c6aa910 upstream.
+
+With this current driver regmap implementation, it is hard to make sense
+of the register addresses displayed using the regmap debugfs interface,
+because they do not correspond to the actual register addresses documented
+in the datasheet. For example, register 1 is displayed as registers 04 thru
+07:
+
+$ cat /sys/kernel/debug/regmap/spi0.0/registers
+  04: 10 -> Port 0, register offset 1
+  05: 10 -> Port 1, register offset 1
+  06: 00 -> Port 2, register offset 1 -> invalid
+  07: 00 -> port 3, register offset 1 -> invalid
+  ...
+
+The reason is that bits 0 and 1 of the register address correspond to the
+channel (port) bits, so the register address itself starts at bit 2, and we
+must 'mentally' shift each register address by 2 bits to get its real
+address/offset.
+
+Also, only channels 0 and 1 are supported by the chip, so channel mask
+combinations of 10b and 11b are invalid, and the display of these
+registers is useless.
+
+This patch adds a separate regmap configuration for each port, similar to
+what is done in the max310x driver, so that register addresses displayed
+match the register addresses in the chip datasheet. Also, each port now has
+its own debugfs entry.
+
+Example with new regmap implementation:
+
+$ cat /sys/kernel/debug/regmap/spi0.0-port0/registers
+1: 10
+2: 01
+3: 00
+...
+
+$ cat /sys/kernel/debug/regmap/spi0.0-port1/registers
+1: 10
+2: 01
+3: 00
+
+As an added bonus, this also simplifies some operations (read/write/modify)
+because it is no longer necessary to manually shift register addresses.
+
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231030211447.974779-1-hugo@hugovil.com
+[Hui: Fixed some conflict when backporting to 5.15.y]
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c |  136 +++++++++++++++++++++++------------------
+ 1 file changed, 79 insertions(+), 57 deletions(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -292,8 +292,9 @@
+                                                 */
+ /* Misc definitions */
++#define SC16IS7XX_SPI_READ_BIT                BIT(7)
+ #define SC16IS7XX_FIFO_SIZE           (64)
+-#define SC16IS7XX_REG_SHIFT           2
++#define SC16IS7XX_GPIOS_PER_BANK      4
+ struct sc16is7xx_devtype {
+       char    name[10];
+@@ -313,6 +314,7 @@ struct sc16is7xx_one_config {
+ struct sc16is7xx_one {
+       struct uart_port                port;
+       u8                              line;
++      struct regmap                   *regmap;
+       struct kthread_work             tx_work;
+       struct kthread_work             reg_work;
+       struct sc16is7xx_one_config     config;
+@@ -344,46 +346,35 @@ static struct uart_driver sc16is7xx_uart
+ #define to_sc16is7xx_port(p,e)        ((container_of((p), struct sc16is7xx_port, e)))
+ #define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e)))
+-static int sc16is7xx_line(struct uart_port *port)
+-{
+-      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+-
+-      return one->line;
+-}
+-
+ static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)
+ {
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       unsigned int val = 0;
+-      const u8 line = sc16is7xx_line(port);
+-      regmap_read(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, &val);
++      regmap_read(one->regmap, reg, &val);
+       return val;
+ }
+ static void sc16is7xx_port_write(struct uart_port *port, u8 reg, u8 val)
+ {
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+-      const u8 line = sc16is7xx_line(port);
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+-      regmap_write(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, val);
++      regmap_write(one->regmap, reg, val);
+ }
+ static void sc16is7xx_fifo_read(struct uart_port *port, unsigned int rxlen)
+ {
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+-      const u8 line = sc16is7xx_line(port);
+-      u8 addr = (SC16IS7XX_RHR_REG << SC16IS7XX_REG_SHIFT) | line;
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+-      regmap_noinc_read(s->regmap, addr, s->buf, rxlen);
++      regmap_noinc_read(one->regmap, SC16IS7XX_RHR_REG, s->buf, rxlen);
+ }
+ static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send)
+ {
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+-      const u8 line = sc16is7xx_line(port);
+-      u8 addr = (SC16IS7XX_THR_REG << SC16IS7XX_REG_SHIFT) | line;
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       /*
+        * Don't send zero-length data, at least on SPI it confuses the chip
+@@ -392,17 +383,15 @@ static void sc16is7xx_fifo_write(struct
+       if (unlikely(!to_send))
+               return;
+-      regmap_noinc_write(s->regmap, addr, s->buf, to_send);
++      regmap_noinc_write(one->regmap, SC16IS7XX_THR_REG, s->buf, to_send);
+ }
+ static void sc16is7xx_port_update(struct uart_port *port, u8 reg,
+                                 u8 mask, u8 val)
+ {
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+-      const u8 line = sc16is7xx_line(port);
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+-      regmap_update_bits(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line,
+-                         mask, val);
++      regmap_update_bits(one->regmap, reg, mask, val);
+ }
+ static int sc16is7xx_alloc_line(void)
+@@ -457,7 +446,7 @@ static const struct sc16is7xx_devtype sc
+ static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg)
+ {
+-      switch (reg >> SC16IS7XX_REG_SHIFT) {
++      switch (reg) {
+       case SC16IS7XX_RHR_REG:
+       case SC16IS7XX_IIR_REG:
+       case SC16IS7XX_LSR_REG:
+@@ -475,7 +464,7 @@ static bool sc16is7xx_regmap_volatile(st
+ static bool sc16is7xx_regmap_precious(struct device *dev, unsigned int reg)
+ {
+-      switch (reg >> SC16IS7XX_REG_SHIFT) {
++      switch (reg) {
+       case SC16IS7XX_RHR_REG:
+               return true;
+       default:
+@@ -505,6 +494,7 @@ static bool sc16is7xx_regmap_noinc(struc
+ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
+ {
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       u8 lcr;
+       unsigned int prescaler = 1;
+       unsigned long clk = port->uartclk, div = clk / 16 / baud;
+@@ -536,10 +526,10 @@ static int sc16is7xx_set_baud(struct uar
+                            SC16IS7XX_LCR_CONF_MODE_B);
+       /* Enable enhanced features */
+-      regcache_cache_bypass(s->regmap, true);
++      regcache_cache_bypass(one->regmap, true);
+       sc16is7xx_port_write(port, SC16IS7XX_EFR_REG,
+                            SC16IS7XX_EFR_ENABLE_BIT);
+-      regcache_cache_bypass(s->regmap, false);
++      regcache_cache_bypass(one->regmap, false);
+       /* Put LCR back to the normal mode */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
+@@ -556,10 +546,10 @@ static int sc16is7xx_set_baud(struct uar
+                            SC16IS7XX_LCR_CONF_MODE_A);
+       /* Write the new divisor */
+-      regcache_cache_bypass(s->regmap, true);
++      regcache_cache_bypass(one->regmap, true);
+       sc16is7xx_port_write(port, SC16IS7XX_DLH_REG, div / 256);
+       sc16is7xx_port_write(port, SC16IS7XX_DLL_REG, div % 256);
+-      regcache_cache_bypass(s->regmap, false);
++      regcache_cache_bypass(one->regmap, false);
+       /* Put LCR back to the normal mode */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
+@@ -891,6 +881,7 @@ static void sc16is7xx_set_termios(struct
+                                 struct ktermios *old)
+ {
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
++      struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+       unsigned int lcr, flow = 0;
+       int baud;
+@@ -951,7 +942,7 @@ static void sc16is7xx_set_termios(struct
+                            SC16IS7XX_LCR_CONF_MODE_B);
+       /* Configure flow control */
+-      regcache_cache_bypass(s->regmap, true);
++      regcache_cache_bypass(one->regmap, true);
+       sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]);
+       sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]);
+       if (termios->c_cflag & CRTSCTS)
+@@ -963,7 +954,7 @@ static void sc16is7xx_set_termios(struct
+               flow |= SC16IS7XX_EFR_SWFLOW1_BIT;
+       sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, flow);
+-      regcache_cache_bypass(s->regmap, false);
++      regcache_cache_bypass(one->regmap, false);
+       /* Update LCR register */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
+@@ -1018,7 +1009,6 @@ static int sc16is7xx_config_rs485(struct
+ static int sc16is7xx_startup(struct uart_port *port)
+ {
+       struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+       unsigned int val;
+       sc16is7xx_power(port, 1);
+@@ -1034,7 +1024,7 @@ static int sc16is7xx_startup(struct uart
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
+                            SC16IS7XX_LCR_CONF_MODE_B);
+-      regcache_cache_bypass(s->regmap, true);
++      regcache_cache_bypass(one->regmap, true);
+       /* Enable write access to enhanced features and internal clock div */
+       sc16is7xx_port_write(port, SC16IS7XX_EFR_REG,
+@@ -1051,7 +1041,7 @@ static int sc16is7xx_startup(struct uart
+                            SC16IS7XX_TCR_RX_RESUME(24) |
+                            SC16IS7XX_TCR_RX_HALT(48));
+-      regcache_cache_bypass(s->regmap, false);
++      regcache_cache_bypass(one->regmap, false);
+       /* Now, initialize the UART */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8);
+@@ -1216,7 +1206,7 @@ static int sc16is7xx_gpio_direction_outp
+ static int sc16is7xx_probe(struct device *dev,
+                          const struct sc16is7xx_devtype *devtype,
+-                         struct regmap *regmap, int irq)
++                         struct regmap *regmaps[], int irq)
+ {
+       unsigned long freq = 0, *pfreq = dev_get_platdata(dev);
+       unsigned int val;
+@@ -1224,16 +1214,16 @@ static int sc16is7xx_probe(struct device
+       int i, ret;
+       struct sc16is7xx_port *s;
+-      if (IS_ERR(regmap))
+-              return PTR_ERR(regmap);
++      for (i = 0; i < devtype->nr_uart; i++)
++              if (IS_ERR(regmaps[i]))
++                      return PTR_ERR(regmaps[i]);
+       /*
+        * This device does not have an identification register that would
+        * tell us if we are really connected to the correct device.
+        * The best we can do is to check if communication is at all possible.
+        */
+-      ret = regmap_read(regmap,
+-                        SC16IS7XX_LSR_REG << SC16IS7XX_REG_SHIFT, &val);
++      ret = regmap_read(regmaps[0], SC16IS7XX_LSR_REG, &val);
+       if (ret < 0)
+               return -EPROBE_DEFER;
+@@ -1267,7 +1257,7 @@ static int sc16is7xx_probe(struct device
+                       return -EINVAL;
+       }
+-      s->regmap = regmap;
++      s->regmap = regmaps[0];
+       s->devtype = devtype;
+       dev_set_drvdata(dev, s);
+       mutex_init(&s->efr_lock);
+@@ -1282,8 +1272,8 @@ static int sc16is7xx_probe(struct device
+       sched_set_fifo(s->kworker_task);
+       /* reset device, purging any pending irq / data */
+-      regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT,
+-                      SC16IS7XX_IOCONTROL_SRESET_BIT);
++      regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG,
++                   SC16IS7XX_IOCONTROL_SRESET_BIT);
+       for (i = 0; i < devtype->nr_uart; ++i) {
+               s->p[i].line            = i;
+@@ -1305,6 +1295,8 @@ static int sc16is7xx_probe(struct device
+               s->p[i].port.rs485_config = sc16is7xx_config_rs485;
+               s->p[i].port.ops        = &sc16is7xx_ops;
+               s->p[i].port.line       = sc16is7xx_alloc_line();
++              s->p[i].regmap          = regmaps[i];
++
+               if (s->p[i].port.line >= SC16IS7XX_MAX_DEVS) {
+                       ret = -ENOMEM;
+                       goto out_ports;
+@@ -1326,13 +1318,13 @@ static int sc16is7xx_probe(struct device
+               sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG,
+                                    SC16IS7XX_LCR_CONF_MODE_B);
+-              regcache_cache_bypass(s->regmap, true);
++              regcache_cache_bypass(regmaps[i], true);
+               /* Enable write access to enhanced features */
+               sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_EFR_REG,
+                                    SC16IS7XX_EFR_ENABLE_BIT);
+-              regcache_cache_bypass(s->regmap, false);
++              regcache_cache_bypass(regmaps[i], false);
+               /* Restore access to general registers */
+               sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG, 0x00);
+@@ -1447,21 +1439,38 @@ static const struct of_device_id __maybe
+ MODULE_DEVICE_TABLE(of, sc16is7xx_dt_ids);
+ static struct regmap_config regcfg = {
+-      .reg_bits = 7,
+-      .pad_bits = 1,
++      .reg_bits = 5,
++      .pad_bits = 3,
+       .val_bits = 8,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_reg = sc16is7xx_regmap_volatile,
+       .precious_reg = sc16is7xx_regmap_precious,
+       .writeable_noinc_reg = sc16is7xx_regmap_noinc,
+       .readable_noinc_reg = sc16is7xx_regmap_noinc,
++      .max_register = SC16IS7XX_EFCR_REG,
+ };
++static const char *sc16is7xx_regmap_name(unsigned int port_id)
++{
++      static char buf[6];
++
++      snprintf(buf, sizeof(buf), "port%d", port_id);
++
++      return buf;
++}
++
++static unsigned int sc16is7xx_regmap_port_mask(unsigned int port_id)
++{
++      /* CH1,CH0 are at bits 2:1. */
++      return port_id << 1;
++}
++
+ #ifdef CONFIG_SERIAL_SC16IS7XX_SPI
+ static int sc16is7xx_spi_probe(struct spi_device *spi)
+ {
+       const struct sc16is7xx_devtype *devtype;
+-      struct regmap *regmap;
++      struct regmap *regmaps[2];
++      unsigned int i;
+       int ret;
+       /* Setup SPI bus */
+@@ -1486,11 +1495,20 @@ static int sc16is7xx_spi_probe(struct sp
+               devtype = (struct sc16is7xx_devtype *)id_entry->driver_data;
+       }
+-      regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) |
+-                            (devtype->nr_uart - 1);
+-      regmap = devm_regmap_init_spi(spi, &regcfg);
++      for (i = 0; i < devtype->nr_uart; i++) {
++              regcfg.name = sc16is7xx_regmap_name(i);
++              /*
++               * If read_flag_mask is 0, the regmap code sets it to a default
++               * of 0x80. Since we specify our own mask, we must add the READ
++               * bit ourselves:
++               */
++              regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i) |
++                      SC16IS7XX_SPI_READ_BIT;
++              regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
++              regmaps[i] = devm_regmap_init_spi(spi, &regcfg);
++      }
+-      return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq);
++      return sc16is7xx_probe(&spi->dev, devtype, regmaps, spi->irq);
+ }
+ static int sc16is7xx_spi_remove(struct spi_device *spi)
+@@ -1529,7 +1547,8 @@ static int sc16is7xx_i2c_probe(struct i2
+                              const struct i2c_device_id *id)
+ {
+       const struct sc16is7xx_devtype *devtype;
+-      struct regmap *regmap;
++      struct regmap *regmaps[2];
++      unsigned int i;
+       if (i2c->dev.of_node) {
+               devtype = device_get_match_data(&i2c->dev);
+@@ -1539,11 +1558,14 @@ static int sc16is7xx_i2c_probe(struct i2
+               devtype = (struct sc16is7xx_devtype *)id->driver_data;
+       }
+-      regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) |
+-                            (devtype->nr_uart - 1);
+-      regmap = devm_regmap_init_i2c(i2c, &regcfg);
++      for (i = 0; i < devtype->nr_uart; i++) {
++              regcfg.name = sc16is7xx_regmap_name(i);
++              regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i);
++              regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
++              regmaps[i] = devm_regmap_init_i2c(i2c, &regcfg);
++      }
+-      return sc16is7xx_probe(&i2c->dev, devtype, regmap, i2c->irq);
++      return sc16is7xx_probe(&i2c->dev, devtype, regmaps, i2c->irq);
+ }
+ static int sc16is7xx_i2c_remove(struct i2c_client *client)
diff --git a/queue-5.15/serial-sc16is7xx-remove-global-regmap-from-struct-sc16is7xx_port.patch b/queue-5.15/serial-sc16is7xx-remove-global-regmap-from-struct-sc16is7xx_port.patch
new file mode 100644 (file)
index 0000000..3039366
--- /dev/null
@@ -0,0 +1,64 @@
+From f6959c5217bd799bcb770b95d3c09b3244e175c6 Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Mon, 11 Dec 2023 12:13:49 -0500
+Subject: serial: sc16is7xx: remove global regmap from struct sc16is7xx_port
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit f6959c5217bd799bcb770b95d3c09b3244e175c6 upstream.
+
+Remove global struct regmap so that it is more obvious that this
+regmap is to be used only in the probe function.
+
+Also add a comment to that effect in probe function.
+
+Fixes: 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
+Cc:  <stable@vger.kernel.org>
+Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231211171353.2901416-3-hugo@hugovil.com
+[Hui: fixed some conflict when backporting to 5.15.y]
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -323,7 +323,6 @@ struct sc16is7xx_one {
+ struct sc16is7xx_port {
+       const struct sc16is7xx_devtype  *devtype;
+-      struct regmap                   *regmap;
+       struct clk                      *clk;
+ #ifdef CONFIG_GPIOLIB
+       struct gpio_chip                gpio;
+@@ -1222,6 +1221,10 @@ static int sc16is7xx_probe(struct device
+        * This device does not have an identification register that would
+        * tell us if we are really connected to the correct device.
+        * The best we can do is to check if communication is at all possible.
++       *
++       * Note: regmap[0] is used in the probe function to access registers
++       * common to all channels/ports, as it is guaranteed to be present on
++       * all variants.
+        */
+       ret = regmap_read(regmaps[0], SC16IS7XX_LSR_REG, &val);
+       if (ret < 0)
+@@ -1257,7 +1260,6 @@ static int sc16is7xx_probe(struct device
+                       return -EINVAL;
+       }
+-      s->regmap = regmaps[0];
+       s->devtype = devtype;
+       dev_set_drvdata(dev, s);
+       mutex_init(&s->efr_lock);
+@@ -1272,7 +1274,7 @@ static int sc16is7xx_probe(struct device
+       sched_set_fifo(s->kworker_task);
+       /* reset device, purging any pending irq / data */
+-      regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG,
++      regmap_write(regmaps[0], SC16IS7XX_IOCONTROL_REG,
+                    SC16IS7XX_IOCONTROL_SRESET_BIT);
+       for (i = 0; i < devtype->nr_uart; ++i) {
diff --git a/queue-5.15/serial-sc16is7xx-remove-unused-line-structure-member.patch b/queue-5.15/serial-sc16is7xx-remove-unused-line-structure-member.patch
new file mode 100644 (file)
index 0000000..68dba99
--- /dev/null
@@ -0,0 +1,40 @@
+From 41a308cbedb2a68a6831f0f2e992e296c4b8aff0 Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Mon, 11 Dec 2023 12:13:50 -0500
+Subject: serial: sc16is7xx: remove unused line structure member
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit 41a308cbedb2a68a6831f0f2e992e296c4b8aff0 upstream.
+
+Now that the driver has been converted to use one regmap per port, the line
+structure member is no longer used, so remove it.
+
+Fixes: 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231211171353.2901416-4-hugo@hugovil.com
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -313,7 +313,6 @@ struct sc16is7xx_one_config {
+ struct sc16is7xx_one {
+       struct uart_port                port;
+-      u8                              line;
+       struct regmap                   *regmap;
+       struct kthread_work             tx_work;
+       struct kthread_work             reg_work;
+@@ -1278,7 +1277,6 @@ static int sc16is7xx_probe(struct device
+                    SC16IS7XX_IOCONTROL_SRESET_BIT);
+       for (i = 0; i < devtype->nr_uart; ++i) {
+-              s->p[i].line            = i;
+               /* Initialize port data */
+               s->p[i].port.dev        = dev;
+               s->p[i].port.irq        = irq;
diff --git a/queue-5.15/serial-sc16is7xx-remove-wasteful-static-buffer-in-sc16is7xx_regmap_name.patch b/queue-5.15/serial-sc16is7xx-remove-wasteful-static-buffer-in-sc16is7xx_regmap_name.patch
new file mode 100644 (file)
index 0000000..2cf804d
--- /dev/null
@@ -0,0 +1,54 @@
+From 6bcab3c8acc88e265c570dea969fd04f137c8a4c Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Mon, 11 Dec 2023 12:13:48 -0500
+Subject: serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name()
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit 6bcab3c8acc88e265c570dea969fd04f137c8a4c upstream.
+
+Using a static buffer inside sc16is7xx_regmap_name() was a convenient and
+simple way to set the regmap name without having to allocate and free a
+buffer each time it is called. The drawback is that the static buffer
+wastes memory for nothing once regmap is fully initialized.
+
+Remove static buffer and use constant strings instead.
+
+This also avoids a truncation warning when using "%d" or "%u" in snprintf
+which was flagged by kernel test robot.
+
+Fixes: 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
+Cc:  <stable@vger.kernel.org> # 6.1.x: 3837a03 serial: sc16is7xx: improve regmap debugfs by using one regmap per port
+Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231211171353.2901416-2-hugo@hugovil.com
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -1450,13 +1450,15 @@ static struct regmap_config regcfg = {
+       .max_register = SC16IS7XX_EFCR_REG,
+ };
+-static const char *sc16is7xx_regmap_name(unsigned int port_id)
++static const char *sc16is7xx_regmap_name(u8 port_id)
+ {
+-      static char buf[6];
+-
+-      snprintf(buf, sizeof(buf), "port%d", port_id);
+-
+-      return buf;
++      switch (port_id) {
++      case 0: return "port0";
++      case 1: return "port1";
++      default:
++              WARN_ON(true);
++              return NULL;
++      }
+ }
+ static unsigned int sc16is7xx_regmap_port_mask(unsigned int port_id)
index 3d06f154f928ecd08f30674895e9f1282fc5792a..afc3d9a732dd5165e1fa611d97f03f7ab79fb76c 100644 (file)
@@ -548,3 +548,18 @@ xhci-dbc-fix-stall-transfer-event-handling.patch
 mmc-mtk-sd-fix-error-handle-of-probe-function.patch
 drm-amd-display-check-bios-images-before-it-is-used.patch
 ocfs2-revert-ocfs2-fix-the-la-space-leak-when-unmounting-an-ocfs2-volume.patch
+crypto-hisilicon-qm-inject-error-before-stopping-queue.patch
+ima-fix-use-after-free-on-a-dentry-s-dname.name.patch
+fou-remove-warn-in-gue_gro_receive-on-unsupported-protocol.patch
+revert-drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch
+scsi-core-fix-scsi_mode_select-buffer-length-handling.patch
+serial-sc16is7xx-improve-regmap-debugfs-by-using-one-regmap-per-port.patch
+serial-sc16is7xx-remove-wasteful-static-buffer-in-sc16is7xx_regmap_name.patch
+serial-sc16is7xx-remove-global-regmap-from-struct-sc16is7xx_port.patch
+serial-sc16is7xx-remove-unused-line-structure-member.patch
+serial-sc16is7xx-change-efr-lock-to-operate-on-each-channels.patch
+gve-fixes-for-napi_poll-when-budget-is-0.patch
+arm64-sve-discard-stale-cpu-state-when-handling-sve-traps.patch
+arm64-smccc-remove-broken-support-for-smcccv1.3-sve-discard-hint.patch
+bluetooth-l2cap-fix-uaf-in-l2cap_connect.patch
+net-dsa-microchip-correct-ksz8795-static-mac-table-access.patch