From: Greg Kroah-Hartman Date: Tue, 18 Feb 2025 13:19:56 +0000 (+0100) Subject: 6.12-stable patches X-Git-Tag: v6.1.129~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a9c6c0f8c136b777b2a11a72fe6aac1fc144eb5;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch alpha-make-stack-16-byte-aligned-most-cases.patch alpha-replace-hardcoded-stack-offsets-with-autogenerated-ones.patch arm64-handle-.arm.attributes-section-in-linker-scripts.patch arm64-rust-clean-rust-1.85.0-warning-using-softfloat-target.patch batman-adv-drop-unmanaged-elp-metric-worker.patch batman-adv-fix-panic-during-interface-removal.patch batman-adv-ignore-neighbor-throughput-metrics-in-error-case.patch btrfs-fix-hole-expansion-when-writing-at-an-offset-beyond-eof.patch can-c_can-fix-unbalanced-runtime-pm-disable-in-error-path.patch can-ctucanfd-handle-skb-allocation-failure.patch can-etas_es58x-fix-potential-null-pointer-dereference-on-udev-serial.patch can-j1939-j1939_sk_send_loop-fix-unable-to-send-messages-with-data-length-zero.patch can-rockchip-rkcanfd_handle_rx_fifo_overflow_int-bail-out-if-skb-cannot-be-allocated.patch cgroup-fix-race-between-fork-and-cgroup.kill.patch cifs-pick-channels-for-individual-subrequests.patch drm-amdgpu-avoid-buffer-overflow-attach-in-smu_sys_set_pp_table.patch drm-amdgpu-bump-version-for-rv-pco-compute-fix.patch drm-amdgpu-gfx9-manually-control-gfxoff-for-cs-on-rv.patch efi-avoid-cold-plugged-memory-for-placing-the-kernel.patch gpio-stmpe-check-return-value-of-stmpe_reg_read-in-stmpe_gpio_irq_sync_unlock.patch gpiolib-acpi-add-a-quirk-for-acer-nitro-anv14.patch igc-set-buffer-type-for-empty-frames-in-igc_init_empty_frame.patch iommu-fix-potential-memory-leak-in-iopf_queue_remove_device.patch kbuild-userprogs-fix-bitsize-and-target-detection-on-clang.patch kvm-nsvm-enter-guest-mode-before-initializing-nested-npt-mmu.patch kvm-x86-load-dr6-with-guest-value-only-before-entering-.vcpu_run-loop.patch kvm-x86-reject-hyper-v-s-send_ipi-hypercalls-if-local-apic-isn-t-in-kernel.patch mlxsw-add-return-value-check-for-mlxsw_sp_port_get_stats_raw.patch mmc-mtk-sd-fix-register-settings-for-hs400-es-mode.patch objtool-rust-add-one-more-noreturn-rust-function.patch partitions-mac-fix-handling-of-bogus-partition-table.patch pci-avoid-flr-for-mediatek-mt7922-wifi.patch perf-x86-intel-ensure-lbrs-are-disabled-when-a-cpu-is-starting.patch perf-x86-intel-fix-arch_perfmon_num_counter_leaf.patch regmap-irq-add-missing-kfree.patch regulator-qcom_smd-add-l2-l5-sub-node-to-mp5496-regulator.patch ring-buffer-unlock-resize-on-mmap-error.patch ring-buffer-update-pages_touched-to-reflect-persistent-buffer-content.patch ring-buffer-validate-the-persistent-meta-data-subbuf-array.patch rust-rbtree-fix-overindented-list-item.patch s390-pci-fix-handling-of-isolated-vfs.patch s390-pci-pull-search-for-parent-pf-out-of-zpci_iov_setup_virtfn.patch sched_ext-fix-incorrect-autogroup-migration-detection.patch serial-8250-fix-fifo-underflow-on-flush.patch serial-port-always-update-iotype-in-__uart_read_properties.patch serial-port-assign-iotype-correctly-when-iobase-is-set.patch tracing-do-not-allow-mmap-of-persistent-ring-buffer.patch usb-add-usb_quirk_no_lpm-quirk-for-sony-xperia-xz1-smartphone.patch usb-cdc-acm-check-control-transfer-buffer-size-before-access.patch usb-cdc-acm-fill-in-renesas-r-car-d3-usb-download-mode-quirk.patch usb-cdc-acm-fix-handling-of-oversized-fragments.patch usb-core-fix-pipe-creation-for-get_bmaxpacketsize0.patch usb-dwc2-gadget-remove-of_node-reference-upon-udc_stop.patch usb-dwc3-fix-timeout-issue-during-controller-enter-exit-from-halt-state.patch usb-gadget-core-flush-gadget-workqueue-after-device-removal.patch usb-gadget-f_midi-fix-midi-streaming-descriptor-lengths.patch usb-gadget-f_midi-fixing-wmaxpacketsize-exceeded-issue-during-midi-bind-retries.patch usb-gadget-udc-renesas_usb3-fix-compiler-warning.patch usb-hub-ignore-non-compliant-devices-with-too-many-configs-or-interfaces.patch usb-pci-quirks-fix-hccparams-register-error-for-ls7a-ehci.patch usb-quirks-add-usb_quirk_no_lpm-quirk-for-teclast-dist.patch usb-roles-set-switch-registered-flag-early-on.patch usb-serial-option-add-meig-smart-slm828.patch usb-serial-option-add-telit-cinterion-fn990b-compositions.patch usb-serial-option-drop-meig-smart-defines.patch usb-serial-option-fix-telit-cinterion-fn990a-name.patch usb-xhci-restore-xhci_pci-support-for-renesas-hcs.patch wifi-ath12k-fix-handling-of-6-ghz-rules.patch --- diff --git a/queue-6.12/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch b/queue-6.12/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch new file mode 100644 index 0000000000..4557a8af15 --- /dev/null +++ b/queue-6.12/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch @@ -0,0 +1,129 @@ +From 3b35a171060f846b08b48646b38c30b5d57d17ff Mon Sep 17 00:00:00 2001 +From: Ivan Kokshaysky +Date: Tue, 4 Feb 2025 23:35:24 +0100 +Subject: alpha: align stack for page fault and user unaligned trap handlers + +From: Ivan Kokshaysky + +commit 3b35a171060f846b08b48646b38c30b5d57d17ff upstream. + +do_page_fault() and do_entUna() are special because they use +non-standard stack frame layout. Fix them manually. + +Cc: stable@vger.kernel.org +Tested-by: Maciej W. Rozycki +Tested-by: Magnus Lindholm +Tested-by: Matt Turner +Reviewed-by: Maciej W. Rozycki +Suggested-by: Maciej W. Rozycki +Signed-off-by: Ivan Kokshaysky +Signed-off-by: Matt Turner +Signed-off-by: Greg Kroah-Hartman +--- + arch/alpha/kernel/entry.S | 20 ++++++++++---------- + arch/alpha/kernel/traps.c | 2 +- + arch/alpha/mm/fault.c | 4 ++-- + 3 files changed, 13 insertions(+), 13 deletions(-) + +--- a/arch/alpha/kernel/entry.S ++++ b/arch/alpha/kernel/entry.S +@@ -194,8 +194,8 @@ CFI_END_OSF_FRAME entArith + CFI_START_OSF_FRAME entMM + SAVE_ALL + /* save $9 - $15 so the inline exception code can manipulate them. */ +- subq $sp, 56, $sp +- .cfi_adjust_cfa_offset 56 ++ subq $sp, 64, $sp ++ .cfi_adjust_cfa_offset 64 + stq $9, 0($sp) + stq $10, 8($sp) + stq $11, 16($sp) +@@ -210,7 +210,7 @@ CFI_START_OSF_FRAME entMM + .cfi_rel_offset $13, 32 + .cfi_rel_offset $14, 40 + .cfi_rel_offset $15, 48 +- addq $sp, 56, $19 ++ addq $sp, 64, $19 + /* handle the fault */ + lda $8, 0x3fff + bic $sp, $8, $8 +@@ -223,7 +223,7 @@ CFI_START_OSF_FRAME entMM + ldq $13, 32($sp) + ldq $14, 40($sp) + ldq $15, 48($sp) +- addq $sp, 56, $sp ++ addq $sp, 64, $sp + .cfi_restore $9 + .cfi_restore $10 + .cfi_restore $11 +@@ -231,7 +231,7 @@ CFI_START_OSF_FRAME entMM + .cfi_restore $13 + .cfi_restore $14 + .cfi_restore $15 +- .cfi_adjust_cfa_offset -56 ++ .cfi_adjust_cfa_offset -64 + /* finish up the syscall as normal. */ + br ret_from_sys_call + CFI_END_OSF_FRAME entMM +@@ -378,8 +378,8 @@ entUnaUser: + .cfi_restore $0 + .cfi_adjust_cfa_offset -256 + SAVE_ALL /* setup normal kernel stack */ +- lda $sp, -56($sp) +- .cfi_adjust_cfa_offset 56 ++ lda $sp, -64($sp) ++ .cfi_adjust_cfa_offset 64 + stq $9, 0($sp) + stq $10, 8($sp) + stq $11, 16($sp) +@@ -395,7 +395,7 @@ entUnaUser: + .cfi_rel_offset $14, 40 + .cfi_rel_offset $15, 48 + lda $8, 0x3fff +- addq $sp, 56, $19 ++ addq $sp, 64, $19 + bic $sp, $8, $8 + jsr $26, do_entUnaUser + ldq $9, 0($sp) +@@ -405,7 +405,7 @@ entUnaUser: + ldq $13, 32($sp) + ldq $14, 40($sp) + ldq $15, 48($sp) +- lda $sp, 56($sp) ++ lda $sp, 64($sp) + .cfi_restore $9 + .cfi_restore $10 + .cfi_restore $11 +@@ -413,7 +413,7 @@ entUnaUser: + .cfi_restore $13 + .cfi_restore $14 + .cfi_restore $15 +- .cfi_adjust_cfa_offset -56 ++ .cfi_adjust_cfa_offset -64 + br ret_from_sys_call + CFI_END_OSF_FRAME entUna + +--- a/arch/alpha/kernel/traps.c ++++ b/arch/alpha/kernel/traps.c +@@ -649,7 +649,7 @@ s_reg_to_mem (unsigned long s_reg) + static int unauser_reg_offsets[32] = { + R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8), + /* r9 ... r15 are stored in front of regs. */ +- -56, -48, -40, -32, -24, -16, -8, ++ -64, -56, -48, -40, -32, -24, -16, /* padding at -8 */ + R(r16), R(r17), R(r18), + R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26), + R(r27), R(r28), R(gp), +--- a/arch/alpha/mm/fault.c ++++ b/arch/alpha/mm/fault.c +@@ -78,8 +78,8 @@ __load_new_mm_context(struct mm_struct * + + /* Macro for exception fixup code to access integer registers. */ + #define dpf_reg(r) \ +- (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \ +- (r) <= 18 ? (r)+10 : (r)-10]) ++ (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \ ++ (r) <= 18 ? (r)+11 : (r)-10]) + + asmlinkage void + do_page_fault(unsigned long address, unsigned long mmcsr, diff --git a/queue-6.12/alpha-make-stack-16-byte-aligned-most-cases.patch b/queue-6.12/alpha-make-stack-16-byte-aligned-most-cases.patch new file mode 100644 index 0000000000..5142f0ba70 --- /dev/null +++ b/queue-6.12/alpha-make-stack-16-byte-aligned-most-cases.patch @@ -0,0 +1,69 @@ +From 0a0f7362b0367634a2d5cb7c96226afc116f19c9 Mon Sep 17 00:00:00 2001 +From: Ivan Kokshaysky +Date: Tue, 4 Feb 2025 23:35:23 +0100 +Subject: alpha: make stack 16-byte aligned (most cases) + +From: Ivan Kokshaysky + +commit 0a0f7362b0367634a2d5cb7c96226afc116f19c9 upstream. + +The problem is that GCC expects 16-byte alignment of the incoming stack +since early 2004, as Maciej found out [1]: + Having actually dug speculatively I can see that the psABI was changed in + GCC 3.5 with commit e5e10fb4a350 ("re PR target/14539 (128-bit long double + improperly aligned)") back in Mar 2004, when the stack pointer alignment + was increased from 8 bytes to 16 bytes, and arch/alpha/kernel/entry.S has + various suspicious stack pointer adjustments, starting with SP_OFF which + is not a whole multiple of 16. + +Also, as Magnus noted, "ALPHA Calling Standard" [2] required the same: + D.3.1 Stack Alignment + This standard requires that stacks be octaword aligned at the time a + new procedure is invoked. + +However: +- the "normal" kernel stack is always misaligned by 8 bytes, thanks to + the odd number of 64-bit words in 'struct pt_regs', which is the very + first thing pushed onto the kernel thread stack; +- syscall, fault, interrupt etc. handlers may, or may not, receive aligned + stack depending on numerous factors. + +Somehow we got away with it until recently, when we ended up with +a stack corruption in kernel/smp.c:smp_call_function_single() due to +its use of 32-byte aligned local data and the compiler doing clever +things allocating it on the stack. + +This adds padding between the PAL-saved and kernel-saved registers +so that 'struct pt_regs' have an even number of 64-bit words. +This makes the stack properly aligned for most of the kernel +code, except two handlers which need special threatment. + +Note: struct pt_regs doesn't belong in uapi/asm; this should be fixed, +but let's put this off until later. + +Link: https://lore.kernel.org/rcu/alpine.DEB.2.21.2501130248010.18889@angie.orcam.me.uk/ [1] +Link: https://bitsavers.org/pdf/dec/alpha/Alpha_Calling_Standard_Rev_2.0_19900427.pdf [2] + +Cc: stable@vger.kernel.org +Tested-by: Maciej W. Rozycki +Tested-by: Magnus Lindholm +Tested-by: Matt Turner +Reviewed-by: Maciej W. Rozycki +Signed-off-by: Ivan Kokshaysky +Signed-off-by: Matt Turner +Signed-off-by: Greg Kroah-Hartman +--- + arch/alpha/include/uapi/asm/ptrace.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/alpha/include/uapi/asm/ptrace.h ++++ b/arch/alpha/include/uapi/asm/ptrace.h +@@ -42,6 +42,8 @@ struct pt_regs { + unsigned long trap_a0; + unsigned long trap_a1; + unsigned long trap_a2; ++/* This makes the stack 16-byte aligned as GCC expects */ ++ unsigned long __pad0; + /* These are saved by PAL-code: */ + unsigned long ps; + unsigned long pc; diff --git a/queue-6.12/alpha-replace-hardcoded-stack-offsets-with-autogenerated-ones.patch b/queue-6.12/alpha-replace-hardcoded-stack-offsets-with-autogenerated-ones.patch new file mode 100644 index 0000000000..c1b4e19b51 --- /dev/null +++ b/queue-6.12/alpha-replace-hardcoded-stack-offsets-with-autogenerated-ones.patch @@ -0,0 +1,53 @@ +From 77b823fa619f97d16409ca37ad4f7936e28c5f83 Mon Sep 17 00:00:00 2001 +From: Ivan Kokshaysky +Date: Tue, 4 Feb 2025 23:35:22 +0100 +Subject: alpha: replace hardcoded stack offsets with autogenerated ones + +From: Ivan Kokshaysky + +commit 77b823fa619f97d16409ca37ad4f7936e28c5f83 upstream. + +This allows the assembly in entry.S to automatically keep in sync with +changes in the stack layout (struct pt_regs and struct switch_stack). + +Cc: stable@vger.kernel.org +Tested-by: Maciej W. Rozycki +Tested-by: Matt Turner +Reviewed-by: Maciej W. Rozycki +Signed-off-by: Ivan Kokshaysky +Signed-off-by: Matt Turner +Signed-off-by: Greg Kroah-Hartman +--- + arch/alpha/kernel/asm-offsets.c | 4 ++++ + arch/alpha/kernel/entry.S | 4 ---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/alpha/kernel/asm-offsets.c ++++ b/arch/alpha/kernel/asm-offsets.c +@@ -19,9 +19,13 @@ static void __used foo(void) + DEFINE(TI_STATUS, offsetof(struct thread_info, status)); + BLANK(); + ++ DEFINE(SP_OFF, offsetof(struct pt_regs, ps)); + DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs)); + BLANK(); + ++ DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack)); ++ BLANK(); ++ + DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache)); + DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register)); + } +--- a/arch/alpha/kernel/entry.S ++++ b/arch/alpha/kernel/entry.S +@@ -15,10 +15,6 @@ + .set noat + .cfi_sections .debug_frame + +-/* Stack offsets. */ +-#define SP_OFF 184 +-#define SWITCH_STACK_SIZE 64 +- + .macro CFI_START_OSF_FRAME func + .align 4 + .globl \func diff --git a/queue-6.12/arm64-handle-.arm.attributes-section-in-linker-scripts.patch b/queue-6.12/arm64-handle-.arm.attributes-section-in-linker-scripts.patch new file mode 100644 index 0000000000..d0ad70481b --- /dev/null +++ b/queue-6.12/arm64-handle-.arm.attributes-section-in-linker-scripts.patch @@ -0,0 +1,57 @@ +From ca0f4fe7cf7183bfbdc67ca2de56ae1fc3a8db2b Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Thu, 6 Feb 2025 10:21:38 -0700 +Subject: arm64: Handle .ARM.attributes section in linker scripts + +From: Nathan Chancellor + +commit ca0f4fe7cf7183bfbdc67ca2de56ae1fc3a8db2b upstream. + +A recent LLVM commit [1] started generating an .ARM.attributes section +similar to the one that exists for 32-bit, which results in orphan +section warnings (or errors if CONFIG_WERROR is enabled) from the linker +because it is not handled in the arm64 linker scripts. + + ld.lld: error: arch/arm64/kernel/vdso/vgettimeofday.o:(.ARM.attributes) is being placed in '.ARM.attributes' + ld.lld: error: arch/arm64/kernel/vdso/vgetrandom.o:(.ARM.attributes) is being placed in '.ARM.attributes' + + ld.lld: error: vmlinux.a(lib/vsprintf.o):(.ARM.attributes) is being placed in '.ARM.attributes' + ld.lld: error: vmlinux.a(lib/win_minmax.o):(.ARM.attributes) is being placed in '.ARM.attributes' + ld.lld: error: vmlinux.a(lib/xarray.o):(.ARM.attributes) is being placed in '.ARM.attributes' + +Discard the new sections in the necessary linker scripts to resolve the +warnings, as the kernel and vDSO do not need to retain it, similar to +the .note.gnu.property section. + +Cc: stable@vger.kernel.org +Fixes: b3e5d80d0c48 ("arm64/build: Warn on orphan section placement") +Link: https://github.com/llvm/llvm-project/commit/ee99c4d4845db66c4daa2373352133f4b237c942 [1] +Signed-off-by: Nathan Chancellor +Link: https://lore.kernel.org/r/20250206-arm64-handle-arm-attributes-in-linker-script-v3-1-d53d169913eb@kernel.org +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/vdso/vdso.lds.S | 1 + + arch/arm64/kernel/vmlinux.lds.S | 1 + + 2 files changed, 2 insertions(+) + +--- a/arch/arm64/kernel/vdso/vdso.lds.S ++++ b/arch/arm64/kernel/vdso/vdso.lds.S +@@ -41,6 +41,7 @@ SECTIONS + */ + /DISCARD/ : { + *(.note.GNU-stack .note.gnu.property) ++ *(.ARM.attributes) + } + .note : { *(.note.*) } :text :note + +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -162,6 +162,7 @@ SECTIONS + /DISCARD/ : { + *(.interp .dynamic) + *(.dynsym .dynstr .hash .gnu.hash) ++ *(.ARM.attributes) + } + + . = KIMAGE_VADDR; diff --git a/queue-6.12/arm64-rust-clean-rust-1.85.0-warning-using-softfloat-target.patch b/queue-6.12/arm64-rust-clean-rust-1.85.0-warning-using-softfloat-target.patch new file mode 100644 index 0000000000..448d1f601d --- /dev/null +++ b/queue-6.12/arm64-rust-clean-rust-1.85.0-warning-using-softfloat-target.patch @@ -0,0 +1,74 @@ +From 446a8351f160d65a1c5df7097f31c74102ed2bb1 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Mon, 10 Feb 2025 17:37:32 +0100 +Subject: arm64: rust: clean Rust 1.85.0 warning using softfloat target + +From: Miguel Ojeda + +commit 446a8351f160d65a1c5df7097f31c74102ed2bb1 upstream. + +Starting with Rust 1.85.0 (to be released 2025-02-20), `rustc` warns +[1] about disabling neon in the aarch64 hardfloat target: + + warning: target feature `neon` cannot be toggled with + `-Ctarget-feature`: unsound on hard-float targets + because it changes float ABI + | + = note: this was previously accepted by the compiler but + is being phased out; it will become a hard error + in a future release! + = note: for more information, see issue #116344 + + +Thus, instead, use the softfloat target instead. + +While trying it out, I found that the kernel sanitizers were not enabled +for that built-in target [2]. Upstream Rust agreed to backport +the enablement for the current beta so that it is ready for +the 1.85.0 release [3] -- thanks! + +However, that still means that before Rust 1.85.0, we cannot switch +since sanitizers could be in use. Thus conditionally do so. + +Cc: stable@vger.kernel.org # Needed in 6.12.y and 6.13.y only (Rust is pinned in older LTSs). +Cc: Catalin Marinas +Cc: Will Deacon +Cc: Matthew Maurer +Cc: Alice Ryhl +Cc: Ralf Jung +Cc: Jubilee Young +Link: https://github.com/rust-lang/rust/pull/133417 [1] +Link: https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/arm64.20neon.20.60-Ctarget-feature.60.20warning/near/495358442 [2] +Link: https://github.com/rust-lang/rust/pull/135905 [3] +Link: https://github.com/rust-lang/rust/issues/116344 +Signed-off-by: Miguel Ojeda +Reviewed-by: Trevor Gross +Tested-by: Matthew Maurer +Reviewed-by: Ralf Jung +Reviewed-by: Alice Ryhl +Link: https://lore.kernel.org/r/20250210163732.281786-1-ojeda@kernel.org +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/Makefile | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index 358c68565bfd..2b25d671365f 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -48,7 +48,11 @@ KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \ + KBUILD_CFLAGS += $(call cc-disable-warning, psabi) + KBUILD_AFLAGS += $(compat_vdso) + ++ifeq ($(call test-ge, $(CONFIG_RUSTC_VERSION), 108500),y) ++KBUILD_RUSTFLAGS += --target=aarch64-unknown-none-softfloat ++else + KBUILD_RUSTFLAGS += --target=aarch64-unknown-none -Ctarget-feature="-neon" ++endif + + KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) + KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) +-- +2.48.1 + diff --git a/queue-6.12/batman-adv-drop-unmanaged-elp-metric-worker.patch b/queue-6.12/batman-adv-drop-unmanaged-elp-metric-worker.patch new file mode 100644 index 0000000000..84bad9c763 --- /dev/null +++ b/queue-6.12/batman-adv-drop-unmanaged-elp-metric-worker.patch @@ -0,0 +1,252 @@ +From 8c8ecc98f5c65947b0070a24bac11e12e47cc65d Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Mon, 20 Jan 2025 00:06:11 +0100 +Subject: batman-adv: Drop unmanaged ELP metric worker + +From: Sven Eckelmann + +commit 8c8ecc98f5c65947b0070a24bac11e12e47cc65d upstream. + +The ELP worker needs to calculate new metric values for all neighbors +"reachable" over an interface. Some of the used metric sources require +locks which might need to sleep. This sleep is incompatible with the RCU +list iterator used for the recorded neighbors. The initial approach to work +around of this problem was to queue another work item per neighbor and then +run this in a new context. + +Even when this solved the RCU vs might_sleep() conflict, it has a major +problems: Nothing was stopping the work item in case it is not needed +anymore - for example because one of the related interfaces was removed or +the batman-adv module was unloaded - resulting in potential invalid memory +accesses. + +Directly canceling the metric worker also has various problems: + +* cancel_work_sync for a to-be-deactivated interface is called with + rtnl_lock held. But the code in the ELP metric worker also tries to use + rtnl_lock() - which will never return in this case. This also means that + cancel_work_sync would never return because it is waiting for the worker + to finish. +* iterating over the neighbor list for the to-be-deactivated interface is + currently done using the RCU specific methods. Which means that it is + possible to miss items when iterating over it without the associated + spinlock - a behaviour which is acceptable for a periodic metric check + but not for a cleanup routine (which must "stop" all still running + workers) + +The better approch is to get rid of the per interface neighbor metric +worker and handle everything in the interface worker. The original problems +are solved by: + +* creating a list of neighbors which require new metric information inside + the RCU protected context, gathering the metric according to the new list + outside the RCU protected context +* only use rcu_trylock inside metric gathering code to avoid a deadlock + when the cancel_delayed_work_sync is called in the interface removal code + (which is called with the rtnl_lock held) + +Cc: stable@vger.kernel.org +Fixes: c833484e5f38 ("batman-adv: ELP - compute the metric based on the estimated throughput") +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/bat_v.c | 2 - + net/batman-adv/bat_v_elp.c | 71 ++++++++++++++++++++++++++++++--------------- + net/batman-adv/bat_v_elp.h | 2 - + net/batman-adv/types.h | 3 - + 4 files changed, 48 insertions(+), 30 deletions(-) + +--- a/net/batman-adv/bat_v.c ++++ b/net/batman-adv/bat_v.c +@@ -113,8 +113,6 @@ static void + batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) + { + ewma_throughput_init(&hardif_neigh->bat_v.throughput); +- INIT_WORK(&hardif_neigh->bat_v.metric_work, +- batadv_v_elp_throughput_metric_update); + } + + /** +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -42,6 +44,18 @@ + #include "send.h" + + /** ++ * struct batadv_v_metric_queue_entry - list of hardif neighbors which require ++ * and metric update ++ */ ++struct batadv_v_metric_queue_entry { ++ /** @hardif_neigh: hardif neighbor scheduled for metric update */ ++ struct batadv_hardif_neigh_node *hardif_neigh; ++ ++ /** @list: list node for metric_queue */ ++ struct list_head list; ++}; ++ ++/** + * batadv_v_elp_start_timer() - restart timer for ELP periodic work + * @hard_iface: the interface for which the timer has to be reset + */ +@@ -137,10 +151,17 @@ static bool batadv_v_elp_get_throughput( + goto default_throughput; + } + ++ /* only use rtnl_trylock because the elp worker will be cancelled while ++ * the rntl_lock is held. the cancel_delayed_work_sync() would otherwise ++ * wait forever when the elp work_item was started and it is then also ++ * trying to rtnl_lock ++ */ ++ if (!rtnl_trylock()) ++ return false; ++ + /* if not a wifi interface, check if this device provides data via + * ethtool (e.g. an Ethernet adapter) + */ +- rtnl_lock(); + ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); + rtnl_unlock(); + if (ret == 0) { +@@ -175,31 +196,19 @@ default_throughput: + /** + * batadv_v_elp_throughput_metric_update() - worker updating the throughput + * metric of a single hop neighbour +- * @work: the work queue item ++ * @neigh: the neighbour to probe + */ +-void batadv_v_elp_throughput_metric_update(struct work_struct *work) ++static void ++batadv_v_elp_throughput_metric_update(struct batadv_hardif_neigh_node *neigh) + { +- struct batadv_hardif_neigh_node_bat_v *neigh_bat_v; +- struct batadv_hardif_neigh_node *neigh; + u32 throughput; + bool valid; + +- neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, +- metric_work); +- neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, +- bat_v); +- + valid = batadv_v_elp_get_throughput(neigh, &throughput); + if (!valid) +- goto put_neigh; ++ return; + + ewma_throughput_add(&neigh->bat_v.throughput, throughput); +- +-put_neigh: +- /* decrement refcounter to balance increment performed before scheduling +- * this task +- */ +- batadv_hardif_neigh_put(neigh); + } + + /** +@@ -273,14 +282,16 @@ batadv_v_elp_wifi_neigh_probe(struct bat + */ + static void batadv_v_elp_periodic_work(struct work_struct *work) + { ++ struct batadv_v_metric_queue_entry *metric_entry; ++ struct batadv_v_metric_queue_entry *metric_safe; + struct batadv_hardif_neigh_node *hardif_neigh; + struct batadv_hard_iface *hard_iface; + struct batadv_hard_iface_bat_v *bat_v; + struct batadv_elp_packet *elp_packet; ++ struct list_head metric_queue; + struct batadv_priv *bat_priv; + struct sk_buff *skb; + u32 elp_interval; +- bool ret; + + bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work); + hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v); +@@ -316,6 +327,8 @@ static void batadv_v_elp_periodic_work(s + + atomic_inc(&hard_iface->bat_v.elp_seqno); + ++ INIT_LIST_HEAD(&metric_queue); ++ + /* The throughput metric is updated on each sent packet. This way, if a + * node is dead and no longer sends packets, batman-adv is still able to + * react timely to its death. +@@ -340,16 +353,28 @@ static void batadv_v_elp_periodic_work(s + + /* Reading the estimated throughput from cfg80211 is a task that + * may sleep and that is not allowed in an rcu protected +- * context. Therefore schedule a task for that. ++ * context. Therefore add it to metric_queue and process it ++ * outside rcu protected context. + */ +- ret = queue_work(batadv_event_workqueue, +- &hardif_neigh->bat_v.metric_work); +- +- if (!ret) ++ metric_entry = kzalloc(sizeof(*metric_entry), GFP_ATOMIC); ++ if (!metric_entry) { + batadv_hardif_neigh_put(hardif_neigh); ++ continue; ++ } ++ ++ metric_entry->hardif_neigh = hardif_neigh; ++ list_add(&metric_entry->list, &metric_queue); + } + rcu_read_unlock(); + ++ list_for_each_entry_safe(metric_entry, metric_safe, &metric_queue, list) { ++ batadv_v_elp_throughput_metric_update(metric_entry->hardif_neigh); ++ ++ batadv_hardif_neigh_put(metric_entry->hardif_neigh); ++ list_del(&metric_entry->list); ++ kfree(metric_entry); ++ } ++ + restart_timer: + batadv_v_elp_start_timer(hard_iface); + out: +--- a/net/batman-adv/bat_v_elp.h ++++ b/net/batman-adv/bat_v_elp.h +@@ -10,7 +10,6 @@ + #include "main.h" + + #include +-#include + + int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface); + void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface); +@@ -19,6 +18,5 @@ void batadv_v_elp_iface_activate(struct + void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface); + int batadv_v_elp_packet_recv(struct sk_buff *skb, + struct batadv_hard_iface *if_incoming); +-void batadv_v_elp_throughput_metric_update(struct work_struct *work); + + #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */ +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -596,9 +596,6 @@ struct batadv_hardif_neigh_node_bat_v { + * neighbor + */ + unsigned long last_unicast_tx; +- +- /** @metric_work: work queue callback item for metric update */ +- struct work_struct metric_work; + }; + + /** diff --git a/queue-6.12/batman-adv-fix-panic-during-interface-removal.patch b/queue-6.12/batman-adv-fix-panic-during-interface-removal.patch new file mode 100644 index 0000000000..75df5586b0 --- /dev/null +++ b/queue-6.12/batman-adv-fix-panic-during-interface-removal.patch @@ -0,0 +1,81 @@ +From ccb7276a6d26d6f8416e315b43b45e15ee7f29e2 Mon Sep 17 00:00:00 2001 +From: Andy Strohman +Date: Thu, 9 Jan 2025 02:27:56 +0000 +Subject: batman-adv: fix panic during interface removal + +From: Andy Strohman + +commit ccb7276a6d26d6f8416e315b43b45e15ee7f29e2 upstream. + +Reference counting is used to ensure that +batadv_hardif_neigh_node and batadv_hard_iface +are not freed before/during +batadv_v_elp_throughput_metric_update work is +finished. + +But there isn't a guarantee that the hard if will +remain associated with a soft interface up until +the work is finished. + +This fixes a crash triggered by reboot that looks +like this: + +Call trace: + batadv_v_mesh_free+0xd0/0x4dc [batman_adv] + batadv_v_elp_throughput_metric_update+0x1c/0xa4 + process_one_work+0x178/0x398 + worker_thread+0x2e8/0x4d0 + kthread+0xd8/0xdc + ret_from_fork+0x10/0x20 + +(the batadv_v_mesh_free call is misleading, +and does not actually happen) + +I was able to make the issue happen more reliably +by changing hardif_neigh->bat_v.metric_work work +to be delayed work. This allowed me to track down +and confirm the fix. + +Cc: stable@vger.kernel.org +Fixes: c833484e5f38 ("batman-adv: ELP - compute the metric based on the estimated throughput") +Signed-off-by: Andy Strohman +[sven@narfation.org: prevent entering batadv_v_elp_get_throughput without + soft_iface] +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/bat_v_elp.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -66,12 +66,19 @@ static void batadv_v_elp_start_timer(str + static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + { + struct batadv_hard_iface *hard_iface = neigh->if_incoming; ++ struct net_device *soft_iface = hard_iface->soft_iface; + struct ethtool_link_ksettings link_settings; + struct net_device *real_netdev; + struct station_info sinfo; + u32 throughput; + int ret; + ++ /* don't query throughput when no longer associated with any ++ * batman-adv interface ++ */ ++ if (!soft_iface) ++ return BATADV_THROUGHPUT_DEFAULT_VALUE; ++ + /* if the user specified a customised value for this interface, then + * return it directly + */ +@@ -141,7 +148,7 @@ static u32 batadv_v_elp_get_throughput(s + + default_throughput: + if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) { +- batadv_info(hard_iface->soft_iface, ++ batadv_info(soft_iface, + "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n", + hard_iface->net_dev->name, + BATADV_THROUGHPUT_DEFAULT_VALUE / 10, diff --git a/queue-6.12/batman-adv-ignore-neighbor-throughput-metrics-in-error-case.patch b/queue-6.12/batman-adv-ignore-neighbor-throughput-metrics-in-error-case.patch new file mode 100644 index 0000000000..bc2151f0e0 --- /dev/null +++ b/queue-6.12/batman-adv-ignore-neighbor-throughput-metrics-in-error-case.patch @@ -0,0 +1,137 @@ +From e7e34ffc976aaae4f465b7898303241b81ceefc3 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Mon, 20 Jan 2025 20:35:28 +0100 +Subject: batman-adv: Ignore neighbor throughput metrics in error case + +From: Sven Eckelmann + +commit e7e34ffc976aaae4f465b7898303241b81ceefc3 upstream. + +If a temporary error happened in the evaluation of the neighbor throughput +information, then the invalid throughput result should not be stored in the +throughtput EWMA. + +Cc: stable@vger.kernel.org +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/bat_v_elp.c | 50 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 34 insertions(+), 16 deletions(-) + +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -59,11 +59,13 @@ static void batadv_v_elp_start_timer(str + /** + * batadv_v_elp_get_throughput() - get the throughput towards a neighbour + * @neigh: the neighbour for which the throughput has to be obtained ++ * @pthroughput: calculated throughput towards the given neighbour in multiples ++ * of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). + * +- * Return: The throughput towards the given neighbour in multiples of 100kpbs +- * (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). ++ * Return: true when value behind @pthroughput was set + */ +-static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ++static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh, ++ u32 *pthroughput) + { + struct batadv_hard_iface *hard_iface = neigh->if_incoming; + struct net_device *soft_iface = hard_iface->soft_iface; +@@ -77,14 +79,16 @@ static u32 batadv_v_elp_get_throughput(s + * batman-adv interface + */ + if (!soft_iface) +- return BATADV_THROUGHPUT_DEFAULT_VALUE; ++ return false; + + /* if the user specified a customised value for this interface, then + * return it directly + */ + throughput = atomic_read(&hard_iface->bat_v.throughput_override); +- if (throughput != 0) +- return throughput; ++ if (throughput != 0) { ++ *pthroughput = throughput; ++ return true; ++ } + + /* if this is a wireless device, then ask its throughput through + * cfg80211 API +@@ -111,19 +115,24 @@ static u32 batadv_v_elp_get_throughput(s + * possible to delete this neighbor. For now set + * the throughput metric to 0. + */ +- return 0; ++ *pthroughput = 0; ++ return true; + } + if (ret) + goto default_throughput; + +- if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) +- return sinfo.expected_throughput / 100; ++ if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) { ++ *pthroughput = sinfo.expected_throughput / 100; ++ return true; ++ } + + /* try to estimate the expected throughput based on reported tx + * rates + */ +- if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) +- return cfg80211_calculate_bitrate(&sinfo.txrate) / 3; ++ if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) { ++ *pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3; ++ return true; ++ } + + goto default_throughput; + } +@@ -142,8 +151,10 @@ static u32 batadv_v_elp_get_throughput(s + hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; + + throughput = link_settings.base.speed; +- if (throughput && throughput != SPEED_UNKNOWN) +- return throughput * 10; ++ if (throughput && throughput != SPEED_UNKNOWN) { ++ *pthroughput = throughput * 10; ++ return true; ++ } + } + + default_throughput: +@@ -157,7 +168,8 @@ default_throughput: + } + + /* if none of the above cases apply, return the base_throughput */ +- return BATADV_THROUGHPUT_DEFAULT_VALUE; ++ *pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE; ++ return true; + } + + /** +@@ -169,15 +181,21 @@ void batadv_v_elp_throughput_metric_upda + { + struct batadv_hardif_neigh_node_bat_v *neigh_bat_v; + struct batadv_hardif_neigh_node *neigh; ++ u32 throughput; ++ bool valid; + + neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, + metric_work); + neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, + bat_v); + +- ewma_throughput_add(&neigh->bat_v.throughput, +- batadv_v_elp_get_throughput(neigh)); ++ valid = batadv_v_elp_get_throughput(neigh, &throughput); ++ if (!valid) ++ goto put_neigh; ++ ++ ewma_throughput_add(&neigh->bat_v.throughput, throughput); + ++put_neigh: + /* decrement refcounter to balance increment performed before scheduling + * this task + */ diff --git a/queue-6.12/btrfs-fix-hole-expansion-when-writing-at-an-offset-beyond-eof.patch b/queue-6.12/btrfs-fix-hole-expansion-when-writing-at-an-offset-beyond-eof.patch new file mode 100644 index 0000000000..a269a425b7 --- /dev/null +++ b/queue-6.12/btrfs-fix-hole-expansion-when-writing-at-an-offset-beyond-eof.patch @@ -0,0 +1,103 @@ +From da2dccd7451de62b175fb8f0808d644959e964c7 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 5 Feb 2025 17:36:48 +0000 +Subject: btrfs: fix hole expansion when writing at an offset beyond EOF + +From: Filipe Manana + +commit da2dccd7451de62b175fb8f0808d644959e964c7 upstream. + +At btrfs_write_check() if our file's i_size is not sector size aligned and +we have a write that starts at an offset larger than the i_size that falls +within the same page of the i_size, then we end up not zeroing the file +range [i_size, write_offset). + +The code is this: + + start_pos = round_down(pos, fs_info->sectorsize); + oldsize = i_size_read(inode); + if (start_pos > oldsize) { + /* Expand hole size to cover write data, preventing empty gap */ + loff_t end_pos = round_up(pos + count, fs_info->sectorsize); + + ret = btrfs_cont_expand(BTRFS_I(inode), oldsize, end_pos); + if (ret) + return ret; + } + +So if our file's i_size is 90269 bytes and a write at offset 90365 bytes +comes in, we get 'start_pos' set to 90112 bytes, which is less than the +i_size and therefore we don't zero out the range [90269, 90365) by +calling btrfs_cont_expand(). + +This is an old bug introduced in commit 9036c10208e1 ("Btrfs: update hole +handling v2"), from 2008, and the buggy code got moved around over the +years. + +Fix this by discarding 'start_pos' and comparing against the write offset +('pos') without any alignment. + +This bug was recently exposed by test case generic/363 which tests this +scenario by polluting ranges beyond EOF with an mmap write and than verify +that after a file increases we get zeroes for the range which is supposed +to be a hole and not what we wrote with the previous mmaped write. + +We're only seeing this exposed now because generic/363 used to run only +on xfs until last Sunday's fstests update. + +The test was failing like this: + + $ ./check generic/363 + FSTYP -- btrfs + PLATFORM -- Linux/x86_64 debian0 6.13.0-rc7-btrfs-next-185+ #17 SMP PREEMPT_DYNAMIC Mon Feb 3 12:28:46 WET 2025 + MKFS_OPTIONS -- /dev/sdc + MOUNT_OPTIONS -- /dev/sdc /home/fdmanana/btrfs-tests/scratch_1 + + generic/363 0s ... [failed, exit status 1]- output mismatch (see /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad) +# --- tests/generic/363.out 2025-02-05 15:31:14.013646509 +0000 +# +++ /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad 2025-02-05 17:25:33.112630781 +0000 + @@ -1 +1,46 @@ + QA output created by 363 + +READ BAD DATA: offset = 0xdcad, size = 0xd921, fname = /home/fdmanana/btrfs-tests/dev/junk + +OFFSET GOOD BAD RANGE + +0x1609d 0x0000 0x3104 0x0 + +operation# (mod 256) for the bad data may be 4 + +0x1609e 0x0000 0x0472 0x1 + +operation# (mod 256) for the bad data may be 4 + ... + (Run 'diff -u /home/fdmanana/git/hub/xfstests/tests/generic/363.out /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad' to see the entire diff) + Ran: generic/363 + Failures: generic/363 + Failed 1 of 1 tests + +Fixes: 9036c10208e1 ("Btrfs: update hole handling v2") +CC: stable@vger.kernel.org +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/file.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1148,7 +1148,6 @@ int btrfs_write_check(struct kiocb *iocb + loff_t pos = iocb->ki_pos; + int ret; + loff_t oldsize; +- loff_t start_pos; + + /* + * Quickly bail out on NOWAIT writes if we don't have the nodatacow or +@@ -1172,9 +1171,8 @@ int btrfs_write_check(struct kiocb *iocb + */ + update_time_for_write(inode); + +- start_pos = round_down(pos, fs_info->sectorsize); + oldsize = i_size_read(inode); +- if (start_pos > oldsize) { ++ if (pos > oldsize) { + /* Expand hole size to cover write data, preventing empty gap */ + loff_t end_pos = round_up(pos + count, fs_info->sectorsize); + diff --git a/queue-6.12/can-c_can-fix-unbalanced-runtime-pm-disable-in-error-path.patch b/queue-6.12/can-c_can-fix-unbalanced-runtime-pm-disable-in-error-path.patch new file mode 100644 index 0000000000..1500975fa1 --- /dev/null +++ b/queue-6.12/can-c_can-fix-unbalanced-runtime-pm-disable-in-error-path.patch @@ -0,0 +1,45 @@ +From 257a2cd3eb578ee63d6bf90475dc4f4b16984139 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Sun, 12 Jan 2025 13:41:52 +0100 +Subject: can: c_can: fix unbalanced runtime PM disable in error path + +From: Krzysztof Kozlowski + +commit 257a2cd3eb578ee63d6bf90475dc4f4b16984139 upstream. + +Runtime PM is enabled as one of the last steps of probe(), so all +earlier gotos to "exit_free_device" label were not correct and were +leading to unbalanced runtime PM disable depth. + +Fixes: 6e2fe01dd6f9 ("can: c_can: move runtime PM enable/disable to c_can_platform") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Vincent Mailhol +Link: https://patch.msgid.link/20250112-syscon-phandle-args-can-v1-1-314d9549906f@linaro.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/c_can/c_can_platform.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/can/c_can/c_can_platform.c ++++ b/drivers/net/can/c_can/c_can_platform.c +@@ -385,15 +385,16 @@ static int c_can_plat_probe(struct platf + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", + KBUILD_MODNAME, ret); +- goto exit_free_device; ++ goto exit_pm_runtime; + } + + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", + KBUILD_MODNAME, priv->base, dev->irq); + return 0; + +-exit_free_device: ++exit_pm_runtime: + pm_runtime_disable(priv->device); ++exit_free_device: + free_c_can_dev(dev); + exit: + dev_err(&pdev->dev, "probe failed\n"); diff --git a/queue-6.12/can-ctucanfd-handle-skb-allocation-failure.patch b/queue-6.12/can-ctucanfd-handle-skb-allocation-failure.patch new file mode 100644 index 0000000000..bcce2a9641 --- /dev/null +++ b/queue-6.12/can-ctucanfd-handle-skb-allocation-failure.patch @@ -0,0 +1,49 @@ +From 9bd24927e3eeb85642c7baa3b28be8bea6c2a078 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Tue, 14 Jan 2025 18:21:38 +0300 +Subject: can: ctucanfd: handle skb allocation failure + +From: Fedor Pchelkin + +commit 9bd24927e3eeb85642c7baa3b28be8bea6c2a078 upstream. + +If skb allocation fails, the pointer to struct can_frame is NULL. This +is actually handled everywhere inside ctucan_err_interrupt() except for +the only place. + +Add the missed NULL check. + +Found by Linux Verification Center (linuxtesting.org) with SVACE static +analysis tool. + +Fixes: 2dcb8e8782d8 ("can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.") +Cc: stable@vger.kernel.org +Signed-off-by: Fedor Pchelkin +Acked-by: Pavel Pisa +Reviewed-by: Vincent Mailhol +Link: https://patch.msgid.link/20250114152138.139580-1-pchelkin@ispras.ru +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/ctucanfd/ctucanfd_base.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/can/ctucanfd/ctucanfd_base.c ++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c +@@ -867,10 +867,12 @@ static void ctucan_err_interrupt(struct + } + break; + case CAN_STATE_ERROR_ACTIVE: +- cf->can_id |= CAN_ERR_CNT; +- cf->data[1] = CAN_ERR_CRTL_ACTIVE; +- cf->data[6] = bec.txerr; +- cf->data[7] = bec.rxerr; ++ if (skb) { ++ cf->can_id |= CAN_ERR_CNT; ++ cf->data[1] = CAN_ERR_CRTL_ACTIVE; ++ cf->data[6] = bec.txerr; ++ cf->data[7] = bec.rxerr; ++ } + break; + default: + netdev_warn(ndev, "unhandled error state (%d:%s)!\n", diff --git a/queue-6.12/can-etas_es58x-fix-potential-null-pointer-dereference-on-udev-serial.patch b/queue-6.12/can-etas_es58x-fix-potential-null-pointer-dereference-on-udev-serial.patch new file mode 100644 index 0000000000..2b37e98d36 --- /dev/null +++ b/queue-6.12/can-etas_es58x-fix-potential-null-pointer-dereference-on-udev-serial.patch @@ -0,0 +1,44 @@ +From a1ad2109ce41c9e3912dadd07ad8a9c640064ffb Mon Sep 17 00:00:00 2001 +From: Vincent Mailhol +Date: Wed, 5 Feb 2025 00:48:15 +0900 +Subject: can: etas_es58x: fix potential NULL pointer dereference on udev->serial + +From: Vincent Mailhol + +commit a1ad2109ce41c9e3912dadd07ad8a9c640064ffb upstream. + +The driver assumed that es58x_dev->udev->serial could never be NULL. +While this is true on commercially available devices, an attacker +could spoof the device identity providing a NULL USB serial number. +That would trigger a NULL pointer dereference. + +Add a check on es58x_dev->udev->serial before accessing it. + +Reported-by: yan kang +Reported-by: yue sun +Closes: https://lore.kernel.org/linux-can/SY8P300MB0421E0013C0EBD2AA46BA709A1F42@SY8P300MB0421.AUSP300.PROD.OUTLOOK.COM/ +Fixes: 9f06631c3f1f ("can: etas_es58x: export product information through devlink_ops::info_get()") +Signed-off-by: Vincent Mailhol +Link: https://patch.msgid.link/20250204154859.9797-2-mailhol.vincent@wanadoo.fr +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/etas_es58x/es58x_devlink.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/etas_es58x/es58x_devlink.c ++++ b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +@@ -248,7 +248,11 @@ static int es58x_devlink_info_get(struct + return ret; + } + +- return devlink_info_serial_number_put(req, es58x_dev->udev->serial); ++ if (es58x_dev->udev->serial) ++ ret = devlink_info_serial_number_put(req, ++ es58x_dev->udev->serial); ++ ++ return ret; + } + + const struct devlink_ops es58x_dl_ops = { diff --git a/queue-6.12/can-j1939-j1939_sk_send_loop-fix-unable-to-send-messages-with-data-length-zero.patch b/queue-6.12/can-j1939-j1939_sk_send_loop-fix-unable-to-send-messages-with-data-length-zero.patch new file mode 100644 index 0000000000..9a112d4f3e --- /dev/null +++ b/queue-6.12/can-j1939-j1939_sk_send_loop-fix-unable-to-send-messages-with-data-length-zero.patch @@ -0,0 +1,78 @@ +From 44de577e61ed239db09f0da9d436866bef9b77dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alexander=20H=C3=B6lzl?= +Date: Wed, 5 Feb 2025 18:46:51 +0100 +Subject: can: j1939: j1939_sk_send_loop(): fix unable to send messages with data length zero +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Hölzl + +commit 44de577e61ed239db09f0da9d436866bef9b77dd upstream. + +The J1939 standard requires the transmission of messages of length 0. + +For example proprietary messages are specified with a data length of 0 +to 1785. The transmission of such messages is not possible. Sending +results in no error being returned but no corresponding can frame +being generated. + +Enable the transmission of zero length J1939 messages. In order to +facilitate this two changes are necessary: + +1) If the transmission of a new message is requested from user space +the message is segmented in j1939_sk_send_loop(). Let the segmentation +take into account zero length messages, do not terminate immediately, +queue the corresponding skb. + +2) j1939_session_skb_get_by_offset() selects the next skb to transmit +for a session. Take into account that there might be zero length skbs +in the queue. + +Signed-off-by: Alexander Hölzl +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/20250205174651.103238-1-alexander.hoelzl@gmx.net +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Cc: stable@vger.kernel.org +[mkl: commit message rephrased] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/j1939/socket.c | 4 ++-- + net/can/j1939/transport.c | 5 +++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/net/can/j1939/socket.c ++++ b/net/can/j1939/socket.c +@@ -1132,7 +1132,7 @@ static int j1939_sk_send_loop(struct j19 + + todo_size = size; + +- while (todo_size) { ++ do { + struct j1939_sk_buff_cb *skcb; + + segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE, +@@ -1177,7 +1177,7 @@ static int j1939_sk_send_loop(struct j19 + + todo_size -= segment_size; + session->total_queued_size += segment_size; +- } ++ } while (todo_size); + + switch (ret) { + case 0: /* OK */ +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -382,8 +382,9 @@ sk_buff *j1939_session_skb_get_by_offset + skb_queue_walk(&session->skb_queue, do_skb) { + do_skcb = j1939_skb_to_cb(do_skb); + +- if (offset_start >= do_skcb->offset && +- offset_start < (do_skcb->offset + do_skb->len)) { ++ if ((offset_start >= do_skcb->offset && ++ offset_start < (do_skcb->offset + do_skb->len)) || ++ (offset_start == 0 && do_skcb->offset == 0 && do_skb->len == 0)) { + skb = do_skb; + } + } diff --git a/queue-6.12/can-rockchip-rkcanfd_handle_rx_fifo_overflow_int-bail-out-if-skb-cannot-be-allocated.patch b/queue-6.12/can-rockchip-rkcanfd_handle_rx_fifo_overflow_int-bail-out-if-skb-cannot-be-allocated.patch new file mode 100644 index 0000000000..a00b425433 --- /dev/null +++ b/queue-6.12/can-rockchip-rkcanfd_handle_rx_fifo_overflow_int-bail-out-if-skb-cannot-be-allocated.patch @@ -0,0 +1,38 @@ +From f7f0adfe64de08803990dc4cbecd2849c04e314a Mon Sep 17 00:00:00 2001 +From: Robin van der Gracht +Date: Mon, 27 Jan 2025 13:16:44 +0100 +Subject: can: rockchip: rkcanfd_handle_rx_fifo_overflow_int(): bail out if skb cannot be allocated + +From: Robin van der Gracht + +commit f7f0adfe64de08803990dc4cbecd2849c04e314a upstream. + +Fix NULL pointer check in rkcanfd_handle_rx_fifo_overflow_int() to +bail out if skb cannot be allocated. + +Fixes: ff60bfbaf67f ("can: rockchip_canfd: add driver for Rockchip CAN-FD controller") +Cc: stable@vger.kernel.org +Signed-off-by: Robin van der Gracht +Link: https://patch.msgid.link/20250208-fix-rockchip-canfd-v1-1-ec533c8a9895@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/rockchip/rockchip_canfd-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c +index df18c85fc078..d9a937ba126c 100644 +--- a/drivers/net/can/rockchip/rockchip_canfd-core.c ++++ b/drivers/net/can/rockchip/rockchip_canfd-core.c +@@ -622,7 +622,7 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv) + netdev_dbg(priv->ndev, "RX-FIFO overflow\n"); + + skb = rkcanfd_alloc_can_err_skb(priv, &cf, ×tamp); +- if (skb) ++ if (!skb) + return 0; + + rkcanfd_get_berr_counter_corrected(priv, &bec); +-- +2.48.1 + diff --git a/queue-6.12/cgroup-fix-race-between-fork-and-cgroup.kill.patch b/queue-6.12/cgroup-fix-race-between-fork-and-cgroup.kill.patch new file mode 100644 index 0000000000..78ebbaef70 --- /dev/null +++ b/queue-6.12/cgroup-fix-race-between-fork-and-cgroup.kill.patch @@ -0,0 +1,165 @@ +From b69bb476dee99d564d65d418e9a20acca6f32c3f Mon Sep 17 00:00:00 2001 +From: Shakeel Butt +Date: Thu, 30 Jan 2025 16:05:42 -0800 +Subject: cgroup: fix race between fork and cgroup.kill +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Shakeel Butt + +commit b69bb476dee99d564d65d418e9a20acca6f32c3f upstream. + +Tejun reported the following race between fork() and cgroup.kill at [1]. + +Tejun: + I was looking at cgroup.kill implementation and wondering whether there + could be a race window. So, __cgroup_kill() does the following: + + k1. Set CGRP_KILL. + k2. Iterate tasks and deliver SIGKILL. + k3. Clear CGRP_KILL. + + The copy_process() does the following: + + c1. Copy a bunch of stuff. + c2. Grab siglock. + c3. Check fatal_signal_pending(). + c4. Commit to forking. + c5. Release siglock. + c6. Call cgroup_post_fork() which puts the task on the css_set and tests + CGRP_KILL. + + The intention seems to be that either a forking task gets SIGKILL and + terminates on c3 or it sees CGRP_KILL on c6 and kills the child. However, I + don't see what guarantees that k3 can't happen before c6. ie. After a + forking task passes c5, k2 can take place and then before the forking task + reaches c6, k3 can happen. Then, nobody would send SIGKILL to the child. + What am I missing? + +This is indeed a race. One way to fix this race is by taking +cgroup_threadgroup_rwsem in write mode in __cgroup_kill() as the fork() +side takes cgroup_threadgroup_rwsem in read mode from cgroup_can_fork() +to cgroup_post_fork(). However that would be heavy handed as this adds +one more potential stall scenario for cgroup.kill which is usually +called under extreme situation like memory pressure. + +To fix this race, let's maintain a sequence number per cgroup which gets +incremented on __cgroup_kill() call. On the fork() side, the +cgroup_can_fork() will cache the sequence number locally and recheck it +against the cgroup's sequence number at cgroup_post_fork() site. If the +sequence numbers mismatch, it means __cgroup_kill() can been called and +we should send SIGKILL to the newly created task. + +Reported-by: Tejun Heo +Closes: https://lore.kernel.org/all/Z5QHE2Qn-QZ6M-KW@slm.duckdns.org/ [1] +Fixes: 661ee6280931 ("cgroup: introduce cgroup.kill") +Cc: stable@vger.kernel.org # v5.14+ +Signed-off-by: Shakeel Butt +Reviewed-by: Michal Koutný +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/cgroup-defs.h | 6 +++--- + include/linux/sched/task.h | 1 + + kernel/cgroup/cgroup.c | 20 ++++++++++++-------- + 3 files changed, 16 insertions(+), 11 deletions(-) + +--- a/include/linux/cgroup-defs.h ++++ b/include/linux/cgroup-defs.h +@@ -71,9 +71,6 @@ enum { + + /* Cgroup is frozen. */ + CGRP_FROZEN, +- +- /* Control group has to be killed. */ +- CGRP_KILL, + }; + + /* cgroup_root->flags */ +@@ -460,6 +457,9 @@ struct cgroup { + + int nr_threaded_children; /* # of live threaded child cgroups */ + ++ /* sequence number for cgroup.kill, serialized by css_set_lock. */ ++ unsigned int kill_seq; ++ + struct kernfs_node *kn; /* cgroup kernfs entry */ + struct cgroup_file procs_file; /* handle for "cgroup.procs" */ + struct cgroup_file events_file; /* handle for "cgroup.events" */ +--- a/include/linux/sched/task.h ++++ b/include/linux/sched/task.h +@@ -43,6 +43,7 @@ struct kernel_clone_args { + void *fn_arg; + struct cgroup *cgrp; + struct css_set *cset; ++ unsigned int kill_seq; + }; + + /* +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -4013,7 +4013,7 @@ static void __cgroup_kill(struct cgroup + lockdep_assert_held(&cgroup_mutex); + + spin_lock_irq(&css_set_lock); +- set_bit(CGRP_KILL, &cgrp->flags); ++ cgrp->kill_seq++; + spin_unlock_irq(&css_set_lock); + + css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED, &it); +@@ -4029,10 +4029,6 @@ static void __cgroup_kill(struct cgroup + send_sig(SIGKILL, task, 0); + } + css_task_iter_end(&it); +- +- spin_lock_irq(&css_set_lock); +- clear_bit(CGRP_KILL, &cgrp->flags); +- spin_unlock_irq(&css_set_lock); + } + + static void cgroup_kill(struct cgroup *cgrp) +@@ -6489,6 +6485,10 @@ static int cgroup_css_set_fork(struct ke + spin_lock_irq(&css_set_lock); + cset = task_css_set(current); + get_css_set(cset); ++ if (kargs->cgrp) ++ kargs->kill_seq = kargs->cgrp->kill_seq; ++ else ++ kargs->kill_seq = cset->dfl_cgrp->kill_seq; + spin_unlock_irq(&css_set_lock); + + if (!(kargs->flags & CLONE_INTO_CGROUP)) { +@@ -6672,6 +6672,7 @@ void cgroup_post_fork(struct task_struct + struct kernel_clone_args *kargs) + __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex) + { ++ unsigned int cgrp_kill_seq = 0; + unsigned long cgrp_flags = 0; + bool kill = false; + struct cgroup_subsys *ss; +@@ -6685,10 +6686,13 @@ void cgroup_post_fork(struct task_struct + + /* init tasks are special, only link regular threads */ + if (likely(child->pid)) { +- if (kargs->cgrp) ++ if (kargs->cgrp) { + cgrp_flags = kargs->cgrp->flags; +- else ++ cgrp_kill_seq = kargs->cgrp->kill_seq; ++ } else { + cgrp_flags = cset->dfl_cgrp->flags; ++ cgrp_kill_seq = cset->dfl_cgrp->kill_seq; ++ } + + WARN_ON_ONCE(!list_empty(&child->cg_list)); + cset->nr_tasks++; +@@ -6723,7 +6727,7 @@ void cgroup_post_fork(struct task_struct + * child down right after we finished preparing it for + * userspace. + */ +- kill = test_bit(CGRP_KILL, &cgrp_flags); ++ kill = kargs->kill_seq != cgrp_kill_seq; + } + + spin_unlock_irq(&css_set_lock); diff --git a/queue-6.12/cifs-pick-channels-for-individual-subrequests.patch b/queue-6.12/cifs-pick-channels-for-individual-subrequests.patch new file mode 100644 index 0000000000..2a34679f86 --- /dev/null +++ b/queue-6.12/cifs-pick-channels-for-individual-subrequests.patch @@ -0,0 +1,86 @@ +From f1bf10d7e909fe898a112f5cae1e97ce34d6484d Mon Sep 17 00:00:00 2001 +From: Shyam Prasad N +Date: Tue, 11 Feb 2025 10:00:25 +0000 +Subject: cifs: pick channels for individual subrequests + +From: Shyam Prasad N + +commit f1bf10d7e909fe898a112f5cae1e97ce34d6484d upstream. + +The netfs library could break down a read request into +multiple subrequests. When multichannel is used, there is +potential to improve performance when each of these +subrequests pick a different channel. + +Today we call cifs_pick_channel when the main read request +is initialized in cifs_init_request. This change moves this to +cifs_prepare_read, which is the right place to pick channel since +it gets called for each subrequest. + +Interestingly cifs_prepare_write already does channel selection +for individual subreq, but looks like it was missed for read. +This is especially important when multichannel is used with +increased rasize. + +In my test setup, with rasize set to 8MB, a sequential read +of large file was taking 11.5s without this change. With the +change, it completed in 9s. The difference is even more signigicant +with bigger rasize. + +Cc: +Cc: David Howells +Signed-off-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/cifsglob.h | 1 - + fs/smb/client/file.c | 7 ++++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -1476,7 +1476,6 @@ struct cifs_io_parms { + struct cifs_io_request { + struct netfs_io_request rreq; + struct cifsFileInfo *cfile; +- struct TCP_Server_Info *server; + pid_t pid; + }; + +--- a/fs/smb/client/file.c ++++ b/fs/smb/client/file.c +@@ -147,7 +147,7 @@ static int cifs_prepare_read(struct netf + struct netfs_io_request *rreq = subreq->rreq; + struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq); + struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq); +- struct TCP_Server_Info *server = req->server; ++ struct TCP_Server_Info *server; + struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb); + size_t size; + int rc = 0; +@@ -156,6 +156,8 @@ static int cifs_prepare_read(struct netf + rdata->xid = get_xid(); + rdata->have_xid = true; + } ++ ++ server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses); + rdata->server = server; + + if (cifs_sb->ctx->rsize == 0) +@@ -198,7 +200,7 @@ static void cifs_issue_read(struct netfs + struct netfs_io_request *rreq = subreq->rreq; + struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq); + struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq); +- struct TCP_Server_Info *server = req->server; ++ struct TCP_Server_Info *server = rdata->server; + int rc = 0; + + cifs_dbg(FYI, "%s: op=%08x[%x] mapping=%p len=%zu/%zu\n", +@@ -265,7 +267,6 @@ static int cifs_init_request(struct netf + open_file = file->private_data; + rreq->netfs_priv = file->private_data; + req->cfile = cifsFileInfo_get(open_file); +- req->server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses); + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) + req->pid = req->cfile->pid; + } else if (rreq->origin != NETFS_WRITEBACK) { diff --git a/queue-6.12/drm-amdgpu-avoid-buffer-overflow-attach-in-smu_sys_set_pp_table.patch b/queue-6.12/drm-amdgpu-avoid-buffer-overflow-attach-in-smu_sys_set_pp_table.patch new file mode 100644 index 0000000000..0e0e627427 --- /dev/null +++ b/queue-6.12/drm-amdgpu-avoid-buffer-overflow-attach-in-smu_sys_set_pp_table.patch @@ -0,0 +1,34 @@ +From 1abb2648698bf10783d2236a6b4a7ca5e8021699 Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 7 Feb 2025 14:44:14 +0800 +Subject: drm/amdgpu: avoid buffer overflow attach in smu_sys_set_pp_table() + +From: Jiang Liu + +commit 1abb2648698bf10783d2236a6b4a7ca5e8021699 upstream. + +It malicious user provides a small pptable through sysfs and then +a bigger pptable, it may cause buffer overflow attack in function +smu_sys_set_pp_table(). + +Reviewed-by: Lijo Lazar +Signed-off-by: Jiang Liu +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -607,7 +607,8 @@ static int smu_sys_set_pp_table(void *ha + return -EIO; + } + +- if (!smu_table->hardcode_pptable) { ++ if (!smu_table->hardcode_pptable || smu_table->power_play_table_size < size) { ++ kfree(smu_table->hardcode_pptable); + smu_table->hardcode_pptable = kzalloc(size, GFP_KERNEL); + if (!smu_table->hardcode_pptable) + return -ENOMEM; diff --git a/queue-6.12/drm-amdgpu-bump-version-for-rv-pco-compute-fix.patch b/queue-6.12/drm-amdgpu-bump-version-for-rv-pco-compute-fix.patch new file mode 100644 index 0000000000..1d2a859db9 --- /dev/null +++ b/queue-6.12/drm-amdgpu-bump-version-for-rv-pco-compute-fix.patch @@ -0,0 +1,35 @@ +From 55ed2b1b50d029dd7e49a35f6628ca64db6d75d8 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 31 Jan 2025 13:53:40 -0500 +Subject: drm/amdgpu: bump version for RV/PCO compute fix + +From: Alex Deucher + +commit 55ed2b1b50d029dd7e49a35f6628ca64db6d75d8 upstream. + +Bump the driver version for RV/PCO compute stability fix +so mesa can use this check to enable compute queues on +RV/PCO. + +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org # 6.12.x +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -119,9 +119,10 @@ + * - 3.58.0 - Add GFX12 DCC support + * - 3.59.0 - Cleared VRAM + * - 3.60.0 - Add AMDGPU_TILING_GFX12_DCC_WRITE_COMPRESS_DISABLE (Vulkan requirement) ++ * - 3.61.0 - Contains fix for RV/PCO compute queues + */ + #define KMS_DRIVER_MAJOR 3 +-#define KMS_DRIVER_MINOR 60 ++#define KMS_DRIVER_MINOR 61 + #define KMS_DRIVER_PATCHLEVEL 0 + + /* diff --git a/queue-6.12/drm-amdgpu-gfx9-manually-control-gfxoff-for-cs-on-rv.patch b/queue-6.12/drm-amdgpu-gfx9-manually-control-gfxoff-for-cs-on-rv.patch new file mode 100644 index 0000000000..e3d2c4050a --- /dev/null +++ b/queue-6.12/drm-amdgpu-gfx9-manually-control-gfxoff-for-cs-on-rv.patch @@ -0,0 +1,90 @@ +From b35eb9128ebeec534eed1cefd6b9b1b7282cf5ba Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 28 Jan 2025 11:55:22 -0500 +Subject: drm/amdgpu/gfx9: manually control gfxoff for CS on RV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alex Deucher + +commit b35eb9128ebeec534eed1cefd6b9b1b7282cf5ba upstream. + +When mesa started using compute queues more often +we started seeing additional hangs with compute queues. +Disabling gfxoff seems to mitigate that. Manually +control gfxoff and gfx pg with command submissions to avoid +any issues related to gfxoff. KFD already does the same +thing for these chips. + +v2: limit to compute +v3: limit to APUs +v4: limit to Raven/PCO +v5: only update the compute ring_funcs +v6: Disable GFX PG +v7: adjust order + +Reviewed-by: Lijo Lazar +Suggested-by: Błażej Szczygieł +Suggested-by: Sergey Kovalenko +Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3861 +Link: https://lists.freedesktop.org/archives/amd-gfx/2025-January/119116.html +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org # 6.12.x +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 36 ++++++++++++++++++++++++++++++++-- + 1 file changed, 34 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -7415,6 +7415,38 @@ static void gfx_v9_0_ring_emit_cleaner_s + amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */ + } + ++static void gfx_v9_0_ring_begin_use_compute(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ struct amdgpu_ip_block *gfx_block = ++ amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); ++ ++ amdgpu_gfx_enforce_isolation_ring_begin_use(ring); ++ ++ /* Raven and PCO APUs seem to have stability issues ++ * with compute and gfxoff and gfx pg. Disable gfx pg during ++ * submission and allow again afterwards. ++ */ ++ if (gfx_block && amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 1, 0)) ++ gfx_v9_0_set_powergating_state(gfx_block, AMD_PG_STATE_UNGATE); ++} ++ ++static void gfx_v9_0_ring_end_use_compute(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ struct amdgpu_ip_block *gfx_block = ++ amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); ++ ++ /* Raven and PCO APUs seem to have stability issues ++ * with compute and gfxoff and gfx pg. Disable gfx pg during ++ * submission and allow again afterwards. ++ */ ++ if (gfx_block && amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 1, 0)) ++ gfx_v9_0_set_powergating_state(gfx_block, AMD_PG_STATE_GATE); ++ ++ amdgpu_gfx_enforce_isolation_ring_end_use(ring); ++} ++ + static const struct amd_ip_funcs gfx_v9_0_ip_funcs = { + .name = "gfx_v9_0", + .early_init = gfx_v9_0_early_init, +@@ -7591,8 +7623,8 @@ static const struct amdgpu_ring_funcs gf + .emit_wave_limit = gfx_v9_0_emit_wave_limit, + .reset = gfx_v9_0_reset_kcq, + .emit_cleaner_shader = gfx_v9_0_ring_emit_cleaner_shader, +- .begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use, +- .end_use = amdgpu_gfx_enforce_isolation_ring_end_use, ++ .begin_use = gfx_v9_0_ring_begin_use_compute, ++ .end_use = gfx_v9_0_ring_end_use_compute, + }; + + static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = { diff --git a/queue-6.12/efi-avoid-cold-plugged-memory-for-placing-the-kernel.patch b/queue-6.12/efi-avoid-cold-plugged-memory-for-placing-the-kernel.patch new file mode 100644 index 0000000000..7b63fd4f02 --- /dev/null +++ b/queue-6.12/efi-avoid-cold-plugged-memory-for-placing-the-kernel.patch @@ -0,0 +1,99 @@ +From ba69e0750b0362870294adab09339a0c39c3beaf Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Sat, 1 Feb 2025 18:21:35 +0100 +Subject: efi: Avoid cold plugged memory for placing the kernel + +From: Ard Biesheuvel + +commit ba69e0750b0362870294adab09339a0c39c3beaf upstream. + +UEFI 2.11 introduced EFI_MEMORY_HOT_PLUGGABLE to annotate system memory +regions that are 'cold plugged' at boot, i.e., hot pluggable memory that +is available from early boot, and described as system RAM by the +firmware. + +Existing loaders and EFI applications running in the boot context will +happily use this memory for allocating data structures that cannot be +freed or moved at runtime, and this prevents the memory from being +unplugged. Going forward, the new EFI_MEMORY_HOT_PLUGGABLE attribute +should be tested, and memory annotated as such should be avoided for +such allocations. + +In the EFI stub, there are a couple of occurrences where, instead of the +high-level AllocatePages() UEFI boot service, a low-level code sequence +is used that traverses the EFI memory map and carves out the requested +number of pages from a free region. This is needed, e.g., for allocating +as low as possible, or for allocating pages at random. + +While AllocatePages() should presumably avoid special purpose memory and +cold plugged regions, this manual approach needs to incorporate this +logic itself, in order to prevent the kernel itself from ending up in a +hot unpluggable region, preventing it from being unplugged. + +So add the EFI_MEMORY_HOTPLUGGABLE macro definition, and check for it +where appropriate. + +Cc: stable@vger.kernel.org +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/efi.c | 6 ++++-- + drivers/firmware/efi/libstub/randomalloc.c | 3 +++ + drivers/firmware/efi/libstub/relocate.c | 3 +++ + include/linux/efi.h | 1 + + 4 files changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -922,13 +922,15 @@ char * __init efi_md_typeattr_format(cha + EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | + EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | + EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO | +- EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) ++ EFI_MEMORY_MORE_RELIABLE | EFI_MEMORY_HOT_PLUGGABLE | ++ EFI_MEMORY_RUNTIME)) + snprintf(pos, size, "|attr=0x%016llx]", + (unsigned long long)attr); + else + snprintf(pos, size, +- "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", ++ "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + attr & EFI_MEMORY_RUNTIME ? "RUN" : "", ++ attr & EFI_MEMORY_HOT_PLUGGABLE ? "HP" : "", + attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "", + attr & EFI_MEMORY_SP ? "SP" : "", +--- a/drivers/firmware/efi/libstub/randomalloc.c ++++ b/drivers/firmware/efi/libstub/randomalloc.c +@@ -25,6 +25,9 @@ static unsigned long get_entry_num_slots + if (md->type != EFI_CONVENTIONAL_MEMORY) + return 0; + ++ if (md->attribute & EFI_MEMORY_HOT_PLUGGABLE) ++ return 0; ++ + if (efi_soft_reserve_enabled() && + (md->attribute & EFI_MEMORY_SP)) + return 0; +--- a/drivers/firmware/efi/libstub/relocate.c ++++ b/drivers/firmware/efi/libstub/relocate.c +@@ -53,6 +53,9 @@ efi_status_t efi_low_alloc_above(unsigne + if (desc->type != EFI_CONVENTIONAL_MEMORY) + continue; + ++ if (desc->attribute & EFI_MEMORY_HOT_PLUGGABLE) ++ continue; ++ + if (efi_soft_reserve_enabled() && + (desc->attribute & EFI_MEMORY_SP)) + continue; +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -128,6 +128,7 @@ typedef struct { + #define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */ + #define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */ + #define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* supports encryption */ ++#define EFI_MEMORY_HOT_PLUGGABLE BIT_ULL(20) /* supports unplugging at runtime */ + #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */ + #define EFI_MEMORY_DESCRIPTOR_VERSION 1 + diff --git a/queue-6.12/gpio-stmpe-check-return-value-of-stmpe_reg_read-in-stmpe_gpio_irq_sync_unlock.patch b/queue-6.12/gpio-stmpe-check-return-value-of-stmpe_reg_read-in-stmpe_gpio_irq_sync_unlock.patch new file mode 100644 index 0000000000..6a0c16d989 --- /dev/null +++ b/queue-6.12/gpio-stmpe-check-return-value-of-stmpe_reg_read-in-stmpe_gpio_irq_sync_unlock.patch @@ -0,0 +1,65 @@ +From b9644fbfbcab13da7f8b37bef7c51e5b8407d031 Mon Sep 17 00:00:00 2001 +From: Wentao Liang +Date: Wed, 12 Feb 2025 10:18:49 +0800 +Subject: gpio: stmpe: Check return value of stmpe_reg_read in stmpe_gpio_irq_sync_unlock + +From: Wentao Liang + +commit b9644fbfbcab13da7f8b37bef7c51e5b8407d031 upstream. + +The stmpe_reg_read function can fail, but its return value is not checked +in stmpe_gpio_irq_sync_unlock. This can lead to silent failures and +incorrect behavior if the hardware access fails. + +This patch adds checks for the return value of stmpe_reg_read. If the +function fails, an error message is logged and the function returns +early to avoid further issues. + +Fixes: b888fb6f2a27 ("gpio: stmpe: i2c transfer are forbiden in atomic context") +Cc: stable@vger.kernel.org # 4.16+ +Signed-off-by: Wentao Liang +Link: https://lore.kernel.org/r/20250212021849.275-1-vulab@iscas.ac.cn +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpio/gpio-stmpe.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/gpio/gpio-stmpe.c ++++ b/drivers/gpio/gpio-stmpe.c +@@ -191,7 +191,7 @@ static void stmpe_gpio_irq_sync_unlock(s + [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, + [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, + }; +- int i, j; ++ int ret, i, j; + + /* + * STMPE1600: to be able to get IRQ from pins, +@@ -199,8 +199,16 @@ static void stmpe_gpio_irq_sync_unlock(s + * GPSR or GPCR registers + */ + if (stmpe->partnum == STMPE1600) { +- stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); +- stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); ++ ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); ++ if (ret < 0) { ++ dev_err(stmpe->dev, "Failed to read GPMR_LSB: %d\n", ret); ++ goto err; ++ } ++ ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); ++ if (ret < 0) { ++ dev_err(stmpe->dev, "Failed to read GPMR_CSB: %d\n", ret); ++ goto err; ++ } + } + + for (i = 0; i < CACHE_NR_REGS; i++) { +@@ -222,6 +230,7 @@ static void stmpe_gpio_irq_sync_unlock(s + } + } + ++err: + mutex_unlock(&stmpe_gpio->irq_lock); + } + diff --git a/queue-6.12/gpiolib-acpi-add-a-quirk-for-acer-nitro-anv14.patch b/queue-6.12/gpiolib-acpi-add-a-quirk-for-acer-nitro-anv14.patch new file mode 100644 index 0000000000..80a06b5433 --- /dev/null +++ b/queue-6.12/gpiolib-acpi-add-a-quirk-for-acer-nitro-anv14.patch @@ -0,0 +1,51 @@ +From 8743d66979e494c5378563e6b5a32e913380abd8 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Tue, 11 Feb 2025 14:32:01 -0600 +Subject: gpiolib: acpi: Add a quirk for Acer Nitro ANV14 + +From: Mario Limonciello + +commit 8743d66979e494c5378563e6b5a32e913380abd8 upstream. + +Spurious immediate wake up events are reported on Acer Nitro ANV14. GPIO 11 is +specified as an edge triggered input and also a wake source but this pin is +supposed to be an output pin for an LED, so it's effectively floating. + +Block the interrupt from getting set up for this GPIO on this device. + +Cc: stable@vger.kernel.org +Reported-by: Delgan +Tested-by: Delgan +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3954 +Signed-off-by: Mario Limonciello +Acked-by: Mika Westerberg +Link: https://lore.kernel.org/r/20250211203222.761206-1-superm1@kernel.org +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpio/gpiolib-acpi.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -1691,6 +1691,20 @@ static const struct dmi_system_id gpioli + .ignore_wake = "PNP0C50:00@8", + }, + }, ++ { ++ /* ++ * Spurious wakeups from GPIO 11 ++ * Found in BIOS 1.04 ++ * https://gitlab.freedesktop.org/drm/amd/-/issues/3954 ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"), ++ }, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .ignore_interrupt = "AMDI0030:00@11", ++ }, ++ }, + {} /* Terminating entry */ + }; + diff --git a/queue-6.12/igc-set-buffer-type-for-empty-frames-in-igc_init_empty_frame.patch b/queue-6.12/igc-set-buffer-type-for-empty-frames-in-igc_init_empty_frame.patch new file mode 100644 index 0000000000..e709e77a68 --- /dev/null +++ b/queue-6.12/igc-set-buffer-type-for-empty-frames-in-igc_init_empty_frame.patch @@ -0,0 +1,35 @@ +From 63f20f00d23d569e4e67859b4e8dcc9de79221cb Mon Sep 17 00:00:00 2001 +From: Song Yoong Siang +Date: Wed, 5 Feb 2025 10:36:03 +0800 +Subject: igc: Set buffer type for empty frames in igc_init_empty_frame + +From: Song Yoong Siang + +commit 63f20f00d23d569e4e67859b4e8dcc9de79221cb upstream. + +Set the buffer type to IGC_TX_BUFFER_TYPE_SKB for empty frame in the +igc_init_empty_frame function. This ensures that the buffer type is +correctly identified and handled during Tx ring cleanup. + +Fixes: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit") +Cc: stable@vger.kernel.org # 6.2+ +Signed-off-by: Song Yoong Siang +Acked-by: Maciej Fijalkowski +Reviewed-by: Simon Horman +Tested-by: Mor Bar-Gabay +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/igc/igc_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -1096,6 +1096,7 @@ static int igc_init_empty_frame(struct i + return -ENOMEM; + } + ++ buffer->type = IGC_TX_BUFFER_TYPE_SKB; + buffer->skb = skb; + buffer->protocol = 0; + buffer->bytecount = skb->len; diff --git a/queue-6.12/iommu-fix-potential-memory-leak-in-iopf_queue_remove_device.patch b/queue-6.12/iommu-fix-potential-memory-leak-in-iopf_queue_remove_device.patch new file mode 100644 index 0000000000..414323ccac --- /dev/null +++ b/queue-6.12/iommu-fix-potential-memory-leak-in-iopf_queue_remove_device.patch @@ -0,0 +1,44 @@ +From 9759ae2cee7cd42b95f1c48aa3749bd02b5ddb08 Mon Sep 17 00:00:00 2001 +From: Lu Baolu +Date: Fri, 17 Jan 2025 13:58:00 +0800 +Subject: iommu: Fix potential memory leak in iopf_queue_remove_device() + +From: Lu Baolu + +commit 9759ae2cee7cd42b95f1c48aa3749bd02b5ddb08 upstream. + +The iopf_queue_remove_device() helper removes a device from the per-iommu +iopf queue when PRI is disabled on the device. It responds to all +outstanding iopf's with an IOMMU_PAGE_RESP_INVALID code and detaches the +device from the queue. + +However, it fails to release the group structure that represents a group +of iopf's awaiting for a response after responding to the hardware. This +can cause a memory leak if iopf_queue_remove_device() is called with +pending iopf's. + +Fix it by calling iopf_free_group() after the iopf group is responded. + +Fixes: 199112327135 ("iommu: Track iopf group instead of last fault") +Cc: stable@vger.kernel.org +Suggested-by: Kevin Tian +Signed-off-by: Lu Baolu +Reviewed-by: Kevin Tian +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20250117055800.782462-1-baolu.lu@linux.intel.com +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/io-pgfault.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iommu/io-pgfault.c ++++ b/drivers/iommu/io-pgfault.c +@@ -478,6 +478,7 @@ void iopf_queue_remove_device(struct iop + + ops->page_response(dev, iopf, &resp); + list_del_init(&group->pending_node); ++ iopf_free_group(group); + } + mutex_unlock(&fault_param->lock); + diff --git a/queue-6.12/kbuild-userprogs-fix-bitsize-and-target-detection-on-clang.patch b/queue-6.12/kbuild-userprogs-fix-bitsize-and-target-detection-on-clang.patch new file mode 100644 index 0000000000..47cef72cb5 --- /dev/null +++ b/queue-6.12/kbuild-userprogs-fix-bitsize-and-target-detection-on-clang.patch @@ -0,0 +1,42 @@ +From 1b71c2fb04e7a713abc6edde4a412416ff3158f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Thu, 13 Feb 2025 15:55:17 +0100 +Subject: kbuild: userprogs: fix bitsize and target detection on clang +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit 1b71c2fb04e7a713abc6edde4a412416ff3158f2 upstream. + +scripts/Makefile.clang was changed in the linked commit to move --target from +KBUILD_CFLAGS to KBUILD_CPPFLAGS, as that generally has a broader scope. +However that variable is not inspected by the userprogs logic, +breaking cross compilation on clang. + +Use both variables to detect bitsize and target arguments for userprogs. + +Fixes: feb843a469fb ("kbuild: add $(CLANG_FLAGS) to KBUILD_CPPFLAGS") +Cc: stable@vger.kernel.org +Signed-off-by: Thomas Weißschuh +Reviewed-by: Nathan Chancellor +Signed-off-by: Masahiro Yamada +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -1057,8 +1057,8 @@ LDFLAGS_vmlinux += --orphan-handling=$(C + endif + + # Align the bit size of userspace programs with the kernel +-KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) +-KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) ++KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) ++KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) + + # make the checker run with the right architecture + CHECKFLAGS += --arch=$(ARCH) diff --git a/queue-6.12/kvm-nsvm-enter-guest-mode-before-initializing-nested-npt-mmu.patch b/queue-6.12/kvm-nsvm-enter-guest-mode-before-initializing-nested-npt-mmu.patch new file mode 100644 index 0000000000..89aa4b97c4 --- /dev/null +++ b/queue-6.12/kvm-nsvm-enter-guest-mode-before-initializing-nested-npt-mmu.patch @@ -0,0 +1,81 @@ +From 46d6c6f3ef0eaff71c2db6d77d4e2ebb7adac34f Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Wed, 29 Jan 2025 17:08:25 -0800 +Subject: KVM: nSVM: Enter guest mode before initializing nested NPT MMU + +From: Sean Christopherson + +commit 46d6c6f3ef0eaff71c2db6d77d4e2ebb7adac34f upstream. + +When preparing vmcb02 for nested VMRUN (or state restore), "enter" guest +mode prior to initializing the MMU for nested NPT so that guest_mode is +set in the MMU's role. KVM's model is that all L2 MMUs are tagged with +guest_mode, as the behavior of hypervisor MMUs tends to be significantly +different than kernel MMUs. + +Practically speaking, the bug is relatively benign, as KVM only directly +queries role.guest_mode in kvm_mmu_free_guest_mode_roots() and +kvm_mmu_page_ad_need_write_protect(), which SVM doesn't use, and in paths +that are optimizations (mmu_page_zap_pte() and +shadow_mmu_try_split_huge_pages()). + +And while the role is incorprated into shadow page usage, because nested +NPT requires KVM to be using NPT for L1, reusing shadow pages across L1 +and L2 is impossible as L1 MMUs will always have direct=1, while L2 MMUs +will have direct=0. + +Hoist the TLB processing and setting of HF_GUEST_MASK to the beginning +of the flow instead of forcing guest_mode in the MMU, as nothing in +nested_vmcb02_prepare_control() between the old and new locations touches +TLB flush requests or HF_GUEST_MASK, i.e. there's no reason to present +inconsistent vCPU state to the MMU. + +Fixes: 69cb877487de ("KVM: nSVM: move MMU setup to nested_prepare_vmcb_control") +Cc: stable@vger.kernel.org +Reported-by: Yosry Ahmed +Reviewed-by: Yosry Ahmed +Link: https://lore.kernel.org/r/20250130010825.220346-1-seanjc@google.com +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/mmu/mmu.c | 2 +- + arch/x86/kvm/svm/nested.c | 10 +++++----- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -5591,7 +5591,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_ + union kvm_mmu_page_role root_role; + + /* NPT requires CR0.PG=1. */ +- WARN_ON_ONCE(cpu_role.base.direct); ++ WARN_ON_ONCE(cpu_role.base.direct || !cpu_role.base.guest_mode); + + root_role = cpu_role.base; + root_role.level = kvm_mmu_get_tdp_level(vcpu); +--- a/arch/x86/kvm/svm/nested.c ++++ b/arch/x86/kvm/svm/nested.c +@@ -646,6 +646,11 @@ static void nested_vmcb02_prepare_contro + u32 pause_count12; + u32 pause_thresh12; + ++ nested_svm_transition_tlb_flush(vcpu); ++ ++ /* Enter Guest-Mode */ ++ enter_guest_mode(vcpu); ++ + /* + * Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2, + * exit_int_info, exit_int_info_err, next_rip, insn_len, insn_bytes. +@@ -762,11 +767,6 @@ static void nested_vmcb02_prepare_contro + } + } + +- nested_svm_transition_tlb_flush(vcpu); +- +- /* Enter Guest-Mode */ +- enter_guest_mode(vcpu); +- + /* + * Merge guest and host intercepts - must be called with vcpu in + * guest-mode to take effect. diff --git a/queue-6.12/kvm-x86-load-dr6-with-guest-value-only-before-entering-.vcpu_run-loop.patch b/queue-6.12/kvm-x86-load-dr6-with-guest-value-only-before-entering-.vcpu_run-loop.patch new file mode 100644 index 0000000000..2354addb36 --- /dev/null +++ b/queue-6.12/kvm-x86-load-dr6-with-guest-value-only-before-entering-.vcpu_run-loop.patch @@ -0,0 +1,240 @@ +From c2fee09fc167c74a64adb08656cb993ea475197e Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 24 Jan 2025 17:18:33 -0800 +Subject: KVM: x86: Load DR6 with guest value only before entering .vcpu_run() loop + +From: Sean Christopherson + +commit c2fee09fc167c74a64adb08656cb993ea475197e upstream. + +Move the conditional loading of hardware DR6 with the guest's DR6 value +out of the core .vcpu_run() loop to fix a bug where KVM can load hardware +with a stale vcpu->arch.dr6. + +When the guest accesses a DR and host userspace isn't debugging the guest, +KVM disables DR interception and loads the guest's values into hardware on +VM-Enter and saves them on VM-Exit. This allows the guest to access DRs +at will, e.g. so that a sequence of DR accesses to configure a breakpoint +only generates one VM-Exit. + +For DR0-DR3, the logic/behavior is identical between VMX and SVM, and also +identical between KVM_DEBUGREG_BP_ENABLED (userspace debugging the guest) +and KVM_DEBUGREG_WONT_EXIT (guest using DRs), and so KVM handles loading +DR0-DR3 in common code, _outside_ of the core kvm_x86_ops.vcpu_run() loop. + +But for DR6, the guest's value doesn't need to be loaded into hardware for +KVM_DEBUGREG_BP_ENABLED, and SVM provides a dedicated VMCB field whereas +VMX requires software to manually load the guest value, and so loading the +guest's value into DR6 is handled by {svm,vmx}_vcpu_run(), i.e. is done +_inside_ the core run loop. + +Unfortunately, saving the guest values on VM-Exit is initiated by common +x86, again outside of the core run loop. If the guest modifies DR6 (in +hardware, when DR interception is disabled), and then the next VM-Exit is +a fastpath VM-Exit, KVM will reload hardware DR6 with vcpu->arch.dr6 and +clobber the guest's actual value. + +The bug shows up primarily with nested VMX because KVM handles the VMX +preemption timer in the fastpath, and the window between hardware DR6 +being modified (in guest context) and DR6 being read by guest software is +orders of magnitude larger in a nested setup. E.g. in non-nested, the +VMX preemption timer would need to fire precisely between #DB injection +and the #DB handler's read of DR6, whereas with a KVM-on-KVM setup, the +window where hardware DR6 is "dirty" extends all the way from L1 writing +DR6 to VMRESUME (in L1). + + L1's view: + ========== + + CPU 0/KVM-7289 [023] d.... 2925.640961: kvm_entry: vcpu 0 + A: L1 Writes DR6 + CPU 0/KVM-7289 [023] d.... 2925.640963: : Set DRs, DR6 = 0xffff0ff1 + + B: CPU 0/KVM-7289 [023] d.... 2925.640967: kvm_exit: vcpu 0 reason EXTERNAL_INTERRUPT intr_info 0x800000ec + + D: L1 reads DR6, arch.dr6 = 0 + CPU 0/KVM-7289 [023] d.... 2925.640969: : Sync DRs, DR6 = 0xffff0ff0 + + CPU 0/KVM-7289 [023] d.... 2925.640976: kvm_entry: vcpu 0 + L2 reads DR6, L1 disables DR interception + CPU 0/KVM-7289 [023] d.... 2925.640980: kvm_exit: vcpu 0 reason DR_ACCESS info1 0x0000000000000216 + CPU 0/KVM-7289 [023] d.... 2925.640983: kvm_entry: vcpu 0 + + CPU 0/KVM-7289 [023] d.... 2925.640983: : Set DRs, DR6 = 0xffff0ff0 + + L2 detects failure + CPU 0/KVM-7289 [023] d.... 2925.640987: kvm_exit: vcpu 0 reason HLT + L1 reads DR6 (confirms failure) + CPU 0/KVM-7289 [023] d.... 2925.640990: : Sync DRs, DR6 = 0xffff0ff0 + + L0's view: + ========== + L2 reads DR6, arch.dr6 = 0 + CPU 23/KVM-5046 [001] d.... 3410.005610: kvm_exit: vcpu 23 reason DR_ACCESS info1 0x0000000000000216 + CPU 23/KVM-5046 [001] ..... 3410.005610: kvm_nested_vmexit: vcpu 23 reason DR_ACCESS info1 0x0000000000000216 + + L2 => L1 nested VM-Exit + CPU 23/KVM-5046 [001] ..... 3410.005610: kvm_nested_vmexit_inject: reason: DR_ACCESS ext_inf1: 0x0000000000000216 + + CPU 23/KVM-5046 [001] d.... 3410.005610: kvm_entry: vcpu 23 + CPU 23/KVM-5046 [001] d.... 3410.005611: kvm_exit: vcpu 23 reason VMREAD + CPU 23/KVM-5046 [001] d.... 3410.005611: kvm_entry: vcpu 23 + CPU 23/KVM-5046 [001] d.... 3410.005612: kvm_exit: vcpu 23 reason VMREAD + CPU 23/KVM-5046 [001] d.... 3410.005612: kvm_entry: vcpu 23 + + L1 writes DR7, L0 disables DR interception + CPU 23/KVM-5046 [001] d.... 3410.005612: kvm_exit: vcpu 23 reason DR_ACCESS info1 0x0000000000000007 + CPU 23/KVM-5046 [001] d.... 3410.005613: kvm_entry: vcpu 23 + + L0 writes DR6 = 0 (arch.dr6) + CPU 23/KVM-5046 [001] d.... 3410.005613: : Set DRs, DR6 = 0xffff0ff0 + + A: + + B: CPU 23/KVM-5046 [001] d.... 3410.005614: kvm_exit: vcpu 23 reason PREEMPTION_TIMER + CPU 23/KVM-5046 [001] d.... 3410.005614: kvm_entry: vcpu 23 + + C: L0 writes DR6 = 0 (arch.dr6) + CPU 23/KVM-5046 [001] d.... 3410.005614: : Set DRs, DR6 = 0xffff0ff0 + + L1 => L2 nested VM-Enter + CPU 23/KVM-5046 [001] d.... 3410.005616: kvm_exit: vcpu 23 reason VMRESUME + + L0 reads DR6, arch.dr6 = 0 + +Reported-by: John Stultz +Closes: https://lkml.kernel.org/r/CANDhNCq5_F3HfFYABqFGCA1bPd_%2BxgNj-iDQhH4tDk%2Bwi8iZZg%40mail.gmail.com +Fixes: 375e28ffc0cf ("KVM: X86: Set host DR6 only on VMX and for KVM_DEBUGREG_WONT_EXIT") +Fixes: d67668e9dd76 ("KVM: x86, SVM: isolate vcpu->arch.dr6 from vmcb->save.dr6") +Cc: stable@vger.kernel.org +Cc: Jim Mattson +Tested-by: John Stultz +Link: https://lore.kernel.org/r/20250125011833.3644371-1-seanjc@google.com +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/kvm-x86-ops.h | 1 + + arch/x86/include/asm/kvm_host.h | 1 + + arch/x86/kvm/svm/svm.c | 13 ++++++------- + arch/x86/kvm/vmx/main.c | 1 + + arch/x86/kvm/vmx/vmx.c | 10 ++++++---- + arch/x86/kvm/vmx/x86_ops.h | 1 + + arch/x86/kvm/x86.c | 3 +++ + 7 files changed, 19 insertions(+), 11 deletions(-) + +--- a/arch/x86/include/asm/kvm-x86-ops.h ++++ b/arch/x86/include/asm/kvm-x86-ops.h +@@ -47,6 +47,7 @@ KVM_X86_OP(set_idt) + KVM_X86_OP(get_gdt) + KVM_X86_OP(set_gdt) + KVM_X86_OP(sync_dirty_debug_regs) ++KVM_X86_OP(set_dr6) + KVM_X86_OP(set_dr7) + KVM_X86_OP(cache_reg) + KVM_X86_OP(get_rflags) +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1674,6 +1674,7 @@ struct kvm_x86_ops { + void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void (*sync_dirty_debug_regs)(struct kvm_vcpu *vcpu); ++ void (*set_dr6)(struct kvm_vcpu *vcpu, unsigned long value); + void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); + void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); + unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -1993,11 +1993,11 @@ static void new_asid(struct vcpu_svm *sv + svm->asid = sd->next_asid++; + } + +-static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value) ++static void svm_set_dr6(struct kvm_vcpu *vcpu, unsigned long value) + { +- struct vmcb *vmcb = svm->vmcb; ++ struct vmcb *vmcb = to_svm(vcpu)->vmcb; + +- if (svm->vcpu.arch.guest_state_protected) ++ if (vcpu->arch.guest_state_protected) + return; + + if (unlikely(value != vmcb->save.dr6)) { +@@ -4234,10 +4234,8 @@ static __no_kcsan fastpath_t svm_vcpu_ru + * Run with all-zero DR6 unless needed, so that we can get the exact cause + * of a #DB. + */ +- if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) +- svm_set_dr6(svm, vcpu->arch.dr6); +- else +- svm_set_dr6(svm, DR6_ACTIVE_LOW); ++ if (likely(!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))) ++ svm_set_dr6(vcpu, DR6_ACTIVE_LOW); + + clgi(); + kvm_load_guest_xsave_state(vcpu); +@@ -5033,6 +5031,7 @@ static struct kvm_x86_ops svm_x86_ops __ + .set_idt = svm_set_idt, + .get_gdt = svm_get_gdt, + .set_gdt = svm_set_gdt, ++ .set_dr6 = svm_set_dr6, + .set_dr7 = svm_set_dr7, + .sync_dirty_debug_regs = svm_sync_dirty_debug_regs, + .cache_reg = svm_cache_reg, +--- a/arch/x86/kvm/vmx/main.c ++++ b/arch/x86/kvm/vmx/main.c +@@ -60,6 +60,7 @@ struct kvm_x86_ops vt_x86_ops __initdata + .set_idt = vmx_set_idt, + .get_gdt = vmx_get_gdt, + .set_gdt = vmx_set_gdt, ++ .set_dr6 = vmx_set_dr6, + .set_dr7 = vmx_set_dr7, + .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs, + .cache_reg = vmx_cache_reg, +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -5631,6 +5631,12 @@ void vmx_sync_dirty_debug_regs(struct kv + set_debugreg(DR6_RESERVED, 6); + } + ++void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) ++{ ++ lockdep_assert_irqs_disabled(); ++ set_debugreg(vcpu->arch.dr6, 6); ++} ++ + void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) + { + vmcs_writel(GUEST_DR7, val); +@@ -7392,10 +7398,6 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu + vmx->loaded_vmcs->host_state.cr4 = cr4; + } + +- /* When KVM_DEBUGREG_WONT_EXIT, dr6 is accessible in guest. */ +- if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) +- set_debugreg(vcpu->arch.dr6, 6); +- + /* When single-stepping over STI and MOV SS, we must clear the + * corresponding interruptibility bits in the guest state. Otherwise + * vmentry fails as it then expects bit 14 (BS) in pending debug +--- a/arch/x86/kvm/vmx/x86_ops.h ++++ b/arch/x86/kvm/vmx/x86_ops.h +@@ -74,6 +74,7 @@ void vmx_get_idt(struct kvm_vcpu *vcpu, + void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); ++void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val); + void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val); + void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu); + void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg); +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -10968,6 +10968,9 @@ static int vcpu_enter_guest(struct kvm_v + set_debugreg(vcpu->arch.eff_db[1], 1); + set_debugreg(vcpu->arch.eff_db[2], 2); + set_debugreg(vcpu->arch.eff_db[3], 3); ++ /* When KVM_DEBUGREG_WONT_EXIT, dr6 is accessible in guest. */ ++ if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) ++ kvm_x86_call(set_dr6)(vcpu, vcpu->arch.dr6); + } else if (unlikely(hw_breakpoint_active())) { + set_debugreg(0, 7); + } diff --git a/queue-6.12/kvm-x86-reject-hyper-v-s-send_ipi-hypercalls-if-local-apic-isn-t-in-kernel.patch b/queue-6.12/kvm-x86-reject-hyper-v-s-send_ipi-hypercalls-if-local-apic-isn-t-in-kernel.patch new file mode 100644 index 0000000000..93699a9f02 --- /dev/null +++ b/queue-6.12/kvm-x86-reject-hyper-v-s-send_ipi-hypercalls-if-local-apic-isn-t-in-kernel.patch @@ -0,0 +1,73 @@ +From a8de7f100bb5989d9c3627d3a223ee1c863f3b69 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 17 Jan 2025 16:34:51 -0800 +Subject: KVM: x86: Reject Hyper-V's SEND_IPI hypercalls if local APIC isn't in-kernel + +From: Sean Christopherson + +commit a8de7f100bb5989d9c3627d3a223ee1c863f3b69 upstream. + +Advertise support for Hyper-V's SEND_IPI and SEND_IPI_EX hypercalls if and +only if the local API is emulated/virtualized by KVM, and explicitly reject +said hypercalls if the local APIC is emulated in userspace, i.e. don't rely +on userspace to opt-in to KVM_CAP_HYPERV_ENFORCE_CPUID. + +Rejecting SEND_IPI and SEND_IPI_EX fixes a NULL-pointer dereference if +Hyper-V enlightenments are exposed to the guest without an in-kernel local +APIC: + + dump_stack+0xbe/0xfd + __kasan_report.cold+0x34/0x84 + kasan_report+0x3a/0x50 + __apic_accept_irq+0x3a/0x5c0 + kvm_hv_send_ipi.isra.0+0x34e/0x820 + kvm_hv_hypercall+0x8d9/0x9d0 + kvm_emulate_hypercall+0x506/0x7e0 + __vmx_handle_exit+0x283/0xb60 + vmx_handle_exit+0x1d/0xd0 + vcpu_enter_guest+0x16b0/0x24c0 + vcpu_run+0xc0/0x550 + kvm_arch_vcpu_ioctl_run+0x170/0x6d0 + kvm_vcpu_ioctl+0x413/0xb20 + __se_sys_ioctl+0x111/0x160 + do_syscal1_64+0x30/0x40 + entry_SYSCALL_64_after_hwframe+0x67/0xd1 + +Note, checking the sending vCPU is sufficient, as the per-VM irqchip_mode +can't be modified after vCPUs are created, i.e. if one vCPU has an +in-kernel local APIC, then all vCPUs have an in-kernel local APIC. + +Reported-by: Dongjie Zou +Fixes: 214ff83d4473 ("KVM: x86: hyperv: implement PV IPI send hypercalls") +Fixes: 2bc39970e932 ("x86/kvm/hyper-v: Introduce KVM_GET_SUPPORTED_HV_CPUID") +Cc: stable@vger.kernel.org +Reviewed-by: Vitaly Kuznetsov +Link: https://lore.kernel.org/r/20250118003454.2619573-2-seanjc@google.com +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/hyperv.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -2226,6 +2226,9 @@ static u64 kvm_hv_send_ipi(struct kvm_vc + u32 vector; + bool all_cpus; + ++ if (!lapic_in_kernel(vcpu)) ++ return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ + if (hc->code == HVCALL_SEND_IPI) { + if (!hc->fast) { + if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi, +@@ -2852,7 +2855,8 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vc + ent->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED; + ent->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; + ent->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; +- ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; ++ if (!vcpu || lapic_in_kernel(vcpu)) ++ ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; + ent->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED; + if (evmcs_ver) + ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; diff --git a/queue-6.12/mlxsw-add-return-value-check-for-mlxsw_sp_port_get_stats_raw.patch b/queue-6.12/mlxsw-add-return-value-check-for-mlxsw_sp_port_get_stats_raw.patch new file mode 100644 index 0000000000..4435c4dae4 --- /dev/null +++ b/queue-6.12/mlxsw-add-return-value-check-for-mlxsw_sp_port_get_stats_raw.patch @@ -0,0 +1,38 @@ +From fee5d688940690cc845937459e340e4e02598e90 Mon Sep 17 00:00:00 2001 +From: Wentao Liang +Date: Wed, 12 Feb 2025 23:23:11 +0800 +Subject: mlxsw: Add return value check for mlxsw_sp_port_get_stats_raw() + +From: Wentao Liang + +commit fee5d688940690cc845937459e340e4e02598e90 upstream. + +Add a check for the return value of mlxsw_sp_port_get_stats_raw() +in __mlxsw_sp_port_get_stats(). If mlxsw_sp_port_get_stats_raw() +returns an error, exit the function to prevent further processing +with potentially invalid data. + +Fixes: 614d509aa1e7 ("mlxsw: Move ethtool_ops to spectrum_ethtool.c") +Cc: stable@vger.kernel.org # 5.9+ +Signed-off-by: Wentao Liang +Reviewed-by: Petr Machata +Link: https://patch.msgid.link/20250212152311.1332-1-vulab@iscas.ac.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +@@ -768,7 +768,9 @@ static void __mlxsw_sp_port_get_stats(st + err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp); + if (err) + return; +- mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); ++ err = mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); ++ if (err) ++ return; + for (i = 0; i < len; i++) { + data[data_index + i] = hw_stats[i].getter(ppcnt_pl); + if (!hw_stats[i].cells_bytes) diff --git a/queue-6.12/mmc-mtk-sd-fix-register-settings-for-hs400-es-mode.patch b/queue-6.12/mmc-mtk-sd-fix-register-settings-for-hs400-es-mode.patch new file mode 100644 index 0000000000..9d9d64b4ea --- /dev/null +++ b/queue-6.12/mmc-mtk-sd-fix-register-settings-for-hs400-es-mode.patch @@ -0,0 +1,104 @@ +From 3e68abf2b9cebe76c6cd4b1aca8e95cd671035a3 Mon Sep 17 00:00:00 2001 +From: Andy-ld Lu +Date: Thu, 23 Jan 2025 17:26:01 +0800 +Subject: mmc: mtk-sd: Fix register settings for hs400(es) mode + +From: Andy-ld Lu + +commit 3e68abf2b9cebe76c6cd4b1aca8e95cd671035a3 upstream. + +For hs400(es) mode, the 'hs400-ds-delay' is typically configured in the +dts. However, some projects may only define 'mediatek,hs400-ds-dly3', +which can lead to initialization failures in hs400es mode. CMD13 reported +response crc error in the mmc_switch_status() just after switching to +hs400es mode. + +[ 1.914038][ T82] mmc0: mmc_select_hs400es failed, error -84 +[ 1.914954][ T82] mmc0: error -84 whilst initialising MMC card + +Currently, the hs400_ds_dly3 value is set within the tuning function. This +means that the PAD_DS_DLY3 field is not configured before tuning process, +which is the reason for the above-mentioned CMD13 response crc error. + +Move the PAD_DS_DLY3 field configuration into msdc_prepare_hs400_tuning(), +and add a value check of hs400_ds_delay to prevent overwriting by zero when +the 'hs400-ds-delay' is not set in the dts. In addition, since hs400(es) +only tune the PAD_DS_DLY1, the PAD_DS_DLY2_SEL bit should be cleared to +bypass it. + +Fixes: c4ac38c6539b ("mmc: mtk-sd: Add HS400 online tuning support") +Signed-off-by: Andy-ld Lu +Reviewed-by: AngeloGioacchino Del Regno +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20250123092644.7359-1-andy-ld.lu@mediatek.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/mtk-sd.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -263,6 +263,7 @@ + #define MSDC_PAD_TUNE_CMD2_SEL BIT(21) /* RW */ + + #define PAD_DS_TUNE_DLY_SEL BIT(0) /* RW */ ++#define PAD_DS_TUNE_DLY2_SEL BIT(1) /* RW */ + #define PAD_DS_TUNE_DLY1 GENMASK(6, 2) /* RW */ + #define PAD_DS_TUNE_DLY2 GENMASK(11, 7) /* RW */ + #define PAD_DS_TUNE_DLY3 GENMASK(16, 12) /* RW */ +@@ -308,6 +309,7 @@ + + /* EMMC50_PAD_DS_TUNE mask */ + #define PAD_DS_DLY_SEL BIT(16) /* RW */ ++#define PAD_DS_DLY2_SEL BIT(15) /* RW */ + #define PAD_DS_DLY1 GENMASK(14, 10) /* RW */ + #define PAD_DS_DLY3 GENMASK(4, 0) /* RW */ + +@@ -2361,13 +2363,23 @@ tune_done: + static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) + { + struct msdc_host *host = mmc_priv(mmc); ++ + host->hs400_mode = true; + +- if (host->top_base) +- writel(host->hs400_ds_delay, +- host->top_base + EMMC50_PAD_DS_TUNE); +- else +- writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); ++ if (host->top_base) { ++ if (host->hs400_ds_dly3) ++ sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE, ++ PAD_DS_DLY3, host->hs400_ds_dly3); ++ if (host->hs400_ds_delay) ++ writel(host->hs400_ds_delay, ++ host->top_base + EMMC50_PAD_DS_TUNE); ++ } else { ++ if (host->hs400_ds_dly3) ++ sdr_set_field(host->base + PAD_DS_TUNE, ++ PAD_DS_TUNE_DLY3, host->hs400_ds_dly3); ++ if (host->hs400_ds_delay) ++ writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); ++ } + /* hs400 mode must set it to 0 */ + sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS); + /* to improve read performance, set outstanding to 2 */ +@@ -2387,14 +2399,11 @@ static int msdc_execute_hs400_tuning(str + if (host->top_base) { + sdr_set_bits(host->top_base + EMMC50_PAD_DS_TUNE, + PAD_DS_DLY_SEL); +- if (host->hs400_ds_dly3) +- sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE, +- PAD_DS_DLY3, host->hs400_ds_dly3); ++ sdr_clr_bits(host->top_base + EMMC50_PAD_DS_TUNE, ++ PAD_DS_DLY2_SEL); + } else { + sdr_set_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY_SEL); +- if (host->hs400_ds_dly3) +- sdr_set_field(host->base + PAD_DS_TUNE, +- PAD_DS_TUNE_DLY3, host->hs400_ds_dly3); ++ sdr_clr_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY2_SEL); + } + + host->hs400_tuning = true; diff --git a/queue-6.12/objtool-rust-add-one-more-noreturn-rust-function.patch b/queue-6.12/objtool-rust-add-one-more-noreturn-rust-function.patch new file mode 100644 index 0000000000..d5f0a27278 --- /dev/null +++ b/queue-6.12/objtool-rust-add-one-more-noreturn-rust-function.patch @@ -0,0 +1,47 @@ +From cee6f9a9c87b6ecfb51845950c28216b231c3610 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Sun, 12 Jan 2025 15:39:51 +0100 +Subject: objtool/rust: add one more `noreturn` Rust function + +From: Miguel Ojeda + +commit cee6f9a9c87b6ecfb51845950c28216b231c3610 upstream. + +Starting with Rust 1.85.0 (currently in beta, to be released 2025-02-20), +under some kernel configurations with `CONFIG_RUST_DEBUG_ASSERTIONS=y`, +one may trigger a new `objtool` warning: + + rust/kernel.o: warning: objtool: _R...securityNtB2_11SecurityCtx8as_bytes() + falls through to next function _R...core3ops4drop4Drop4drop() + +due to a call to the `noreturn` symbol: + + core::panicking::assert_failed:: + +Thus add it to the list so that `objtool` knows it is actually `noreturn`. +Do so matching with `strstr` since it is a generic. + +See commit 56d680dd23c3 ("objtool/rust: list `noreturn` Rust functions") +for more details. + +Cc: stable@vger.kernel.org # Needed in 6.12.y and 6.13.y only (Rust is pinned in older LTSs). +Fixes: 56d680dd23c3 ("objtool/rust: list `noreturn` Rust functions") +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20250112143951.751139-1-ojeda@kernel.org +[ Updated Cc: stable@ to include 6.13.y. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + tools/objtool/check.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -218,6 +218,7 @@ static bool is_rust_noreturn(const struc + str_ends_with(func->name, "_4core9panicking18panic_bounds_check") || + str_ends_with(func->name, "_4core9panicking19assert_failed_inner") || + str_ends_with(func->name, "_4core9panicking36panic_misaligned_pointer_dereference") || ++ strstr(func->name, "_4core9panicking13assert_failed") || + strstr(func->name, "_4core9panicking11panic_const24panic_const_") || + (strstr(func->name, "_4core5slice5index24slice_") && + str_ends_with(func->name, "_fail")); diff --git a/queue-6.12/partitions-mac-fix-handling-of-bogus-partition-table.patch b/queue-6.12/partitions-mac-fix-handling-of-bogus-partition-table.patch new file mode 100644 index 0000000000..01b471dd4c --- /dev/null +++ b/queue-6.12/partitions-mac-fix-handling-of-bogus-partition-table.patch @@ -0,0 +1,69 @@ +From 80e648042e512d5a767da251d44132553fe04ae0 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Fri, 14 Feb 2025 02:39:50 +0100 +Subject: partitions: mac: fix handling of bogus partition table + +From: Jann Horn + +commit 80e648042e512d5a767da251d44132553fe04ae0 upstream. + +Fix several issues in partition probing: + + - The bailout for a bad partoffset must use put_dev_sector(), since the + preceding read_part_sector() succeeded. + - If the partition table claims a silly sector size like 0xfff bytes + (which results in partition table entries straddling sector boundaries), + bail out instead of accessing out-of-bounds memory. + - We must not assume that the partition table contains proper NUL + termination - use strnlen() and strncmp() instead of strlen() and + strcmp(). + +Cc: stable@vger.kernel.org +Signed-off-by: Jann Horn +Link: https://lore.kernel.org/r/20250214-partition-mac-v1-1-c1c626dffbd5@google.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/partitions/mac.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/block/partitions/mac.c ++++ b/block/partitions/mac.c +@@ -53,13 +53,25 @@ int mac_partition(struct parsed_partitio + } + secsize = be16_to_cpu(md->block_size); + put_dev_sector(sect); ++ ++ /* ++ * If the "block size" is not a power of 2, things get weird - we might ++ * end up with a partition straddling a sector boundary, so we wouldn't ++ * be able to read a partition entry with read_part_sector(). ++ * Real block sizes are probably (?) powers of two, so just require ++ * that. ++ */ ++ if (!is_power_of_2(secsize)) ++ return -1; + datasize = round_down(secsize, 512); + data = read_part_sector(state, datasize / 512, §); + if (!data) + return -1; + partoffset = secsize % 512; +- if (partoffset + sizeof(*part) > datasize) ++ if (partoffset + sizeof(*part) > datasize) { ++ put_dev_sector(sect); + return -1; ++ } + part = (struct mac_partition *) (data + partoffset); + if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { + put_dev_sector(sect); +@@ -112,8 +124,8 @@ int mac_partition(struct parsed_partitio + int i, l; + + goodness++; +- l = strlen(part->name); +- if (strcmp(part->name, "/") == 0) ++ l = strnlen(part->name, sizeof(part->name)); ++ if (strncmp(part->name, "/", sizeof(part->name)) == 0) + goodness++; + for (i = 0; i <= l - 4; ++i) { + if (strncasecmp(part->name + i, "root", diff --git a/queue-6.12/pci-avoid-flr-for-mediatek-mt7922-wifi.patch b/queue-6.12/pci-avoid-flr-for-mediatek-mt7922-wifi.patch new file mode 100644 index 0000000000..67eeed3cc3 --- /dev/null +++ b/queue-6.12/pci-avoid-flr-for-mediatek-mt7922-wifi.patch @@ -0,0 +1,81 @@ +From 81f64e925c29fe6e99f04b131fac1935ac931e81 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Wed, 12 Feb 2025 13:35:16 -0600 +Subject: PCI: Avoid FLR for Mediatek MT7922 WiFi +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjorn Helgaas + +commit 81f64e925c29fe6e99f04b131fac1935ac931e81 upstream. + +The Mediatek MT7922 WiFi device advertises FLR support, but it apparently +does not work, and all subsequent config reads return ~0: + + pci 0000:01:00.0: [14c3:0616] type 00 class 0x028000 PCIe Endpoint + pciback 0000:01:00.0: not ready 65535ms after FLR; giving up + +After an FLR, pci_dev_wait() waits for the device to become ready. Prior +to d591f6804e7e ("PCI: Wait for device readiness with Configuration RRS"), +it polls PCI_COMMAND until it is something other that PCI_POSSIBLE_ERROR +(~0). If it times out, pci_dev_wait() returns -ENOTTY and +__pci_reset_function_locked() tries the next available reset method. +Typically this is Secondary Bus Reset, which does work, so the MT7922 is +eventually usable. + +After d591f6804e7e, if Configuration Request Retry Status Software +Visibility (RRS SV) is enabled, pci_dev_wait() polls PCI_VENDOR_ID until it +is something other than the special 0x0001 Vendor ID that indicates a +completion with RRS status. + +When RRS SV is enabled, reads of PCI_VENDOR_ID should return either 0x0001, +i.e., the config read was completed with RRS, or a valid Vendor ID. On the +MT7922, it seems that all config reads after FLR return ~0 indefinitely. +When pci_dev_wait() reads PCI_VENDOR_ID and gets 0xffff, it assumes that's +a valid Vendor ID and the device is now ready, so it returns with success. + +After pci_dev_wait() returns success, we restore config space and continue. +Since the MT7922 is not actually ready after the FLR, the restore fails and +the device is unusable. + +We considered changing pci_dev_wait() to continue polling if a +PCI_VENDOR_ID read returns either 0x0001 or 0xffff. This "works" as it did +before d591f6804e7e, although we have to wait for the timeout and then fall +back to SBR. But it doesn't work for SR-IOV VFs, which *always* return +0xffff as the Vendor ID. + +Mark Mediatek MT7922 WiFi devices to avoid the use of FLR completely. This +will cause fallback to another reset method, such as SBR. + +Link: https://lore.kernel.org/r/20250212193516.88741-1-helgaas@kernel.org +Fixes: d591f6804e7e ("PCI: Wait for device readiness with Configuration RRS") +Link: https://github.com/QubesOS/qubes-issues/issues/9689#issuecomment-2582927149 +Link: https://lore.kernel.org/r/Z4pHll_6GX7OUBzQ@mail-itl +Signed-off-by: Bjorn Helgaas +Tested-by: Marek Marczykowski-Górecki +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5522,7 +5522,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IN + * AMD Matisse USB 3.0 Host Controller 0x149c + * Intel 82579LM Gigabit Ethernet Controller 0x1502 + * Intel 82579V Gigabit Ethernet Controller 0x1503 +- * ++ * Mediatek MT7922 802.11ax PCI Express Wireless Network Adapter + */ + static void quirk_no_flr(struct pci_dev *dev) + { +@@ -5534,6 +5534,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AM + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x7901, quirk_no_flr); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_no_flr); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_no_flr); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MEDIATEK, 0x0616, quirk_no_flr); + + /* FLR may cause the SolidRun SNET DPU (rev 0x1) to hang */ + static void quirk_no_flr_snet(struct pci_dev *dev) diff --git a/queue-6.12/perf-x86-intel-ensure-lbrs-are-disabled-when-a-cpu-is-starting.patch b/queue-6.12/perf-x86-intel-ensure-lbrs-are-disabled-when-a-cpu-is-starting.patch new file mode 100644 index 0000000000..c9fe941fd1 --- /dev/null +++ b/queue-6.12/perf-x86-intel-ensure-lbrs-are-disabled-when-a-cpu-is-starting.patch @@ -0,0 +1,56 @@ +From c631a2de7ae48d50434bdc205d901423f8577c65 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Thu, 30 Jan 2025 17:07:21 -0800 +Subject: perf/x86/intel: Ensure LBRs are disabled when a CPU is starting + +From: Sean Christopherson + +commit c631a2de7ae48d50434bdc205d901423f8577c65 upstream. + +Explicitly clear DEBUGCTL.LBR when a CPU is starting, prior to purging the +LBR MSRs themselves, as at least one system has been found to transfer +control to the kernel with LBRs enabled (it's unclear whether it's a BIOS +flaw or a CPU goof). Because the kernel preserves the original DEBUGCTL, +even when toggling LBRs, leaving DEBUGCTL.LBR as is results in running +with LBRs enabled at all times. + +Closes: https://lore.kernel.org/all/c9d8269bff69f6359731d758e3b1135dedd7cc61.camel@redhat.com +Reported-by: Maxim Levitsky +Signed-off-by: Sean Christopherson +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Maxim Levitsky +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20250131010721.470503-1-seanjc@google.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/events/intel/core.c | 5 ++++- + arch/x86/include/asm/msr-index.h | 3 ++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4993,8 +4993,11 @@ static void intel_pmu_cpu_starting(int c + + init_debug_store_on_cpu(cpu); + /* +- * Deal with CPUs that don't clear their LBRs on power-up. ++ * Deal with CPUs that don't clear their LBRs on power-up, and that may ++ * even boot with LBRs enabled. + */ ++ if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr) ++ msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT); + intel_pmu_lbr_reset(); + + cpuc->lbr_sel = NULL; +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -395,7 +395,8 @@ + #define MSR_IA32_PASID_VALID BIT_ULL(31) + + /* DEBUGCTLMSR bits (others vary by model): */ +-#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ ++#define DEBUGCTLMSR_LBR_BIT 0 /* last branch recording */ ++#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT) + #define DEBUGCTLMSR_BTF_SHIFT 1 + #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ + #define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2) diff --git a/queue-6.12/perf-x86-intel-fix-arch_perfmon_num_counter_leaf.patch b/queue-6.12/perf-x86-intel-fix-arch_perfmon_num_counter_leaf.patch new file mode 100644 index 0000000000..32c2738e19 --- /dev/null +++ b/queue-6.12/perf-x86-intel-fix-arch_perfmon_num_counter_leaf.patch @@ -0,0 +1,103 @@ +From 47a973fd75639fe80d59f9e1860113bb2a0b112b Mon Sep 17 00:00:00 2001 +From: Kan Liang +Date: Wed, 29 Jan 2025 07:48:19 -0800 +Subject: perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF + +From: Kan Liang + +commit 47a973fd75639fe80d59f9e1860113bb2a0b112b upstream. + +The EAX of the CPUID Leaf 023H enumerates the mask of valid sub-leaves. +To tell the availability of the sub-leaf 1 (enumerate the counter mask), +perf should check the bit 1 (0x2) of EAS, rather than bit 0 (0x1). + +The error is not user-visible on bare metal. Because the sub-leaf 0 and +the sub-leaf 1 are always available. However, it may bring issues in a +virtualization environment when a VMM only enumerates the sub-leaf 0. + +Introduce the cpuid35_e?x to replace the macros, which makes the +implementation style consistent. + +Fixes: eb467aaac21e ("perf/x86/intel: Support Architectural PerfMon Extension leaf") +Signed-off-by: Kan Liang +Signed-off-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20250129154820.3755948-3-kan.liang@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/events/intel/core.c | 18 ++++++++++-------- + arch/x86/include/asm/perf_event.h | 28 +++++++++++++++++++++++++--- + 2 files changed, 35 insertions(+), 11 deletions(-) + +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4865,20 +4865,22 @@ static inline bool intel_pmu_broken_perf + + static void update_pmu_cap(struct x86_hybrid_pmu *pmu) + { +- unsigned int sub_bitmaps, eax, ebx, ecx, edx; ++ unsigned int cntr, fixed_cntr, ecx, edx; ++ union cpuid35_eax eax; ++ union cpuid35_ebx ebx; + +- cpuid(ARCH_PERFMON_EXT_LEAF, &sub_bitmaps, &ebx, &ecx, &edx); ++ cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx); + +- if (ebx & ARCH_PERFMON_EXT_UMASK2) ++ if (ebx.split.umask2) + pmu->config_mask |= ARCH_PERFMON_EVENTSEL_UMASK2; +- if (ebx & ARCH_PERFMON_EXT_EQ) ++ if (ebx.split.eq) + pmu->config_mask |= ARCH_PERFMON_EVENTSEL_EQ; + +- if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) { ++ if (eax.split.cntr_subleaf) { + cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF, +- &eax, &ebx, &ecx, &edx); +- pmu->cntr_mask64 = eax; +- pmu->fixed_cntr_mask64 = ebx; ++ &cntr, &fixed_cntr, &ecx, &edx); ++ pmu->cntr_mask64 = cntr; ++ pmu->fixed_cntr_mask64 = fixed_cntr; + } + + if (!intel_pmu_broken_perf_cap()) { +--- a/arch/x86/include/asm/perf_event.h ++++ b/arch/x86/include/asm/perf_event.h +@@ -187,11 +187,33 @@ union cpuid10_edx { + * detection/enumeration details: + */ + #define ARCH_PERFMON_EXT_LEAF 0x00000023 +-#define ARCH_PERFMON_EXT_UMASK2 0x1 +-#define ARCH_PERFMON_EXT_EQ 0x2 +-#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1 + #define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1 + ++union cpuid35_eax { ++ struct { ++ unsigned int leaf0:1; ++ /* Counters Sub-Leaf */ ++ unsigned int cntr_subleaf:1; ++ /* Auto Counter Reload Sub-Leaf */ ++ unsigned int acr_subleaf:1; ++ /* Events Sub-Leaf */ ++ unsigned int events_subleaf:1; ++ unsigned int reserved:28; ++ } split; ++ unsigned int full; ++}; ++ ++union cpuid35_ebx { ++ struct { ++ /* UnitMask2 Supported */ ++ unsigned int umask2:1; ++ /* EQ-bit Supported */ ++ unsigned int eq:1; ++ unsigned int reserved:30; ++ } split; ++ unsigned int full; ++}; ++ + /* + * Intel Architectural LBR CPUID detection/enumeration details: + */ diff --git a/queue-6.12/regmap-irq-add-missing-kfree.patch b/queue-6.12/regmap-irq-add-missing-kfree.patch new file mode 100644 index 0000000000..0d11b8b603 --- /dev/null +++ b/queue-6.12/regmap-irq-add-missing-kfree.patch @@ -0,0 +1,40 @@ +From 32ffed055dcee17f6705f545b069e44a66067808 Mon Sep 17 00:00:00 2001 +From: Jiasheng Jiang +Date: Wed, 5 Feb 2025 00:43:43 +0000 +Subject: regmap-irq: Add missing kfree() + +From: Jiasheng Jiang + +commit 32ffed055dcee17f6705f545b069e44a66067808 upstream. + +Add kfree() for "d->main_status_buf" to the error-handling path to prevent +a memory leak. + +Fixes: a2d21848d921 ("regmap: regmap-irq: Add main status register support") +Cc: stable@vger.kernel.org # v5.1+ +Signed-off-by: Jiasheng Jiang +Link: https://patch.msgid.link/20250205004343.14413-1-jiashengjiangcool@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/regmap/regmap-irq.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/base/regmap/regmap-irq.c ++++ b/drivers/base/regmap/regmap-irq.c +@@ -909,6 +909,7 @@ err_alloc: + kfree(d->wake_buf); + kfree(d->mask_buf_def); + kfree(d->mask_buf); ++ kfree(d->main_status_buf); + kfree(d->status_buf); + kfree(d->status_reg_buf); + if (d->config_buf) { +@@ -984,6 +985,7 @@ void regmap_del_irq_chip(int irq, struct + kfree(d->wake_buf); + kfree(d->mask_buf_def); + kfree(d->mask_buf); ++ kfree(d->main_status_buf); + kfree(d->status_reg_buf); + kfree(d->status_buf); + if (d->config_buf) { diff --git a/queue-6.12/regulator-qcom_smd-add-l2-l5-sub-node-to-mp5496-regulator.patch b/queue-6.12/regulator-qcom_smd-add-l2-l5-sub-node-to-mp5496-regulator.patch new file mode 100644 index 0000000000..42c7bd058b --- /dev/null +++ b/queue-6.12/regulator-qcom_smd-add-l2-l5-sub-node-to-mp5496-regulator.patch @@ -0,0 +1,32 @@ +From b0eddc21900fb44f8c5db95710479865e3700fbd Mon Sep 17 00:00:00 2001 +From: Varadarajan Narayanan +Date: Wed, 5 Feb 2025 13:16:56 +0530 +Subject: regulator: qcom_smd: Add l2, l5 sub-node to mp5496 regulator + +From: Varadarajan Narayanan + +commit b0eddc21900fb44f8c5db95710479865e3700fbd upstream. + +Adding l2, l5 sub-node entry to mp5496 regulator node. + +Cc: stable@vger.kernel.org +Acked-by: Rob Herring +Signed-off-by: Varadarajan Narayanan +Link: https://patch.msgid.link/20250205074657.4142365-2-quic_varada@quicinc.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml ++++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +@@ -22,7 +22,7 @@ description: + Each sub-node is identified using the node's name, with valid values listed + for each of the pmics below. + +- For mp5496, s1, s2 ++ For mp5496, s1, s2, l2, l5 + + For pm2250, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, + l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22 diff --git a/queue-6.12/ring-buffer-unlock-resize-on-mmap-error.patch b/queue-6.12/ring-buffer-unlock-resize-on-mmap-error.patch new file mode 100644 index 0000000000..01f2609e51 --- /dev/null +++ b/queue-6.12/ring-buffer-unlock-resize-on-mmap-error.patch @@ -0,0 +1,36 @@ +From 9ba0e1755a40f9920ad0f4168031291b3eb58d7b Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Thu, 13 Feb 2025 13:19:57 -0500 +Subject: ring-buffer: Unlock resize on mmap error + +From: Steven Rostedt + +commit 9ba0e1755a40f9920ad0f4168031291b3eb58d7b upstream. + +Memory mapping the tracing ring buffer will disable resizing the buffer. +But if there's an error in the memory mapping like an invalid parameter, +the function exits out without re-enabling the resizing of the ring +buffer, preventing the ring buffer from being resized after that. + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mathieu Desnoyers +Cc: Vincent Donnefort +Link: https://lore.kernel.org/20250213131957.530ec3c5@gandalf.local.home +Fixes: 117c39200d9d7 ("ring-buffer: Introducing ring-buffer mapping functions") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -7157,6 +7157,7 @@ int ring_buffer_map(struct trace_buffer + kfree(cpu_buffer->subbuf_ids); + cpu_buffer->subbuf_ids = NULL; + rb_free_meta_page(cpu_buffer); ++ atomic_dec(&cpu_buffer->resize_disabled); + } + + unlock: diff --git a/queue-6.12/ring-buffer-update-pages_touched-to-reflect-persistent-buffer-content.patch b/queue-6.12/ring-buffer-update-pages_touched-to-reflect-persistent-buffer-content.patch new file mode 100644 index 0000000000..ff97e8d572 --- /dev/null +++ b/queue-6.12/ring-buffer-update-pages_touched-to-reflect-persistent-buffer-content.patch @@ -0,0 +1,46 @@ +From 97937834ae876f29565415ab15f1284666dc6be3 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 14 Feb 2025 12:35:12 -0500 +Subject: ring-buffer: Update pages_touched to reflect persistent buffer content + +From: Steven Rostedt + +commit 97937834ae876f29565415ab15f1284666dc6be3 upstream. + +The pages_touched field represents the number of subbuffers in the ring +buffer that have content that can be read. This is used in accounting of +"dirty_pages" and "buffer_percent" to allow the user to wait for the +buffer to be filled to a certain amount before it reads the buffer in +blocking mode. + +The persistent buffer never updated this value so it was set to zero, and +this accounting would take it as it had no content. This would cause user +space to wait for content even though there's enough content in the ring +buffer that satisfies the buffer_percent. + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mathieu Desnoyers +Cc: Vincent Donnefort +Link: https://lore.kernel.org/20250214123512.0631436e@gandalf.local.home +Fixes: 5f3b6e839f3ce ("ring-buffer: Validate boot range memory events") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -1850,6 +1850,11 @@ static void rb_meta_validate_events(stru + cpu_buffer->cpu); + goto invalid; + } ++ ++ /* If the buffer has content, update pages_touched */ ++ if (ret) ++ local_inc(&cpu_buffer->pages_touched); ++ + entries += ret; + entry_bytes += local_read(&head_page->page->commit); + local_set(&cpu_buffer->head_page->entries, ret); diff --git a/queue-6.12/ring-buffer-validate-the-persistent-meta-data-subbuf-array.patch b/queue-6.12/ring-buffer-validate-the-persistent-meta-data-subbuf-array.patch new file mode 100644 index 0000000000..698d391332 --- /dev/null +++ b/queue-6.12/ring-buffer-validate-the-persistent-meta-data-subbuf-array.patch @@ -0,0 +1,124 @@ +From f5b95f1fa2ef3a03f49eeec658ba97e721412b32 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 14 Feb 2025 10:28:20 -0500 +Subject: ring-buffer: Validate the persistent meta data subbuf array + +From: Steven Rostedt + +commit f5b95f1fa2ef3a03f49eeec658ba97e721412b32 upstream. + +The meta data for a mapped ring buffer contains an array of indexes of all +the subbuffers. The first entry is the reader page, and the rest of the +entries lay out the order of the subbuffers in how the ring buffer link +list is to be created. + +The validator currently makes sure that all the entries are within the +range of 0 and nr_subbufs. But it does not check if there are any +duplicates. + +While working on the ring buffer, I corrupted this array, where I added +duplicates. The validator did not catch it and created the ring buffer +link list on top of it. Luckily, the corruption was only that the reader +page was also in the writer path and only presented corrupted data but did +not crash the kernel. But if there were duplicates in the writer side, +then it could corrupt the ring buffer link list and cause a crash. + +Create a bitmask array with the size of the number of subbuffers. Then +clear it. When walking through the subbuf array checking to see if the +entries are within the range, test if its bit is already set in the +subbuf_mask. If it is, then there is duplicates and fail the validation. +If not, set the corresponding bit and continue. + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mathieu Desnoyers +Cc: Vincent Donnefort +Link: https://lore.kernel.org/20250214102820.7509ddea@gandalf.local.home +Fixes: c76883f18e59b ("ring-buffer: Add test if range of boot buffer is valid") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index 07b421115692..0419d41a2060 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -1672,7 +1672,8 @@ static void *rb_range_buffer(struct ring_buffer_per_cpu *cpu_buffer, int idx) + * must be the same. + */ + static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu, +- struct trace_buffer *buffer, int nr_pages) ++ struct trace_buffer *buffer, int nr_pages, ++ unsigned long *subbuf_mask) + { + int subbuf_size = PAGE_SIZE; + struct buffer_data_page *subbuf; +@@ -1680,6 +1681,9 @@ static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu, + unsigned long buffers_end; + int i; + ++ if (!subbuf_mask) ++ return false; ++ + /* Check the meta magic and meta struct size */ + if (meta->magic != RING_BUFFER_META_MAGIC || + meta->struct_size != sizeof(*meta)) { +@@ -1712,6 +1716,8 @@ static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu, + + subbuf = rb_subbufs_from_meta(meta); + ++ bitmap_clear(subbuf_mask, 0, meta->nr_subbufs); ++ + /* Is the meta buffers and the subbufs themselves have correct data? */ + for (i = 0; i < meta->nr_subbufs; i++) { + if (meta->buffers[i] < 0 || +@@ -1725,6 +1731,12 @@ static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu, + return false; + } + ++ if (test_bit(meta->buffers[i], subbuf_mask)) { ++ pr_info("Ring buffer boot meta [%d] array has duplicates\n", cpu); ++ return false; ++ } ++ ++ set_bit(meta->buffers[i], subbuf_mask); + subbuf = (void *)subbuf + subbuf_size; + } + +@@ -1889,17 +1901,22 @@ static void rb_meta_init_text_addr(struct ring_buffer_meta *meta) + static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages) + { + struct ring_buffer_meta *meta; ++ unsigned long *subbuf_mask; + unsigned long delta; + void *subbuf; + int cpu; + int i; + ++ /* Create a mask to test the subbuf array */ ++ subbuf_mask = bitmap_alloc(nr_pages + 1, GFP_KERNEL); ++ /* If subbuf_mask fails to allocate, then rb_meta_valid() will return false */ ++ + for (cpu = 0; cpu < nr_cpu_ids; cpu++) { + void *next_meta; + + meta = rb_range_meta(buffer, nr_pages, cpu); + +- if (rb_meta_valid(meta, cpu, buffer, nr_pages)) { ++ if (rb_meta_valid(meta, cpu, buffer, nr_pages, subbuf_mask)) { + /* Make the mappings match the current address */ + subbuf = rb_subbufs_from_meta(meta); + delta = (unsigned long)subbuf - meta->first_buffer; +@@ -1943,6 +1960,7 @@ static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages) + subbuf += meta->subbuf_size; + } + } ++ bitmap_free(subbuf_mask); + } + + static void *rbm_start(struct seq_file *m, loff_t *pos) +-- +2.48.1 + diff --git a/queue-6.12/rust-rbtree-fix-overindented-list-item.patch b/queue-6.12/rust-rbtree-fix-overindented-list-item.patch new file mode 100644 index 0000000000..ae27f42169 --- /dev/null +++ b/queue-6.12/rust-rbtree-fix-overindented-list-item.patch @@ -0,0 +1,58 @@ +From 2e4f982cf392af2f1282b5537a72144e064799e3 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Fri, 7 Feb 2025 00:20:22 +0100 +Subject: rust: rbtree: fix overindented list item + +From: Miguel Ojeda + +commit 2e4f982cf392af2f1282b5537a72144e064799e3 upstream. + +Starting with Rust 1.86.0 (to be released 2025-04-03), Clippy will have +a new lint, `doc_overindented_list_items` [1], which catches cases of +overindented list items. + +The lint has been added by Yutaro Ohno, based on feedback from the kernel +[2] on a patch that fixed a similar case -- commit 0c5928deada1 ("rust: +block: fix formatting in GenDisk doc"). + +Clippy reports a few cases in the kernel, apart from the one already +fixed in the commit above. One is this one: + + error: doc list item overindented + --> rust/kernel/rbtree.rs:1152:5 + | + 1152 | /// null, it is a pointer to the root of the [`RBTree`]. + | ^^^^ help: try using ` ` (2 spaces) + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_overindented_list_items + = note: `-D clippy::doc-overindented-list-items` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_overindented_list_items)]` + +Thus clean it up. + +Cc: Yutaro Ohno +Cc: stable@vger.kernel.org # Needed in 6.12.y and 6.13.y only (Rust is pinned in older LTSs). +Fixes: a335e9591404 ("rust: rbtree: add `RBTree::entry`") +Link: https://github.com/rust-lang/rust-clippy/pull/13711 [1] +Link: https://github.com/rust-lang/rust-clippy/issues/13601 [2] +Reviewed-by: Alice Ryhl +Reviewed-by: Yutaro Ohno +Link: https://lore.kernel.org/r/20250206232022.599998-1-ojeda@kernel.org +[ There are a few other cases, so updated message. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/rbtree.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/rbtree.rs ++++ b/rust/kernel/rbtree.rs +@@ -1147,7 +1147,7 @@ pub struct VacantEntry<'a, K, V> { + /// # Invariants + /// - `parent` may be null if the new node becomes the root. + /// - `child_field_of_parent` is a valid pointer to the left-child or right-child of `parent`. If `parent` is +-/// null, it is a pointer to the root of the [`RBTree`]. ++/// null, it is a pointer to the root of the [`RBTree`]. + struct RawVacantEntry<'a, K, V> { + rbtree: *mut RBTree, + /// The node that will become the parent of the new node if we insert one. diff --git a/queue-6.12/s390-pci-fix-handling-of-isolated-vfs.patch b/queue-6.12/s390-pci-fix-handling-of-isolated-vfs.patch new file mode 100644 index 0000000000..883a1c27f3 --- /dev/null +++ b/queue-6.12/s390-pci-fix-handling-of-isolated-vfs.patch @@ -0,0 +1,106 @@ +From 2844ddbd540fc84d7571cca65d6c43088e4d6952 Mon Sep 17 00:00:00 2001 +From: Niklas Schnelle +Date: Fri, 7 Feb 2025 13:30:17 +0100 +Subject: s390/pci: Fix handling of isolated VFs + +From: Niklas Schnelle + +commit 2844ddbd540fc84d7571cca65d6c43088e4d6952 upstream. + +In contrast to the commit message of the fixed commit VFs whose parent +PF is not configured are not always isolated, that is put on their own +PCI domain. This is because for VFs to be added to an existing PCI +domain it is enough for that PCI domain to share the same topology ID or +PCHID. Such a matching PCI domain without a parent PF may exist when +a PF from the same PCI card created the domain with the VF being a child +of a different, non accessible, PF. While not causing technical issues +it makes the rules which VFs are isolated inconsistent. + +Fix this by explicitly checking that the parent PF exists on the PCI +domain determined by the topology ID or PCHID before registering the VF. +This works because a parent PF which is under control of this Linux +instance must be enabled and configured at the point where its child VFs +appear because otherwise SR-IOV could not have been enabled on the +parent. + +Fixes: 25f39d3dcb48 ("s390/pci: Ignore RID for isolated VFs") +Cc: stable@vger.kernel.org +Reviewed-by: Halil Pasic +Signed-off-by: Niklas Schnelle +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/pci/pci_bus.c | 20 ++++++++++++++++++++ + arch/s390/pci/pci_iov.c | 2 +- + arch/s390/pci/pci_iov.h | 7 +++++++ + 3 files changed, 28 insertions(+), 1 deletion(-) + +--- a/arch/s390/pci/pci_bus.c ++++ b/arch/s390/pci/pci_bus.c +@@ -331,6 +331,17 @@ error: + return rc; + } + ++static bool zpci_bus_is_isolated_vf(struct zpci_bus *zbus, struct zpci_dev *zdev) ++{ ++ struct pci_dev *pdev; ++ ++ pdev = zpci_iov_find_parent_pf(zbus, zdev); ++ if (!pdev) ++ return true; ++ pci_dev_put(pdev); ++ return false; ++} ++ + int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops) + { + bool topo_is_tid = zdev->tid_avail; +@@ -345,6 +356,15 @@ int zpci_bus_device_register(struct zpci + + topo = topo_is_tid ? zdev->tid : zdev->pchid; + zbus = zpci_bus_get(topo, topo_is_tid); ++ /* ++ * An isolated VF gets its own domain/bus even if there exists ++ * a matching domain/bus already ++ */ ++ if (zbus && zpci_bus_is_isolated_vf(zbus, zdev)) { ++ zpci_bus_put(zbus); ++ zbus = NULL; ++ } ++ + if (!zbus) { + zbus = zpci_bus_alloc(topo, topo_is_tid); + if (!zbus) +--- a/arch/s390/pci/pci_iov.c ++++ b/arch/s390/pci/pci_iov.c +@@ -74,7 +74,7 @@ static int zpci_iov_link_virtfn(struct p + * found. If the function is not a VF or has no RequesterID information, + * NULL is returned as well. + */ +-static struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev) ++struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev) + { + int i, vfid, devfn, cand_devfn; + struct pci_dev *pdev; +--- a/arch/s390/pci/pci_iov.h ++++ b/arch/s390/pci/pci_iov.h +@@ -17,6 +17,8 @@ void zpci_iov_map_resources(struct pci_d + + int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn); + ++struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev); ++ + #else /* CONFIG_PCI_IOV */ + static inline void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn) {} + +@@ -26,5 +28,10 @@ static inline int zpci_iov_setup_virtfn( + { + return 0; + } ++ ++static inline struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev) ++{ ++ return NULL; ++} + #endif /* CONFIG_PCI_IOV */ + #endif /* __S390_PCI_IOV_h */ diff --git a/queue-6.12/s390-pci-pull-search-for-parent-pf-out-of-zpci_iov_setup_virtfn.patch b/queue-6.12/s390-pci-pull-search-for-parent-pf-out-of-zpci_iov_setup_virtfn.patch new file mode 100644 index 0000000000..7181ee917a --- /dev/null +++ b/queue-6.12/s390-pci-pull-search-for-parent-pf-out-of-zpci_iov_setup_virtfn.patch @@ -0,0 +1,110 @@ +From 05793884a1f30509e477de9da233ab73584b1c8c Mon Sep 17 00:00:00 2001 +From: Niklas Schnelle +Date: Fri, 7 Feb 2025 13:30:16 +0100 +Subject: s390/pci: Pull search for parent PF out of zpci_iov_setup_virtfn() + +From: Niklas Schnelle + +commit 05793884a1f30509e477de9da233ab73584b1c8c upstream. + +This creates a new zpci_iov_find_parent_pf() function which a future +commit can use to find if a VF has a configured parent PF. Use +zdev->rid instead of zdev->devfn such that the new function can be used +before it has been decided if the RID will be exposed and zdev->devfn is +set. Also handle the hypotheical case that the RID is not available but +there is an otherwise matching zbus. + +Fixes: 25f39d3dcb48 ("s390/pci: Ignore RID for isolated VFs") +Cc: stable@vger.kernel.org +Reviewed-by: Halil Pasic +Signed-off-by: Niklas Schnelle +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/pci/pci_iov.c | 56 ++++++++++++++++++++++++++++++----------- + 1 file changed, 42 insertions(+), 14 deletions(-) + +diff --git a/arch/s390/pci/pci_iov.c b/arch/s390/pci/pci_iov.c +index ead062bf2b41..c7fdf5e79b3c 100644 +--- a/arch/s390/pci/pci_iov.c ++++ b/arch/s390/pci/pci_iov.c +@@ -60,18 +60,35 @@ static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, in + return 0; + } + +-int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn) ++/** ++ * zpci_iov_find_parent_pf - Find the parent PF, if any, of the given function ++ * @zbus: The bus that the PCI function is on, or would be added on ++ * @zdev: The PCI function ++ * ++ * Finds the parent PF, if it exists and is configured, of the given PCI function ++ * and increments its refcount. Th PF is searched for on the provided bus so the ++ * caller has to ensure that this is the correct bus to search. This function may ++ * be used before adding the PCI function to a zbus. ++ * ++ * Return: Pointer to the struct pci_dev of the parent PF or NULL if it not ++ * found. If the function is not a VF or has no RequesterID information, ++ * NULL is returned as well. ++ */ ++static struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev) + { +- int i, cand_devfn; +- struct zpci_dev *zdev; ++ int i, vfid, devfn, cand_devfn; + struct pci_dev *pdev; +- int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/ +- int rc = 0; + + if (!zbus->multifunction) +- return 0; +- +- /* If the parent PF for the given VF is also configured in the ++ return NULL; ++ /* Non-VFs and VFs without RID available don't have a parent */ ++ if (!zdev->vfn || !zdev->rid_available) ++ return NULL; ++ /* Linux vfid starts at 0 vfn at 1 */ ++ vfid = zdev->vfn - 1; ++ devfn = zdev->rid & ZPCI_RID_MASK_DEVFN; ++ /* ++ * If the parent PF for the given VF is also configured in the + * instance, it must be on the same zbus. + * We can then identify the parent PF by checking what + * devfn the VF would have if it belonged to that PF using the PF's +@@ -85,15 +102,26 @@ int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn + if (!pdev) + continue; + cand_devfn = pci_iov_virtfn_devfn(pdev, vfid); +- if (cand_devfn == virtfn->devfn) { +- rc = zpci_iov_link_virtfn(pdev, virtfn, vfid); +- /* balance pci_get_slot() */ +- pci_dev_put(pdev); +- break; +- } ++ if (cand_devfn == devfn) ++ return pdev; + /* balance pci_get_slot() */ + pci_dev_put(pdev); + } + } ++ return NULL; ++} ++ ++int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn) ++{ ++ struct zpci_dev *zdev = to_zpci(virtfn); ++ struct pci_dev *pdev_pf; ++ int rc = 0; ++ ++ pdev_pf = zpci_iov_find_parent_pf(zbus, zdev); ++ if (pdev_pf) { ++ /* Linux' vfids start at 0 while zdev->vfn starts at 1 */ ++ rc = zpci_iov_link_virtfn(pdev_pf, virtfn, zdev->vfn - 1); ++ pci_dev_put(pdev_pf); ++ } + return rc; + } +-- +2.48.1 + diff --git a/queue-6.12/sched_ext-fix-incorrect-autogroup-migration-detection.patch b/queue-6.12/sched_ext-fix-incorrect-autogroup-migration-detection.patch new file mode 100644 index 0000000000..156d061b0e --- /dev/null +++ b/queue-6.12/sched_ext-fix-incorrect-autogroup-migration-detection.patch @@ -0,0 +1,164 @@ +From d6f3e7d564b2309e1f17e709a70eca78d7ca2bb8 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Fri, 24 Jan 2025 12:22:12 -1000 +Subject: sched_ext: Fix incorrect autogroup migration detection + +From: Tejun Heo + +commit d6f3e7d564b2309e1f17e709a70eca78d7ca2bb8 upstream. + +scx_move_task() is called from sched_move_task() and tells the BPF scheduler +that cgroup migration is being committed. sched_move_task() is used by both +cgroup and autogroup migrations and scx_move_task() tried to filter out +autogroup migrations by testing the destination cgroup and PF_EXITING but +this is not enough. In fact, without explicitly tagging the thread which is +doing the cgroup migration, there is no good way to tell apart +scx_move_task() invocations for racing migration to the root cgroup and an +autogroup migration. + +This led to scx_move_task() incorrectly ignoring a migration from non-root +cgroup to an autogroup of the root cgroup triggering the following warning: + + WARNING: CPU: 7 PID: 1 at kernel/sched/ext.c:3725 scx_cgroup_can_attach+0x196/0x340 + ... + Call Trace: + + cgroup_migrate_execute+0x5b1/0x700 + cgroup_attach_task+0x296/0x400 + __cgroup_procs_write+0x128/0x140 + cgroup_procs_write+0x17/0x30 + kernfs_fop_write_iter+0x141/0x1f0 + vfs_write+0x31d/0x4a0 + __x64_sys_write+0x72/0xf0 + do_syscall_64+0x82/0x160 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fix it by adding an argument to sched_move_task() that indicates whether the +moving is for a cgroup or autogroup migration. After the change, +scx_move_task() is called only for cgroup migrations and renamed to +scx_cgroup_move_task(). + +Link: https://github.com/sched-ext/scx/issues/370 +Fixes: 819513666966 ("sched_ext: Add cgroup support") +Cc: stable@vger.kernel.org # v6.12+ +Acked-by: Peter Zijlstra (Intel) +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sched/autogroup.c | 4 ++-- + kernel/sched/core.c | 7 ++++--- + kernel/sched/ext.c | 15 +-------------- + kernel/sched/ext.h | 4 ++-- + kernel/sched/sched.h | 2 +- + 5 files changed, 10 insertions(+), 22 deletions(-) + +--- a/kernel/sched/autogroup.c ++++ b/kernel/sched/autogroup.c +@@ -150,7 +150,7 @@ void sched_autogroup_exit_task(struct ta + * see this thread after that: we can no longer use signal->autogroup. + * See the PF_EXITING check in task_wants_autogroup(). + */ +- sched_move_task(p); ++ sched_move_task(p, true); + } + + static void +@@ -182,7 +182,7 @@ autogroup_move_group(struct task_struct + * sched_autogroup_exit_task(). + */ + for_each_thread(p, t) +- sched_move_task(t); ++ sched_move_task(t, true); + + unlock_task_sighand(p, &flags); + autogroup_kref_put(prev); +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -8953,7 +8953,7 @@ static void sched_change_group(struct ta + * now. This function just updates tsk->se.cfs_rq and tsk->se.parent to reflect + * its new group. + */ +-void sched_move_task(struct task_struct *tsk) ++void sched_move_task(struct task_struct *tsk, bool for_autogroup) + { + int queued, running, queue_flags = + DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK; +@@ -8982,7 +8982,8 @@ void sched_move_task(struct task_struct + put_prev_task(rq, tsk); + + sched_change_group(tsk, group); +- scx_move_task(tsk); ++ if (!for_autogroup) ++ scx_cgroup_move_task(tsk); + + if (queued) + enqueue_task(rq, tsk, queue_flags); +@@ -9083,7 +9084,7 @@ static void cpu_cgroup_attach(struct cgr + struct cgroup_subsys_state *css; + + cgroup_taskset_for_each(task, css, tset) +- sched_move_task(task); ++ sched_move_task(task, false); + + scx_cgroup_finish_attach(); + } +--- a/kernel/sched/ext.c ++++ b/kernel/sched/ext.c +@@ -3919,25 +3919,12 @@ err: + return ops_sanitize_err("cgroup_prep_move", ret); + } + +-void scx_move_task(struct task_struct *p) ++void scx_cgroup_move_task(struct task_struct *p) + { + if (!scx_cgroup_enabled) + return; + + /* +- * We're called from sched_move_task() which handles both cgroup and +- * autogroup moves. Ignore the latter. +- * +- * Also ignore exiting tasks, because in the exit path tasks transition +- * from the autogroup to the root group, so task_group_is_autogroup() +- * alone isn't able to catch exiting autogroup tasks. This is safe for +- * cgroup_move(), because cgroup migrations never happen for PF_EXITING +- * tasks. +- */ +- if (task_group_is_autogroup(task_group(p)) || (p->flags & PF_EXITING)) +- return; +- +- /* + * @p must have ops.cgroup_prep_move() called on it and thus + * cgrp_moving_from set. + */ +--- a/kernel/sched/ext.h ++++ b/kernel/sched/ext.h +@@ -73,7 +73,7 @@ static inline void scx_update_idle(struc + int scx_tg_online(struct task_group *tg); + void scx_tg_offline(struct task_group *tg); + int scx_cgroup_can_attach(struct cgroup_taskset *tset); +-void scx_move_task(struct task_struct *p); ++void scx_cgroup_move_task(struct task_struct *p); + void scx_cgroup_finish_attach(void); + void scx_cgroup_cancel_attach(struct cgroup_taskset *tset); + void scx_group_set_weight(struct task_group *tg, unsigned long cgrp_weight); +@@ -82,7 +82,7 @@ void scx_group_set_idle(struct task_grou + static inline int scx_tg_online(struct task_group *tg) { return 0; } + static inline void scx_tg_offline(struct task_group *tg) {} + static inline int scx_cgroup_can_attach(struct cgroup_taskset *tset) { return 0; } +-static inline void scx_move_task(struct task_struct *p) {} ++static inline void scx_cgroup_move_task(struct task_struct *p) {} + static inline void scx_cgroup_finish_attach(void) {} + static inline void scx_cgroup_cancel_attach(struct cgroup_taskset *tset) {} + static inline void scx_group_set_weight(struct task_group *tg, unsigned long cgrp_weight) {} +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -572,7 +572,7 @@ extern void sched_online_group(struct ta + extern void sched_destroy_group(struct task_group *tg); + extern void sched_release_group(struct task_group *tg); + +-extern void sched_move_task(struct task_struct *tsk); ++extern void sched_move_task(struct task_struct *tsk, bool for_autogroup); + + #ifdef CONFIG_FAIR_GROUP_SCHED + extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); diff --git a/queue-6.12/serial-8250-fix-fifo-underflow-on-flush.patch b/queue-6.12/serial-8250-fix-fifo-underflow-on-flush.patch new file mode 100644 index 0000000000..74f6c2cda6 --- /dev/null +++ b/queue-6.12/serial-8250-fix-fifo-underflow-on-flush.patch @@ -0,0 +1,114 @@ +From 9e512eaaf8f4008c44ede3dfc0fbc9d9c5118583 Mon Sep 17 00:00:00 2001 +From: John Keeping +Date: Sat, 8 Feb 2025 12:41:44 +0000 +Subject: serial: 8250: Fix fifo underflow on flush + +From: John Keeping + +commit 9e512eaaf8f4008c44ede3dfc0fbc9d9c5118583 upstream. + +When flushing the serial port's buffer, uart_flush_buffer() calls +kfifo_reset() but if there is an outstanding DMA transfer then the +completion function will consume data from the kfifo via +uart_xmit_advance(), underflowing and leading to ongoing DMA as the +driver tries to transmit another 2^32 bytes. + +This is readily reproduced with serial-generic and amidi sending even +short messages as closing the device on exit will wait for the fifo to +drain and in the underflow case amidi hangs for 30 seconds on exit in +tty_wait_until_sent(). A trace of that gives: + + kworker/1:1-84 [001] 51.769423: bprint: serial8250_tx_dma: tx_size=3 fifo_len=3 + amidi-763 [001] 51.769460: bprint: uart_flush_buffer: resetting fifo + irq/21-fe530000-76 [000] 51.769474: bprint: __dma_tx_complete: tx_size=3 + irq/21-fe530000-76 [000] 51.769479: bprint: serial8250_tx_dma: tx_size=4096 fifo_len=4294967293 + irq/21-fe530000-76 [000] 51.781295: bprint: __dma_tx_complete: tx_size=4096 + irq/21-fe530000-76 [000] 51.781301: bprint: serial8250_tx_dma: tx_size=4096 fifo_len=4294963197 + irq/21-fe530000-76 [000] 51.793131: bprint: __dma_tx_complete: tx_size=4096 + irq/21-fe530000-76 [000] 51.793135: bprint: serial8250_tx_dma: tx_size=4096 fifo_len=4294959101 + irq/21-fe530000-76 [000] 51.804949: bprint: __dma_tx_complete: tx_size=4096 + +Since the port lock is held in when the kfifo is reset in +uart_flush_buffer() and in __dma_tx_complete(), adding a flush_buffer +hook to adjust the outstanding DMA byte count is sufficient to avoid the +kfifo underflow. + +Fixes: 9ee4b83e51f74 ("serial: 8250: Add support for dmaengine") +Cc: stable +Signed-off-by: John Keeping +Link: https://lore.kernel.org/r/20250208124148.1189191-1-jkeeping@inmusicbrands.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250.h | 2 ++ + drivers/tty/serial/8250/8250_dma.c | 16 ++++++++++++++++ + drivers/tty/serial/8250/8250_port.c | 9 +++++++++ + 3 files changed, 27 insertions(+) + +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -374,6 +374,7 @@ static inline int is_omap1510_8250(struc + + #ifdef CONFIG_SERIAL_8250_DMA + extern int serial8250_tx_dma(struct uart_8250_port *); ++extern void serial8250_tx_dma_flush(struct uart_8250_port *); + extern int serial8250_rx_dma(struct uart_8250_port *); + extern void serial8250_rx_dma_flush(struct uart_8250_port *); + extern int serial8250_request_dma(struct uart_8250_port *); +@@ -406,6 +407,7 @@ static inline int serial8250_tx_dma(stru + { + return -1; + } ++static inline void serial8250_tx_dma_flush(struct uart_8250_port *p) { } + static inline int serial8250_rx_dma(struct uart_8250_port *p) + { + return -1; +--- a/drivers/tty/serial/8250/8250_dma.c ++++ b/drivers/tty/serial/8250/8250_dma.c +@@ -149,6 +149,22 @@ err: + return ret; + } + ++void serial8250_tx_dma_flush(struct uart_8250_port *p) ++{ ++ struct uart_8250_dma *dma = p->dma; ++ ++ if (!dma->tx_running) ++ return; ++ ++ /* ++ * kfifo_reset() has been called by the serial core, avoid ++ * advancing and underflowing in __dma_tx_complete(). ++ */ ++ dma->tx_size = 0; ++ ++ dmaengine_terminate_async(dma->rxchan); ++} ++ + int serial8250_rx_dma(struct uart_8250_port *p) + { + struct uart_8250_dma *dma = p->dma; +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -2524,6 +2524,14 @@ static void serial8250_shutdown(struct u + serial8250_do_shutdown(port); + } + ++static void serial8250_flush_buffer(struct uart_port *port) ++{ ++ struct uart_8250_port *up = up_to_u8250p(port); ++ ++ if (up->dma) ++ serial8250_tx_dma_flush(up); ++} ++ + static unsigned int serial8250_do_get_divisor(struct uart_port *port, + unsigned int baud, + unsigned int *frac) +@@ -3207,6 +3215,7 @@ static const struct uart_ops serial8250_ + .break_ctl = serial8250_break_ctl, + .startup = serial8250_startup, + .shutdown = serial8250_shutdown, ++ .flush_buffer = serial8250_flush_buffer, + .set_termios = serial8250_set_termios, + .set_ldisc = serial8250_set_ldisc, + .pm = serial8250_pm, diff --git a/queue-6.12/serial-port-always-update-iotype-in-__uart_read_properties.patch b/queue-6.12/serial-port-always-update-iotype-in-__uart_read_properties.patch new file mode 100644 index 0000000000..d3f522f01f --- /dev/null +++ b/queue-6.12/serial-port-always-update-iotype-in-__uart_read_properties.patch @@ -0,0 +1,44 @@ +From e8486bd50ecf63c9a1e25271f258a8d959f2672f Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Fri, 24 Jan 2025 18:10:47 +0200 +Subject: serial: port: Always update ->iotype in __uart_read_properties() + +From: Andy Shevchenko + +commit e8486bd50ecf63c9a1e25271f258a8d959f2672f upstream. + +The documentation of the __uart_read_properties() states that +->iotype member is always altered after the function call, but +the code doesn't do that in the case when use_defaults == false +and the value of reg-io-width is unsupported. Make sure the code +follows the documentation. + +Note, the current users of the uart_read_and_validate_port_properties() +will fail and the change doesn't affect their behaviour, neither +users of uart_read_port_properties() will be affected since the +alteration happens there even in the current code flow. + +Fixes: e894b6005dce ("serial: port: Introduce a common helper to read properties") +Cc: stable +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20250124161530.398361-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/serial_port.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/serial_port.c ++++ b/drivers/tty/serial/serial_port.c +@@ -228,11 +228,11 @@ static int __uart_read_properties(struct + port->iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32; + break; + default: ++ port->iotype = UPIO_UNKNOWN; + if (!use_defaults) { + dev_err(dev, "Unsupported reg-io-width (%u)\n", value); + return -EINVAL; + } +- port->iotype = UPIO_UNKNOWN; + break; + } + } diff --git a/queue-6.12/serial-port-assign-iotype-correctly-when-iobase-is-set.patch b/queue-6.12/serial-port-assign-iotype-correctly-when-iobase-is-set.patch new file mode 100644 index 0000000000..3e4ef46b35 --- /dev/null +++ b/queue-6.12/serial-port-assign-iotype-correctly-when-iobase-is-set.patch @@ -0,0 +1,44 @@ +From 166ac2bba167d575e7146beaa66093bc7c072f43 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Fri, 24 Jan 2025 18:10:46 +0200 +Subject: serial: port: Assign ->iotype correctly when ->iobase is set + +From: Andy Shevchenko + +commit 166ac2bba167d575e7146beaa66093bc7c072f43 upstream. + +Currently the ->iotype is always assigned to the UPIO_MEM when +the respective property is not found. However, this will not +support the cases when user wants to have UPIO_PORT to be set +or preserved. Support this scenario by checking ->iobase value +and default the ->iotype respectively. + +Fixes: 1117a6fdc7c1 ("serial: 8250_of: Switch to use uart_read_port_properties()") +Fixes: e894b6005dce ("serial: port: Introduce a common helper to read properties") +Cc: stable +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20250124161530.398361-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/serial_port.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/serial_port.c ++++ b/drivers/tty/serial/serial_port.c +@@ -173,6 +173,7 @@ EXPORT_SYMBOL(uart_remove_one_port); + * The caller is responsible to initialize the following fields of the @port + * ->dev (must be valid) + * ->flags ++ * ->iobase + * ->mapbase + * ->mapsize + * ->regshift (if @use_defaults is false) +@@ -214,7 +215,7 @@ static int __uart_read_properties(struct + /* Read the registers I/O access type (default: MMIO 8-bit) */ + ret = device_property_read_u32(dev, "reg-io-width", &value); + if (ret) { +- port->iotype = UPIO_MEM; ++ port->iotype = port->iobase ? UPIO_PORT : UPIO_MEM; + } else { + switch (value) { + case 1: diff --git a/queue-6.12/series b/queue-6.12/series index a470fc6288..d0dfebeeb5 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -91,3 +91,72 @@ orangefs-fix-a-oob-in-orangefs_debug_write.patch kbuild-suppress-stdout-from-merge_config-for-silent-.patch asoc-intel-bytcr_rt5640-add-dmi-quirk-for-vexia-edu-.patch kbuild-use-fzero-init-padding-bits-all.patch +batman-adv-fix-panic-during-interface-removal.patch +batman-adv-ignore-neighbor-throughput-metrics-in-error-case.patch +batman-adv-drop-unmanaged-elp-metric-worker.patch +drm-amdgpu-gfx9-manually-control-gfxoff-for-cs-on-rv.patch +drm-amdgpu-bump-version-for-rv-pco-compute-fix.patch +drm-amdgpu-avoid-buffer-overflow-attach-in-smu_sys_set_pp_table.patch +kvm-x86-reject-hyper-v-s-send_ipi-hypercalls-if-local-apic-isn-t-in-kernel.patch +kvm-x86-load-dr6-with-guest-value-only-before-entering-.vcpu_run-loop.patch +kvm-nsvm-enter-guest-mode-before-initializing-nested-npt-mmu.patch +perf-x86-intel-fix-arch_perfmon_num_counter_leaf.patch +perf-x86-intel-ensure-lbrs-are-disabled-when-a-cpu-is-starting.patch +ring-buffer-unlock-resize-on-mmap-error.patch +tracing-do-not-allow-mmap-of-persistent-ring-buffer.patch +ring-buffer-validate-the-persistent-meta-data-subbuf-array.patch +ring-buffer-update-pages_touched-to-reflect-persistent-buffer-content.patch +usb-gadget-f_midi-fixing-wmaxpacketsize-exceeded-issue-during-midi-bind-retries.patch +usb-dwc3-fix-timeout-issue-during-controller-enter-exit-from-halt-state.patch +usb-roles-set-switch-registered-flag-early-on.patch +usb-gadget-udc-renesas_usb3-fix-compiler-warning.patch +usb-dwc2-gadget-remove-of_node-reference-upon-udc_stop.patch +usb-xhci-restore-xhci_pci-support-for-renesas-hcs.patch +usb-pci-quirks-fix-hccparams-register-error-for-ls7a-ehci.patch +usb-core-fix-pipe-creation-for-get_bmaxpacketsize0.patch +usb-quirks-add-usb_quirk_no_lpm-quirk-for-teclast-dist.patch +usb-add-usb_quirk_no_lpm-quirk-for-sony-xperia-xz1-smartphone.patch +usb-gadget-f_midi-fix-midi-streaming-descriptor-lengths.patch +usb-hub-ignore-non-compliant-devices-with-too-many-configs-or-interfaces.patch +usb-cdc-acm-fill-in-renesas-r-car-d3-usb-download-mode-quirk.patch +usb-cdc-acm-check-control-transfer-buffer-size-before-access.patch +usb-cdc-acm-fix-handling-of-oversized-fragments.patch +usb-gadget-core-flush-gadget-workqueue-after-device-removal.patch +usb-serial-option-add-meig-smart-slm828.patch +usb-serial-option-add-telit-cinterion-fn990b-compositions.patch +usb-serial-option-fix-telit-cinterion-fn990a-name.patch +usb-serial-option-drop-meig-smart-defines.patch +can-ctucanfd-handle-skb-allocation-failure.patch +can-c_can-fix-unbalanced-runtime-pm-disable-in-error-path.patch +can-j1939-j1939_sk_send_loop-fix-unable-to-send-messages-with-data-length-zero.patch +can-rockchip-rkcanfd_handle_rx_fifo_overflow_int-bail-out-if-skb-cannot-be-allocated.patch +can-etas_es58x-fix-potential-null-pointer-dereference-on-udev-serial.patch +alpha-make-stack-16-byte-aligned-most-cases.patch +wifi-ath12k-fix-handling-of-6-ghz-rules.patch +pci-avoid-flr-for-mediatek-mt7922-wifi.patch +kbuild-userprogs-fix-bitsize-and-target-detection-on-clang.patch +efi-avoid-cold-plugged-memory-for-placing-the-kernel.patch +arm64-rust-clean-rust-1.85.0-warning-using-softfloat-target.patch +objtool-rust-add-one-more-noreturn-rust-function.patch +rust-rbtree-fix-overindented-list-item.patch +cgroup-fix-race-between-fork-and-cgroup.kill.patch +serial-port-assign-iotype-correctly-when-iobase-is-set.patch +serial-port-always-update-iotype-in-__uart_read_properties.patch +serial-8250-fix-fifo-underflow-on-flush.patch +alpha-replace-hardcoded-stack-offsets-with-autogenerated-ones.patch +alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch +s390-pci-pull-search-for-parent-pf-out-of-zpci_iov_setup_virtfn.patch +s390-pci-fix-handling-of-isolated-vfs.patch +gpiolib-acpi-add-a-quirk-for-acer-nitro-anv14.patch +gpio-stmpe-check-return-value-of-stmpe_reg_read-in-stmpe_gpio_irq_sync_unlock.patch +partitions-mac-fix-handling-of-bogus-partition-table.patch +sched_ext-fix-incorrect-autogroup-migration-detection.patch +regulator-qcom_smd-add-l2-l5-sub-node-to-mp5496-regulator.patch +iommu-fix-potential-memory-leak-in-iopf_queue_remove_device.patch +regmap-irq-add-missing-kfree.patch +arm64-handle-.arm.attributes-section-in-linker-scripts.patch +mmc-mtk-sd-fix-register-settings-for-hs400-es-mode.patch +igc-set-buffer-type-for-empty-frames-in-igc_init_empty_frame.patch +cifs-pick-channels-for-individual-subrequests.patch +mlxsw-add-return-value-check-for-mlxsw_sp_port_get_stats_raw.patch +btrfs-fix-hole-expansion-when-writing-at-an-offset-beyond-eof.patch diff --git a/queue-6.12/tracing-do-not-allow-mmap-of-persistent-ring-buffer.patch b/queue-6.12/tracing-do-not-allow-mmap-of-persistent-ring-buffer.patch new file mode 100644 index 0000000000..2c156f86eb --- /dev/null +++ b/queue-6.12/tracing-do-not-allow-mmap-of-persistent-ring-buffer.patch @@ -0,0 +1,101 @@ +From 129fe718819cc5e24ea2f489db9ccd4371f0c6f6 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 14 Feb 2025 11:55:47 -0500 +Subject: tracing: Do not allow mmap() of persistent ring buffer + +From: Steven Rostedt + +commit 129fe718819cc5e24ea2f489db9ccd4371f0c6f6 upstream. + +When trying to mmap a trace instance buffer that is attached to +reserve_mem, it would crash: + + BUG: unable to handle page fault for address: ffffe97bd00025c8 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 2862f3067 P4D 2862f3067 PUD 0 + Oops: Oops: 0000 [#1] PREEMPT_RT SMP PTI + CPU: 4 UID: 0 PID: 981 Comm: mmap-rb Not tainted 6.14.0-rc2-test-00003-g7f1a5e3fbf9e-dirty #233 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 + RIP: 0010:validate_page_before_insert+0x5/0xb0 + Code: e2 01 89 d0 c3 cc cc cc cc 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 <48> 8b 46 08 a8 01 75 67 66 90 48 89 f0 8b 50 34 85 d2 74 76 48 89 + RSP: 0018:ffffb148c2f3f968 EFLAGS: 00010246 + RAX: ffff9fa5d3322000 RBX: ffff9fa5ccff9c08 RCX: 00000000b879ed29 + RDX: ffffe97bd00025c0 RSI: ffffe97bd00025c0 RDI: ffff9fa5ccff9c08 + RBP: ffffb148c2f3f9f0 R08: 0000000000000004 R09: 0000000000000004 + R10: 0000000000000000 R11: 0000000000000200 R12: 0000000000000000 + R13: 00007f16a18d5000 R14: ffff9fa5c48db6a8 R15: 0000000000000000 + FS: 00007f16a1b54740(0000) GS:ffff9fa73df00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: ffffe97bd00025c8 CR3: 00000001048c6006 CR4: 0000000000172ef0 + Call Trace: + + ? __die_body.cold+0x19/0x1f + ? __die+0x2e/0x40 + ? page_fault_oops+0x157/0x2b0 + ? search_module_extables+0x53/0x80 + ? validate_page_before_insert+0x5/0xb0 + ? kernelmode_fixup_or_oops.isra.0+0x5f/0x70 + ? __bad_area_nosemaphore+0x16e/0x1b0 + ? bad_area_nosemaphore+0x16/0x20 + ? do_kern_addr_fault+0x77/0x90 + ? exc_page_fault+0x22b/0x230 + ? asm_exc_page_fault+0x2b/0x30 + ? validate_page_before_insert+0x5/0xb0 + ? vm_insert_pages+0x151/0x400 + __rb_map_vma+0x21f/0x3f0 + ring_buffer_map+0x21b/0x2f0 + tracing_buffers_mmap+0x70/0xd0 + __mmap_region+0x6f0/0xbd0 + mmap_region+0x7f/0x130 + do_mmap+0x475/0x610 + vm_mmap_pgoff+0xf2/0x1d0 + ksys_mmap_pgoff+0x166/0x200 + __x64_sys_mmap+0x37/0x50 + x64_sys_call+0x1670/0x1d70 + do_syscall_64+0xbb/0x1d0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +The reason was that the code that maps the ring buffer pages to user space +has: + + page = virt_to_page((void *)cpu_buffer->subbuf_ids[s]); + +And uses that in: + + vm_insert_pages(vma, vma->vm_start, pages, &nr_pages); + +But virt_to_page() does not work with vmap()'d memory which is what the +persistent ring buffer has. It is rather trivial to allow this, but for +now just disable mmap() of instances that have their ring buffer from the +reserve_mem option. + +If an mmap() is performed on a persistent buffer it will return -ENODEV +just like it would if the .mmap field wasn't defined in the +file_operations structure. + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mathieu Desnoyers +Cc: Vincent Donnefort +Link: https://lore.kernel.org/20250214115547.0d7287d3@gandalf.local.home +Fixes: 9b7bdf6f6ece6 ("tracing: Have trace_printk not use binary prints if boot buffer") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -8364,6 +8364,10 @@ static int tracing_buffers_mmap(struct f + struct trace_iterator *iter = &info->iter; + int ret = 0; + ++ /* Currently the boot mapped buffer is not supported for mmap */ ++ if (iter->tr->flags & TRACE_ARRAY_FL_BOOT) ++ return -ENODEV; ++ + ret = get_snapshot_map(iter->tr); + if (ret) + return ret; diff --git a/queue-6.12/usb-add-usb_quirk_no_lpm-quirk-for-sony-xperia-xz1-smartphone.patch b/queue-6.12/usb-add-usb_quirk_no_lpm-quirk-for-sony-xperia-xz1-smartphone.patch new file mode 100644 index 0000000000..8ac42e28b6 --- /dev/null +++ b/queue-6.12/usb-add-usb_quirk_no_lpm-quirk-for-sony-xperia-xz1-smartphone.patch @@ -0,0 +1,55 @@ +From 159daf1258227f44b26b5d38f4aa8f37b8cca663 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 6 Feb 2025 17:18:36 +0200 +Subject: USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone + +From: Mathias Nyman + +commit 159daf1258227f44b26b5d38f4aa8f37b8cca663 upstream. + +The fastboot tool for communicating with Android bootloaders does not +work reliably with this device if USB 2 Link Power Management (LPM) +is enabled. + +Various fastboot commands are affected, including the +following, which usually reproduces the problem within two tries: + + fastboot getvar kernel + getvar:kernel FAILED (remote: 'GetVar Variable Not found') + +This issue was hidden on many systems up until commit 63a1f8454962 +("xhci: stored cached port capability values in one place") as the xhci +driver failed to detect USB 2 LPM support if USB 3 ports were listed +before USB 2 ports in the "supported protocol capabilities". + +Adding the quirk resolves the issue. No drawbacks are expected since +the device uses different USB product IDs outside of fastboot mode, and +since fastboot commands worked before, until LPM was enabled on the +tested system by the aforementioned commit. + +Based on a patch from Forest from which most of the +code and commit message is taken. + +Cc: stable +Reported-by: Forest +Closes: https://lore.kernel.org/hk8umj9lv4l4qguftdq1luqtdrpa1gks5l@sonic.net +Tested-by: Forest +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250206151836.51742-1-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -432,6 +432,9 @@ static const struct usb_device_id usb_qu + { USB_DEVICE(0x0c45, 0x7056), .driver_info = + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + ++ /* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */ ++ { USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, diff --git a/queue-6.12/usb-cdc-acm-check-control-transfer-buffer-size-before-access.patch b/queue-6.12/usb-cdc-acm-check-control-transfer-buffer-size-before-access.patch new file mode 100644 index 0000000000..63696b11b9 --- /dev/null +++ b/queue-6.12/usb-cdc-acm-check-control-transfer-buffer-size-before-access.patch @@ -0,0 +1,66 @@ +From e563b01208f4d1f609bcab13333b6c0e24ce6a01 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 12 Feb 2025 19:15:15 +0100 +Subject: usb: cdc-acm: Check control transfer buffer size before access + +From: Jann Horn + +commit e563b01208f4d1f609bcab13333b6c0e24ce6a01 upstream. + +If the first fragment is shorter than struct usb_cdc_notification, we can't +calculate an expected_size. Log an error and discard the notification +instead of reading lengths from memory outside the received data, which can +lead to memory corruption when the expected_size decreases between +fragments, causing `expected_size - acm->nb_index` to wrap. + +This issue has been present since the beginning of git history; however, +it only leads to memory corruption since commit ea2583529cd1 +("cdc-acm: reassemble fragmented notifications"). + +A mitigating factor is that acm_ctrl_irq() can only execute after userspace +has opened /dev/ttyACM*; but if ModemManager is running, ModemManager will +do that automatically depending on the USB device's vendor/product IDs and +its other interfaces. + +Cc: stable +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Jann Horn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/cdc-acm.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -371,7 +371,7 @@ static void acm_process_notification(str + static void acm_ctrl_irq(struct urb *urb) + { + struct acm *acm = urb->context; +- struct usb_cdc_notification *dr = urb->transfer_buffer; ++ struct usb_cdc_notification *dr; + unsigned int current_size = urb->actual_length; + unsigned int expected_size, copy_size, alloc_size; + int retval; +@@ -398,9 +398,20 @@ static void acm_ctrl_irq(struct urb *urb + + usb_mark_last_busy(acm->dev); + +- if (acm->nb_index) ++ if (acm->nb_index == 0) { ++ /* ++ * The first chunk of a message must contain at least the ++ * notification header with the length field, otherwise we ++ * can't get an expected_size. ++ */ ++ if (current_size < sizeof(struct usb_cdc_notification)) { ++ dev_dbg(&acm->control->dev, "urb too short\n"); ++ goto exit; ++ } ++ dr = urb->transfer_buffer; ++ } else { + dr = (struct usb_cdc_notification *)acm->notification_buffer; +- ++ } + /* size = notification-header + (optional) data */ + expected_size = sizeof(struct usb_cdc_notification) + + le16_to_cpu(dr->wLength); diff --git a/queue-6.12/usb-cdc-acm-fill-in-renesas-r-car-d3-usb-download-mode-quirk.patch b/queue-6.12/usb-cdc-acm-fill-in-renesas-r-car-d3-usb-download-mode-quirk.patch new file mode 100644 index 0000000000..6f5bb10986 --- /dev/null +++ b/queue-6.12/usb-cdc-acm-fill-in-renesas-r-car-d3-usb-download-mode-quirk.patch @@ -0,0 +1,46 @@ +From 7284922f3e4fa285dff1b8bb593aa9a0b8458f30 Mon Sep 17 00:00:00 2001 +From: Marek Vasut +Date: Sun, 9 Feb 2025 15:56:11 +0100 +Subject: USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk + +From: Marek Vasut + +commit 7284922f3e4fa285dff1b8bb593aa9a0b8458f30 upstream. + +Add Renesas R-Car D3 USB Download mode quirk and update comments +on all the other Renesas R-Car USB Download mode quirks to discern +them from each other. This follows R-Car Series, 3rd Generation +reference manual Rev.2.00 chapter 19.2.8 USB download mode . + +Fixes: 6d853c9e4104 ("usb: cdc-acm: Add DISABLE_ECHO for Renesas USB Download mode") +Cc: stable +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20250209145708.106914-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/cdc-acm.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1727,13 +1727,16 @@ static const struct usb_device_id acm_id + { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +- { USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, +- { USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, +- { USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */ ++ .driver_info = DISABLE_ECHO, /* Don't echo banner */ ++ }, ++ { USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, + { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ diff --git a/queue-6.12/usb-cdc-acm-fix-handling-of-oversized-fragments.patch b/queue-6.12/usb-cdc-acm-fix-handling-of-oversized-fragments.patch new file mode 100644 index 0000000000..e99a54d115 --- /dev/null +++ b/queue-6.12/usb-cdc-acm-fix-handling-of-oversized-fragments.patch @@ -0,0 +1,42 @@ +From 12e712964f41d05ae034989892de445781c46730 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 12 Feb 2025 19:15:16 +0100 +Subject: usb: cdc-acm: Fix handling of oversized fragments + +From: Jann Horn + +commit 12e712964f41d05ae034989892de445781c46730 upstream. + +If we receive an initial fragment of size 8 bytes which specifies a wLength +of 1 byte (so the reassembled message is supposed to be 9 bytes long), and +we then receive a second fragment of size 9 bytes (which is not supposed to +happen), we currently wrongly bypass the fragment reassembly code but still +pass the pointer to the acm->notification_buffer to +acm_process_notification(). + +Make this less wrong by always going through fragment reassembly when we +expect more fragments. + +Before this patch, receiving an overlong fragment could lead to `newctrl` +in acm_process_notification() being uninitialized data (instead of data +coming from the device). + +Cc: stable +Fixes: ea2583529cd1 ("cdc-acm: reassemble fragmented notifications") +Signed-off-by: Jann Horn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/cdc-acm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -416,7 +416,7 @@ static void acm_ctrl_irq(struct urb *urb + expected_size = sizeof(struct usb_cdc_notification) + + le16_to_cpu(dr->wLength); + +- if (current_size < expected_size) { ++ if (acm->nb_index != 0 || current_size < expected_size) { + /* notification is transmitted fragmented, reassemble */ + if (acm->nb_size < expected_size) { + u8 *new_buffer; diff --git a/queue-6.12/usb-core-fix-pipe-creation-for-get_bmaxpacketsize0.patch b/queue-6.12/usb-core-fix-pipe-creation-for-get_bmaxpacketsize0.patch new file mode 100644 index 0000000000..be877cab34 --- /dev/null +++ b/queue-6.12/usb-core-fix-pipe-creation-for-get_bmaxpacketsize0.patch @@ -0,0 +1,64 @@ +From 4aac0db5a0ebc599d4ad9bf5ebab78afa1f33e10 Mon Sep 17 00:00:00 2001 +From: Stefan Eichenberger +Date: Mon, 3 Feb 2025 11:58:24 +0100 +Subject: usb: core: fix pipe creation for get_bMaxPacketSize0 + +From: Stefan Eichenberger + +commit 4aac0db5a0ebc599d4ad9bf5ebab78afa1f33e10 upstream. + +When usb_control_msg is used in the get_bMaxPacketSize0 function, the +USB pipe does not include the endpoint device number. This can cause +failures when a usb hub port is reinitialized after encountering a bad +cable connection. As a result, the system logs the following error +messages: +usb usb2-port1: cannot reset (err = -32) +usb usb2-port1: Cannot enable. Maybe the USB cable is bad? +usb usb2-port1: attempt power cycle +usb 2-1: new high-speed USB device number 5 using ci_hdrc +usb 2-1: device descriptor read/8, error -71 + +The problem began after commit 85d07c556216 ("USB: core: Unite old +scheme and new scheme descriptor reads"). There +usb_get_device_descriptor was replaced with get_bMaxPacketSize0. Unlike +usb_get_device_descriptor, the get_bMaxPacketSize0 function uses the +macro usb_rcvaddr0pipe, which does not include the endpoint device +number. usb_get_device_descriptor, on the other hand, used the macro +usb_rcvctrlpipe, which includes the endpoint device number. + +By modifying the get_bMaxPacketSize0 function to use usb_rcvctrlpipe +instead of usb_rcvaddr0pipe, the issue can be resolved. This change will +ensure that the endpoint device number is included in the USB pipe, +preventing reinitialization failures. If the endpoint has not set the +device number yet, it will still work because the device number is 0 in +udev. + +Cc: stable +Fixes: 85d07c556216 ("USB: core: Unite old scheme and new scheme descriptor reads") +Signed-off-by: Stefan Eichenberger +Reviewed-by: Alan Stern +Link: https://lore.kernel.org/r/20250203105840.17539-1-eichest@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4698,7 +4698,6 @@ void usb_ep0_reinit(struct usb_device *u + EXPORT_SYMBOL_GPL(usb_ep0_reinit); + + #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) +-#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) + + static int hub_set_address(struct usb_device *udev, int devnum) + { +@@ -4804,7 +4803,7 @@ static int get_bMaxPacketSize0(struct us + for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) { + /* Start with invalid values in case the transfer fails */ + buf->bDescriptorType = buf->bMaxPacketSize0 = 0; +- rc = usb_control_msg(udev, usb_rcvaddr0pipe(), ++ rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + USB_DT_DEVICE << 8, 0, + buf, size, diff --git a/queue-6.12/usb-dwc2-gadget-remove-of_node-reference-upon-udc_stop.patch b/queue-6.12/usb-dwc2-gadget-remove-of_node-reference-upon-udc_stop.patch new file mode 100644 index 0000000000..a96a9b4692 --- /dev/null +++ b/queue-6.12/usb-dwc2-gadget-remove-of_node-reference-upon-udc_stop.patch @@ -0,0 +1,51 @@ +From 58cd423820d5b5610977e55e4acdd06628829ede Mon Sep 17 00:00:00 2001 +From: Fabrice Gasnier +Date: Fri, 24 Jan 2025 18:33:25 +0100 +Subject: usb: dwc2: gadget: remove of_node reference upon udc_stop + +From: Fabrice Gasnier + +commit 58cd423820d5b5610977e55e4acdd06628829ede upstream. + +In dwc2_hsotg_udc_start(), e.g. when binding composite driver, "of_node" +is set to hsotg->dev->of_node. + +It causes errors when binding the gadget driver several times, on +stm32mp157c-ev1 board. Below error is seen: +"pin PA10 already requested by 49000000.usb-otg; cannot claim for gadget.0" + +The first time, no issue is seen as when registering the driver, of_node +isn't NULL: +-> gadget_dev_desc_UDC_store + -> usb_gadget_register_driver_owner + -> driver_register + ... + -> really_probe -> pinctrl_bind_pins (no effect) + +Then dwc2_hsotg_udc_start() sets of_node. + +The second time (stop the gadget, reconfigure it, then start it again), +of_node has been set, so the probing code tries to acquire pins for the +gadget. These pins are hold by the controller, hence the error. + +So clear gadget.dev.of_node in udc_stop() routine to avoid the issue. + +Fixes: 7d7b22928b90 ("usb: gadget: s3c-hsotg: Propagate devicetree to gadget drivers") +Cc: stable +Signed-off-by: Fabrice Gasnier +Link: https://lore.kernel.org/r/20250124173325.2747710-1-fabrice.gasnier@foss.st.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/gadget.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -4615,6 +4615,7 @@ static int dwc2_hsotg_udc_stop(struct us + spin_lock_irqsave(&hsotg->lock, flags); + + hsotg->driver = NULL; ++ hsotg->gadget.dev.of_node = NULL; + hsotg->gadget.speed = USB_SPEED_UNKNOWN; + hsotg->enabled = 0; + diff --git a/queue-6.12/usb-dwc3-fix-timeout-issue-during-controller-enter-exit-from-halt-state.patch b/queue-6.12/usb-dwc3-fix-timeout-issue-during-controller-enter-exit-from-halt-state.patch new file mode 100644 index 0000000000..6833f8e2dd --- /dev/null +++ b/queue-6.12/usb-dwc3-fix-timeout-issue-during-controller-enter-exit-from-halt-state.patch @@ -0,0 +1,91 @@ +From d3a8c28426fc1fb3252753a9f1db0d691ffc21b0 Mon Sep 17 00:00:00 2001 +From: Selvarasu Ganesan +Date: Sat, 1 Feb 2025 22:09:02 +0530 +Subject: usb: dwc3: Fix timeout issue during controller enter/exit from halt state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Selvarasu Ganesan + +commit d3a8c28426fc1fb3252753a9f1db0d691ffc21b0 upstream. + +There is a frequent timeout during controller enter/exit from halt state +after toggling the run_stop bit by SW. This timeout occurs when +performing frequent role switches between host and device, causing +device enumeration issues due to the timeout. This issue was not present +when USB2 suspend PHY was disabled by passing the SNPS quirks +(snps,dis_u2_susphy_quirk and snps,dis_enblslpm_quirk) from the DTS. +However, there is a requirement to enable USB2 suspend PHY by setting of +GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY bits when controller starts +in gadget or host mode results in the timeout issue. + +This commit addresses this timeout issue by ensuring that the bits +GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting +the dwc3_gadget_run_stop sequence and restoring them after the +dwc3_gadget_run_stop sequence is completed. + +Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver") +Cc: stable +Signed-off-by: Selvarasu Ganesan +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20250201163903.459-1-selvarasu.g@samsung.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2618,10 +2618,38 @@ static int dwc3_gadget_run_stop(struct d + { + u32 reg; + u32 timeout = 2000; ++ u32 saved_config = 0; + + if (pm_runtime_suspended(dwc->dev)) + return 0; + ++ /* ++ * When operating in USB 2.0 speeds (HS/FS), ensure that ++ * GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting ++ * or stopping the controller. This resolves timeout issues that occur ++ * during frequent role switches between host and device modes. ++ * ++ * Save and clear these settings, then restore them after completing the ++ * controller start or stop sequence. ++ * ++ * This solution was discovered through experimentation as it is not ++ * mentioned in the dwc3 programming guide. It has been tested on an ++ * Exynos platforms. ++ */ ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { ++ saved_config |= DWC3_GUSB2PHYCFG_SUSPHY; ++ reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; ++ } ++ ++ if (reg & DWC3_GUSB2PHYCFG_ENBLSLPM) { ++ saved_config |= DWC3_GUSB2PHYCFG_ENBLSLPM; ++ reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; ++ } ++ ++ if (saved_config) ++ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); ++ + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + if (is_on) { + if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) { +@@ -2649,6 +2677,12 @@ static int dwc3_gadget_run_stop(struct d + reg &= DWC3_DSTS_DEVCTRLHLT; + } while (--timeout && !(!is_on ^ !reg)); + ++ if (saved_config) { ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ reg |= saved_config; ++ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); ++ } ++ + if (!timeout) + return -ETIMEDOUT; + diff --git a/queue-6.12/usb-gadget-core-flush-gadget-workqueue-after-device-removal.patch b/queue-6.12/usb-gadget-core-flush-gadget-workqueue-after-device-removal.patch new file mode 100644 index 0000000000..4b0fac0ce5 --- /dev/null +++ b/queue-6.12/usb-gadget-core-flush-gadget-workqueue-after-device-removal.patch @@ -0,0 +1,46 @@ +From 399a45e5237ca14037120b1b895bd38a3b4492ea Mon Sep 17 00:00:00 2001 +From: Roy Luo +Date: Tue, 4 Feb 2025 23:36:42 +0000 +Subject: usb: gadget: core: flush gadget workqueue after device removal + +From: Roy Luo + +commit 399a45e5237ca14037120b1b895bd38a3b4492ea upstream. + +device_del() can lead to new work being scheduled in gadget->work +workqueue. This is observed, for example, with the dwc3 driver with the +following call stack: + device_del() + gadget_unbind_driver() + usb_gadget_disconnect_locked() + dwc3_gadget_pullup() + dwc3_gadget_soft_disconnect() + usb_gadget_set_state() + schedule_work(&gadget->work) + +Move flush_work() after device_del() to ensure the workqueue is cleaned +up. + +Fixes: 5702f75375aa9 ("usb: gadget: udc-core: move sysfs_notify() to a workqueue") +Cc: stable +Signed-off-by: Roy Luo +Reviewed-by: Alan Stern +Reviewed-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20250204233642.666991-1-royluo@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1543,8 +1543,8 @@ void usb_del_gadget(struct usb_gadget *g + + kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); + sysfs_remove_link(&udc->dev.kobj, "gadget"); +- flush_work(&gadget->work); + device_del(&gadget->dev); ++ flush_work(&gadget->work); + ida_free(&gadget_id_numbers, gadget->id_number); + cancel_work_sync(&udc->vbus_work); + device_unregister(&udc->dev); diff --git a/queue-6.12/usb-gadget-f_midi-fix-midi-streaming-descriptor-lengths.patch b/queue-6.12/usb-gadget-f_midi-fix-midi-streaming-descriptor-lengths.patch new file mode 100644 index 0000000000..a94694b7c4 --- /dev/null +++ b/queue-6.12/usb-gadget-f_midi-fix-midi-streaming-descriptor-lengths.patch @@ -0,0 +1,52 @@ +From da1668997052ed1cb00322e1f3b63702615c9429 Mon Sep 17 00:00:00 2001 +From: John Keeping +Date: Thu, 30 Jan 2025 19:50:34 +0000 +Subject: usb: gadget: f_midi: fix MIDI Streaming descriptor lengths + +From: John Keeping + +commit da1668997052ed1cb00322e1f3b63702615c9429 upstream. + +While the MIDI jacks are configured correctly, and the MIDIStreaming +endpoint descriptors are filled with the correct information, +bNumEmbMIDIJack and bLength are set incorrectly in these descriptors. + +This does not matter when the numbers of in and out ports are equal, but +when they differ the host will receive broken descriptors with +uninitialized stack memory leaking into the descriptor for whichever +value is smaller. + +The precise meaning of "in" and "out" in the port counts is not clearly +defined and can be confusing. But elsewhere the driver consistently +uses this to match the USB meaning of IN and OUT viewed from the host, +so that "in" ports send data to the host and "out" ports receive data +from it. + +Cc: stable +Fixes: c8933c3f79568 ("USB: gadget: f_midi: allow a dynamic number of input and output ports") +Signed-off-by: John Keeping +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20250130195035.3883857-1-jkeeping@inmusicbrands.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_midi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -1009,11 +1009,11 @@ static int f_midi_bind(struct usb_config + } + + /* configure the endpoint descriptors ... */ +- ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); +- ms_out_desc.bNumEmbMIDIJack = midi->in_ports; ++ ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); ++ ms_out_desc.bNumEmbMIDIJack = midi->out_ports; + +- ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); +- ms_in_desc.bNumEmbMIDIJack = midi->out_ports; ++ ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); ++ ms_in_desc.bNumEmbMIDIJack = midi->in_ports; + + /* ... and add them to the list */ + endpoint_descriptor_index = i; diff --git a/queue-6.12/usb-gadget-f_midi-fixing-wmaxpacketsize-exceeded-issue-during-midi-bind-retries.patch b/queue-6.12/usb-gadget-f_midi-fixing-wmaxpacketsize-exceeded-issue-during-midi-bind-retries.patch new file mode 100644 index 0000000000..c78d4ca205 --- /dev/null +++ b/queue-6.12/usb-gadget-f_midi-fixing-wmaxpacketsize-exceeded-issue-during-midi-bind-retries.patch @@ -0,0 +1,64 @@ +From 9e8b21410f310c50733f6e1730bae5a8e30d3570 Mon Sep 17 00:00:00 2001 +From: Selvarasu Ganesan +Date: Sat, 18 Jan 2025 11:31:33 +0530 +Subject: usb: gadget: f_midi: Fixing wMaxPacketSize exceeded issue during MIDI bind retries + +From: Selvarasu Ganesan + +commit 9e8b21410f310c50733f6e1730bae5a8e30d3570 upstream. + +The current implementation sets the wMaxPacketSize of bulk in/out +endpoints to 1024 bytes at the end of the f_midi_bind function. However, +in cases where there is a failure in the first midi bind attempt, +consider rebinding. This scenario may encounter an f_midi_bind issue due +to the previous bind setting the bulk endpoint's wMaxPacketSize to 1024 +bytes, which exceeds the ep->maxpacket_limit where configured dwc3 TX/RX +FIFO's maxpacket size of 512 bytes for IN/OUT endpoints in support HS +speed only. + +Here the term "rebind" in this context refers to attempting to bind the +MIDI function a second time in certain scenarios. The situations where +rebinding is considered include: + + * When there is a failure in the first UDC write attempt, which may be + caused by other functions bind along with MIDI. + * Runtime composition change : Example : MIDI,ADB to MIDI. Or MIDI to + MIDI,ADB. + +This commit addresses this issue by resetting the wMaxPacketSize before +endpoint claim. And here there is no need to reset all values in the usb +endpoint descriptor structure, as all members except wMaxPacketSize and +bEndpointAddress have predefined values. + +This ensures that restores the endpoint to its expected configuration, +and preventing conflicts with value of ep->maxpacket_limit. It also +aligns with the approach used in other function drivers, which treat +endpoint descriptors as if they were full speed before endpoint claim. + +Fixes: 46decc82ffd5 ("usb: gadget: unconditionally allocate hs/ss descriptor in bind operation") +Cc: stable@vger.kernel.org +Signed-off-by: Selvarasu Ganesan +Link: https://lore.kernel.org/r/20250118060134.927-1-selvarasu.g@samsung.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_midi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -907,6 +907,15 @@ static int f_midi_bind(struct usb_config + + status = -ENODEV; + ++ /* ++ * Reset wMaxPacketSize with maximum packet size of FS bulk transfer before ++ * endpoint claim. This ensures that the wMaxPacketSize does not exceed the ++ * limit during bind retries where configured dwc3 TX/RX FIFO's maxpacket ++ * size of 512 bytes for IN/OUT endpoints in support HS speed only. ++ */ ++ bulk_in_desc.wMaxPacketSize = cpu_to_le16(64); ++ bulk_out_desc.wMaxPacketSize = cpu_to_le16(64); ++ + /* allocate instance-specific endpoints */ + midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); + if (!midi->in_ep) diff --git a/queue-6.12/usb-gadget-udc-renesas_usb3-fix-compiler-warning.patch b/queue-6.12/usb-gadget-udc-renesas_usb3-fix-compiler-warning.patch new file mode 100644 index 0000000000..a7cf112924 --- /dev/null +++ b/queue-6.12/usb-gadget-udc-renesas_usb3-fix-compiler-warning.patch @@ -0,0 +1,38 @@ +From 335a1fc1193481f8027f176649c72868172f6f8b Mon Sep 17 00:00:00 2001 +From: Guo Ren +Date: Wed, 22 Jan 2025 03:12:31 -0500 +Subject: usb: gadget: udc: renesas_usb3: Fix compiler warning + +From: Guo Ren + +commit 335a1fc1193481f8027f176649c72868172f6f8b upstream. + +drivers/usb/gadget/udc/renesas_usb3.c: In function 'renesas_usb3_probe': +drivers/usb/gadget/udc/renesas_usb3.c:2638:73: warning: '%d' +directive output may be truncated writing between 1 and 11 bytes into a +region of size 6 [-Wformat-truncation=] +2638 | snprintf(usb3_ep->ep_name, sizeof(usb3_ep->ep_name), "ep%d", i); + ^~~~~~~~~~~~~~~~~~~~~~~~ ^~ ^ + +Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") +Cc: stable@vger.kernel.org +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202501201409.BIQPtkeB-lkp@intel.com/ +Signed-off-by: Guo Ren +Link: https://lore.kernel.org/r/20250122081231.47594-1-guoren@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/renesas_usb3.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -310,7 +310,7 @@ struct renesas_usb3_request { + struct list_head queue; + }; + +-#define USB3_EP_NAME_SIZE 8 ++#define USB3_EP_NAME_SIZE 16 + struct renesas_usb3_ep { + struct usb_ep ep; + struct renesas_usb3 *usb3; diff --git a/queue-6.12/usb-hub-ignore-non-compliant-devices-with-too-many-configs-or-interfaces.patch b/queue-6.12/usb-hub-ignore-non-compliant-devices-with-too-many-configs-or-interfaces.patch new file mode 100644 index 0000000000..92fe5b2f05 --- /dev/null +++ b/queue-6.12/usb-hub-ignore-non-compliant-devices-with-too-many-configs-or-interfaces.patch @@ -0,0 +1,79 @@ +From 2240fed37afbcdb5e8b627bc7ad986891100e05d Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 22 Jan 2025 14:26:17 -0500 +Subject: USB: hub: Ignore non-compliant devices with too many configs or interfaces + +From: Alan Stern + +commit 2240fed37afbcdb5e8b627bc7ad986891100e05d upstream. + +Robert Morris created a test program which can cause +usb_hub_to_struct_hub() to dereference a NULL or inappropriate +pointer: + +Oops: general protection fault, probably for non-canonical address +0xcccccccccccccccc: 0000 [#1] SMP DEBUG_PAGEALLOC PTI +CPU: 7 UID: 0 PID: 117 Comm: kworker/7:1 Not tainted 6.13.0-rc3-00017-gf44d154d6e3d #14 +Hardware name: FreeBSD BHYVE/BHYVE, BIOS 14.0 10/17/2021 +Workqueue: usb_hub_wq hub_event +RIP: 0010:usb_hub_adjust_deviceremovable+0x78/0x110 +... +Call Trace: + + ? die_addr+0x31/0x80 + ? exc_general_protection+0x1b4/0x3c0 + ? asm_exc_general_protection+0x26/0x30 + ? usb_hub_adjust_deviceremovable+0x78/0x110 + hub_probe+0x7c7/0xab0 + usb_probe_interface+0x14b/0x350 + really_probe+0xd0/0x2d0 + ? __pfx___device_attach_driver+0x10/0x10 + __driver_probe_device+0x6e/0x110 + driver_probe_device+0x1a/0x90 + __device_attach_driver+0x7e/0xc0 + bus_for_each_drv+0x7f/0xd0 + __device_attach+0xaa/0x1a0 + bus_probe_device+0x8b/0xa0 + device_add+0x62e/0x810 + usb_set_configuration+0x65d/0x990 + usb_generic_driver_probe+0x4b/0x70 + usb_probe_device+0x36/0xd0 + +The cause of this error is that the device has two interfaces, and the +hub driver binds to interface 1 instead of interface 0, which is where +usb_hub_to_struct_hub() looks. + +We can prevent the problem from occurring by refusing to accept hub +devices that violate the USB spec by having more than one +configuration or interface. + +Reported-and-tested-by: Robert Morris +Cc: stable +Closes: https://lore.kernel.org/linux-usb/95564.1737394039@localhost/ +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/c27f3bf4-63d8-4fb5-ac82-09e3cd19f61c@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1848,6 +1848,17 @@ static int hub_probe(struct usb_interfac + hdev = interface_to_usbdev(intf); + + /* ++ * The USB 2.0 spec prohibits hubs from having more than one ++ * configuration or interface, and we rely on this prohibition. ++ * Refuse to accept a device that violates it. ++ */ ++ if (hdev->descriptor.bNumConfigurations > 1 || ++ hdev->actconfig->desc.bNumInterfaces > 1) { ++ dev_err(&intf->dev, "Invalid hub with more than one config or interface\n"); ++ return -EINVAL; ++ } ++ ++ /* + * Set default autosuspend delay as 0 to speedup bus suspend, + * based on the below considerations: + * diff --git a/queue-6.12/usb-pci-quirks-fix-hccparams-register-error-for-ls7a-ehci.patch b/queue-6.12/usb-pci-quirks-fix-hccparams-register-error-for-ls7a-ehci.patch new file mode 100644 index 0000000000..106de34d37 --- /dev/null +++ b/queue-6.12/usb-pci-quirks-fix-hccparams-register-error-for-ls7a-ehci.patch @@ -0,0 +1,54 @@ +From e71f7f42e3c874ac3314b8f250e8416a706165af Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Sun, 2 Feb 2025 20:49:35 +0800 +Subject: USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI + +From: Huacai Chen + +commit e71f7f42e3c874ac3314b8f250e8416a706165af upstream. + +LS7A EHCI controller doesn't have extended capabilities, so the EECP +(EHCI Extended Capabilities Pointer) field of HCCPARAMS register should +be 0x0, but it reads as 0xa0 now. This is a hardware flaw and will be +fixed in future, now just clear the EECP field to avoid error messages +on boot: + +...... +[ 0.581675] pci 0000:00:04.1: EHCI: unrecognized capability ff +[ 0.581699] pci 0000:00:04.1: EHCI: unrecognized capability ff +[ 0.581716] pci 0000:00:04.1: EHCI: unrecognized capability ff +[ 0.581851] pci 0000:00:04.1: EHCI: unrecognized capability ff +...... +[ 0.581916] pci 0000:00:05.1: EHCI: unrecognized capability ff +[ 0.581951] pci 0000:00:05.1: EHCI: unrecognized capability ff +[ 0.582704] pci 0000:00:05.1: EHCI: unrecognized capability ff +[ 0.582799] pci 0000:00:05.1: EHCI: unrecognized capability ff +...... + +Cc: stable +Signed-off-by: Baoqi Zhang +Signed-off-by: Huacai Chen +Link: https://lore.kernel.org/r/20250202124935.480500-1-chenhuacai@loongson.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/pci-quirks.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -958,6 +958,15 @@ static void quirk_usb_disable_ehci(struc + * booting from USB disk or using a usb keyboard + */ + hcc_params = readl(base + EHCI_HCC_PARAMS); ++ ++ /* LS7A EHCI controller doesn't have extended capabilities, the ++ * EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS ++ * register should be 0x0 but it reads as 0xa0. So clear it to ++ * avoid error messages on boot. ++ */ ++ if (pdev->vendor == PCI_VENDOR_ID_LOONGSON && pdev->device == 0x7a14) ++ hcc_params &= ~(0xffL << 8); ++ + offset = (hcc_params >> 8) & 0xff; + while (offset && --count) { + pci_read_config_dword(pdev, offset, &cap); diff --git a/queue-6.12/usb-quirks-add-usb_quirk_no_lpm-quirk-for-teclast-dist.patch b/queue-6.12/usb-quirks-add-usb_quirk_no_lpm-quirk-for-teclast-dist.patch new file mode 100644 index 0000000000..95b546e47f --- /dev/null +++ b/queue-6.12/usb-quirks-add-usb_quirk_no_lpm-quirk-for-teclast-dist.patch @@ -0,0 +1,33 @@ +From e169d96eecd447ff7fd7542ca5fa0911f5622054 Mon Sep 17 00:00:00 2001 +From: Lei Huang +Date: Wed, 12 Feb 2025 17:38:29 +0800 +Subject: USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist + +From: Lei Huang + +commit e169d96eecd447ff7fd7542ca5fa0911f5622054 upstream. + +Teclast disk used on Huawei hisi platforms doesn't work well, +losing connectivity intermittently if LPM is enabled. +Add quirk disable LPM to resolve the issue. + +Signed-off-by: Lei Huang +Cc: stable +Link: https://lore.kernel.org/r/20250212093829.7379-1-huanglei814@163.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -522,6 +522,9 @@ static const struct usb_device_id usb_qu + /* Blackmagic Design UltraStudio SDI */ + { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Teclast disk */ ++ { USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Hauppauge HVR-950q */ + { USB_DEVICE(0x2040, 0x7200), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, diff --git a/queue-6.12/usb-roles-set-switch-registered-flag-early-on.patch b/queue-6.12/usb-roles-set-switch-registered-flag-early-on.patch new file mode 100644 index 0000000000..7e6b840388 --- /dev/null +++ b/queue-6.12/usb-roles-set-switch-registered-flag-early-on.patch @@ -0,0 +1,66 @@ +From 634775a752a86784511018a108f3b530cc3399a7 Mon Sep 17 00:00:00 2001 +From: Elson Roy Serrao +Date: Thu, 6 Feb 2025 11:39:50 -0800 +Subject: usb: roles: set switch registered flag early on + +From: Elson Roy Serrao + +commit 634775a752a86784511018a108f3b530cc3399a7 upstream. + +The role switch registration and set_role() can happen in parallel as they +are invoked independent of each other. There is a possibility that a driver +might spend significant amount of time in usb_role_switch_register() API +due to the presence of time intensive operations like component_add() +which operate under common mutex. This leads to a time window after +allocating the switch and before setting the registered flag where the set +role notifications are dropped. Below timeline summarizes this behavior + +Thread1 | Thread2 +usb_role_switch_register() | + | | + ---> allocate switch | + | | + ---> component_add() | usb_role_switch_set_role() + | | | + | | --> Drop role notifications + | | since sw->registered + | | flag is not set. + | | + --->Set registered flag.| + +To avoid this, set the registered flag early on in the switch register +API. + +Fixes: b787a3e78175 ("usb: roles: don't get/set_role() when usb_role_switch is unregistered") +Cc: stable +Signed-off-by: Elson Roy Serrao +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250206193950.22421-1-quic_eserrao@quicinc.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/roles/class.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/roles/class.c ++++ b/drivers/usb/roles/class.c +@@ -387,8 +387,11 @@ usb_role_switch_register(struct device * + dev_set_name(&sw->dev, "%s-role-switch", + desc->name ? desc->name : dev_name(parent)); + ++ sw->registered = true; ++ + ret = device_register(&sw->dev); + if (ret) { ++ sw->registered = false; + put_device(&sw->dev); + return ERR_PTR(ret); + } +@@ -399,8 +402,6 @@ usb_role_switch_register(struct device * + dev_warn(&sw->dev, "failed to add component\n"); + } + +- sw->registered = true; +- + /* TODO: Symlinks for the host port and the device controller. */ + + return sw; diff --git a/queue-6.12/usb-serial-option-add-meig-smart-slm828.patch b/queue-6.12/usb-serial-option-add-meig-smart-slm828.patch new file mode 100644 index 0000000000..c8667a82f6 --- /dev/null +++ b/queue-6.12/usb-serial-option-add-meig-smart-slm828.patch @@ -0,0 +1,85 @@ +From db79e75460fc59b19f9c89d4b068e61cee59f37d Mon Sep 17 00:00:00 2001 +From: "Chester A. Unal" +Date: Fri, 24 Jan 2025 10:28:00 +0000 +Subject: USB: serial: option: add MeiG Smart SLM828 + +From: Chester A. Unal + +commit db79e75460fc59b19f9c89d4b068e61cee59f37d upstream. + +MeiG Smart SLM828 is an LTE-A CAT6 modem with the mPCIe form factor. The +"Cls=ff(vend.) Sub=10 Prot=02" and "Cls=ff(vend.) Sub=10 Prot=03" +interfaces respond to AT commands. Add these interfaces. + +The product ID the modem uses is shared across multiple modems. Therefore, +add comments to describe which interface is used for which modem. + +T: Bus=01 Lev=01 Prnt=05 Port=01 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=2dee ProdID=4d22 Rev=05.04 +S: Manufacturer=MEIG +S: Product=LTE-A Module +S: SerialNumber=4da7ec42 +C: #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=10 Prot=01 Driver=(none) +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=02 Driver=(none) +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=03 Driver=(none) +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=04 Driver=(none) +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) +E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=05 Driver=qmi_wwan +E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: Chester A. Unal +Link: https://lore.kernel.org/20250124-for-johan-meig-slm828-v2-1-6b4cd3f6344f@arinc9.com +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -621,7 +621,10 @@ static void option_instat_callback(struc + + /* MeiG Smart Technology products */ + #define MEIGSMART_VENDOR_ID 0x2dee +-/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */ ++/* ++ * MeiG Smart SLM828, SRM815, and SRM825L use the same product ID. SLM828 is ++ * based on Qualcomm SDX12. SRM815 and SRM825L are based on Qualcomm 315. ++ */ + #define MEIGSMART_PRODUCT_SRM825L 0x4d22 + /* MeiG Smart SLM320 based on UNISOC UIS8910 */ + #define MEIGSMART_PRODUCT_SLM320 0x4d41 +@@ -2405,10 +2408,12 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ + .driver_info = NCTRL(1) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ diff --git a/queue-6.12/usb-serial-option-add-telit-cinterion-fn990b-compositions.patch b/queue-6.12/usb-serial-option-add-telit-cinterion-fn990b-compositions.patch new file mode 100644 index 0000000000..e8593441c4 --- /dev/null +++ b/queue-6.12/usb-serial-option-add-telit-cinterion-fn990b-compositions.patch @@ -0,0 +1,208 @@ +From c979fb5ece2dc11cc9cc3d5c66f750e210bfdee2 Mon Sep 17 00:00:00 2001 +From: Fabio Porcedda +Date: Wed, 5 Feb 2025 18:16:45 +0100 +Subject: USB: serial: option: add Telit Cinterion FN990B compositions + +From: Fabio Porcedda + +commit c979fb5ece2dc11cc9cc3d5c66f750e210bfdee2 upstream. + +Add the following Telit Cinterion FN990B40 compositions: + +0x10d0: rmnet + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb +T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 17 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=10d0 Rev=05.15 +S: Manufacturer=Telit Cinterion +S: Product=FN990 +S: SerialNumber=43b38f19 +C: #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +0x10d1: MBIM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb +T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 16 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=10d1 Rev=05.15 +S: Manufacturer=Telit Cinterion +S: Product=FN990 +S: SerialNumber=43b38f19 +C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim +E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +0x10d2: RNDIS + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb +T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 18 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=10d2 Rev=05.15 +S: Manufacturer=Telit Cinterion +S: Product=FN990 +S: SerialNumber=43b38f19 +C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host +E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +0x10d3: ECM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb +T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 20 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=10d3 Rev=05.15 +S: Manufacturer=Telit Cinterion +S: Product=FN990 +S: SerialNumber=43b38f19 +C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether +E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Cc: stable@vger.kernel.org +Signed-off-by: Fabio Porcedda +Reviewed-by: Daniele Palmas +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1406,6 +1406,22 @@ static const struct usb_device_id option + .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ + .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x60) }, /* Telit FN990B (rmnet) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x30), ++ .driver_info = NCTRL(5) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x60) }, /* Telit FN990B (MBIM) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x30), ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x60) }, /* Telit FN990B (RNDIS) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x30), ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x60) }, /* Telit FN990B (ECM) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x30), ++ .driver_info = NCTRL(6) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), diff --git a/queue-6.12/usb-serial-option-drop-meig-smart-defines.patch b/queue-6.12/usb-serial-option-drop-meig-smart-defines.patch new file mode 100644 index 0000000000..8dfa9b3bee --- /dev/null +++ b/queue-6.12/usb-serial-option-drop-meig-smart-defines.patch @@ -0,0 +1,74 @@ +From 6aa8a63c471eb6756aabd03f880feffe6a7af6c9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 11 Feb 2025 15:45:16 +0100 +Subject: USB: serial: option: drop MeiG Smart defines + +From: Johan Hovold + +commit 6aa8a63c471eb6756aabd03f880feffe6a7af6c9 upstream. + +Several MeiG Smart modems apparently use the same product id, making the +defines even less useful. + +Drop them in favour of using comments consistently to make the id table +slightly less unwieldy. + +Cc: stable@vger.kernel.org +Acked-by: Chester A. Unal +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 28 ++++++++-------------------- + 1 file changed, 8 insertions(+), 20 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -619,18 +619,6 @@ static void option_instat_callback(struc + /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ + #define LUAT_PRODUCT_AIR720U 0x4e00 + +-/* MeiG Smart Technology products */ +-#define MEIGSMART_VENDOR_ID 0x2dee +-/* +- * MeiG Smart SLM828, SRM815, and SRM825L use the same product ID. SLM828 is +- * based on Qualcomm SDX12. SRM815 and SRM825L are based on Qualcomm 315. +- */ +-#define MEIGSMART_PRODUCT_SRM825L 0x4d22 +-/* MeiG Smart SLM320 based on UNISOC UIS8910 */ +-#define MEIGSMART_PRODUCT_SLM320 0x4d41 +-/* MeiG Smart SLM770A based on ASR1803 */ +-#define MEIGSMART_PRODUCT_SLM770A 0x4d57 +- + /* Device flags */ + + /* Highest interface number which can be used with NCTRL() and RSVD() */ +@@ -2366,6 +2354,14 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ +@@ -2422,14 +2418,6 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ + .driver_info = NCTRL(1) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ diff --git a/queue-6.12/usb-serial-option-fix-telit-cinterion-fn990a-name.patch b/queue-6.12/usb-serial-option-fix-telit-cinterion-fn990a-name.patch new file mode 100644 index 0000000000..3ee474d0b8 --- /dev/null +++ b/queue-6.12/usb-serial-option-fix-telit-cinterion-fn990a-name.patch @@ -0,0 +1,43 @@ +From 12606fe73f33647c5e79bf666833bf0b225e649d Mon Sep 17 00:00:00 2001 +From: Fabio Porcedda +Date: Wed, 5 Feb 2025 18:16:47 +0100 +Subject: USB: serial: option: fix Telit Cinterion FN990A name + +From: Fabio Porcedda + +commit 12606fe73f33647c5e79bf666833bf0b225e649d upstream. + +The correct name for FN990 is FN990A so use it in order to avoid +confusion with FN990B. + +Signed-off-by: Fabio Porcedda +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1370,15 +1370,15 @@ static const struct usb_device_id option + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */ + .driver_info = NCTRL(2) | RSVD(3) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */ + .driver_info = RSVD(0) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, diff --git a/queue-6.12/usb-xhci-restore-xhci_pci-support-for-renesas-hcs.patch b/queue-6.12/usb-xhci-restore-xhci_pci-support-for-renesas-hcs.patch new file mode 100644 index 0000000000..cb75cd2298 --- /dev/null +++ b/queue-6.12/usb-xhci-restore-xhci_pci-support-for-renesas-hcs.patch @@ -0,0 +1,55 @@ +From c81d9fcd5b9402166048f377d4e5e0ee6f9ef26d Mon Sep 17 00:00:00 2001 +From: Michal Pecio +Date: Tue, 28 Jan 2025 10:45:29 +0100 +Subject: usb: xhci: Restore xhci_pci support for Renesas HCs + +From: Michal Pecio + +commit c81d9fcd5b9402166048f377d4e5e0ee6f9ef26d upstream. + +Some Renesas HCs require firmware upload to work, this is handled by the +xhci_pci_renesas driver. Other variants of those chips load firmware from +a SPI flash and are ready to work with xhci_pci alone. + +A refactor merged in v6.12 broke the latter configuration so that users +are finding their hardware ignored by the normal driver and are forced to +enable the firmware loader which isn't really necessary on their systems. + +Let xhci_pci work with those chips as before when the firmware loader is +disabled by kernel configuration. + +Fixes: 25f51b76f90f ("xhci-pci: Make xhci-pci-renesas a proper modular driver") +Cc: stable +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219616 +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219726 +Signed-off-by: Michal Pecio +Tested-by: Nicolai Buchwitz +Link: https://lore.kernel.org/r/20250128104529.58a79bfc@foxbook +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-pci.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -656,8 +656,8 @@ put_runtime_pm: + } + EXPORT_SYMBOL_NS_GPL(xhci_pci_common_probe, xhci); + +-static const struct pci_device_id pci_ids_reject[] = { +- /* handled by xhci-pci-renesas */ ++/* handled by xhci-pci-renesas if enabled */ ++static const struct pci_device_id pci_ids_renesas[] = { + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0014) }, + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0015) }, + { /* end: all zeroes */ } +@@ -665,7 +665,8 @@ static const struct pci_device_id pci_id + + static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + { +- if (pci_match_id(pci_ids_reject, dev)) ++ if (IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS) && ++ pci_match_id(pci_ids_renesas, dev)) + return -ENODEV; + + return xhci_pci_common_probe(dev, id); diff --git a/queue-6.12/wifi-ath12k-fix-handling-of-6-ghz-rules.patch b/queue-6.12/wifi-ath12k-fix-handling-of-6-ghz-rules.patch new file mode 100644 index 0000000000..f54661e124 --- /dev/null +++ b/queue-6.12/wifi-ath12k-fix-handling-of-6-ghz-rules.patch @@ -0,0 +1,145 @@ +From 64a1ba4072b34af1b76bf15fca5c2075b8cc4d64 Mon Sep 17 00:00:00 2001 +From: Aditya Kumar Singh +Date: Thu, 23 Jan 2025 21:51:38 +0530 +Subject: wifi: ath12k: fix handling of 6 GHz rules + +From: Aditya Kumar Singh + +commit 64a1ba4072b34af1b76bf15fca5c2075b8cc4d64 upstream. + +In the US country code, to avoid including 6 GHz rules in the 5 GHz rules +list, the number of 5 GHz rules is set to a default constant value of 4 +(REG_US_5G_NUM_REG_RULES). However, if there are more than 4 valid 5 GHz +rules, the current logic will bypass the legitimate 6 GHz rules. + +For example, if there are 5 valid 5 GHz rules and 1 valid 6 GHz rule, the +current logic will only consider 4 of the 5 GHz rules, treating the last +valid rule as a 6 GHz rule. Consequently, the actual 6 GHz rule is never +processed, leading to the eventual disabling of 6 GHz channels. + +To fix this issue, instead of hardcoding the value to 4, use a helper +function to determine the number of 6 GHz rules present in the 5 GHz rules +list and ignore only those rules. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 + +Cc: stable@vger.kernel.org +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Aditya Kumar Singh +Link: https://patch.msgid.link/20250123-fix_6ghz_rules_handling-v1-1-d734bfa58ff4@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath12k/wmi.c | 61 +++++++++++++++++++++++++--------- + drivers/net/wireless/ath/ath12k/wmi.h | 1 + 2 files changed, 45 insertions(+), 17 deletions(-) + +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -4681,6 +4681,22 @@ static struct ath12k_reg_rule + return reg_rule_ptr; + } + ++static u8 ath12k_wmi_ignore_num_extra_rules(struct ath12k_wmi_reg_rule_ext_params *rule, ++ u32 num_reg_rules) ++{ ++ u8 num_invalid_5ghz_rules = 0; ++ u32 count, start_freq; ++ ++ for (count = 0; count < num_reg_rules; count++) { ++ start_freq = le32_get_bits(rule[count].freq_info, REG_RULE_START_FREQ); ++ ++ if (start_freq >= ATH12K_MIN_6G_FREQ) ++ num_invalid_5ghz_rules++; ++ } ++ ++ return num_invalid_5ghz_rules; ++} ++ + static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, + struct sk_buff *skb, + struct ath12k_reg_info *reg_info) +@@ -4691,6 +4707,7 @@ static int ath12k_pull_reg_chan_list_ext + u32 num_2g_reg_rules, num_5g_reg_rules; + u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u32 num_6g_reg_rules_cl[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; ++ u8 num_invalid_5ghz_ext_rules; + u32 total_reg_rules = 0; + int ret, i, j; + +@@ -4784,20 +4801,6 @@ static int ath12k_pull_reg_chan_list_ext + + memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN); + +- /* FIXME: Currently FW includes 6G reg rule also in 5G rule +- * list for country US. +- * Having same 6G reg rule in 5G and 6G rules list causes +- * intersect check to be true, and same rules will be shown +- * multiple times in iw cmd. So added hack below to avoid +- * parsing 6G rule from 5G reg rule list, and this can be +- * removed later, after FW updates to remove 6G reg rule +- * from 5G rules list. +- */ +- if (memcmp(reg_info->alpha2, "US", 2) == 0) { +- reg_info->num_5g_reg_rules = REG_US_5G_NUM_REG_RULES; +- num_5g_reg_rules = reg_info->num_5g_reg_rules; +- } +- + reg_info->dfs_region = le32_to_cpu(ev->dfs_region); + reg_info->phybitmap = le32_to_cpu(ev->phybitmap); + reg_info->num_phy = le32_to_cpu(ev->num_phy); +@@ -4900,8 +4903,29 @@ static int ath12k_pull_reg_chan_list_ext + } + } + ++ ext_wmi_reg_rule += num_2g_reg_rules; ++ ++ /* Firmware might include 6 GHz reg rule in 5 GHz rule list ++ * for few countries along with separate 6 GHz rule. ++ * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list ++ * causes intersect check to be true, and same rules will be ++ * shown multiple times in iw cmd. ++ * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list ++ */ ++ num_invalid_5ghz_ext_rules = ath12k_wmi_ignore_num_extra_rules(ext_wmi_reg_rule, ++ num_5g_reg_rules); ++ ++ if (num_invalid_5ghz_ext_rules) { ++ ath12k_dbg(ab, ATH12K_DBG_WMI, ++ "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules", ++ reg_info->alpha2, reg_info->num_5g_reg_rules, ++ num_invalid_5ghz_ext_rules); ++ ++ num_5g_reg_rules = num_5g_reg_rules - num_invalid_5ghz_ext_rules; ++ reg_info->num_5g_reg_rules = num_5g_reg_rules; ++ } ++ + if (num_5g_reg_rules) { +- ext_wmi_reg_rule += num_2g_reg_rules; + reg_info->reg_rules_5g_ptr = + create_ext_reg_rules_from_wmi(num_5g_reg_rules, + ext_wmi_reg_rule); +@@ -4913,7 +4937,12 @@ static int ath12k_pull_reg_chan_list_ext + } + } + +- ext_wmi_reg_rule += num_5g_reg_rules; ++ /* We have adjusted the number of 5 GHz reg rules above. But still those ++ * many rules needs to be adjusted in ext_wmi_reg_rule. ++ * ++ * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases. ++ */ ++ ext_wmi_reg_rule += (num_5g_reg_rules + num_invalid_5ghz_ext_rules); + + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { + reg_info->reg_rules_6g_ap_ptr[i] = +--- a/drivers/net/wireless/ath/ath12k/wmi.h ++++ b/drivers/net/wireless/ath/ath12k/wmi.h +@@ -3943,7 +3943,6 @@ struct ath12k_wmi_eht_rate_set_params { + #define MAX_REG_RULES 10 + #define REG_ALPHA2_LEN 2 + #define MAX_6G_REG_RULES 5 +-#define REG_US_5G_NUM_REG_RULES 4 + + enum wmi_start_event_param { + WMI_VDEV_START_RESP_EVENT = 0,