From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id BD4A91584AD for ; Fri, 09 May 2025 10:57:15 +0000 (UTC) Received: from lists.gentoo.org (bobolink.gentoo.org [140.211.166.189]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) (Authenticated sender: relay-lists.gentoo.org@gentoo.org) by smtp.gentoo.org (Postfix) with ESMTPSA id A57973432CA for ; Fri, 09 May 2025 10:57:15 +0000 (UTC) Received: from bobolink.gentoo.org (localhost [127.0.0.1]) by bobolink.gentoo.org (Postfix) with ESMTP id 42D9B11036F; Fri, 09 May 2025 10:57:14 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bobolink.gentoo.org (Postfix) with ESMTPS id 396C611036F for ; Fri, 09 May 2025 10:57:14 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 4E9FC342FED for ; Fri, 09 May 2025 10:57:13 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id EAE60146D for ; Fri, 09 May 2025 10:57:11 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1746788218.97a927178861131f62887a80fe1e3721bcf3410c.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:6.12 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1027_linux-6.12.28.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 97a927178861131f62887a80fe1e3721bcf3410c X-VCS-Branch: 6.12 Date: Fri, 09 May 2025 10:57:11 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: b9cc1562-b972-4919-b5b9-3b9c1eeeb0aa X-Archives-Hash: 8f4e1f4aa38af405e866d4507dc66582 commit: 97a927178861131f62887a80fe1e3721bcf3410c Author: Mike Pagano gentoo org> AuthorDate: Fri May 9 10:56:58 2025 +0000 Commit: Mike Pagano gentoo org> CommitDate: Fri May 9 10:56:58 2025 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=97a92717 Linux patch 6.12.28 Signed-off-by: Mike Pagano gentoo.org> 0000_README | 4 + 1027_linux-6.12.28.patch | 6726 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 6730 insertions(+) diff --git a/0000_README b/0000_README index acc6bba1..f98bc820 100644 --- a/0000_README +++ b/0000_README @@ -151,6 +151,10 @@ Patch: 1026_linux-6.12.27.patch From: https://www.kernel.org Desc: Linux 6.12.27 +Patch: 1027_linux-6.12.28.patch +From: https://www.kernel.org +Desc: Linux 6.12.28 + Patch: 1500_fortify-copy-size-value-range-tracking-fix.patch From: https://git.kernel.org/ Desc: fortify: Hide run-time copy size from value range tracking diff --git a/1027_linux-6.12.28.patch b/1027_linux-6.12.28.patch new file mode 100644 index 00000000..7a76e822 --- /dev/null +++ b/1027_linux-6.12.28.patch @@ -0,0 +1,6726 @@ +diff --git a/Makefile b/Makefile +index 77f5d180902cd6..f26e0f946f02ee 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 12 +-SUBLEVEL = 27 ++SUBLEVEL = 28 + EXTRAVERSION = + NAME = Baby Opossum Posse + +diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi +index f2386dcb9ff2c0..dda4fa91b2f2cc 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi +@@ -40,6 +40,9 @@ ethphy1: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&gpio4>; + interrupts = <16 IRQ_TYPE_LEVEL_LOW>; ++ micrel,led-mode = <1>; ++ clocks = <&clks IMX6UL_CLK_ENET_REF>; ++ clock-names = "rmii-ref"; + status = "okay"; + }; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi +index 40cbb071f265cf..f904d6b1c84bf0 100644 +--- a/arch/arm64/boot/dts/freescale/imx95.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx95.dtsi +@@ -1478,7 +1478,7 @@ pcie0: pcie@4c300000 { + reg = <0 0x4c300000 0 0x10000>, + <0 0x60100000 0 0xfe00000>, + <0 0x4c360000 0 0x10000>, +- <0 0x4c340000 0 0x2000>; ++ <0 0x4c340000 0 0x4000>; + reg-names = "dbi", "config", "atu", "app"; + ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>, + <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>; +@@ -1518,7 +1518,7 @@ pcie0_ep: pcie-ep@4c300000 { + reg = <0 0x4c300000 0 0x10000>, + <0 0x4c360000 0 0x1000>, + <0 0x4c320000 0 0x1000>, +- <0 0x4c340000 0 0x2000>, ++ <0 0x4c340000 0 0x4000>, + <0 0x4c370000 0 0x10000>, + <0x9 0 1 0>; + reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space"; +@@ -1545,7 +1545,7 @@ pcie1: pcie@4c380000 { + reg = <0 0x4c380000 0 0x10000>, + <8 0x80100000 0 0xfe00000>, + <0 0x4c3e0000 0 0x10000>, +- <0 0x4c3c0000 0 0x2000>; ++ <0 0x4c3c0000 0 0x4000>; + reg-names = "dbi", "config", "atu", "app"; + ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>, + <0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>; +@@ -1585,7 +1585,7 @@ pcie1_ep: pcie-ep@4c380000 { + reg = <0 0x4c380000 0 0x10000>, + <0 0x4c3e0000 0 0x1000>, + <0 0x4c3a0000 0 0x1000>, +- <0 0x4c3c0000 0 0x2000>, ++ <0 0x4c3c0000 0 0x4000>, + <0 0x4c3f0000 0 0x10000>, + <0xa 0 1 0>; + reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space"; +diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi +index 1167cf63d7e87a..cd9b92144a42cb 100644 +--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi ++++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi +@@ -114,14 +114,13 @@ scmi_vdda18adc: regulator@7 { + }; + + intc: interrupt-controller@4ac00000 { +- compatible = "arm,cortex-a7-gic"; ++ compatible = "arm,gic-400"; + #interrupt-cells = <3>; +- #address-cells = <1>; + interrupt-controller; + reg = <0x0 0x4ac10000 0x0 0x1000>, +- <0x0 0x4ac20000 0x0 0x2000>, +- <0x0 0x4ac40000 0x0 0x2000>, +- <0x0 0x4ac60000 0x0 0x2000>; ++ <0x0 0x4ac20000 0x0 0x20000>, ++ <0x0 0x4ac40000 0x0 0x20000>, ++ <0x0 0x4ac60000 0x0 0x20000>; + }; + + psci { +diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c +index 0f51fd10b4b063..30e79f111b35e3 100644 +--- a/arch/arm64/kernel/proton-pack.c ++++ b/arch/arm64/kernel/proton-pack.c +@@ -879,10 +879,12 @@ static u8 spectre_bhb_loop_affected(void) + static const struct midr_range spectre_bhb_k132_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), ++ {}, + }; + static const struct midr_range spectre_bhb_k38_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), ++ {}, + }; + static const struct midr_range spectre_bhb_k32_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), +diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h +index 38fc0b188e0842..96831c98860658 100644 +--- a/arch/parisc/include/uapi/asm/socket.h ++++ b/arch/parisc/include/uapi/asm/socket.h +@@ -132,11 +132,15 @@ + #define SO_PASSPIDFD 0x404A + #define SO_PEERPIDFD 0x404B + +-#define SO_DEVMEM_LINEAR 78 ++#define SCM_TS_OPT_ID 0x404C ++ ++#define SO_RCVPRIORITY 0x404D ++ ++#define SO_DEVMEM_LINEAR 0x404E + #define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR +-#define SO_DEVMEM_DMABUF 79 ++#define SO_DEVMEM_DMABUF 0x404F + #define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF +-#define SO_DEVMEM_DONTNEED 80 ++#define SO_DEVMEM_DONTNEED 0x4050 + + #if !defined(__KERNEL__) + +diff --git a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c +index 34495446e051c2..71829cb7bc812a 100644 +--- a/arch/parisc/math-emu/driver.c ++++ b/arch/parisc/math-emu/driver.c +@@ -97,9 +97,19 @@ handle_fpe(struct pt_regs *regs) + + memcpy(regs->fr, frcopy, sizeof regs->fr); + if (signalcode != 0) { +- force_sig_fault(signalcode >> 24, signalcode & 0xffffff, +- (void __user *) regs->iaoq[0]); +- return -1; ++ int sig = signalcode >> 24; ++ ++ if (sig == SIGFPE) { ++ /* ++ * Clear floating point trap bit to avoid trapping ++ * again on the first floating-point instruction in ++ * the userspace signal handler. ++ */ ++ regs->fr[0] &= ~(1ULL << 38); ++ } ++ force_sig_fault(sig, signalcode & 0xffffff, ++ (void __user *) regs->iaoq[0]); ++ return -1; + } + + return signalcode ? -1 : 0; +diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper +index b1f5549a3c9c40..fd6db10ef9e65e 100755 +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -234,10 +234,8 @@ fi + + # suppress some warnings in recent ld versions + nowarn="-z noexecstack" +-if ! ld_is_lld; then +- if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then +- nowarn="$nowarn --no-warn-rwx-segments" +- fi ++if "${CROSS}ld" -v --no-warn-rwx-segments >/dev/null 2>&1; then ++ nowarn="$nowarn --no-warn-rwx-segments" + fi + + platformo=$object/"$platform".o +diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c +index b0d927009af83c..04189689c127e3 100644 +--- a/arch/powerpc/mm/book3s64/radix_pgtable.c ++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c +@@ -1132,6 +1132,19 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in + pmd_t *pmd; + pte_t *pte; + ++ /* ++ * Make sure we align the start vmemmap addr so that we calculate ++ * the correct start_pfn in altmap boundary check to decided whether ++ * we should use altmap or RAM based backing memory allocation. Also ++ * the address need to be aligned for set_pte operation. ++ ++ * If the start addr is already PMD_SIZE aligned we will try to use ++ * a pmd mapping. We don't want to be too aggressive here beacause ++ * that will cause more allocations in RAM. So only if the namespace ++ * vmemmap start addr is PMD_SIZE aligned we will use PMD mapping. ++ */ ++ ++ start = ALIGN_DOWN(start, PAGE_SIZE); + for (addr = start; addr < end; addr = next) { + next = pmd_addr_end(addr, end); + +@@ -1157,8 +1170,8 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in + * in altmap block allocation failures, in which case + * we fallback to RAM for vmemmap allocation. + */ +- if (altmap && (!IS_ALIGNED(addr, PMD_SIZE) || +- altmap_cross_boundary(altmap, addr, PMD_SIZE))) { ++ if (!IS_ALIGNED(addr, PMD_SIZE) || (altmap && ++ altmap_cross_boundary(altmap, addr, PMD_SIZE))) { + /* + * make sure we don't create altmap mappings + * covering things outside the device. +diff --git a/arch/x86/boot/compressed/mem.c b/arch/x86/boot/compressed/mem.c +index f676156d9f3db4..0e9f84ab4bdcd1 100644 +--- a/arch/x86/boot/compressed/mem.c ++++ b/arch/x86/boot/compressed/mem.c +@@ -34,14 +34,11 @@ static bool early_is_tdx_guest(void) + + void arch_accept_memory(phys_addr_t start, phys_addr_t end) + { +- static bool sevsnp; +- + /* Platform-specific memory-acceptance call goes here */ + if (early_is_tdx_guest()) { + if (!tdx_accept_memory(start, end)) + panic("TDX: Failed to accept memory\n"); +- } else if (sevsnp || (sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) { +- sevsnp = true; ++ } else if (early_is_sevsnp_guest()) { + snp_accept_memory(start, end); + } else { + error("Cannot accept memory: unknown platform\n"); +diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c +index f49f7eef1dba07..a93e3633886699 100644 +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -644,3 +644,43 @@ void sev_prep_identity_maps(unsigned long top_level_pgt) + + sev_verify_cbit(top_level_pgt); + } ++ ++bool early_is_sevsnp_guest(void) ++{ ++ static bool sevsnp; ++ ++ if (sevsnp) ++ return true; ++ ++ if (!(sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) ++ return false; ++ ++ sevsnp = true; ++ ++ if (!snp_vmpl) { ++ unsigned int eax, ebx, ecx, edx; ++ ++ /* ++ * CPUID Fn8000_001F_EAX[28] - SVSM support ++ */ ++ eax = 0x8000001f; ++ ecx = 0; ++ native_cpuid(&eax, &ebx, &ecx, &edx); ++ if (eax & BIT(28)) { ++ struct msr m; ++ ++ /* Obtain the address of the calling area to use */ ++ boot_rdmsr(MSR_SVSM_CAA, &m); ++ boot_svsm_caa = (void *)m.q; ++ boot_svsm_caa_pa = m.q; ++ ++ /* ++ * The real VMPL level cannot be discovered, but the ++ * memory acceptance routines make no use of that so ++ * any non-zero value suffices here. ++ */ ++ snp_vmpl = U8_MAX; ++ } ++ } ++ return true; ++} +diff --git a/arch/x86/boot/compressed/sev.h b/arch/x86/boot/compressed/sev.h +index 4e463f33186df4..d3900384b8abb5 100644 +--- a/arch/x86/boot/compressed/sev.h ++++ b/arch/x86/boot/compressed/sev.h +@@ -13,12 +13,14 @@ + bool sev_snp_enabled(void); + void snp_accept_memory(phys_addr_t start, phys_addr_t end); + u64 sev_get_status(void); ++bool early_is_sevsnp_guest(void); + + #else + + static inline bool sev_snp_enabled(void) { return false; } + static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { } + static inline u64 sev_get_status(void) { return 0; } ++static inline bool early_is_sevsnp_guest(void) { return false; } + + #endif + +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index d737d53d03aa94..471eaa46d55f8d 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -753,7 +753,7 @@ void x86_pmu_enable_all(int added) + } + } + +-static inline int is_x86_event(struct perf_event *event) ++int is_x86_event(struct perf_event *event) + { + int i; + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index f86e47afd56099..5e43d390f7a3dd 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4333,7 +4333,7 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data) + arr[pebs_enable] = (struct perf_guest_switch_msr){ + .msr = MSR_IA32_PEBS_ENABLE, + .host = cpuc->pebs_enabled & ~cpuc->intel_ctrl_guest_mask, +- .guest = pebs_mask & ~cpuc->intel_ctrl_host_mask, ++ .guest = pebs_mask & ~cpuc->intel_ctrl_host_mask & kvm_pmu->pebs_enable, + }; + + if (arr[pebs_enable].host) { +diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h +index 8c616656391ec4..76b6d8469dba8c 100644 +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -110,9 +110,16 @@ static inline bool is_topdown_event(struct perf_event *event) + return is_metric_event(event) || is_slots_event(event); + } + ++int is_x86_event(struct perf_event *event); ++ ++static inline bool check_leader_group(struct perf_event *leader, int flags) ++{ ++ return is_x86_event(leader) ? !!(leader->hw.flags & flags) : false; ++} ++ + static inline bool is_branch_counters_group(struct perf_event *event) + { +- return event->group_leader->hw.flags & PERF_X86_EVENT_BRANCH_COUNTERS; ++ return check_leader_group(event->group_leader, PERF_X86_EVENT_BRANCH_COUNTERS); + } + + struct amd_nb { +diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c +index ad8d6a363f24ae..444798c5374f48 100644 +--- a/block/blk-mq-cpumap.c ++++ b/block/blk-mq-cpumap.c +@@ -87,7 +87,6 @@ void blk_mq_map_hw_queues(struct blk_mq_queue_map *qmap, + return; + + fallback: +- WARN_ON_ONCE(qmap->nr_queues > 1); +- blk_mq_clear_mq_map(qmap); ++ blk_mq_map_queues(qmap); + } + EXPORT_SYMBOL_GPL(blk_mq_map_hw_queues); +diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c +index 88df2cdc46b62b..168d03d5aa1d07 100644 +--- a/drivers/accel/ivpu/ivpu_drv.c ++++ b/drivers/accel/ivpu/ivpu_drv.c +@@ -36,8 +36,6 @@ + __stringify(DRM_IVPU_DRIVER_MINOR) "." + #endif + +-static struct lock_class_key submitted_jobs_xa_lock_class_key; +- + int ivpu_dbg_mask; + module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644); + MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros."); +@@ -260,6 +258,9 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) + if (ret) + goto err_xa_erase; + ++ file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); ++ file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; ++ + mutex_unlock(&vdev->context_list_lock); + drm_dev_exit(idx); + +@@ -452,26 +453,6 @@ static const struct drm_driver driver = { + .minor = DRM_IVPU_DRIVER_MINOR, + }; + +-static void ivpu_context_abort_invalid(struct ivpu_device *vdev) +-{ +- struct ivpu_file_priv *file_priv; +- unsigned long ctx_id; +- +- mutex_lock(&vdev->context_list_lock); +- +- xa_for_each(&vdev->context_xa, ctx_id, file_priv) { +- if (!file_priv->has_mmu_faults || file_priv->aborted) +- continue; +- +- mutex_lock(&file_priv->lock); +- ivpu_context_abort_locked(file_priv); +- file_priv->aborted = true; +- mutex_unlock(&file_priv->lock); +- } +- +- mutex_unlock(&vdev->context_list_lock); +-} +- + static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg) + { + struct ivpu_device *vdev = arg; +@@ -485,9 +466,6 @@ static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg) + case IVPU_HW_IRQ_SRC_IPC: + ivpu_ipc_irq_thread_handler(vdev); + break; +- case IVPU_HW_IRQ_SRC_MMU_EVTQ: +- ivpu_context_abort_invalid(vdev); +- break; + case IVPU_HW_IRQ_SRC_DCT: + ivpu_pm_dct_irq_thread_handler(vdev); + break; +@@ -604,13 +582,21 @@ static int ivpu_dev_init(struct ivpu_device *vdev) + xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); + xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1); + xa_init_flags(&vdev->db_xa, XA_FLAGS_ALLOC1); +- lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); + INIT_LIST_HEAD(&vdev->bo_list); + ++ vdev->db_limit.min = IVPU_MIN_DB; ++ vdev->db_limit.max = IVPU_MAX_DB; ++ ++ INIT_WORK(&vdev->context_abort_work, ivpu_context_abort_thread_handler); ++ + ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); + if (ret) + goto err_xa_destroy; + ++ ret = drmm_mutex_init(&vdev->drm, &vdev->submitted_jobs_lock); ++ if (ret) ++ goto err_xa_destroy; ++ + ret = drmm_mutex_init(&vdev->drm, &vdev->bo_list_lock); + if (ret) + goto err_xa_destroy; +diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h +index 9430a24994c32e..a5707a85e72556 100644 +--- a/drivers/accel/ivpu/ivpu_drv.h ++++ b/drivers/accel/ivpu/ivpu_drv.h +@@ -46,6 +46,9 @@ + #define IVPU_MIN_DB 1 + #define IVPU_MAX_DB 255 + ++#define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) ++#define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) ++ + #define IVPU_NUM_ENGINES 2 + #define IVPU_NUM_PRIORITIES 4 + #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) +@@ -134,12 +137,16 @@ struct ivpu_device { + struct mutex context_list_lock; /* Protects user context addition/removal */ + struct xarray context_xa; + struct xa_limit context_xa_limit; ++ struct work_struct context_abort_work; + + struct xarray db_xa; ++ struct xa_limit db_limit; ++ u32 db_next; + + struct mutex bo_list_lock; /* Protects bo_list */ + struct list_head bo_list; + ++ struct mutex submitted_jobs_lock; /* Protects submitted_jobs */ + struct xarray submitted_jobs_xa; + struct ivpu_ipc_consumer job_done_consumer; + +@@ -171,6 +178,8 @@ struct ivpu_file_priv { + struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ + struct list_head ms_instance_list; + struct ivpu_bo *ms_info_bo; ++ struct xa_limit job_limit; ++ u32 job_id_next; + bool has_mmu_faults; + bool bound; + bool aborted; +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index 71792dab3c2107..3855e2df1e0c83 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -14,7 +14,7 @@ + #define PLL_PROFILING_FREQ_DEFAULT 38400000 + #define PLL_PROFILING_FREQ_HIGH 400000000 + +-#define DCT_DEFAULT_ACTIVE_PERCENT 15u ++#define DCT_DEFAULT_ACTIVE_PERCENT 30u + #define DCT_PERIOD_US 35300u + + int ivpu_hw_btrs_info_init(struct ivpu_device *vdev); +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index 91f7f6f3ca675b..27121c66e48f81 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -21,8 +21,6 @@ + #include "vpu_boot_api.h" + + #define CMD_BUF_IDX 0 +-#define JOB_ID_JOB_MASK GENMASK(7, 0) +-#define JOB_ID_CONTEXT_MASK GENMASK(31, 8) + #define JOB_MAX_BUFFER_COUNT 65535 + + static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq) +@@ -79,7 +77,6 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, + + static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) + { +- struct xa_limit db_xa_limit = {.max = IVPU_MAX_DB, .min = IVPU_MIN_DB}; + struct ivpu_device *vdev = file_priv->vdev; + struct ivpu_cmdq *cmdq; + int ret; +@@ -88,8 +85,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) + if (!cmdq) + return NULL; + +- ret = xa_alloc(&vdev->db_xa, &cmdq->db_id, NULL, db_xa_limit, GFP_KERNEL); +- if (ret) { ++ ret = xa_alloc_cyclic(&vdev->db_xa, &cmdq->db_id, NULL, vdev->db_limit, &vdev->db_next, ++ GFP_KERNEL); ++ if (ret < 0) { + ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); + goto err_free_cmdq; + } +@@ -337,6 +335,8 @@ void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) + + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_OS) + ivpu_jsm_context_release(vdev, file_priv->ctx.id); ++ ++ file_priv->aborted = true; + } + + static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) +@@ -354,7 +354,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) + return -EBUSY; + } + +- entry = &cmdq->jobq->job[tail]; ++ entry = &cmdq->jobq->slot[tail].job; + entry->batch_buf_addr = job->cmd_buf_vpu_addr; + entry->job_id = job->job_id; + entry->flags = 0; +@@ -469,16 +469,14 @@ static struct ivpu_job *ivpu_job_remove_from_submitted_jobs(struct ivpu_device * + { + struct ivpu_job *job; + +- xa_lock(&vdev->submitted_jobs_xa); +- job = __xa_erase(&vdev->submitted_jobs_xa, job_id); ++ lockdep_assert_held(&vdev->submitted_jobs_lock); + ++ job = xa_erase(&vdev->submitted_jobs_xa, job_id); + if (xa_empty(&vdev->submitted_jobs_xa) && job) { + vdev->busy_time = ktime_add(ktime_sub(ktime_get(), vdev->busy_start_ts), + vdev->busy_time); + } + +- xa_unlock(&vdev->submitted_jobs_xa); +- + return job; + } + +@@ -486,6 +484,28 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 + { + struct ivpu_job *job; + ++ lockdep_assert_held(&vdev->submitted_jobs_lock); ++ ++ job = xa_load(&vdev->submitted_jobs_xa, job_id); ++ if (!job) ++ return -ENOENT; ++ ++ if (job_status == VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW) { ++ guard(mutex)(&job->file_priv->lock); ++ ++ if (job->file_priv->has_mmu_faults) ++ return 0; ++ ++ /* ++ * Mark context as faulty and defer destruction of the job to jobs abort thread ++ * handler to synchronize between both faults and jobs returning context violation ++ * status and ensure both are handled in the same way ++ */ ++ job->file_priv->has_mmu_faults = true; ++ queue_work(system_wq, &vdev->context_abort_work); ++ return 0; ++ } ++ + job = ivpu_job_remove_from_submitted_jobs(vdev, job_id); + if (!job) + return -ENOENT; +@@ -503,6 +523,10 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 + ivpu_stop_job_timeout_detection(vdev); + + ivpu_rpm_put(vdev); ++ ++ if (!xa_empty(&vdev->submitted_jobs_xa)) ++ ivpu_start_job_timeout_detection(vdev); ++ + return 0; + } + +@@ -511,15 +535,18 @@ void ivpu_jobs_abort_all(struct ivpu_device *vdev) + struct ivpu_job *job; + unsigned long id; + ++ mutex_lock(&vdev->submitted_jobs_lock); ++ + xa_for_each(&vdev->submitted_jobs_xa, id, job) + ivpu_job_signal_and_destroy(vdev, id, DRM_IVPU_JOB_STATUS_ABORTED); ++ ++ mutex_unlock(&vdev->submitted_jobs_lock); + } + + static int ivpu_job_submit(struct ivpu_job *job, u8 priority) + { + struct ivpu_file_priv *file_priv = job->file_priv; + struct ivpu_device *vdev = job->vdev; +- struct xa_limit job_id_range; + struct ivpu_cmdq *cmdq; + bool is_first_job; + int ret; +@@ -528,27 +555,25 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) + if (ret < 0) + return ret; + ++ mutex_lock(&vdev->submitted_jobs_lock); + mutex_lock(&file_priv->lock); + +- cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx, priority); ++ cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); + if (!cmdq) { + ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", + file_priv->ctx.id, job->engine_idx, priority); + ret = -EINVAL; +- goto err_unlock_file_priv; ++ goto err_unlock; + } + +- job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); +- job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK; +- +- xa_lock(&vdev->submitted_jobs_xa); + is_first_job = xa_empty(&vdev->submitted_jobs_xa); +- ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL); +- if (ret) { ++ ret = xa_alloc_cyclic(&vdev->submitted_jobs_xa, &job->job_id, job, file_priv->job_limit, ++ &file_priv->job_id_next, GFP_KERNEL); ++ if (ret < 0) { + ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", + file_priv->ctx.id); + ret = -EBUSY; +- goto err_unlock_submitted_jobs_xa; ++ goto err_unlock; + } + + ret = ivpu_cmdq_push_job(cmdq, job); +@@ -570,20 +595,20 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) + job->job_id, file_priv->ctx.id, job->engine_idx, priority, + job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); + +- xa_unlock(&vdev->submitted_jobs_xa); +- + mutex_unlock(&file_priv->lock); + +- if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_HW)) ++ if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_HW)) { + ivpu_job_signal_and_destroy(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS); ++ } ++ ++ mutex_unlock(&vdev->submitted_jobs_lock); + + return 0; + + err_erase_xa: +- __xa_erase(&vdev->submitted_jobs_xa, job->job_id); +-err_unlock_submitted_jobs_xa: +- xa_unlock(&vdev->submitted_jobs_xa); +-err_unlock_file_priv: ++ xa_erase(&vdev->submitted_jobs_xa, job->job_id); ++err_unlock: ++ mutex_unlock(&vdev->submitted_jobs_lock); + mutex_unlock(&file_priv->lock); + ivpu_rpm_put(vdev); + return ret; +@@ -753,7 +778,6 @@ ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr, + struct vpu_jsm_msg *jsm_msg) + { + struct vpu_ipc_msg_payload_job_done *payload; +- int ret; + + if (!jsm_msg) { + ivpu_err(vdev, "IPC message has no JSM payload\n"); +@@ -766,9 +790,10 @@ ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr, + } + + payload = (struct vpu_ipc_msg_payload_job_done *)&jsm_msg->payload; +- ret = ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status); +- if (!ret && !xa_empty(&vdev->submitted_jobs_xa)) +- ivpu_start_job_timeout_detection(vdev); ++ ++ mutex_lock(&vdev->submitted_jobs_lock); ++ ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status); ++ mutex_unlock(&vdev->submitted_jobs_lock); + } + + void ivpu_job_done_consumer_init(struct ivpu_device *vdev) +@@ -781,3 +806,41 @@ void ivpu_job_done_consumer_fini(struct ivpu_device *vdev) + { + ivpu_ipc_consumer_del(vdev, &vdev->job_done_consumer); + } ++ ++void ivpu_context_abort_thread_handler(struct work_struct *work) ++{ ++ struct ivpu_device *vdev = container_of(work, struct ivpu_device, context_abort_work); ++ struct ivpu_file_priv *file_priv; ++ unsigned long ctx_id; ++ struct ivpu_job *job; ++ unsigned long id; ++ ++ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) ++ ivpu_jsm_reset_engine(vdev, 0); ++ ++ mutex_lock(&vdev->context_list_lock); ++ xa_for_each(&vdev->context_xa, ctx_id, file_priv) { ++ if (!file_priv->has_mmu_faults || file_priv->aborted) ++ continue; ++ ++ mutex_lock(&file_priv->lock); ++ ivpu_context_abort_locked(file_priv); ++ mutex_unlock(&file_priv->lock); ++ } ++ mutex_unlock(&vdev->context_list_lock); ++ ++ if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) ++ return; ++ ++ ivpu_jsm_hws_resume_engine(vdev, 0); ++ /* ++ * In hardware scheduling mode NPU already has stopped processing jobs ++ * and won't send us any further notifications, thus we have to free job related resources ++ * and notify userspace ++ */ ++ mutex_lock(&vdev->submitted_jobs_lock); ++ xa_for_each(&vdev->submitted_jobs_xa, id, job) ++ if (job->file_priv->aborted) ++ ivpu_job_signal_and_destroy(vdev, job->job_id, DRM_IVPU_JOB_STATUS_ABORTED); ++ mutex_unlock(&vdev->submitted_jobs_lock); ++} +diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h +index 6accb94028c7a2..0ae77f0638fadc 100644 +--- a/drivers/accel/ivpu/ivpu_job.h ++++ b/drivers/accel/ivpu/ivpu_job.h +@@ -64,6 +64,7 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev); + + void ivpu_job_done_consumer_init(struct ivpu_device *vdev); + void ivpu_job_done_consumer_fini(struct ivpu_device *vdev); ++void ivpu_context_abort_thread_handler(struct work_struct *work); + + void ivpu_jobs_abort_all(struct ivpu_device *vdev); + +diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c +index f7618b605f0219..ae91ad24d10d86 100644 +--- a/drivers/accel/ivpu/ivpu_jsm_msg.c ++++ b/drivers/accel/ivpu/ivpu_jsm_msg.c +@@ -48,9 +48,10 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) + IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP_RSP); +- IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT); ++ IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED); + IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL); + IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE); ++ IVPU_CASE_TO_STR(VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED); + IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB_DONE); +diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c +index c078e214b22129..fb15eb75b5ba9a 100644 +--- a/drivers/accel/ivpu/ivpu_mmu.c ++++ b/drivers/accel/ivpu/ivpu_mmu.c +@@ -917,8 +917,7 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) + REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons); + } + +- if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_MMU_EVTQ)) +- ivpu_err_ratelimited(vdev, "IRQ FIFO full\n"); ++ queue_work(system_wq, &vdev->context_abort_work); + } + + void ivpu_mmu_evtq_dump(struct ivpu_device *vdev) +diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c +index fbb61a2c3b19ce..d1fbad78f61ba0 100644 +--- a/drivers/accel/ivpu/ivpu_pm.c ++++ b/drivers/accel/ivpu/ivpu_pm.c +@@ -421,16 +421,17 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent) + active_us = (DCT_PERIOD_US * active_percent) / 100; + inactive_us = DCT_PERIOD_US - active_us; + ++ vdev->pm->dct_active_percent = active_percent; ++ ++ ivpu_dbg(vdev, PM, "DCT requested %u%% (D0: %uus, D0i2: %uus)\n", ++ active_percent, active_us, inactive_us); ++ + ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); + if (ret) { + ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret); + return ret; + } + +- vdev->pm->dct_active_percent = active_percent; +- +- ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n", +- active_percent, active_us, inactive_us); + return 0; + } + +@@ -438,15 +439,16 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev) + { + int ret; + ++ vdev->pm->dct_active_percent = 0; ++ ++ ivpu_dbg(vdev, PM, "DCT requested to be disabled\n"); ++ + ret = ivpu_jsm_dct_disable(vdev); + if (ret) { + ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret); + return ret; + } + +- vdev->pm->dct_active_percent = 0; +- +- ivpu_dbg(vdev, PM, "DCT disabled\n"); + return 0; + } + +@@ -458,7 +460,7 @@ void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev) + if (ivpu_hw_btrs_dct_get_request(vdev, &enable)) + return; + +- if (vdev->pm->dct_active_percent) ++ if (enable) + ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT); + else + ret = ivpu_pm_dct_disable(vdev); +diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c +index 616477fc17fa07..8a616791c32f5e 100644 +--- a/drivers/accel/ivpu/ivpu_sysfs.c ++++ b/drivers/accel/ivpu/ivpu_sysfs.c +@@ -30,11 +30,12 @@ npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *b + struct ivpu_device *vdev = to_ivpu_device(drm); + ktime_t total, now = 0; + +- xa_lock(&vdev->submitted_jobs_xa); ++ mutex_lock(&vdev->submitted_jobs_lock); ++ + total = vdev->busy_time; + if (!xa_empty(&vdev->submitted_jobs_xa)) + now = ktime_sub(ktime_get(), vdev->busy_start_ts); +- xa_unlock(&vdev->submitted_jobs_xa); ++ mutex_unlock(&vdev->submitted_jobs_lock); + + return sysfs_emit(buf, "%lld\n", ktime_to_us(ktime_add(total, now))); + } +diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h +index 82954b91b7481c..908e68ea1c39c2 100644 +--- a/drivers/accel/ivpu/vpu_boot_api.h ++++ b/drivers/accel/ivpu/vpu_boot_api.h +@@ -1,14 +1,13 @@ + /* SPDX-License-Identifier: MIT */ + /* +- * Copyright (c) 2020-2023, Intel Corporation. ++ * Copyright (c) 2020-2024, Intel Corporation. + */ + + #ifndef VPU_BOOT_API_H + #define VPU_BOOT_API_H + + /* +- * =========== FW API version information beginning ================ +- * The bellow values will be used to construct the version info this way: ++ * The below values will be used to construct the version info this way: + * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | + * VPU_BOOT_API_VER_MINOR; + * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes +@@ -27,19 +26,18 @@ + * Minor version changes when API backward compatibility is preserved. + * Resets to 0 if Major version is incremented. + */ +-#define VPU_BOOT_API_VER_MINOR 24 ++#define VPU_BOOT_API_VER_MINOR 26 + + /* + * API header changed (field names, documentation, formatting) but API itself has not been changed + */ +-#define VPU_BOOT_API_VER_PATCH 0 ++#define VPU_BOOT_API_VER_PATCH 3 + + /* + * Index in the API version table + * Must be unique for each API + */ + #define VPU_BOOT_API_VER_INDEX 0 +-/* ------------ FW API version information end ---------------------*/ + + #pragma pack(push, 4) + +@@ -164,8 +162,6 @@ enum vpu_trace_destination { + /* VPU 30xx HW component IDs are sequential, so define first and last IDs. */ + #define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT + #define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15 +-#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_30XX_FIRST +-#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_30XX_LAST + + struct vpu_boot_l2_cache_config { + u8 use; +@@ -199,6 +195,17 @@ struct vpu_warm_boot_section { + */ + #define POWER_PROFILE_SURVIVABILITY 0x1 + ++/** ++ * Enum for dvfs_mode boot param. ++ */ ++enum vpu_governor { ++ VPU_GOV_DEFAULT = 0, /* Default Governor for the system */ ++ VPU_GOV_MAX_PERFORMANCE = 1, /* Maximum performance governor */ ++ VPU_GOV_ON_DEMAND = 2, /* On Demand frequency control governor */ ++ VPU_GOV_POWER_SAVE = 3, /* Power save governor */ ++ VPU_GOV_ON_DEMAND_PRIORITY_AWARE = 4 /* On Demand priority based governor */ ++}; ++ + struct vpu_boot_params { + u32 magic; + u32 vpu_id; +@@ -301,7 +308,14 @@ struct vpu_boot_params { + u32 temp_sensor_period_ms; + /** PLL ratio for efficient clock frequency */ + u32 pn_freq_pll_ratio; +- /** DVFS Mode: Default: 0, Max Performance: 1, On Demand: 2, Power Save: 3 */ ++ /** ++ * DVFS Mode: ++ * 0 - Default, DVFS mode selected by the firmware ++ * 1 - Max Performance ++ * 2 - On Demand ++ * 3 - Power Save ++ * 4 - On Demand Priority Aware ++ */ + u32 dvfs_mode; + /** + * Depending on DVFS Mode: +@@ -332,8 +346,8 @@ struct vpu_boot_params { + u64 d0i3_entry_vpu_ts; + /* + * The system time of the host operating system in microseconds. +- * E.g the number of microseconds since 1st of January 1970, or whatever date the +- * host operating system uses to maintain system time. ++ * E.g the number of microseconds since 1st of January 1970, or whatever ++ * date the host operating system uses to maintain system time. + * This value will be used to track system time on the VPU. + * The KMD is required to update this value on every VPU reset. + */ +@@ -382,10 +396,7 @@ struct vpu_boot_params { + u32 pad6[734]; + }; + +-/* +- * Magic numbers set between host and vpu to detect corruptio of tracing init +- */ +- ++/* Magic numbers set between host and vpu to detect corruption of tracing init */ + #define VPU_TRACING_BUFFER_CANARY (0xCAFECAFE) + + /* Tracing buffer message format definitions */ +@@ -405,7 +416,9 @@ struct vpu_tracing_buffer_header { + u32 host_canary_start; + /* offset from start of buffer for trace entries */ + u32 read_index; +- u32 pad_to_cache_line_size_0[14]; ++ /* keeps track of wrapping on the reader side */ ++ u32 read_wrap_count; ++ u32 pad_to_cache_line_size_0[13]; + /* End of first cache line */ + + /** +diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h +index 33f462b1a25d88..7215c144158cbd 100644 +--- a/drivers/accel/ivpu/vpu_jsm_api.h ++++ b/drivers/accel/ivpu/vpu_jsm_api.h +@@ -22,7 +22,7 @@ + /* + * Minor version changes when API backward compatibility is preserved. + */ +-#define VPU_JSM_API_VER_MINOR 16 ++#define VPU_JSM_API_VER_MINOR 25 + + /* + * API header changed (field names, documentation, formatting) but API itself has not been changed +@@ -36,7 +36,7 @@ + + /* + * Number of Priority Bands for Hardware Scheduling +- * Bands: RealTime, Focus, Normal, Idle ++ * Bands: Idle(0), Normal(1), Focus(2), RealTime(3) + */ + #define VPU_HWS_NUM_PRIORITY_BANDS 4 + +@@ -74,6 +74,7 @@ + #define VPU_JSM_STATUS_MVNCI_INTERNAL_ERROR 0xCU + /* Job status returned when the job was preempted mid-inference */ + #define VPU_JSM_STATUS_PREEMPTED_MID_INFERENCE 0xDU ++#define VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW 0xEU + + /* + * Host <-> VPU IPC channels. +@@ -86,18 +87,58 @@ + /* + * Job flags bit masks. + */ +-#define VPU_JOB_FLAGS_NULL_SUBMISSION_MASK 0x00000001 +-#define VPU_JOB_FLAGS_PRIVATE_DATA_MASK 0xFF000000 ++enum { ++ /* ++ * Null submission mask. ++ * When set, batch buffer's commands are not processed but returned as ++ * successful immediately, except fences and timestamps. ++ * When cleared, batch buffer's commands are processed normally. ++ * Used for testing and profiling purposes. ++ */ ++ VPU_JOB_FLAGS_NULL_SUBMISSION_MASK = (1 << 0U), ++ /* ++ * Inline command mask. ++ * When set, the object in job queue is an inline command (see struct vpu_inline_cmd below). ++ * When cleared, the object in job queue is a job (see struct vpu_job_queue_entry below). ++ */ ++ VPU_JOB_FLAGS_INLINE_CMD_MASK = (1 << 1U), ++ /* ++ * VPU private data mask. ++ * Reserved for the VPU to store private data about the job (or inline command) ++ * while being processed. ++ */ ++ VPU_JOB_FLAGS_PRIVATE_DATA_MASK = 0xFFFF0000U ++}; + + /* +- * Sizes of the reserved areas in jobs, in bytes. ++ * Job queue flags bit masks. + */ +-#define VPU_JOB_RESERVED_BYTES 8 ++enum { ++ /* ++ * No job done notification mask. ++ * When set, indicates that no job done notification should be sent for any ++ * job from this queue. When cleared, indicates that job done notification ++ * should be sent for every job completed from this queue. ++ */ ++ VPU_JOB_QUEUE_FLAGS_NO_JOB_DONE_MASK = (1 << 0U), ++ /* ++ * Native fence usage mask. ++ * When set, indicates that job queue uses native fences (as inline commands ++ * in job queue). Such queues may also use legacy fences (as commands in batch buffers). ++ * When cleared, indicates the job queue only uses legacy fences. ++ * NOTE: For queues using native fences, VPU expects that all jobs in the queue ++ * are immediately followed by an inline command object. This object is expected ++ * to be a fence signal command in most cases, but can also be a NOP in case the host ++ * does not need per-job fence signalling. Other inline commands objects can be ++ * inserted between "job and inline command" pairs. ++ */ ++ VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), + +-/* +- * Sizes of the reserved areas in job queues, in bytes. +- */ +-#define VPU_JOB_QUEUE_RESERVED_BYTES 52 ++ /* ++ * Enable turbo mode for testing NPU performance; not recommended for regular usage. ++ */ ++ VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U) ++}; + + /* + * Max length (including trailing NULL char) of trace entity name (e.g., the +@@ -140,24 +181,113 @@ + */ + #define VPU_HWS_INVALID_CMDQ_HANDLE 0ULL + ++/* ++ * Inline commands types. ++ */ ++/* ++ * NOP. ++ * VPU does nothing other than consuming the inline command object. ++ */ ++#define VPU_INLINE_CMD_TYPE_NOP 0x0 ++/* ++ * Fence wait. ++ * VPU waits for the fence current value to reach monitored value. ++ * Fence wait operations are executed upon job dispatching. While waiting for ++ * the fence to be satisfied, VPU blocks fetching of the next objects in the queue. ++ * Jobs present in the queue prior to the fence wait object may be processed ++ * concurrently. ++ */ ++#define VPU_INLINE_CMD_TYPE_FENCE_WAIT 0x1 ++/* ++ * Fence signal. ++ * VPU sets the fence current value to the provided value. If new current value ++ * is equal to or higher than monitored value, VPU sends fence signalled notification ++ * to the host. Fence signal operations are executed upon completion of all the jobs ++ * present in the queue prior to them, and in-order relative to each other in the queue. ++ * But jobs in-between them may be processed concurrently and may complete out-of-order. ++ */ ++#define VPU_INLINE_CMD_TYPE_FENCE_SIGNAL 0x2 ++ ++/* ++ * Job scheduling priority bands for both hardware scheduling and OS scheduling. ++ */ ++enum vpu_job_scheduling_priority_band { ++ VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE = 0, ++ VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL = 1, ++ VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS = 2, ++ VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME = 3, ++ VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT = 4, ++}; ++ + /* + * Job format. ++ * Jobs defines the actual workloads to be executed by a given engine. + */ + struct vpu_job_queue_entry { +- u64 batch_buf_addr; /**< Address of VPU commands batch buffer */ +- u32 job_id; /**< Job ID */ +- u32 flags; /**< Flags bit field, see VPU_JOB_FLAGS_* above */ +- u64 root_page_table_addr; /**< Address of root page table to use for this job */ +- u64 root_page_table_update_counter; /**< Page tables update events counter */ +- u64 primary_preempt_buf_addr; ++ /**< Address of VPU commands batch buffer */ ++ u64 batch_buf_addr; ++ /**< Job ID */ ++ u32 job_id; ++ /**< Flags bit field, see VPU_JOB_FLAGS_* above */ ++ u32 flags; ++ /** ++ * Doorbell ring timestamp taken by KMD from SoC's global system clock, in ++ * microseconds. NPU can convert this value to its own fixed clock's timebase, ++ * to match other profiling timestamps. ++ */ ++ u64 doorbell_timestamp; ++ /**< Extra id for job tracking, used only in the firmware perf traces */ ++ u64 host_tracking_id; + /**< Address of the primary preemption buffer to use for this job */ +- u32 primary_preempt_buf_size; ++ u64 primary_preempt_buf_addr; + /**< Size of the primary preemption buffer to use for this job */ +- u32 secondary_preempt_buf_size; ++ u32 primary_preempt_buf_size; + /**< Size of secondary preemption buffer to use for this job */ +- u64 secondary_preempt_buf_addr; ++ u32 secondary_preempt_buf_size; + /**< Address of secondary preemption buffer to use for this job */ +- u8 reserved_0[VPU_JOB_RESERVED_BYTES]; ++ u64 secondary_preempt_buf_addr; ++ u64 reserved_0; ++}; ++ ++/* ++ * Inline command format. ++ * Inline commands are the commands executed at scheduler level (typically, ++ * synchronization directives). Inline command and job objects must be of ++ * the same size and have flags field at same offset. ++ */ ++struct vpu_inline_cmd { ++ u64 reserved_0; ++ /* Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */ ++ u32 type; ++ /* Flags bit field, see VPU_JOB_FLAGS_* above. */ ++ u32 flags; ++ /* Inline command payload. Depends on inline command type. */ ++ union { ++ /* Fence (wait and signal) commands' payload. */ ++ struct { ++ /* Fence object handle. */ ++ u64 fence_handle; ++ /* User VA of the current fence value. */ ++ u64 current_value_va; ++ /* User VA of the monitored fence value (read-only). */ ++ u64 monitored_value_va; ++ /* Value to wait for or write in fence location. */ ++ u64 value; ++ /* User VA of the log buffer in which to add log entry on completion. */ ++ u64 log_buffer_va; ++ } fence; ++ /* Other commands do not have a payload. */ ++ /* Payload definition for future inline commands can be inserted here. */ ++ u64 reserved_1[6]; ++ } payload; ++}; ++ ++/* ++ * Job queue slots can be populated either with job objects or inline command objects. ++ */ ++union vpu_jobq_slot { ++ struct vpu_job_queue_entry job; ++ struct vpu_inline_cmd inline_cmd; + }; + + /* +@@ -167,7 +297,21 @@ struct vpu_job_queue_header { + u32 engine_idx; + u32 head; + u32 tail; +- u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES]; ++ u32 flags; ++ /* Set to 1 to indicate priority_band field is valid */ ++ u32 priority_band_valid; ++ /* ++ * Priority for the work of this job queue, valid only if the HWS is NOT used ++ * and the `priority_band_valid` is set to 1. It is applied only during ++ * the VPU_JSM_MSG_REGISTER_DB message processing. ++ * The device firmware might use the `priority_band` to optimize the power ++ * management logic, but it will not affect the order of jobs. ++ * Available priority bands: @see enum vpu_job_scheduling_priority_band ++ */ ++ u32 priority_band; ++ /* Inside realtime band assigns a further priority, limited to 0..31 range */ ++ u32 realtime_priority_level; ++ u32 reserved_0[9]; + }; + + /* +@@ -175,7 +319,7 @@ struct vpu_job_queue_header { + */ + struct vpu_job_queue { + struct vpu_job_queue_header header; +- struct vpu_job_queue_entry job[]; ++ union vpu_jobq_slot slot[]; + }; + + /** +@@ -197,9 +341,7 @@ enum vpu_trace_entity_type { + struct vpu_hws_log_buffer_header { + /* Written by VPU after adding a log entry. Initialised by host to 0. */ + u32 first_free_entry_index; +- /* Incremented by VPU every time the VPU overwrites the 0th entry; +- * initialised by host to 0. +- */ ++ /* Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */ + u32 wraparound_count; + /* + * This is the number of buffers that can be stored in the log buffer provided by the host. +@@ -230,14 +372,80 @@ struct vpu_hws_log_buffer_entry { + u64 operation_data[2]; + }; + ++/* Native fence log buffer types. */ ++enum vpu_hws_native_fence_log_type { ++ VPU_HWS_NATIVE_FENCE_LOG_TYPE_WAITS = 1, ++ VPU_HWS_NATIVE_FENCE_LOG_TYPE_SIGNALS = 2 ++}; ++ ++/* HWS native fence log buffer header. */ ++struct vpu_hws_native_fence_log_header { ++ union { ++ struct { ++ /* Index of the first free entry in buffer. */ ++ u32 first_free_entry_idx; ++ /* Incremented each time NPU wraps around the buffer to write next entry. */ ++ u32 wraparound_count; ++ }; ++ /* Field allowing atomic update of both fields above. */ ++ u64 atomic_wraparound_and_entry_idx; ++ }; ++ /* Log buffer type, see enum vpu_hws_native_fence_log_type. */ ++ u64 type; ++ /* Allocated number of entries in the log buffer. */ ++ u64 entry_nb; ++ u64 reserved[2]; ++}; ++ ++/* Native fence log operation types. */ ++enum vpu_hws_native_fence_log_op { ++ VPU_HWS_NATIVE_FENCE_LOG_OP_SIGNAL_EXECUTED = 0, ++ VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED = 1 ++}; ++ ++/* HWS native fence log entry. */ ++struct vpu_hws_native_fence_log_entry { ++ /* Newly signaled/unblocked fence value. */ ++ u64 fence_value; ++ /* Native fence object handle to which this operation belongs. */ ++ u64 fence_handle; ++ /* Operation type, see enum vpu_hws_native_fence_log_op. */ ++ u64 op_type; ++ u64 reserved_0; ++ /* ++ * VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED only: Timestamp at which fence ++ * wait was started (in NPU SysTime). ++ */ ++ u64 fence_wait_start_ts; ++ u64 reserved_1; ++ /* Timestamp at which fence operation was completed (in NPU SysTime). */ ++ u64 fence_end_ts; ++}; ++ ++/* Native fence log buffer. */ ++struct vpu_hws_native_fence_log_buffer { ++ struct vpu_hws_native_fence_log_header header; ++ struct vpu_hws_native_fence_log_entry entry[]; ++}; ++ + /* + * Host <-> VPU IPC messages types. + */ + enum vpu_ipc_msg_type { + VPU_JSM_MSG_UNKNOWN = 0xFFFFFFFF, ++ + /* IPC Host -> Device, Async commands */ + VPU_JSM_MSG_ASYNC_CMD = 0x1100, + VPU_JSM_MSG_ENGINE_RESET = VPU_JSM_MSG_ASYNC_CMD, ++ /** ++ * Preempt engine. The NPU stops (preempts) all the jobs currently ++ * executing on the target engine making the engine become idle and ready to ++ * execute new jobs. ++ * NOTE: The NPU does not remove unstarted jobs (if any) from job queues of ++ * the target engine, but it stops processing them (until the queue doorbell ++ * is rung again); the host is responsible to reset the job queue, either ++ * after preemption or when resubmitting jobs to the queue. ++ */ + VPU_JSM_MSG_ENGINE_PREEMPT = 0x1101, + VPU_JSM_MSG_REGISTER_DB = 0x1102, + VPU_JSM_MSG_UNREGISTER_DB = 0x1103, +@@ -323,9 +531,10 @@ enum vpu_ipc_msg_type { + * NOTE: Please introduce new ASYNC commands before this one. * + */ + VPU_JSM_MSG_STATE_DUMP = 0x11FF, ++ + /* IPC Host -> Device, General commands */ + VPU_JSM_MSG_GENERAL_CMD = 0x1200, +- VPU_JSM_MSG_BLOB_DEINIT = VPU_JSM_MSG_GENERAL_CMD, ++ VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED = VPU_JSM_MSG_GENERAL_CMD, + /** + * Control dyndbg behavior by executing a dyndbg command; equivalent to + * Linux command: `echo '' > /dynamic_debug/control`. +@@ -335,8 +544,12 @@ enum vpu_ipc_msg_type { + * Perform the save procedure for the D0i3 entry + */ + VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202, ++ + /* IPC Device -> Host, Job completion */ + VPU_JSM_MSG_JOB_DONE = 0x2100, ++ /* IPC Device -> Host, Fence signalled */ ++ VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED = 0x2101, ++ + /* IPC Device -> Host, Async command completion */ + VPU_JSM_MSG_ASYNC_CMD_DONE = 0x2200, + VPU_JSM_MSG_ENGINE_RESET_DONE = VPU_JSM_MSG_ASYNC_CMD_DONE, +@@ -422,6 +635,7 @@ enum vpu_ipc_msg_type { + * NOTE: Please introduce new ASYNC responses before this one. * + */ + VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF, ++ + /* IPC Device -> Host, General command completion */ + VPU_JSM_MSG_GENERAL_CMD_DONE = 0x2300, + VPU_JSM_MSG_BLOB_DEINIT_DONE = VPU_JSM_MSG_GENERAL_CMD_DONE, +@@ -600,11 +814,6 @@ struct vpu_jsm_metric_streamer_update { + u64 next_buffer_size; + }; + +-struct vpu_ipc_msg_payload_blob_deinit { +- /* 64-bit unique ID for the blob to be de-initialized. */ +- u64 blob_id; +-}; +- + struct vpu_ipc_msg_payload_job_done { + /* Engine to which the job was submitted. */ + u32 engine_idx; +@@ -622,6 +831,21 @@ struct vpu_ipc_msg_payload_job_done { + u64 cmdq_id; + }; + ++/* ++ * Notification message upon native fence signalling. ++ * @see VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED ++ */ ++struct vpu_ipc_msg_payload_native_fence_signalled { ++ /* Engine ID. */ ++ u32 engine_idx; ++ /* Host SSID. */ ++ u32 host_ssid; ++ /* CMDQ ID */ ++ u64 cmdq_id; ++ /* Fence object handle. */ ++ u64 fence_handle; ++}; ++ + struct vpu_jsm_engine_reset_context { + /* Host SSID */ + u32 host_ssid; +@@ -700,11 +924,6 @@ struct vpu_ipc_msg_payload_get_power_level_count_done { + u8 power_limit[16]; + }; + +-struct vpu_ipc_msg_payload_blob_deinit_done { +- /* 64-bit unique ID for the blob de-initialized. */ +- u64 blob_id; +-}; +- + /* HWS priority band setup request / response */ + struct vpu_ipc_msg_payload_hws_priority_band_setup { + /* +@@ -794,7 +1013,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { + u32 reserved_0; + /* Command queue id */ + u64 cmdq_id; +- /* Priority band to assign to work of this context */ ++ /* ++ * Priority band to assign to work of this context. ++ * Available priority bands: @see enum vpu_job_scheduling_priority_band ++ */ + u32 priority_band; + /* Inside realtime band assigns a further priority */ + u32 realtime_priority_level; +@@ -869,9 +1091,7 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log { + */ + u64 notify_index; + /* +- * Enable extra events to be output to log for debug of scheduling algorithm. +- * Interpreted by VPU as a boolean to enable or disable, expected values are +- * 0 and 1. ++ * Field is now deprecated, will be removed when KMD is updated to support removal + */ + u32 enable_extra_events; + /* Zero Padding */ +@@ -1243,10 +1463,10 @@ union vpu_ipc_msg_payload { + struct vpu_jsm_metric_streamer_start metric_streamer_start; + struct vpu_jsm_metric_streamer_stop metric_streamer_stop; + struct vpu_jsm_metric_streamer_update metric_streamer_update; +- struct vpu_ipc_msg_payload_blob_deinit blob_deinit; + struct vpu_ipc_msg_payload_ssid_release ssid_release; + struct vpu_jsm_hws_register_db hws_register_db; + struct vpu_ipc_msg_payload_job_done job_done; ++ struct vpu_ipc_msg_payload_native_fence_signalled native_fence_signalled; + struct vpu_ipc_msg_payload_engine_reset_done engine_reset_done; + struct vpu_ipc_msg_payload_engine_preempt_done engine_preempt_done; + struct vpu_ipc_msg_payload_register_db_done register_db_done; +@@ -1254,7 +1474,6 @@ union vpu_ipc_msg_payload { + struct vpu_ipc_msg_payload_query_engine_hb_done query_engine_hb_done; + struct vpu_ipc_msg_payload_get_power_level_count_done get_power_level_count_done; + struct vpu_jsm_metric_streamer_done metric_streamer_done; +- struct vpu_ipc_msg_payload_blob_deinit_done blob_deinit_done; + struct vpu_ipc_msg_payload_trace_config trace_config; + struct vpu_ipc_msg_payload_trace_capability_rsp trace_capability; + struct vpu_ipc_msg_payload_trace_get_name trace_get_name; +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index ef353ca13c356a..bdf09e8b898d05 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -6374,7 +6374,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, + seq_printf(m, " node %d", buffer->target_node->debug_id); + seq_printf(m, " size %zd:%zd offset %lx\n", + buffer->data_size, buffer->offsets_size, +- proc->alloc.buffer - buffer->user_data); ++ buffer->user_data - proc->alloc.buffer); + } + + static void print_binder_work_ilocked(struct seq_file *m, +diff --git a/drivers/base/module.c b/drivers/base/module.c +index 5bc71bea883a06..218aaa0964552f 100644 +--- a/drivers/base/module.c ++++ b/drivers/base/module.c +@@ -42,16 +42,13 @@ int module_add_driver(struct module *mod, const struct device_driver *drv) + if (mod) + mk = &mod->mkobj; + else if (drv->mod_name) { +- struct kobject *mkobj; +- +- /* Lookup built-in module entry in /sys/modules */ +- mkobj = kset_find_obj(module_kset, drv->mod_name); +- if (mkobj) { +- mk = container_of(mkobj, struct module_kobject, kobj); ++ /* Lookup or create built-in module entry in /sys/modules */ ++ mk = lookup_or_create_module_kobject(drv->mod_name); ++ if (mk) { + /* remember our module structure */ + drv->p->mkobj = mk; +- /* kset_find_obj took a reference */ +- kobject_put(mkobj); ++ /* lookup_or_create_module_kobject took a reference */ ++ kobject_put(&mk->kobj); + } + } + +diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c +index ab465e13c1f60f..d225f0a37f985d 100644 +--- a/drivers/bluetooth/btintel_pcie.c ++++ b/drivers/bluetooth/btintel_pcie.c +@@ -581,8 +581,10 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb) + /* This is a debug event that comes from IML and OP image when it + * starts execution. There is no need pass this event to stack. + */ +- if (skb->data[2] == 0x97) ++ if (skb->data[2] == 0x97) { ++ hci_recv_diag(hdev, skb); + return 0; ++ } + } + + return hci_recv_frame(hdev, skb); +@@ -598,7 +600,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, + u8 pkt_type; + u16 plen; + u32 pcie_pkt_type; +- struct sk_buff *new_skb; + void *pdata; + struct hci_dev *hdev = data->hdev; + +@@ -675,24 +676,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, + + bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen); + +- new_skb = bt_skb_alloc(plen, GFP_ATOMIC); +- if (!new_skb) { +- bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u", +- skb->len); +- ret = -ENOMEM; +- goto exit_error; +- } +- +- hci_skb_pkt_type(new_skb) = pkt_type; +- skb_put_data(new_skb, skb->data, plen); ++ hci_skb_pkt_type(skb) = pkt_type; + hdev->stat.byte_rx += plen; ++ skb_trim(skb, plen); + + if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT) +- ret = btintel_pcie_recv_event(hdev, new_skb); ++ ret = btintel_pcie_recv_event(hdev, skb); + else +- ret = hci_recv_frame(hdev, new_skb); ++ ret = hci_recv_frame(hdev, skb); ++ skb = NULL; /* skb is freed in the callee */ + + exit_error: ++ if (skb) ++ kfree_skb(skb); ++ + if (ret) + hdev->stat.err_rx++; + +@@ -706,16 +703,10 @@ static void btintel_pcie_rx_work(struct work_struct *work) + struct btintel_pcie_data *data = container_of(work, + struct btintel_pcie_data, rx_work); + struct sk_buff *skb; +- int err; +- struct hci_dev *hdev = data->hdev; + + /* Process the sk_buf in queue and send to the HCI layer */ + while ((skb = skb_dequeue(&data->rx_skb_q))) { +- err = btintel_pcie_recv_frame(data, skb); +- if (err) +- bt_dev_err(hdev, "Failed to send received frame: %d", +- err); +- kfree_skb(skb); ++ btintel_pcie_recv_frame(data, skb); + } + } + +@@ -770,10 +761,8 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data) + bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia); + + /* Check CR_TIA and CR_HIA for change */ +- if (cr_tia == cr_hia) { +- bt_dev_warn(hdev, "RXQ: no new CD found"); ++ if (cr_tia == cr_hia) + return; +- } + + rxq = &data->rxq; + +@@ -809,6 +798,16 @@ static irqreturn_t btintel_pcie_msix_isr(int irq, void *data) + return IRQ_WAKE_THREAD; + } + ++static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data) ++{ ++ return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM]; ++} ++ ++static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data) ++{ ++ return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM]; ++} ++ + static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) + { + struct msix_entry *entry = dev_id; +@@ -836,12 +835,18 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) + btintel_pcie_msix_gp0_handler(data); + + /* For TX */ +- if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) ++ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) { + btintel_pcie_msix_tx_handle(data); ++ if (!btintel_pcie_is_rxq_empty(data)) ++ btintel_pcie_msix_rx_handle(data); ++ } + + /* For RX */ +- if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) ++ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) { + btintel_pcie_msix_rx_handle(data); ++ if (!btintel_pcie_is_txackq_empty(data)) ++ btintel_pcie_msix_tx_handle(data); ++ } + + /* + * Before sending the interrupt the HW disables it to prevent a nested +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 151054a718522a..7e1f03231b4c90 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -371,6 +371,42 @@ static const struct usb_device_id quirks_table[] = { + /* QCA WCN785x chipset */ + { USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe0fc), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe0f3), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe100), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe103), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe10a), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe10d), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe11b), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe11c), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe11f), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe141), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe14a), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe14b), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe14d), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3623), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3624), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2c7c, 0x0130), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2c7c, 0x0131), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2c7c, 0x0132), .driver_info = BTUSB_QCA_WCN6855 | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Broadcom BCM2035 */ + { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, +@@ -2939,22 +2975,16 @@ static void btusb_coredump_qca(struct hci_dev *hdev) + bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err); + } + +-/* +- * ==0: not a dump pkt. +- * < 0: fails to handle a dump pkt +- * > 0: otherwise. +- */ ++/* Return: 0 on success, negative errno on failure. */ + static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) + { +- int ret = 1; ++ int ret = 0; + u8 pkt_type; + u8 *sk_ptr; + unsigned int sk_len; + u16 seqno; + u32 dump_size; + +- struct hci_event_hdr *event_hdr; +- struct hci_acl_hdr *acl_hdr; + struct qca_dump_hdr *dump_hdr; + struct btusb_data *btdata = hci_get_drvdata(hdev); + struct usb_device *udev = btdata->udev; +@@ -2964,30 +2994,14 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) + sk_len = skb->len; + + if (pkt_type == HCI_ACLDATA_PKT) { +- acl_hdr = hci_acl_hdr(skb); +- if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE) +- return 0; + sk_ptr += HCI_ACL_HDR_SIZE; + sk_len -= HCI_ACL_HDR_SIZE; +- event_hdr = (struct hci_event_hdr *)sk_ptr; +- } else { +- event_hdr = hci_event_hdr(skb); + } + +- if ((event_hdr->evt != HCI_VENDOR_PKT) +- || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) +- return 0; +- + sk_ptr += HCI_EVENT_HDR_SIZE; + sk_len -= HCI_EVENT_HDR_SIZE; + + dump_hdr = (struct qca_dump_hdr *)sk_ptr; +- if ((sk_len < offsetof(struct qca_dump_hdr, data)) +- || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) +- || (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) +- return 0; +- +- /*it is dump pkt now*/ + seqno = le16_to_cpu(dump_hdr->seqno); + if (seqno == 0) { + set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags); +@@ -3061,17 +3075,84 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) + return ret; + } + ++/* Return: true if the ACL packet is a dump packet, false otherwise. */ ++static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb) ++{ ++ u8 *sk_ptr; ++ unsigned int sk_len; ++ ++ struct hci_event_hdr *event_hdr; ++ struct hci_acl_hdr *acl_hdr; ++ struct qca_dump_hdr *dump_hdr; ++ ++ sk_ptr = skb->data; ++ sk_len = skb->len; ++ ++ acl_hdr = hci_acl_hdr(skb); ++ if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE) ++ return false; ++ ++ sk_ptr += HCI_ACL_HDR_SIZE; ++ sk_len -= HCI_ACL_HDR_SIZE; ++ event_hdr = (struct hci_event_hdr *)sk_ptr; ++ ++ if ((event_hdr->evt != HCI_VENDOR_PKT) || ++ (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) ++ return false; ++ ++ sk_ptr += HCI_EVENT_HDR_SIZE; ++ sk_len -= HCI_EVENT_HDR_SIZE; ++ ++ dump_hdr = (struct qca_dump_hdr *)sk_ptr; ++ if ((sk_len < offsetof(struct qca_dump_hdr, data)) || ++ (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) || ++ (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) ++ return false; ++ ++ return true; ++} ++ ++/* Return: true if the event packet is a dump packet, false otherwise. */ ++static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb) ++{ ++ u8 *sk_ptr; ++ unsigned int sk_len; ++ ++ struct hci_event_hdr *event_hdr; ++ struct qca_dump_hdr *dump_hdr; ++ ++ sk_ptr = skb->data; ++ sk_len = skb->len; ++ ++ event_hdr = hci_event_hdr(skb); ++ ++ if ((event_hdr->evt != HCI_VENDOR_PKT) ++ || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) ++ return false; ++ ++ sk_ptr += HCI_EVENT_HDR_SIZE; ++ sk_len -= HCI_EVENT_HDR_SIZE; ++ ++ dump_hdr = (struct qca_dump_hdr *)sk_ptr; ++ if ((sk_len < offsetof(struct qca_dump_hdr, data)) || ++ (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) || ++ (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) ++ return false; ++ ++ return true; ++} ++ + static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb) + { +- if (handle_dump_pkt_qca(hdev, skb)) +- return 0; ++ if (acl_pkt_is_dump_qca(hdev, skb)) ++ return handle_dump_pkt_qca(hdev, skb); + return hci_recv_frame(hdev, skb); + } + + static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb) + { +- if (handle_dump_pkt_qca(hdev, skb)) +- return 0; ++ if (evt_pkt_is_dump_qca(hdev, skb)) ++ return handle_dump_pkt_qca(hdev, skb); + return hci_recv_frame(hdev, skb); + } + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 67b4e3d18ffe22..1f52bced4c2959 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -534,16 +534,18 @@ void cpufreq_disable_fast_switch(struct cpufreq_policy *policy) + EXPORT_SYMBOL_GPL(cpufreq_disable_fast_switch); + + static unsigned int __resolve_freq(struct cpufreq_policy *policy, +- unsigned int target_freq, unsigned int relation) ++ unsigned int target_freq, ++ unsigned int min, unsigned int max, ++ unsigned int relation) + { + unsigned int idx; + +- target_freq = clamp_val(target_freq, policy->min, policy->max); ++ target_freq = clamp_val(target_freq, min, max); + + if (!policy->freq_table) + return target_freq; + +- idx = cpufreq_frequency_table_target(policy, target_freq, relation); ++ idx = cpufreq_frequency_table_target(policy, target_freq, min, max, relation); + policy->cached_resolved_idx = idx; + policy->cached_target_freq = target_freq; + return policy->freq_table[idx].frequency; +@@ -563,7 +565,21 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy, + unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, + unsigned int target_freq) + { +- return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE); ++ unsigned int min = READ_ONCE(policy->min); ++ unsigned int max = READ_ONCE(policy->max); ++ ++ /* ++ * If this function runs in parallel with cpufreq_set_policy(), it may ++ * read policy->min before the update and policy->max after the update ++ * or the other way around, so there is no ordering guarantee. ++ * ++ * Resolve this by always honoring the max (in case it comes from ++ * thermal throttling or similar). ++ */ ++ if (unlikely(min > max)) ++ min = max; ++ ++ return __resolve_freq(policy, target_freq, min, max, CPUFREQ_RELATION_LE); + } + EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq); + +@@ -2323,7 +2339,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, + if (cpufreq_disabled()) + return -ENODEV; + +- target_freq = __resolve_freq(policy, target_freq, relation); ++ target_freq = __resolve_freq(policy, target_freq, policy->min, ++ policy->max, relation); + + pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", + policy->cpu, target_freq, relation, old_target_freq); +@@ -2647,11 +2664,18 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, + * Resolve policy min/max to available frequencies. It ensures + * no frequency resolution will neither overshoot the requested maximum + * nor undershoot the requested minimum. ++ * ++ * Avoid storing intermediate values in policy->max or policy->min and ++ * compiler optimizations around them because they may be accessed ++ * concurrently by cpufreq_driver_resolve_freq() during the update. + */ +- policy->min = new_data.min; +- policy->max = new_data.max; +- policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L); +- policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H); ++ WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, ++ new_data.min, new_data.max, ++ CPUFREQ_RELATION_H)); ++ new_data.min = __resolve_freq(policy, new_data.min, new_data.min, ++ new_data.max, CPUFREQ_RELATION_L); ++ WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min); ++ + trace_cpu_frequency_limits(policy); + + cpufreq_update_pressure(policy); +diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c +index a7c38b8b3e7890..0e65d37c923113 100644 +--- a/drivers/cpufreq/cpufreq_ondemand.c ++++ b/drivers/cpufreq/cpufreq_ondemand.c +@@ -76,7 +76,8 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, + return freq_next; + } + +- index = cpufreq_frequency_table_target(policy, freq_next, relation); ++ index = cpufreq_frequency_table_target(policy, freq_next, policy->min, ++ policy->max, relation); + freq_req = freq_table[index].frequency; + freq_reduc = freq_req * od_tuners->powersave_bias / 1000; + freq_avg = freq_req - freq_reduc; +diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c +index 10e80d912b8d85..178e17009a16ef 100644 +--- a/drivers/cpufreq/freq_table.c ++++ b/drivers/cpufreq/freq_table.c +@@ -116,8 +116,8 @@ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy) + EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); + + int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, +- unsigned int target_freq, +- unsigned int relation) ++ unsigned int target_freq, unsigned int min, ++ unsigned int max, unsigned int relation) + { + struct cpufreq_frequency_table optimal = { + .driver_data = ~0, +@@ -148,7 +148,7 @@ int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, + cpufreq_for_each_valid_entry_idx(pos, table, i) { + freq = pos->frequency; + +- if ((freq < policy->min) || (freq > policy->max)) ++ if (freq < min || freq > max) + continue; + if (freq == target_freq) { + optimal.driver_data = i; +diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c +index 400337f3b572da..54e7310454cc64 100644 +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -600,6 +600,9 @@ static bool turbo_is_disabled(void) + { + u64 misc_en; + ++ if (!cpu_feature_enabled(X86_FEATURE_IDA)) ++ return true; ++ + rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); + + return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE); +diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c +index fe89f5c4837f49..8420862c90a4d5 100644 +--- a/drivers/edac/altera_edac.c ++++ b/drivers/edac/altera_edac.c +@@ -99,7 +99,7 @@ static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id) + if (status & priv->ecc_stat_ce_mask) { + regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, + &err_addr); +- if (priv->ecc_uecnt_offset) ++ if (priv->ecc_cecnt_offset) + regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, + &err_count); + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count, +@@ -1005,9 +1005,6 @@ altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask, + } + } + +- /* Interrupt mode set to every SBERR */ +- regmap_write(ecc_mgr_map, ALTR_A10_ECC_INTMODE_OFST, +- ALTR_A10_ECC_INTMODE); + /* Enable ECC */ + ecc_set_bits(ecc_ctrl_en_mask, (ecc_block_base + + ALTR_A10_ECC_CTRL_OFST)); +@@ -2127,6 +2124,10 @@ static int altr_edac_a10_probe(struct platform_device *pdev) + return PTR_ERR(edac->ecc_mgr_map); + } + ++ /* Set irq mask for DDR SBE to avoid any pending irq before registration */ ++ regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_SET_OFST, ++ (A10_SYSMGR_ECC_INTMASK_SDMMCB | A10_SYSMGR_ECC_INTMASK_DDR0)); ++ + edac->irq_chip.name = pdev->dev.of_node->name; + edac->irq_chip.irq_mask = a10_eccmgr_irq_mask; + edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask; +diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h +index 3727e72c8c2e70..7248d24c4908d7 100644 +--- a/drivers/edac/altera_edac.h ++++ b/drivers/edac/altera_edac.h +@@ -249,6 +249,8 @@ struct altr_sdram_mc_data { + #define A10_SYSMGR_ECC_INTMASK_SET_OFST 0x94 + #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98 + #define A10_SYSMGR_ECC_INTMASK_OCRAM BIT(1) ++#define A10_SYSMGR_ECC_INTMASK_SDMMCB BIT(16) ++#define A10_SYSMGR_ECC_INTMASK_DDR0 BIT(17) + + #define A10_SYSMGR_ECC_INTSTAT_SERR_OFST 0x9C + #define A10_SYSMGR_ECC_INTSTAT_DERR_OFST 0xA0 +diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c +index 2c2ec3c35f1561..dce448687e28e7 100644 +--- a/drivers/firmware/arm_ffa/driver.c ++++ b/drivers/firmware/arm_ffa/driver.c +@@ -280,7 +280,8 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, + memcpy(buffer + idx, drv_info->rx_buffer + idx * sz, + buf_sz); + +- ffa_rx_release(); ++ if (!(flags & PARTITION_INFO_GET_RETURN_COUNT_ONLY)) ++ ffa_rx_release(); + + mutex_unlock(&drv_info->rx_lock); + +diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c +index 157172a5f2b577..782c9bec8361c5 100644 +--- a/drivers/firmware/arm_scmi/bus.c ++++ b/drivers/firmware/arm_scmi/bus.c +@@ -260,6 +260,9 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent, + if (!dev) + return NULL; + ++ /* Drop the refcnt bumped implicitly by device_find_child */ ++ put_device(dev); ++ + return to_scmi_dev(dev); + } + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index ae53f26da945f8..1160a439e92a85 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -185,7 +185,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS + bool "Enable refcount backtrace history in the DP MST helpers" + depends on STACKTRACE_SUPPORT + select STACKDEPOT +- depends on DRM_KMS_HELPER ++ select DRM_KMS_HELPER + depends on DEBUG_KERNEL + depends on EXPERT + help +diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c +index 41421da63a0846..a11f556b3ff113 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c ++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c +@@ -361,7 +361,7 @@ static void nbio_v7_11_get_clockgating_state(struct amdgpu_device *adev, + *flags |= AMD_CG_SUPPORT_BIF_LS; + } + +-#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) ++#define MMIO_REG_HOLE_OFFSET 0x44000 + + static void nbio_v7_11_set_reg_remap(struct amdgpu_device *adev) + { +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index f3cbff86155705..115fb3bc456437 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -1887,26 +1887,6 @@ static enum dmub_ips_disable_type dm_get_default_ips_mode( + + switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) { + case IP_VERSION(3, 5, 0): +- /* +- * On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to +- * cause a hard hang. A fix exists for newer PMFW. +- * +- * As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest +- * IPS state in all cases, except for s0ix and all displays off (DPMS), +- * where IPS2 is allowed. +- * +- * When checking pmfw version, use the major and minor only. +- */ +- if ((adev->pm.fw_version & 0x00FFFF00) < 0x005D6300) +- ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF; +- else if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(11, 5, 0)) +- /* +- * Other ASICs with DCN35 that have residency issues with +- * IPS2 in idle. +- * We want them to use IPS2 only in display off cases. +- */ +- ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF; +- break; + case IP_VERSION(3, 5, 1): + ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF; + break; +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +index c0dc2324404908..10ba4d7bf63254 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +@@ -172,7 +172,10 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work, + struct mod_hdcp_display_adjustment display_adjust; + unsigned int conn_index = aconnector->base.index; + +- mutex_lock(&hdcp_w->mutex); ++ guard(mutex)(&hdcp_w->mutex); ++ drm_connector_get(&aconnector->base); ++ if (hdcp_w->aconnector[conn_index]) ++ drm_connector_put(&hdcp_w->aconnector[conn_index]->base); + hdcp_w->aconnector[conn_index] = aconnector; + + memset(&link_adjust, 0, sizeof(link_adjust)); +@@ -209,7 +212,6 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work, + mod_hdcp_update_display(&hdcp_w->hdcp, conn_index, &link_adjust, &display_adjust, &hdcp_w->output); + + process_output(hdcp_w); +- mutex_unlock(&hdcp_w->mutex); + } + + static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, +@@ -220,8 +222,7 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, + struct drm_connector_state *conn_state = aconnector->base.state; + unsigned int conn_index = aconnector->base.index; + +- mutex_lock(&hdcp_w->mutex); +- hdcp_w->aconnector[conn_index] = aconnector; ++ guard(mutex)(&hdcp_w->mutex); + + /* the removal of display will invoke auth reset -> hdcp destroy and + * we'd expect the Content Protection (CP) property changed back to +@@ -237,9 +238,11 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, + } + + mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output); +- ++ if (hdcp_w->aconnector[conn_index]) { ++ drm_connector_put(&hdcp_w->aconnector[conn_index]->base); ++ hdcp_w->aconnector[conn_index] = NULL; ++ } + process_output(hdcp_w); +- mutex_unlock(&hdcp_w->mutex); + } + + void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index) +@@ -247,7 +250,7 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde + struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; + unsigned int conn_index; + +- mutex_lock(&hdcp_w->mutex); ++ guard(mutex)(&hdcp_w->mutex); + + mod_hdcp_reset_connection(&hdcp_w->hdcp, &hdcp_w->output); + +@@ -256,11 +259,13 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde + for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) { + hdcp_w->encryption_status[conn_index] = + MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; ++ if (hdcp_w->aconnector[conn_index]) { ++ drm_connector_put(&hdcp_w->aconnector[conn_index]->base); ++ hdcp_w->aconnector[conn_index] = NULL; ++ } + } + + process_output(hdcp_w); +- +- mutex_unlock(&hdcp_w->mutex); + } + + void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index) +@@ -277,7 +282,7 @@ static void event_callback(struct work_struct *work) + hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue, + callback_dwork); + +- mutex_lock(&hdcp_work->mutex); ++ guard(mutex)(&hdcp_work->mutex); + + cancel_delayed_work(&hdcp_work->callback_dwork); + +@@ -285,8 +290,6 @@ static void event_callback(struct work_struct *work) + &hdcp_work->output); + + process_output(hdcp_work); +- +- mutex_unlock(&hdcp_work->mutex); + } + + static void event_property_update(struct work_struct *work) +@@ -323,7 +326,7 @@ static void event_property_update(struct work_struct *work) + continue; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); +- mutex_lock(&hdcp_work->mutex); ++ guard(mutex)(&hdcp_work->mutex); + + if (conn_state->commit) { + ret = wait_for_completion_interruptible_timeout(&conn_state->commit->hw_done, +@@ -355,7 +358,6 @@ static void event_property_update(struct work_struct *work) + drm_hdcp_update_content_protection(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED); + } +- mutex_unlock(&hdcp_work->mutex); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + } + } +@@ -368,7 +370,7 @@ static void event_property_validate(struct work_struct *work) + struct amdgpu_dm_connector *aconnector; + unsigned int conn_index; + +- mutex_lock(&hdcp_work->mutex); ++ guard(mutex)(&hdcp_work->mutex); + + for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; + conn_index++) { +@@ -408,8 +410,6 @@ static void event_property_validate(struct work_struct *work) + schedule_work(&hdcp_work->property_update_work); + } + } +- +- mutex_unlock(&hdcp_work->mutex); + } + + static void event_watchdog_timer(struct work_struct *work) +@@ -420,7 +420,7 @@ static void event_watchdog_timer(struct work_struct *work) + struct hdcp_workqueue, + watchdog_timer_dwork); + +- mutex_lock(&hdcp_work->mutex); ++ guard(mutex)(&hdcp_work->mutex); + + cancel_delayed_work(&hdcp_work->watchdog_timer_dwork); + +@@ -429,8 +429,6 @@ static void event_watchdog_timer(struct work_struct *work) + &hdcp_work->output); + + process_output(hdcp_work); +- +- mutex_unlock(&hdcp_work->mutex); + } + + static void event_cpirq(struct work_struct *work) +@@ -439,13 +437,11 @@ static void event_cpirq(struct work_struct *work) + + hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work); + +- mutex_lock(&hdcp_work->mutex); ++ guard(mutex)(&hdcp_work->mutex); + + mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output); + + process_output(hdcp_work); +- +- mutex_unlock(&hdcp_work->mutex); + } + + void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work) +@@ -479,7 +475,7 @@ static bool enable_assr(void *handle, struct dc_link *link) + + dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf; + +- mutex_lock(&psp->dtm_context.mutex); ++ guard(mutex)(&psp->dtm_context.mutex); + memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); + + dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE; +@@ -494,8 +490,6 @@ static bool enable_assr(void *handle, struct dc_link *link) + res = false; + } + +- mutex_unlock(&psp->dtm_context.mutex); +- + return res; + } + +@@ -504,6 +498,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) + struct hdcp_workqueue *hdcp_work = handle; + struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx; + int link_index = aconnector->dc_link->link_index; ++ unsigned int conn_index = aconnector->base.index; + struct mod_hdcp_display *display = &hdcp_work[link_index].display; + struct mod_hdcp_link *link = &hdcp_work[link_index].link; + struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; +@@ -557,13 +552,14 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) + (!!aconnector->base.state) ? + aconnector->base.state->hdcp_content_type : -1); + +- mutex_lock(&hdcp_w->mutex); ++ guard(mutex)(&hdcp_w->mutex); + + mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output); +- ++ drm_connector_get(&aconnector->base); ++ if (hdcp_w->aconnector[conn_index]) ++ drm_connector_put(&hdcp_w->aconnector[conn_index]->base); ++ hdcp_w->aconnector[conn_index] = aconnector; + process_output(hdcp_w); +- mutex_unlock(&hdcp_w->mutex); +- + } + + /** +diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c +index ce82c9451dfe7d..e2cf118ff01d33 100644 +--- a/drivers/gpu/drm/drm_file.c ++++ b/drivers/gpu/drm/drm_file.c +@@ -938,6 +938,10 @@ void drm_show_fdinfo(struct seq_file *m, struct file *f) + struct drm_file *file = f->private_data; + struct drm_device *dev = file->minor->dev; + struct drm_printer p = drm_seq_file_printer(m); ++ int idx; ++ ++ if (!drm_dev_enter(dev, &idx)) ++ return; + + drm_printf(&p, "drm-driver:\t%s\n", dev->driver->name); + drm_printf(&p, "drm-client-id:\t%llu\n", file->client_id); +@@ -952,6 +956,8 @@ void drm_show_fdinfo(struct seq_file *m, struct file *f) + + if (dev->driver->show_fdinfo) + dev->driver->show_fdinfo(&p, file); ++ ++ drm_dev_exit(idx); + } + EXPORT_SYMBOL(drm_show_fdinfo); + +diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c +index 34bca756757660..3ea9f23b4f67af 100644 +--- a/drivers/gpu/drm/drm_mipi_dbi.c ++++ b/drivers/gpu/drm/drm_mipi_dbi.c +@@ -404,12 +404,16 @@ static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev) + u16 height = drm->mode_config.min_height; + u16 width = drm->mode_config.min_width; + struct mipi_dbi *dbi = &dbidev->dbi; +- size_t len = width * height * 2; ++ const struct drm_format_info *dst_format; ++ size_t len; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + ++ dst_format = drm_format_info(dbidev->pixel_format); ++ len = drm_format_info_min_pitch(dst_format, 0, width) * height; ++ + memset(dbidev->tx_buf, 0, len); + + mipi_dbi_set_window_address(dbidev, 0, width - 1, 0, height - 1); +diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h +index 9aae779c4da318..4969d3de2bac3d 100644 +--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h ++++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h +@@ -23,6 +23,7 @@ int intel_pxp_gsccs_init(struct intel_pxp *pxp); + + int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, int arb_session_id); + void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id); ++bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp); + + #else + static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp) +@@ -34,8 +35,11 @@ static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp) + return 0; + } + +-#endif ++static inline bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp) ++{ ++ return false; ++} + +-bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp); ++#endif + + #endif /*__INTEL_PXP_GSCCS_H__ */ +diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +index 2a942dc6a6dc23..2a82119eb58ed8 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.c ++++ b/drivers/gpu/drm/meson/meson_vclk.c +@@ -790,13 +790,13 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, + FREQ_1000_1001(params[i].pixel_freq)); + DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n", + i, params[i].phy_freq, +- FREQ_1000_1001(params[i].phy_freq/1000)*1000); ++ FREQ_1000_1001(params[i].phy_freq/10)*10); + /* Match strict frequency */ + if (phy_freq == params[i].phy_freq && + vclk_freq == params[i].vclk_freq) + return MODE_OK; + /* Match 1000/1001 variant */ +- if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) && ++ if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) && + vclk_freq == FREQ_1000_1001(params[i].vclk_freq)) + return MODE_OK; + } +@@ -1070,7 +1070,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + + for (freq = 0 ; params[freq].pixel_freq ; ++freq) { + if ((phy_freq == params[freq].phy_freq || +- phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) && ++ phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) && + (vclk_freq == params[freq].vclk_freq || + vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) { + if (vclk_freq != params[freq].vclk_freq) +diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c +index 7cc84472cecec2..edddfc036c6d1e 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fence.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c +@@ -90,7 +90,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error) + while (!list_empty(&fctx->pending)) { + fence = list_entry(fctx->pending.next, typeof(*fence), head); + +- if (error) ++ if (error && !dma_fence_is_signaled_locked(&fence->base)) + dma_fence_set_error(&fence->base, error); + + if (nouveau_fence_signal(fence)) +diff --git a/drivers/gpu/drm/tests/drm_gem_shmem_test.c b/drivers/gpu/drm/tests/drm_gem_shmem_test.c +index fd4215e2f982d2..925fbc2cda700a 100644 +--- a/drivers/gpu/drm/tests/drm_gem_shmem_test.c ++++ b/drivers/gpu/drm/tests/drm_gem_shmem_test.c +@@ -216,6 +216,9 @@ static void drm_gem_shmem_test_get_pages_sgt(struct kunit *test) + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt); + KUNIT_EXPECT_NULL(test, shmem->sgt); + ++ ret = kunit_add_action_or_reset(test, kfree_wrapper, sgt); ++ KUNIT_ASSERT_EQ(test, ret, 0); ++ + ret = kunit_add_action_or_reset(test, sg_free_table_wrapper, sgt); + KUNIT_ASSERT_EQ(test, ret, 0); + +diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c +index b11bc0f00dfda1..0248597c6269a3 100644 +--- a/drivers/gpu/drm/xe/xe_hw_engine.c ++++ b/drivers/gpu/drm/xe/xe_hw_engine.c +@@ -381,12 +381,6 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe) + blit_cctl_val, + XE_RTP_ACTION_FLAG(ENGINE_BASE))) + }, +- /* Use Fixed slice CCS mode */ +- { XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"), +- XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)), +- XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE, +- RCU_MODE_FIXED_SLICE_CCS_MODE)) +- }, + /* Disable WMTP if HW doesn't support it */ + { XE_RTP_NAME("DISABLE_WMTP_ON_UNSUPPORTED_HW"), + XE_RTP_RULES(FUNC(xe_rtp_cfeg_wmtp_disabled)), +@@ -454,6 +448,12 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe) + XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ, + XE_RTP_ACTION_FLAG(ENGINE_BASE))) + }, ++ /* Use Fixed slice CCS mode */ ++ { XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"), ++ XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)), ++ XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE, ++ RCU_MODE_FIXED_SLICE_CCS_MODE)) ++ }, + {} + }; + +diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c +index 976d43f73f3830..86b41cd48ad4cb 100644 +--- a/drivers/i2c/busses/i2c-imx-lpi2c.c ++++ b/drivers/i2c/busses/i2c-imx-lpi2c.c +@@ -652,9 +652,9 @@ static int lpi2c_imx_probe(struct platform_device *pdev) + return 0; + + rpm_disable: +- pm_runtime_put(&pdev->dev); +- pm_runtime_disable(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); ++ pm_runtime_put_sync(&pdev->dev); ++ pm_runtime_disable(&pdev->dev); + + return ret; + } +diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c +index dbe2d13972feff..ff11cd7e5c068c 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -3655,6 +3655,14 @@ static int __init parse_ivrs_acpihid(char *str) + while (*uid == '0' && *(uid + 1)) + uid++; + ++ if (strlen(hid) >= ACPIHID_HID_LEN) { ++ pr_err("Invalid command line: hid is too long\n"); ++ return 1; ++ } else if (strlen(uid) >= ACPIHID_UID_LEN) { ++ pr_err("Invalid command line: uid is too long\n"); ++ return 1; ++ } ++ + i = early_acpihid_map_size++; + memcpy(early_acpihid_map[i].hid, hid, strlen(hid)); + memcpy(early_acpihid_map[i].uid, uid, strlen(uid)); +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +index a7c36654dee5a5..32f3e91a7d7f5d 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +@@ -397,6 +397,12 @@ struct iommu_domain *arm_smmu_sva_domain_alloc(struct device *dev, + return ERR_CAST(smmu_domain); + smmu_domain->domain.type = IOMMU_DOMAIN_SVA; + smmu_domain->domain.ops = &arm_smmu_sva_domain_ops; ++ ++ /* ++ * Choose page_size as the leaf page size for invalidation when ++ * ARM_SMMU_FEAT_RANGE_INV is present ++ */ ++ smmu_domain->domain.pgsize_bitmap = PAGE_SIZE; + smmu_domain->smmu = smmu; + + ret = xa_alloc(&arm_smmu_asid_xa, &asid, smmu_domain, +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +index 6bf8ecbbe0c263..780e2d9e4ea819 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -3220,6 +3220,7 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu, + mutex_lock(&smmu->streams_mutex); + for (i = 0; i < fwspec->num_ids; i++) { + struct arm_smmu_stream *new_stream = &master->streams[i]; ++ struct rb_node *existing; + u32 sid = fwspec->ids[i]; + + new_stream->id = sid; +@@ -3230,10 +3231,20 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu, + break; + + /* Insert into SID tree */ +- if (rb_find_add(&new_stream->node, &smmu->streams, +- arm_smmu_streams_cmp_node)) { +- dev_warn(master->dev, "stream %u already in tree\n", +- sid); ++ existing = rb_find_add(&new_stream->node, &smmu->streams, ++ arm_smmu_streams_cmp_node); ++ if (existing) { ++ struct arm_smmu_master *existing_master = ++ rb_entry(existing, struct arm_smmu_stream, node) ++ ->master; ++ ++ /* Bridged PCI devices may end up with duplicated IDs */ ++ if (existing_master == master) ++ continue; ++ ++ dev_warn(master->dev, ++ "stream %u already in tree from dev %s\n", sid, ++ dev_name(existing_master->dev)); + ret = -EINVAL; + break; + } +diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c +index 038a66388564a8..157542c07aaafa 100644 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -4666,6 +4666,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx); + ++/* QM57/QS57 integrated gfx malfunctions with dmar */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_iommu_igfx); ++ + /* Broadwell igfx malfunctions with dmar */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx); +@@ -4743,7 +4746,6 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev) + } + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt); + +diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c +index 7942d8eb3d00ea..f772deb9cba574 100644 +--- a/drivers/irqchip/irq-qcom-mpm.c ++++ b/drivers/irqchip/irq-qcom-mpm.c +@@ -227,6 +227,9 @@ static int qcom_mpm_alloc(struct irq_domain *domain, unsigned int virq, + if (ret) + return ret; + ++ if (pin == GPIO_NO_WAKE_IRQ) ++ return irq_domain_disconnect_hierarchy(domain, virq); ++ + ret = irq_domain_set_hwirq_and_chip(domain, virq, pin, + &qcom_mpm_chip, priv); + if (ret) +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index 23e0b71b991e75..ca60ef209df837 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -68,6 +68,8 @@ + #define LIST_DIRTY 1 + #define LIST_SIZE 2 + ++#define SCAN_RESCHED_CYCLE 16 ++ + /*--------------------------------------------------------------*/ + + /* +@@ -2414,7 +2416,12 @@ static void __scan(struct dm_bufio_client *c) + + atomic_long_dec(&c->need_shrink); + freed++; +- cond_resched(); ++ ++ if (unlikely(freed % SCAN_RESCHED_CYCLE == 0)) { ++ dm_bufio_unlock(c); ++ cond_resched(); ++ dm_bufio_lock(c); ++ } + } + } + } +diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c +index b35b779b170443..450e1a7e7bac7a 100644 +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -5173,7 +5173,7 @@ static void dm_integrity_dtr(struct dm_target *ti) + BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress)); + BUG_ON(!list_empty(&ic->wait_list)); + +- if (ic->mode == 'B') ++ if (ic->mode == 'B' && ic->bitmap_flush_work.work.func) + cancel_delayed_work_sync(&ic->bitmap_flush_work); + if (ic->metadata_wq) + destroy_workqueue(ic->metadata_wq); +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index dbd39b9722b912..9cacc49f2cb04e 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -523,8 +523,9 @@ static char **realloc_argv(unsigned int *size, char **old_argv) + gfp = GFP_NOIO; + } + argv = kmalloc_array(new_size, sizeof(*argv), gfp); +- if (argv && old_argv) { +- memcpy(argv, old_argv, *size * sizeof(*argv)); ++ if (argv) { ++ if (old_argv) ++ memcpy(argv, old_argv, *size * sizeof(*argv)); + *size = new_size; + } + +diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c +index f73b84bae0c4c7..6ebb3d1eeb4d6f 100644 +--- a/drivers/mmc/host/renesas_sdhi_core.c ++++ b/drivers/mmc/host/renesas_sdhi_core.c +@@ -1112,26 +1112,26 @@ int renesas_sdhi_probe(struct platform_device *pdev, + num_irqs = platform_irq_count(pdev); + if (num_irqs < 0) { + ret = num_irqs; +- goto eirq; ++ goto edisclk; + } + + /* There must be at least one IRQ source */ + if (!num_irqs) { + ret = -ENXIO; +- goto eirq; ++ goto edisclk; + } + + for (i = 0; i < num_irqs; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + ret = irq; +- goto eirq; ++ goto edisclk; + } + + ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq, 0, + dev_name(&pdev->dev), host); + if (ret) +- goto eirq; ++ goto edisclk; + } + + ret = tmio_mmc_host_probe(host); +@@ -1143,8 +1143,6 @@ int renesas_sdhi_probe(struct platform_device *pdev, + + return ret; + +-eirq: +- tmio_mmc_host_remove(host); + edisclk: + renesas_sdhi_clk_disable(host); + efree: +diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c +index 940f1b71226d64..7b35d24c38d765 100644 +--- a/drivers/net/dsa/ocelot/felix_vsc9959.c ++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c +@@ -1543,7 +1543,7 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) + struct tc_taprio_qopt_offload *taprio; + struct ocelot_port *ocelot_port; + struct timespec64 base_ts; +- int port; ++ int i, port; + u32 val; + + mutex_lock(&ocelot->fwd_domain_lock); +@@ -1575,6 +1575,9 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) + QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M, + QSYS_PARAM_CFG_REG_3); + ++ for (i = 0; i < taprio->num_entries; i++) ++ vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]); ++ + ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, + QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, + QSYS_TAS_PARAM_CFG_CTRL); +diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c +index b76a9b7e0aed66..889a18962270aa 100644 +--- a/drivers/net/ethernet/amd/pds_core/auxbus.c ++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c +@@ -172,34 +172,31 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf, + return padev; + } + +-int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) ++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf, ++ struct pds_auxiliary_dev **pd_ptr) + { + struct pds_auxiliary_dev *padev; +- int err = 0; + +- if (!cf) +- return -ENODEV; ++ if (!*pd_ptr) ++ return; + + mutex_lock(&pf->config_lock); + +- padev = pf->vfs[cf->vf_id].padev; +- if (padev) { +- pds_client_unregister(pf, padev->client_id); +- auxiliary_device_delete(&padev->aux_dev); +- auxiliary_device_uninit(&padev->aux_dev); +- padev->client_id = 0; +- } +- pf->vfs[cf->vf_id].padev = NULL; ++ padev = *pd_ptr; ++ pds_client_unregister(pf, padev->client_id); ++ auxiliary_device_delete(&padev->aux_dev); ++ auxiliary_device_uninit(&padev->aux_dev); ++ *pd_ptr = NULL; + + mutex_unlock(&pf->config_lock); +- return err; + } + +-int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) ++int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf, ++ enum pds_core_vif_types vt, ++ struct pds_auxiliary_dev **pd_ptr) + { + struct pds_auxiliary_dev *padev; + char devname[PDS_DEVNAME_LEN]; +- enum pds_core_vif_types vt; + unsigned long mask; + u16 vt_support; + int client_id; +@@ -208,6 +205,9 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) + if (!cf) + return -ENODEV; + ++ if (vt >= PDS_DEV_TYPE_MAX) ++ return -EINVAL; ++ + mutex_lock(&pf->config_lock); + + mask = BIT_ULL(PDSC_S_FW_DEAD) | +@@ -219,17 +219,10 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) + goto out_unlock; + } + +- /* We only support vDPA so far, so it is the only one to +- * be verified that it is available in the Core device and +- * enabled in the devlink param. In the future this might +- * become a loop for several VIF types. +- */ +- + /* Verify that the type is supported and enabled. It is not + * an error if there is no auxbus device support for this + * VF, it just means something else needs to happen with it. + */ +- vt = PDS_DEV_TYPE_VDPA; + vt_support = !!le16_to_cpu(pf->dev_ident.vif_types[vt]); + if (!(vt_support && + pf->viftype_status[vt].supported && +@@ -255,7 +248,7 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) + err = PTR_ERR(padev); + goto out_unlock; + } +- pf->vfs[cf->vf_id].padev = padev; ++ *pd_ptr = padev; + + out_unlock: + mutex_unlock(&pf->config_lock); +diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h +index ec637dc4327a5d..becd3104473c2e 100644 +--- a/drivers/net/ethernet/amd/pds_core/core.h ++++ b/drivers/net/ethernet/amd/pds_core/core.h +@@ -303,8 +303,11 @@ void pdsc_health_thread(struct work_struct *work); + int pdsc_register_notify(struct notifier_block *nb); + void pdsc_unregister_notify(struct notifier_block *nb); + void pdsc_notify(unsigned long event, void *data); +-int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf); +-int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf); ++int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf, ++ enum pds_core_vif_types vt, ++ struct pds_auxiliary_dev **pd_ptr); ++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf, ++ struct pds_auxiliary_dev **pd_ptr); + + void pdsc_process_adminq(struct pdsc_qcq *qcq); + void pdsc_work_thread(struct work_struct *work); +diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c +index ca23cde385e67b..d8dc39da4161fb 100644 +--- a/drivers/net/ethernet/amd/pds_core/devlink.c ++++ b/drivers/net/ethernet/amd/pds_core/devlink.c +@@ -56,8 +56,11 @@ int pdsc_dl_enable_set(struct devlink *dl, u32 id, + for (vf_id = 0; vf_id < pdsc->num_vfs; vf_id++) { + struct pdsc *vf = pdsc->vfs[vf_id].vf; + +- err = ctx->val.vbool ? pdsc_auxbus_dev_add(vf, pdsc) : +- pdsc_auxbus_dev_del(vf, pdsc); ++ if (ctx->val.vbool) ++ err = pdsc_auxbus_dev_add(vf, pdsc, vt_entry->vif_id, ++ &pdsc->vfs[vf_id].padev); ++ else ++ pdsc_auxbus_dev_del(vf, pdsc, &pdsc->vfs[vf_id].padev); + } + + return err; +diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c +index 660268ff95623f..a3a68889137b63 100644 +--- a/drivers/net/ethernet/amd/pds_core/main.c ++++ b/drivers/net/ethernet/amd/pds_core/main.c +@@ -190,7 +190,8 @@ static int pdsc_init_vf(struct pdsc *vf) + devl_unlock(dl); + + pf->vfs[vf->vf_id].vf = vf; +- err = pdsc_auxbus_dev_add(vf, pf); ++ err = pdsc_auxbus_dev_add(vf, pf, PDS_DEV_TYPE_VDPA, ++ &pf->vfs[vf->vf_id].padev); + if (err) { + devl_lock(dl); + devl_unregister(dl); +@@ -417,7 +418,7 @@ static void pdsc_remove(struct pci_dev *pdev) + + pf = pdsc_get_pf_struct(pdsc->pdev); + if (!IS_ERR(pf)) { +- pdsc_auxbus_dev_del(pdsc, pf); ++ pdsc_auxbus_dev_del(pdsc, pf, &pf->vfs[pdsc->vf_id].padev); + pf->vfs[pdsc->vf_id].vf = NULL; + } + } else { +@@ -482,7 +483,8 @@ static void pdsc_reset_prepare(struct pci_dev *pdev) + + pf = pdsc_get_pf_struct(pdsc->pdev); + if (!IS_ERR(pf)) +- pdsc_auxbus_dev_del(pdsc, pf); ++ pdsc_auxbus_dev_del(pdsc, pf, ++ &pf->vfs[pdsc->vf_id].padev); + } + + pdsc_unmap_bars(pdsc); +@@ -527,7 +529,8 @@ static void pdsc_reset_done(struct pci_dev *pdev) + + pf = pdsc_get_pf_struct(pdsc->pdev); + if (!IS_ERR(pf)) +- pdsc_auxbus_dev_add(pdsc, pf); ++ pdsc_auxbus_dev_add(pdsc, pf, PDS_DEV_TYPE_VDPA, ++ &pf->vfs[pdsc->vf_id].padev); + } + } + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c +index 230726d7b74f63..d41b58fad37bbf 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c +@@ -373,8 +373,13 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata, + } + + /* Set up the header page info */ +- xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa, +- XGBE_SKB_ALLOC_SIZE); ++ if (pdata->netdev->features & NETIF_F_RXCSUM) { ++ xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa, ++ XGBE_SKB_ALLOC_SIZE); ++ } else { ++ xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa, ++ pdata->rx_buf_size); ++ } + + /* Set up the buffer page info */ + xgbe_set_buffer_data(&rdata->rx.buf, &ring->rx_buf_pa, +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +index f393228d41c7be..f1b0fb02b3cd14 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +@@ -320,6 +320,18 @@ static void xgbe_config_sph_mode(struct xgbe_prv_data *pdata) + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE); + } + ++static void xgbe_disable_sph_mode(struct xgbe_prv_data *pdata) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < pdata->channel_count; i++) { ++ if (!pdata->channel[i]->rx_ring) ++ break; ++ ++ XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_CR, SPH, 0); ++ } ++} ++ + static int xgbe_write_rss_reg(struct xgbe_prv_data *pdata, unsigned int type, + unsigned int index, unsigned int val) + { +@@ -3545,8 +3557,12 @@ static int xgbe_init(struct xgbe_prv_data *pdata) + xgbe_config_tx_coalesce(pdata); + xgbe_config_rx_buffer_size(pdata); + xgbe_config_tso_mode(pdata); +- xgbe_config_sph_mode(pdata); +- xgbe_config_rss(pdata); ++ ++ if (pdata->netdev->features & NETIF_F_RXCSUM) { ++ xgbe_config_sph_mode(pdata); ++ xgbe_config_rss(pdata); ++ } ++ + desc_if->wrapper_tx_desc_init(pdata); + desc_if->wrapper_rx_desc_init(pdata); + xgbe_enable_dma_interrupts(pdata); +@@ -3702,5 +3718,9 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if) + hw_if->disable_vxlan = xgbe_disable_vxlan; + hw_if->set_vxlan_id = xgbe_set_vxlan_id; + ++ /* For Split Header*/ ++ hw_if->enable_sph = xgbe_config_sph_mode; ++ hw_if->disable_sph = xgbe_disable_sph_mode; ++ + DBGPR("<--xgbe_init_function_ptrs\n"); + } +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +index 5475867708f426..8bc49259d71af1 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +@@ -2257,10 +2257,17 @@ static int xgbe_set_features(struct net_device *netdev, + if (ret) + return ret; + +- if ((features & NETIF_F_RXCSUM) && !rxcsum) ++ if ((features & NETIF_F_RXCSUM) && !rxcsum) { ++ hw_if->enable_sph(pdata); ++ hw_if->enable_vxlan(pdata); + hw_if->enable_rx_csum(pdata); +- else if (!(features & NETIF_F_RXCSUM) && rxcsum) ++ schedule_work(&pdata->restart_work); ++ } else if (!(features & NETIF_F_RXCSUM) && rxcsum) { ++ hw_if->disable_sph(pdata); ++ hw_if->disable_vxlan(pdata); + hw_if->disable_rx_csum(pdata); ++ schedule_work(&pdata->restart_work); ++ } + + if ((features & NETIF_F_HW_VLAN_CTAG_RX) && !rxvlan) + hw_if->enable_rx_vlan_stripping(pdata); +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h +index d85386cac8d166..ed5d43c16d0e23 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe.h ++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h +@@ -865,6 +865,10 @@ struct xgbe_hw_if { + void (*enable_vxlan)(struct xgbe_prv_data *); + void (*disable_vxlan)(struct xgbe_prv_data *); + void (*set_vxlan_id)(struct xgbe_prv_data *); ++ ++ /* For Split Header */ ++ void (*enable_sph)(struct xgbe_prv_data *pdata); ++ void (*disable_sph)(struct xgbe_prv_data *pdata); + }; + + /* This structure represents implementation specific routines for an +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 016dcfec8d4965..12b61a6fcda428 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1986,6 +1986,7 @@ static struct sk_buff *bnxt_rx_vlan(struct sk_buff *skb, u8 cmp_type, + } + return skb; + vlan_err: ++ skb_mark_for_recycle(skb); + dev_kfree_skb(skb); + return NULL; + } +@@ -3320,6 +3321,9 @@ static void bnxt_free_tx_skbs(struct bnxt *bp) + } + netdev_tx_reset_queue(netdev_get_tx_queue(bp->dev, i)); + } ++ ++ if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) ++ bnxt_ptp_free_txts_skbs(bp->ptp_cfg); + } + + static void bnxt_free_one_rx_ring(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) +@@ -11076,6 +11080,9 @@ static void bnxt_init_napi(struct bnxt *bp) + poll_fn = bnxt_poll_p5; + else if (BNXT_CHIP_TYPE_NITRO_A0(bp)) + cp_nr_rings--; ++ ++ set_bit(BNXT_STATE_NAPI_DISABLED, &bp->state); ++ + for (i = 0; i < cp_nr_rings; i++) { + bnapi = bp->bnapi[i]; + netif_napi_add(bp->dev, &bnapi->napi, poll_fn); +@@ -11844,13 +11851,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up) + set_bit(BNXT_STATE_ABORT_ERR, &bp->state); + return rc; + } ++ /* IRQ will be initialized later in bnxt_request_irq()*/ + bnxt_clear_int_mode(bp); +- rc = bnxt_init_int_mode(bp); +- if (rc) { +- clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state); +- netdev_err(bp->dev, "init int mode failed\n"); +- return rc; +- } + } + rc = bnxt_cancel_reservations(bp, fw_reset); + } +@@ -12249,8 +12251,6 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) + /* VF-reps may need to be re-opened after the PF is re-opened */ + if (BNXT_PF(bp)) + bnxt_vf_reps_open(bp); +- if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) +- WRITE_ONCE(bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS); + bnxt_ptp_init_rtc(bp, true); + bnxt_ptp_cfg_tstamp_filters(bp); + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) +@@ -15421,8 +15421,8 @@ static void bnxt_remove_one(struct pci_dev *pdev) + + bnxt_rdma_aux_device_del(bp); + +- bnxt_ptp_clear(bp); + unregister_netdev(dev); ++ bnxt_ptp_clear(bp); + + bnxt_rdma_aux_device_uninit(bp); + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +index 4e2b938ed1f7e0..d80ce437435f05 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +@@ -66,20 +66,30 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, + } + } + ++ if (cmn_req->req_type == ++ cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) ++ info->dest_buf_size += len; ++ + if (info->dest_buf) { + if ((info->seg_start + off + len) <= + BNXT_COREDUMP_BUF_LEN(info->buf_len)) { +- memcpy(info->dest_buf + off, dma_buf, len); ++ u16 copylen = min_t(u16, len, ++ info->dest_buf_size - off); ++ ++ memcpy(info->dest_buf + off, dma_buf, copylen); ++ if (copylen < len) ++ break; + } else { + rc = -ENOBUFS; ++ if (cmn_req->req_type == ++ cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) { ++ kfree(info->dest_buf); ++ info->dest_buf = NULL; ++ } + break; + } + } + +- if (cmn_req->req_type == +- cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) +- info->dest_buf_size += len; +- + if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE)) + break; + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index b901ecb57f2552..54ae90526d8ffc 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -2041,6 +2041,17 @@ static int bnxt_get_regs_len(struct net_device *dev) + return reg_len; + } + ++#define BNXT_PCIE_32B_ENTRY(start, end) \ ++ { offsetof(struct pcie_ctx_hw_stats, start), \ ++ offsetof(struct pcie_ctx_hw_stats, end) } ++ ++static const struct { ++ u16 start; ++ u16 end; ++} bnxt_pcie_32b_entries[] = { ++ BNXT_PCIE_32B_ENTRY(pcie_ltssm_histogram[0], pcie_ltssm_histogram[3]), ++}; ++ + static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *_p) + { +@@ -2072,12 +2083,27 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs, + req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr); + rc = hwrm_req_send(bp, req); + if (!rc) { +- __le64 *src = (__le64 *)hw_pcie_stats; +- u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN); +- int i; +- +- for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++) +- dst[i] = le64_to_cpu(src[i]); ++ u8 *dst = (u8 *)(_p + BNXT_PXP_REG_LEN); ++ u8 *src = (u8 *)hw_pcie_stats; ++ int i, j; ++ ++ for (i = 0, j = 0; i < sizeof(*hw_pcie_stats); ) { ++ if (i >= bnxt_pcie_32b_entries[j].start && ++ i <= bnxt_pcie_32b_entries[j].end) { ++ u32 *dst32 = (u32 *)(dst + i); ++ ++ *dst32 = le32_to_cpu(*(__le32 *)(src + i)); ++ i += 4; ++ if (i > bnxt_pcie_32b_entries[j].end && ++ j < ARRAY_SIZE(bnxt_pcie_32b_entries) - 1) ++ j++; ++ } else { ++ u64 *dst64 = (u64 *)(dst + i); ++ ++ *dst64 = le64_to_cpu(*(__le64 *)(src + i)); ++ i += 8; ++ } ++ } + } + hwrm_req_drop(bp, req); + } +@@ -4848,6 +4874,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, + if (!bp->num_tests || !BNXT_PF(bp)) + return; + ++ memset(buf, 0, sizeof(u64) * bp->num_tests); + if (etest->flags & ETH_TEST_FL_OFFLINE && + bnxt_ulp_registered(bp->edev)) { + etest->flags |= ETH_TEST_FL_FAILED; +@@ -4855,7 +4882,6 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, + return; + } + +- memset(buf, 0, sizeof(u64) * bp->num_tests); + if (!netif_running(dev)) { + etest->flags |= ETH_TEST_FL_FAILED; + return; +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +index 781225d3ba8ffc..650034a4bb46d1 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +@@ -777,6 +777,27 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) + return HZ; + } + ++void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp) ++{ ++ struct bnxt_ptp_tx_req *txts_req; ++ u16 cons = ptp->txts_cons; ++ ++ /* make sure ptp aux worker finished with ++ * possible BNXT_STATE_OPEN set ++ */ ++ ptp_cancel_worker_sync(ptp->ptp_clock); ++ ++ ptp->tx_avail = BNXT_MAX_TX_TS; ++ while (cons != ptp->txts_prod) { ++ txts_req = &ptp->txts_req[cons]; ++ if (!IS_ERR_OR_NULL(txts_req->tx_skb)) ++ dev_kfree_skb_any(txts_req->tx_skb); ++ cons = NEXT_TXTS(cons); ++ } ++ ptp->txts_cons = cons; ++ ptp_schedule_worker(ptp->ptp_clock, 0); ++} ++ + int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod) + { + spin_lock_bh(&ptp->ptp_tx_lock); +@@ -1095,7 +1116,6 @@ int bnxt_ptp_init(struct bnxt *bp) + void bnxt_ptp_clear(struct bnxt *bp) + { + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; +- int i; + + if (!ptp) + return; +@@ -1107,12 +1127,5 @@ void bnxt_ptp_clear(struct bnxt *bp) + kfree(ptp->ptp_info.pin_config); + ptp->ptp_info.pin_config = NULL; + +- for (i = 0; i < BNXT_MAX_TX_TS; i++) { +- if (ptp->txts_req[i].tx_skb) { +- dev_kfree_skb_any(ptp->txts_req[i].tx_skb); +- ptp->txts_req[i].tx_skb = NULL; +- } +- } +- + bnxt_unmap_ptp_regs(bp); + } +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h +index 61e89bb2d2690c..999b497990bce6 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h +@@ -174,6 +174,7 @@ int bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp); + void bnxt_ptp_reapply_pps(struct bnxt *bp); + int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr); + int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr); ++void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp); + int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod); + void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod); + int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts); +diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c +index d0ea9260787061..6bf8a7aeef9081 100644 +--- a/drivers/net/ethernet/dlink/dl2k.c ++++ b/drivers/net/ethernet/dlink/dl2k.c +@@ -352,7 +352,7 @@ parse_eeprom (struct net_device *dev) + eth_hw_addr_set(dev, psrom->mac_addr); + + if (np->chip_id == CHIP_IP1000A) { +- np->led_mode = psrom->led_mode; ++ np->led_mode = le16_to_cpu(psrom->led_mode); + return 0; + } + +diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h +index 195dc6cfd8955c..0e33e2eaae9606 100644 +--- a/drivers/net/ethernet/dlink/dl2k.h ++++ b/drivers/net/ethernet/dlink/dl2k.h +@@ -335,7 +335,7 @@ typedef struct t_SROM { + u16 sub_system_id; /* 0x06 */ + u16 pci_base_1; /* 0x08 (IP1000A only) */ + u16 pci_base_2; /* 0x0a (IP1000A only) */ +- u16 led_mode; /* 0x0c (IP1000A only) */ ++ __le16 led_mode; /* 0x0c (IP1000A only) */ + u16 reserved1[9]; /* 0x0e-0x1f */ + u8 mac_addr[6]; /* 0x20-0x25 */ + u8 reserved2[10]; /* 0x26-0x2f */ +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 2b05d9c6c21a43..04906897615d87 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -714,7 +714,12 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq, + txq->bd.cur = bdp; + + /* Trigger transmission start */ +- writel(0, txq->bd.reg_desc_active); ++ if (!(fep->quirks & FEC_QUIRK_ERR007885) || ++ !readl(txq->bd.reg_desc_active) || ++ !readl(txq->bd.reg_desc_active) || ++ !readl(txq->bd.reg_desc_active) || ++ !readl(txq->bd.reg_desc_active)) ++ writel(0, txq->bd.reg_desc_active); + + return 0; + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +index 9bbece25552b17..3d70c97a0bedf6 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +@@ -60,7 +60,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { + .name = "tm_qset", + .cmd = HNAE3_DBG_CMD_TM_QSET, + .dentry = HNS3_DBG_DENTRY_TM, +- .buf_len = HNS3_DBG_READ_LEN, ++ .buf_len = HNS3_DBG_READ_LEN_1MB, + .init = hns3_dbg_common_file_init, + }, + { +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index dc60ac3bde7f2c..24062a40a7793f 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -473,20 +473,14 @@ static void hns3_mask_vector_irq(struct hns3_enet_tqp_vector *tqp_vector, + writel(mask_en, tqp_vector->mask_addr); + } + +-static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector) ++static void hns3_irq_enable(struct hns3_enet_tqp_vector *tqp_vector) + { + napi_enable(&tqp_vector->napi); + enable_irq(tqp_vector->vector_irq); +- +- /* enable vector */ +- hns3_mask_vector_irq(tqp_vector, 1); + } + +-static void hns3_vector_disable(struct hns3_enet_tqp_vector *tqp_vector) ++static void hns3_irq_disable(struct hns3_enet_tqp_vector *tqp_vector) + { +- /* disable vector */ +- hns3_mask_vector_irq(tqp_vector, 0); +- + disable_irq(tqp_vector->vector_irq); + napi_disable(&tqp_vector->napi); + cancel_work_sync(&tqp_vector->rx_group.dim.work); +@@ -707,11 +701,42 @@ static int hns3_set_rx_cpu_rmap(struct net_device *netdev) + return 0; + } + ++static void hns3_enable_irqs_and_tqps(struct net_device *netdev) ++{ ++ struct hns3_nic_priv *priv = netdev_priv(netdev); ++ struct hnae3_handle *h = priv->ae_handle; ++ u16 i; ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_irq_enable(&priv->tqp_vector[i]); ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_mask_vector_irq(&priv->tqp_vector[i], 1); ++ ++ for (i = 0; i < h->kinfo.num_tqps; i++) ++ hns3_tqp_enable(h->kinfo.tqp[i]); ++} ++ ++static void hns3_disable_irqs_and_tqps(struct net_device *netdev) ++{ ++ struct hns3_nic_priv *priv = netdev_priv(netdev); ++ struct hnae3_handle *h = priv->ae_handle; ++ u16 i; ++ ++ for (i = 0; i < h->kinfo.num_tqps; i++) ++ hns3_tqp_disable(h->kinfo.tqp[i]); ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_mask_vector_irq(&priv->tqp_vector[i], 0); ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_irq_disable(&priv->tqp_vector[i]); ++} ++ + static int hns3_nic_net_up(struct net_device *netdev) + { + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; +- int i, j; + int ret; + + ret = hns3_nic_reset_all_ring(h); +@@ -720,23 +745,13 @@ static int hns3_nic_net_up(struct net_device *netdev) + + clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); + +- /* enable the vectors */ +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_enable(&priv->tqp_vector[i]); +- +- /* enable rcb */ +- for (j = 0; j < h->kinfo.num_tqps; j++) +- hns3_tqp_enable(h->kinfo.tqp[j]); ++ hns3_enable_irqs_and_tqps(netdev); + + /* start the ae_dev */ + ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0; + if (ret) { + set_bit(HNS3_NIC_STATE_DOWN, &priv->state); +- while (j--) +- hns3_tqp_disable(h->kinfo.tqp[j]); +- +- for (j = i - 1; j >= 0; j--) +- hns3_vector_disable(&priv->tqp_vector[j]); ++ hns3_disable_irqs_and_tqps(netdev); + } + + return ret; +@@ -823,17 +838,9 @@ static void hns3_reset_tx_queue(struct hnae3_handle *h) + static void hns3_nic_net_down(struct net_device *netdev) + { + struct hns3_nic_priv *priv = netdev_priv(netdev); +- struct hnae3_handle *h = hns3_get_handle(netdev); + const struct hnae3_ae_ops *ops; +- int i; + +- /* disable vectors */ +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_disable(&priv->tqp_vector[i]); +- +- /* disable rcb */ +- for (i = 0; i < h->kinfo.num_tqps; i++) +- hns3_tqp_disable(h->kinfo.tqp[i]); ++ hns3_disable_irqs_and_tqps(netdev); + + /* stop ae_dev */ + ops = priv->ae_handle->ae_algo->ops; +@@ -5864,8 +5871,6 @@ int hns3_set_channels(struct net_device *netdev, + void hns3_external_lb_prepare(struct net_device *ndev, bool if_running) + { + struct hns3_nic_priv *priv = netdev_priv(ndev); +- struct hnae3_handle *h = priv->ae_handle; +- int i; + + if (!if_running) + return; +@@ -5876,11 +5881,7 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running) + netif_carrier_off(ndev); + netif_tx_disable(ndev); + +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_disable(&priv->tqp_vector[i]); +- +- for (i = 0; i < h->kinfo.num_tqps; i++) +- hns3_tqp_disable(h->kinfo.tqp[i]); ++ hns3_disable_irqs_and_tqps(ndev); + + /* delay ring buffer clearing to hns3_reset_notify_uninit_enet + * during reset process, because driver may not be able +@@ -5896,7 +5897,6 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running) + { + struct hns3_nic_priv *priv = netdev_priv(ndev); + struct hnae3_handle *h = priv->ae_handle; +- int i; + + if (!if_running) + return; +@@ -5912,11 +5912,7 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running) + + clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); + +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_enable(&priv->tqp_vector[i]); +- +- for (i = 0; i < h->kinfo.num_tqps; i++) +- hns3_tqp_enable(h->kinfo.tqp[i]); ++ hns3_enable_irqs_and_tqps(ndev); + + netif_tx_wake_all_queues(ndev); + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +index 181af419b878d5..0ffda5146bae58 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +@@ -439,6 +439,13 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev) + ptp->info.settime64 = hclge_ptp_settime; + + ptp->info.n_alarm = 0; ++ ++ spin_lock_init(&ptp->lock); ++ ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET; ++ ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE; ++ ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF; ++ hdev->ptp = ptp; ++ + ptp->clock = ptp_clock_register(&ptp->info, &hdev->pdev->dev); + if (IS_ERR(ptp->clock)) { + dev_err(&hdev->pdev->dev, +@@ -450,12 +457,6 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev) + return -ENODEV; + } + +- spin_lock_init(&ptp->lock); +- ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET; +- ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE; +- ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF; +- hdev->ptp = ptp; +- + return 0; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index fd5992164846b1..8f5a85b97ac0c5 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -1294,9 +1294,8 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) + rtnl_unlock(); + } + +-static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) ++static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable) + { +- struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; + + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, +@@ -1305,6 +1304,19 @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); + } + ++static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) ++{ ++ struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); ++ int ret; ++ ++ ret = hclgevf_en_hw_strip_rxvtag_cmd(hdev, enable); ++ if (ret) ++ return ret; ++ ++ hdev->rxvtag_strip_en = enable; ++ return 0; ++} ++ + static int hclgevf_reset_tqp(struct hnae3_handle *handle) + { + #define HCLGEVF_RESET_ALL_QUEUE_DONE 1U +@@ -2206,12 +2218,13 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) + tc_valid, tc_size); + } + +-static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) ++static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev, ++ bool rxvtag_strip_en) + { + struct hnae3_handle *nic = &hdev->nic; + int ret; + +- ret = hclgevf_en_hw_strip_rxvtag(nic, true); ++ ret = hclgevf_en_hw_strip_rxvtag(nic, rxvtag_strip_en); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to enable rx vlan offload, ret = %d\n", ret); +@@ -2881,7 +2894,7 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) + if (ret) + return ret; + +- ret = hclgevf_init_vlan_config(hdev); ++ ret = hclgevf_init_vlan_config(hdev, hdev->rxvtag_strip_en); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed(%d) to initialize VLAN config\n", ret); +@@ -2996,7 +3009,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) + goto err_config; + } + +- ret = hclgevf_init_vlan_config(hdev); ++ ret = hclgevf_init_vlan_config(hdev, true); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed(%d) to initialize VLAN config\n", ret); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +index cccef32284616b..0208425ab594f5 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +@@ -253,6 +253,7 @@ struct hclgevf_dev { + int *vector_irq; + + bool gro_en; ++ bool rxvtag_strip_en; + + unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)]; + +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +index 14e3f0f89c78d6..ef755cee64ca99 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +@@ -2091,6 +2091,11 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) + pf = vf->pf; + dev = ice_pf_to_dev(pf); + vf_vsi = ice_get_vf_vsi(vf); ++ if (!vf_vsi) { ++ dev_err(dev, "Can not get FDIR vf_vsi for VF %u\n", vf->vf_id); ++ v_ret = VIRTCHNL_STATUS_ERR_PARAM; ++ goto err_exit; ++ } + + #define ICE_VF_MAX_FDIR_FILTERS 128 + if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) || +diff --git a/drivers/net/ethernet/intel/idpf/idpf.h b/drivers/net/ethernet/intel/idpf/idpf.h +index 66544faab710aa..aef0e9775a3305 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf.h ++++ b/drivers/net/ethernet/intel/idpf/idpf.h +@@ -629,13 +629,13 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 |\ + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6) + +-#define IDPF_CAP_RX_CSUM_L4V4 (\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP) ++#define IDPF_CAP_TX_CSUM_L4V4 (\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP |\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP) + +-#define IDPF_CAP_RX_CSUM_L4V6 (\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP) ++#define IDPF_CAP_TX_CSUM_L4V6 (\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP |\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP) + + #define IDPF_CAP_RX_CSUM (\ + VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 |\ +@@ -644,11 +644,9 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\ + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP) + +-#define IDPF_CAP_SCTP_CSUM (\ ++#define IDPF_CAP_TX_SCTP_CSUM (\ + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP |\ +- VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP) ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP) + + #define IDPF_CAP_TUNNEL_TX_CSUM (\ + VIRTCHNL2_CAP_TX_CSUM_L3_SINGLE_TUNNEL |\ +diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c +index a3d6b8f198a86a..5ce663d04de00b 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c ++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c +@@ -703,8 +703,10 @@ static int idpf_cfg_netdev(struct idpf_vport *vport) + { + struct idpf_adapter *adapter = vport->adapter; + struct idpf_vport_config *vport_config; ++ netdev_features_t other_offloads = 0; ++ netdev_features_t csum_offloads = 0; ++ netdev_features_t tso_offloads = 0; + netdev_features_t dflt_features; +- netdev_features_t offloads = 0; + struct idpf_netdev_priv *np; + struct net_device *netdev; + u16 idx = vport->idx; +@@ -766,53 +768,32 @@ static int idpf_cfg_netdev(struct idpf_vport *vport) + + if (idpf_is_cap_ena_all(adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS)) + dflt_features |= NETIF_F_RXHASH; +- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V4)) +- dflt_features |= NETIF_F_IP_CSUM; +- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V6)) +- dflt_features |= NETIF_F_IPV6_CSUM; ++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V4)) ++ csum_offloads |= NETIF_F_IP_CSUM; ++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V6)) ++ csum_offloads |= NETIF_F_IPV6_CSUM; + if (idpf_is_cap_ena(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM)) +- dflt_features |= NETIF_F_RXCSUM; +- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_SCTP_CSUM)) +- dflt_features |= NETIF_F_SCTP_CRC; ++ csum_offloads |= NETIF_F_RXCSUM; ++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_SCTP_CSUM)) ++ csum_offloads |= NETIF_F_SCTP_CRC; + + if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV4_TCP)) +- dflt_features |= NETIF_F_TSO; ++ tso_offloads |= NETIF_F_TSO; + if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV6_TCP)) +- dflt_features |= NETIF_F_TSO6; ++ tso_offloads |= NETIF_F_TSO6; + if (idpf_is_cap_ena_all(adapter, IDPF_SEG_CAPS, + VIRTCHNL2_CAP_SEG_IPV4_UDP | + VIRTCHNL2_CAP_SEG_IPV6_UDP)) +- dflt_features |= NETIF_F_GSO_UDP_L4; ++ tso_offloads |= NETIF_F_GSO_UDP_L4; + if (idpf_is_cap_ena_all(adapter, IDPF_RSC_CAPS, IDPF_CAP_RSC)) +- offloads |= NETIF_F_GRO_HW; +- /* advertise to stack only if offloads for encapsulated packets is +- * supported +- */ +- if (idpf_is_cap_ena(vport->adapter, IDPF_SEG_CAPS, +- VIRTCHNL2_CAP_SEG_TX_SINGLE_TUNNEL)) { +- offloads |= NETIF_F_GSO_UDP_TUNNEL | +- NETIF_F_GSO_GRE | +- NETIF_F_GSO_GRE_CSUM | +- NETIF_F_GSO_PARTIAL | +- NETIF_F_GSO_UDP_TUNNEL_CSUM | +- NETIF_F_GSO_IPXIP4 | +- NETIF_F_GSO_IPXIP6 | +- 0; +- +- if (!idpf_is_cap_ena_all(vport->adapter, IDPF_CSUM_CAPS, +- IDPF_CAP_TUNNEL_TX_CSUM)) +- netdev->gso_partial_features |= +- NETIF_F_GSO_UDP_TUNNEL_CSUM; +- +- netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; +- offloads |= NETIF_F_TSO_MANGLEID; +- } ++ other_offloads |= NETIF_F_GRO_HW; + if (idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_LOOPBACK)) +- offloads |= NETIF_F_LOOPBACK; ++ other_offloads |= NETIF_F_LOOPBACK; + +- netdev->features |= dflt_features; +- netdev->hw_features |= dflt_features | offloads; +- netdev->hw_enc_features |= dflt_features | offloads; ++ netdev->features |= dflt_features | csum_offloads | tso_offloads; ++ netdev->hw_features |= netdev->features | other_offloads; ++ netdev->vlan_features |= netdev->features | other_offloads; ++ netdev->hw_enc_features |= dflt_features | other_offloads; + idpf_set_ethtool_ops(netdev); + SET_NETDEV_DEV(netdev, &adapter->pdev->dev); + +@@ -1127,11 +1108,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, + + num_max_q = max(max_q->max_txq, max_q->max_rxq); + vport->q_vector_idxs = kcalloc(num_max_q, sizeof(u16), GFP_KERNEL); +- if (!vport->q_vector_idxs) { +- kfree(vport); ++ if (!vport->q_vector_idxs) ++ goto free_vport; + +- return NULL; +- } + idpf_vport_init(vport, max_q); + + /* This alloc is done separate from the LUT because it's not strictly +@@ -1141,11 +1120,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, + */ + rss_data = &adapter->vport_config[idx]->user_config.rss_data; + rss_data->rss_key = kzalloc(rss_data->rss_key_size, GFP_KERNEL); +- if (!rss_data->rss_key) { +- kfree(vport); ++ if (!rss_data->rss_key) ++ goto free_vector_idxs; + +- return NULL; +- } + /* Initialize default rss key */ + netdev_rss_key_fill((void *)rss_data->rss_key, rss_data->rss_key_size); + +@@ -1158,6 +1135,13 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, + adapter->next_vport = idpf_get_free_slot(adapter); + + return vport; ++ ++free_vector_idxs: ++ kfree(vport->q_vector_idxs); ++free_vport: ++ kfree(vport); ++ ++ return NULL; + } + + /** +diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c +index 7557bb6694c090..734da1680c5a48 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf_main.c ++++ b/drivers/net/ethernet/intel/idpf/idpf_main.c +@@ -89,6 +89,7 @@ static void idpf_shutdown(struct pci_dev *pdev) + { + struct idpf_adapter *adapter = pci_get_drvdata(pdev); + ++ cancel_delayed_work_sync(&adapter->serv_task); + cancel_delayed_work_sync(&adapter->vc_event_task); + idpf_vc_core_deinit(adapter); + idpf_deinit_dflt_mbx(adapter); +diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c +index 612ed26a29c5d4..efc7b30e421133 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ptp.c ++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c +@@ -1290,6 +1290,8 @@ void igc_ptp_reset(struct igc_adapter *adapter) + /* reset the tstamp_config */ + igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); + ++ mutex_lock(&adapter->ptm_lock); ++ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + + switch (adapter->hw.mac.type) { +@@ -1308,7 +1310,6 @@ void igc_ptp_reset(struct igc_adapter *adapter) + if (!igc_is_crosststamp_supported(adapter)) + break; + +- mutex_lock(&adapter->ptm_lock); + wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT); + wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT); + +@@ -1332,7 +1333,6 @@ void igc_ptp_reset(struct igc_adapter *adapter) + netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n"); + + igc_ptm_reset(hw); +- mutex_unlock(&adapter->ptm_lock); + break; + default: + /* No work to do. */ +@@ -1349,5 +1349,7 @@ void igc_ptp_reset(struct igc_adapter *adapter) + out: + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + ++ mutex_unlock(&adapter->ptm_lock); ++ + wrfl(); + } +diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +index a89f80bac39b8d..1b2f5cae06449d 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +@@ -1184,7 +1184,7 @@ static void octep_hb_timeout_task(struct work_struct *work) + miss_cnt); + rtnl_lock(); + if (netif_running(oct->netdev)) +- octep_stop(oct->netdev); ++ dev_close(oct->netdev); + rtnl_unlock(); + } + +diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c +index 18c922dd5fc64d..ccb69bc5c95292 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c +@@ -835,7 +835,9 @@ static void octep_vf_tx_timeout(struct net_device *netdev, unsigned int txqueue) + struct octep_vf_device *oct = netdev_priv(netdev); + + netdev_hold(netdev, NULL, GFP_ATOMIC); +- schedule_work(&oct->tx_timeout_task); ++ if (!schedule_work(&oct->tx_timeout_task)) ++ netdev_put(netdev, NULL); ++ + } + + static int octep_vf_set_mac(struct net_device *netdev, void *p) +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 223aee1af44304..c5d5b9ff8bc42f 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -269,12 +269,8 @@ static const char * const mtk_clks_source_name[] = { + "ethwarp_wocpu2", + "ethwarp_wocpu1", + "ethwarp_wocpu0", +- "top_usxgmii0_sel", +- "top_usxgmii1_sel", + "top_sgm0_sel", + "top_sgm1_sel", +- "top_xfi_phy0_xtal_sel", +- "top_xfi_phy1_xtal_sel", + "top_eth_gmii_sel", + "top_eth_refck_50m_sel", + "top_eth_sys_200m_sel", +@@ -2206,14 +2202,18 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + ring->data[idx] = new_data; + rxd->rxd1 = (unsigned int)dma_addr; + release_desc: ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { ++ if (unlikely(dma_addr == DMA_MAPPING_ERROR)) ++ addr64 = FIELD_GET(RX_DMA_ADDR64_MASK, ++ rxd->rxd2); ++ else ++ addr64 = RX_DMA_PREP_ADDR64(dma_addr); ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + rxd->rxd2 = RX_DMA_LSO; + else +- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); +- +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) && +- likely(dma_addr != DMA_MAPPING_ERROR)) +- rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); ++ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size) | addr64; + + ring->calc_idx = idx; + done++; +diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c +index 25989c79c92e61..c2ab87828d8589 100644 +--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c ++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c +@@ -1163,6 +1163,7 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget) + struct net_device *ndev = priv->ndev; + unsigned int head = ring->head; + unsigned int entry = ring->tail; ++ unsigned long flags; + + while (entry != head && count < (MTK_STAR_RING_NUM_DESCS - 1)) { + ret = mtk_star_tx_complete_one(priv); +@@ -1182,9 +1183,9 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget) + netif_wake_queue(ndev); + + if (napi_complete(napi)) { +- spin_lock(&priv->lock); ++ spin_lock_irqsave(&priv->lock, flags); + mtk_star_enable_dma_irq(priv, false, true); +- spin_unlock(&priv->lock); ++ spin_unlock_irqrestore(&priv->lock, flags); + } + + return 0; +@@ -1341,16 +1342,16 @@ static int mtk_star_rx(struct mtk_star_priv *priv, int budget) + static int mtk_star_rx_poll(struct napi_struct *napi, int budget) + { + struct mtk_star_priv *priv; ++ unsigned long flags; + int work_done = 0; + + priv = container_of(napi, struct mtk_star_priv, rx_napi); + + work_done = mtk_star_rx(priv, budget); +- if (work_done < budget) { +- napi_complete_done(napi, work_done); +- spin_lock(&priv->lock); ++ if (work_done < budget && napi_complete_done(napi, work_done)) { ++ spin_lock_irqsave(&priv->lock, flags); + mtk_star_enable_dma_irq(priv, true, false); +- spin_unlock(&priv->lock); ++ spin_unlock_irqrestore(&priv->lock, flags); + } + + return work_done; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +index 09433b91be176f..c8adf309ecad04 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +@@ -177,6 +177,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + + priv = ptpsq->txqsq.priv; + ++ rtnl_lock(); + mutex_lock(&priv->state_lock); + chs = &priv->channels; + netdev = priv->netdev; +@@ -184,22 +185,19 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + carrier_ok = netif_carrier_ok(netdev); + netif_carrier_off(netdev); + +- rtnl_lock(); + mlx5e_deactivate_priv_channels(priv); +- rtnl_unlock(); + + mlx5e_ptp_close(chs->ptp); + err = mlx5e_ptp_open(priv, &chs->params, chs->c[0]->lag_port, &chs->ptp); + +- rtnl_lock(); + mlx5e_activate_priv_channels(priv); +- rtnl_unlock(); + + /* return carrier back if needed */ + if (carrier_ok) + netif_carrier_on(netdev); + + mutex_unlock(&priv->state_lock); ++ rtnl_unlock(); + + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +index e4e487c8431b88..b9cf79e2712440 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +@@ -165,9 +165,6 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, + struct flow_match_enc_keyid enc_keyid; + void *misc_c, *misc_v; + +- misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters); +- misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); +- + if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) + return 0; + +@@ -182,6 +179,30 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, + err = mlx5e_tc_tun_parse_vxlan_gbp_option(priv, spec, f); + if (err) + return err; ++ ++ /* We can't mix custom tunnel headers with symbolic ones and we ++ * don't have a symbolic field name for GBP, so we use custom ++ * tunnel headers in this case. We need hardware support to ++ * match on custom tunnel headers, but we already know it's ++ * supported because the previous call successfully checked for ++ * that. ++ */ ++ misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, ++ misc_parameters_5); ++ misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, ++ misc_parameters_5); ++ ++ /* Shift by 8 to account for the reserved bits in the vxlan ++ * header after the VNI. ++ */ ++ MLX5_SET(fte_match_set_misc5, misc_c, tunnel_header_1, ++ be32_to_cpu(enc_keyid.mask->keyid) << 8); ++ MLX5_SET(fte_match_set_misc5, misc_v, tunnel_header_1, ++ be32_to_cpu(enc_keyid.key->keyid) << 8); ++ ++ spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_5; ++ ++ return 0; + } + + /* match on VNI is required */ +@@ -195,6 +216,11 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, + return -EOPNOTSUPP; + } + ++ misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, ++ misc_parameters); ++ misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, ++ misc_parameters); ++ + MLX5_SET(fte_match_set_misc, misc_c, vxlan_vni, + be32_to_cpu(enc_keyid.mask->keyid)); + MLX5_SET(fte_match_set_misc, misc_v, vxlan_vni, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 6b3b1afe831214..218d5402cd1a65 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -1750,9 +1750,6 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr + !list_is_first(&attr->list, &flow->attrs)) + return 0; + +- if (flow_flag_test(flow, SLOW)) +- return 0; +- + esw_attr = attr->esw_attr; + if (!esw_attr->split_count || + esw_attr->split_count == esw_attr->out_count - 1) +@@ -1766,7 +1763,7 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr + for (i = esw_attr->split_count; i < esw_attr->out_count; i++) { + /* external dest with encap is considered as internal by firmware */ + if (esw_attr->dests[i].vport == MLX5_VPORT_UPLINK && +- !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP_VALID)) ++ !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP)) + ext_dest = true; + else + int_dest = true; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 3950b1d4b3d8e5..988df7047b01d7 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -3514,7 +3514,9 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) + int err; + + mutex_init(&esw->offloads.termtbl_mutex); +- mlx5_rdma_enable_roce(esw->dev); ++ err = mlx5_rdma_enable_roce(esw->dev); ++ if (err) ++ goto err_roce; + + err = mlx5_esw_host_number_init(esw); + if (err) +@@ -3575,6 +3577,7 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) + esw_offloads_metadata_uninit(esw); + err_metadata: + mlx5_rdma_disable_roce(esw->dev); ++err_roce: + mutex_destroy(&esw->offloads.termtbl_mutex); + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +index a42f6cd99b7448..5c552b71e371c5 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +@@ -118,8 +118,8 @@ static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid * + + static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev) + { ++ u8 mac[ETH_ALEN] = {}; + union ib_gid gid; +- u8 mac[ETH_ALEN]; + + mlx5_rdma_make_default_gid(dev, &gid); + return mlx5_core_roce_gid_set(dev, 0, +@@ -140,17 +140,17 @@ void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev) + mlx5_nic_vport_disable_roce(dev); + } + +-void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) ++int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) + { + int err; + + if (!MLX5_CAP_GEN(dev, roce)) +- return; ++ return 0; + + err = mlx5_nic_vport_enable_roce(dev); + if (err) { + mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err); +- return; ++ return err; + } + + err = mlx5_rdma_add_roce_addr(dev); +@@ -165,10 +165,11 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) + goto del_roce_addr; + } + +- return; ++ return err; + + del_roce_addr: + mlx5_rdma_del_roce_addr(dev); + disable_roce: + mlx5_nic_vport_disable_roce(dev); ++ return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.h b/drivers/net/ethernet/mellanox/mlx5/core/rdma.h +index 750cff2a71a4bb..3d9e76c3d42fb1 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.h +@@ -8,12 +8,12 @@ + + #ifdef CONFIG_MLX5_ESWITCH + +-void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev); ++int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev); + void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev); + + #else /* CONFIG_MLX5_ESWITCH */ + +-static inline void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) {} ++static inline int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) { return 0; } + static inline void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev) {} + + #endif /* CONFIG_MLX5_ESWITCH */ +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 4dc5adcda6a381..547255ca1c4efa 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -1815,6 +1815,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, + if (nr_frags <= 0) { + tx->frame_data0 |= TX_DESC_DATA0_LS_; + tx->frame_data0 |= TX_DESC_DATA0_IOC_; ++ tx->frame_last = tx->frame_first; + } + tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; + tx_descriptor->data0 = cpu_to_le32(tx->frame_data0); +@@ -1884,6 +1885,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx, + tx->frame_first = 0; + tx->frame_data0 = 0; + tx->frame_tail = 0; ++ tx->frame_last = 0; + return -ENOMEM; + } + +@@ -1924,16 +1926,18 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx, + TX_DESC_DATA0_DTYPE_DATA_) { + tx->frame_data0 |= TX_DESC_DATA0_LS_; + tx->frame_data0 |= TX_DESC_DATA0_IOC_; ++ tx->frame_last = tx->frame_tail; + } + +- tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; +- buffer_info = &tx->buffer_info[tx->frame_tail]; ++ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_last]; ++ buffer_info = &tx->buffer_info[tx->frame_last]; + buffer_info->skb = skb; + if (time_stamp) + buffer_info->flags |= TX_BUFFER_INFO_FLAG_TIMESTAMP_REQUESTED; + if (ignore_sync) + buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC; + ++ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; + tx_descriptor->data0 = cpu_to_le32(tx->frame_data0); + tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail); + tx->last_tail = tx->frame_tail; +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 8ef897c114d3ce..2f0cab0c85e1d0 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -980,6 +980,7 @@ struct lan743x_tx { + u32 frame_first; + u32 frame_data0; + u32 frame_tail; ++ u32 frame_last; + + struct lan743x_tx_buffer_info *buffer_info; + +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index ef93df52088710..08bee56aea35f3 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -830,6 +830,7 @@ EXPORT_SYMBOL(ocelot_vlan_prepare); + int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, + bool untagged) + { ++ struct ocelot_port *ocelot_port = ocelot->ports[port]; + int err; + + /* Ignore VID 0 added to our RX filter by the 8021q module, since +@@ -849,6 +850,11 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, + ocelot_bridge_vlan_find(ocelot, vid)); + if (err) + return err; ++ } else if (ocelot_port->pvid_vlan && ++ ocelot_bridge_vlan_find(ocelot, vid) == ocelot_port->pvid_vlan) { ++ err = ocelot_port_set_pvid(ocelot, port, NULL); ++ if (err) ++ return err; + } + + /* Untagged egress vlan clasification */ +diff --git a/drivers/net/ethernet/realtek/rtase/rtase_main.c b/drivers/net/ethernet/realtek/rtase/rtase_main.c +index 86dd034fdddc52..3a588aaa89c58a 100644 +--- a/drivers/net/ethernet/realtek/rtase/rtase_main.c ++++ b/drivers/net/ethernet/realtek/rtase/rtase_main.c +@@ -1924,8 +1924,8 @@ static u16 rtase_calc_time_mitigation(u32 time_us) + + time_us = min_t(int, time_us, RTASE_MITI_MAX_TIME); + +- msb = fls(time_us); +- if (msb >= RTASE_MITI_COUNT_BIT_NUM) { ++ if (time_us > RTASE_MITI_TIME_COUNT_MASK) { ++ msb = fls(time_us); + time_unit = msb - RTASE_MITI_COUNT_BIT_NUM; + time_count = time_us >> (msb - RTASE_MITI_COUNT_BIT_NUM); + } else { +diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c +index 89dc4c401a8de4..e4d993f3137407 100644 +--- a/drivers/net/ethernet/vertexcom/mse102x.c ++++ b/drivers/net/ethernet/vertexcom/mse102x.c +@@ -6,6 +6,7 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -33,7 +34,7 @@ + #define CMD_CTR (0x2 << CMD_SHIFT) + + #define CMD_MASK GENMASK(15, CMD_SHIFT) +-#define LEN_MASK GENMASK(CMD_SHIFT - 1, 0) ++#define LEN_MASK GENMASK(CMD_SHIFT - 2, 0) + + #define DET_CMD_LEN 4 + #define DET_SOF_LEN 2 +@@ -262,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp, + } + + static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff, +- unsigned int frame_len) ++ unsigned int frame_len, bool drop) + { + struct mse102x_net_spi *mses = to_mse102x_spi(mse); + struct spi_transfer *xfer = &mses->spi_xfer; +@@ -280,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff, + netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n", + __func__, ret); + mse->stats.xfer_err++; ++ } else if (drop) { ++ netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__); ++ ret = -EINVAL; + } else if (*sof != cpu_to_be16(DET_SOF)) { + netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n", + __func__, *sof); +@@ -307,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + struct sk_buff *skb; + unsigned int rxalign; + unsigned int rxlen; ++ bool drop = false; + __be16 rx = 0; + u16 cmd_resp; + u8 *rxpkt; +@@ -329,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n", + __func__, cmd_resp); + mse->stats.invalid_rts++; +- return; ++ drop = true; ++ goto drop; + } + + net_dbg_ratelimited("%s: Unexpected response to first CMD\n", +@@ -337,12 +343,20 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + } + + rxlen = cmd_resp & LEN_MASK; +- if (!rxlen) { +- net_dbg_ratelimited("%s: No frame length defined\n", __func__); ++ if (rxlen < ETH_ZLEN || rxlen > VLAN_ETH_FRAME_LEN) { ++ net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__, ++ rxlen); + mse->stats.invalid_len++; +- return; ++ drop = true; + } + ++ /* In case of a invalid CMD_RTS, the frame must be consumed anyway. ++ * So assume the maximum possible frame length. ++ */ ++drop: ++ if (drop) ++ rxlen = VLAN_ETH_FRAME_LEN; ++ + rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4); + skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign); + if (!skb) +@@ -353,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + * They are copied, but ignored. + */ + rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN; +- if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) { ++ if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) { + mse->ndev->stats.rx_errors++; + dev_kfree_skb(skb); + return; +@@ -509,6 +523,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse) + static int mse102x_net_open(struct net_device *ndev) + { + struct mse102x_net *mse = netdev_priv(ndev); ++ struct mse102x_net_spi *mses = to_mse102x_spi(mse); + int ret; + + ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT, +@@ -524,6 +539,13 @@ static int mse102x_net_open(struct net_device *ndev) + + netif_carrier_on(ndev); + ++ /* The SPI interrupt can stuck in case of pending packet(s). ++ * So poll for possible packet(s) to re-arm the interrupt. ++ */ ++ mutex_lock(&mses->lock); ++ mse102x_rx_pkt_spi(mse); ++ mutex_unlock(&mses->lock); ++ + netif_dbg(mse, ifup, ndev, "network device up\n"); + + return 0; +diff --git a/drivers/net/mdio/mdio-mux-meson-gxl.c b/drivers/net/mdio/mdio-mux-meson-gxl.c +index 89554021b5ccc4..f9f02d31364921 100644 +--- a/drivers/net/mdio/mdio-mux-meson-gxl.c ++++ b/drivers/net/mdio/mdio-mux-meson-gxl.c +@@ -17,6 +17,7 @@ + #define REG2_LEDACT GENMASK(23, 22) + #define REG2_LEDLINK GENMASK(25, 24) + #define REG2_DIV4SEL BIT(27) ++#define REG2_REVERSED BIT(28) + #define REG2_ADCBYPASS BIT(30) + #define REG2_CLKINSEL BIT(31) + #define ETH_REG3 0x4 +@@ -65,7 +66,7 @@ static void gxl_enable_internal_mdio(struct gxl_mdio_mux *priv) + * The only constraint is that it must match the one in + * drivers/net/phy/meson-gxl.c to properly match the PHY. + */ +- writel(FIELD_PREP(REG2_PHYID, EPHY_GXL_ID), ++ writel(REG2_REVERSED | FIELD_PREP(REG2_PHYID, EPHY_GXL_ID), + priv->regs + ETH_REG2); + + /* Enable the internal phy */ +diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c +index bb0bf141587274..7b3739b29c8f72 100644 +--- a/drivers/net/usb/rndis_host.c ++++ b/drivers/net/usb/rndis_host.c +@@ -630,16 +630,6 @@ static const struct driver_info zte_rndis_info = { + .tx_fixup = rndis_tx_fixup, + }; + +-static const struct driver_info wwan_rndis_info = { +- .description = "Mobile Broadband RNDIS device", +- .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT, +- .bind = rndis_bind, +- .unbind = rndis_unbind, +- .status = rndis_status, +- .rx_fixup = rndis_rx_fixup, +- .tx_fixup = rndis_tx_fixup, +-}; +- + /*-------------------------------------------------------------------------*/ + + static const struct usb_device_id products [] = { +@@ -676,11 +666,9 @@ static const struct usb_device_id products [] = { + USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), + .driver_info = (unsigned long) &rndis_info, + }, { +- /* Mobile Broadband Modem, seen in Novatel Verizon USB730L and +- * Telit FN990A (RNDIS) +- */ ++ /* Novatel Verizon USB730L */ + USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1), +- .driver_info = (unsigned long)&wwan_rndis_info, ++ .driver_info = (unsigned long) &rndis_info, + }, + { }, // END + }; +diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c +index 6e6e9f05509ab0..06d19e90eadb59 100644 +--- a/drivers/net/vxlan/vxlan_vnifilter.c ++++ b/drivers/net/vxlan/vxlan_vnifilter.c +@@ -627,7 +627,11 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan, + * default dst remote_ip previously added for this vni + */ + if (!vxlan_addr_any(&vninode->remote_ip) || +- !vxlan_addr_any(&dst->remote_ip)) ++ !vxlan_addr_any(&dst->remote_ip)) { ++ u32 hash_index = fdb_head_index(vxlan, all_zeros_mac, ++ vninode->vni); ++ ++ spin_lock_bh(&vxlan->hash_lock[hash_index]); + __vxlan_fdb_delete(vxlan, all_zeros_mac, + (vxlan_addr_any(&vninode->remote_ip) ? + dst->remote_ip : vninode->remote_ip), +@@ -635,6 +639,8 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan, + vninode->vni, vninode->vni, + dst->remote_ifindex, + true); ++ spin_unlock_bh(&vxlan->hash_lock[hash_index]); ++ } + + if (vxlan->dev->flags & IFF_UP) { + if (vxlan_addr_multicast(&vninode->remote_ip) && +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +index 8afbf529c74503..0364b81f6e9163 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -896,14 +896,16 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) + } + + /* 1) Prepare USB boot loader for runtime image */ +- brcmf_usb_dl_cmd(devinfo, DL_START, &state, sizeof(state)); ++ err = brcmf_usb_dl_cmd(devinfo, DL_START, &state, sizeof(state)); ++ if (err) ++ goto fail; + + rdlstate = le32_to_cpu(state.state); + rdlbytes = le32_to_cpu(state.bytes); + + /* 2) Check we are in the Waiting state */ + if (rdlstate != DL_WAITING) { +- brcmf_err("Failed to DL_START\n"); ++ brcmf_err("Invalid DL state: %u\n", rdlstate); + err = -EINVAL; + goto fail; + } +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +index 98563757ce2c9d..405bba199fe7fb 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +@@ -148,6 +148,7 @@ + * during a error FW error. + */ + #define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101) ++#define CSR_FUNC_SCRATCH_POWER_OFF_MASK 0xFFFF + + /* Bits for CSR_HW_IF_CONFIG_REG */ + #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F) +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +index 3c9d91496c8267..3b3dcaf33c9d9e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +@@ -347,7 +347,6 @@ void __releases(nic_access) + iwl_trans_release_nic_access(struct iwl_trans *trans) + { + iwl_trans_pcie_release_nic_access(trans); +- __release(nic_access); + } + IWL_EXPORT_SYMBOL(iwl_trans_release_nic_access); + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index 9dd0e0a51ce5cc..9141ea57abfce1 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -1651,11 +1651,27 @@ static int _iwl_pci_resume(struct device *device, bool restore) + * Scratch value was altered, this means the device was powered off, we + * need to reset it completely. + * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan, +- * so assume that any bits there mean that the device is usable. ++ * but not bits [15:8]. So if we have bits set in lower word, assume ++ * the device is alive. ++ * For older devices, just try silently to grab the NIC. + */ +- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ && +- !iwl_read32(trans, CSR_FUNC_SCRATCH)) +- device_was_powered_off = true; ++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { ++ if (!(iwl_read32(trans, CSR_FUNC_SCRATCH) & ++ CSR_FUNC_SCRATCH_POWER_OFF_MASK)) ++ device_was_powered_off = true; ++ } else { ++ /* ++ * bh are re-enabled by iwl_trans_pcie_release_nic_access, ++ * so re-enable them if _iwl_trans_pcie_grab_nic_access fails. ++ */ ++ local_bh_disable(); ++ if (_iwl_trans_pcie_grab_nic_access(trans, true)) { ++ iwl_trans_pcie_release_nic_access(trans); ++ } else { ++ device_was_powered_off = true; ++ local_bh_enable(); ++ } ++ } + + if (restore || device_was_powered_off) { + trans->state = IWL_TRANS_NO_FW; +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +index ebe9b25cc53a99..6019114a5d1aa6 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +@@ -558,10 +558,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans); + void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions, + struct device *dev); + +-bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans); +-#define _iwl_trans_pcie_grab_nic_access(trans) \ ++bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent); ++#define _iwl_trans_pcie_grab_nic_access(trans, silent) \ + __cond_lock(nic_access_nobh, \ +- likely(__iwl_trans_pcie_grab_nic_access(trans))) ++ likely(__iwl_trans_pcie_grab_nic_access(trans, silent))) + + /***************************************************** + * RX +@@ -1102,7 +1102,8 @@ void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, + int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs, + u32 *val); + bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans); +-void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans); ++void __releases(nic_access_nobh) ++iwl_trans_pcie_release_nic_access(struct iwl_trans *trans); + + /* transport gen 1 exported functions */ + void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr); +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index d19b3bd0866bda..18d7d59ae58147 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -2191,7 +2191,7 @@ EXPORT_SYMBOL(iwl_trans_pcie_remove); + * This version doesn't disable BHs but rather assumes they're + * already disabled. + */ +-bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) ++bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) + { + int ret; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +@@ -2243,6 +2243,11 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) + if (unlikely(ret < 0)) { + u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL); + ++ if (silent) { ++ spin_unlock(&trans_pcie->reg_lock); ++ return false; ++ } ++ + WARN_ONCE(1, + "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", + cntrl); +@@ -2273,7 +2278,7 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) + bool ret; + + local_bh_disable(); +- ret = __iwl_trans_pcie_grab_nic_access(trans); ++ ret = __iwl_trans_pcie_grab_nic_access(trans, false); + if (ret) { + /* keep BHs disabled until iwl_trans_pcie_release_nic_access */ + return ret; +@@ -2282,7 +2287,8 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) + return false; + } + +-void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) ++void __releases(nic_access_nobh) ++iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + +@@ -2309,6 +2315,7 @@ void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) + * scheduled on different CPUs (after we drop reg_lock). + */ + out: ++ __release(nic_access_nobh); + spin_unlock_bh(&trans_pcie->reg_lock); + } + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index 9fcdd06e126ae1..f0213a6b8cf536 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -1021,7 +1021,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, + * returned. This needs to be done only on NICs that have + * apmg_wake_up_wa set (see above.) + */ +- if (!_iwl_trans_pcie_grab_nic_access(trans)) ++ if (!_iwl_trans_pcie_grab_nic_access(trans, false)) + return -EIO; + + /* +diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.c b/drivers/net/wireless/purelifi/plfxlc/mac.c +index eae93efa615044..82d1bf7edba20d 100644 +--- a/drivers/net/wireless/purelifi/plfxlc/mac.c ++++ b/drivers/net/wireless/purelifi/plfxlc/mac.c +@@ -102,7 +102,6 @@ int plfxlc_mac_init_hw(struct ieee80211_hw *hw) + void plfxlc_mac_release(struct plfxlc_mac *mac) + { + plfxlc_chip_release(&mac->chip); +- lockdep_assert_held(&mac->lock); + } + + int plfxlc_op_start(struct ieee80211_hw *hw) +diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig +index 486afe59818454..09ed1f61c9a85a 100644 +--- a/drivers/nvme/host/Kconfig ++++ b/drivers/nvme/host/Kconfig +@@ -97,6 +97,7 @@ config NVME_TCP_TLS + depends on NVME_TCP + select NET_HANDSHAKE + select KEYS ++ select TLS + help + Enables TLS encryption for NVMe TCP using the netlink handshake API. + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index e70618e8d35eb4..83ee433b694150 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3535,7 +3535,7 @@ static pci_ers_result_t nvme_slot_reset(struct pci_dev *pdev) + + dev_info(dev->ctrl.device, "restart after slot reset\n"); + pci_restore_state(pdev); +- if (!nvme_try_sched_reset(&dev->ctrl)) ++ if (nvme_try_sched_reset(&dev->ctrl)) + nvme_unquiesce_io_queues(&dev->ctrl); + return PCI_ERS_RESULT_RECOVERED; + } +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 854aa6a070ca87..4cc72be28c7319 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -1944,7 +1944,7 @@ static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue) + cancel_work_sync(&queue->io_work); + } + +-static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) ++static void nvme_tcp_stop_queue_nowait(struct nvme_ctrl *nctrl, int qid) + { + struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); + struct nvme_tcp_queue *queue = &ctrl->queues[qid]; +@@ -1963,6 +1963,31 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) + mutex_unlock(&queue->queue_lock); + } + ++static void nvme_tcp_wait_queue(struct nvme_ctrl *nctrl, int qid) ++{ ++ struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); ++ struct nvme_tcp_queue *queue = &ctrl->queues[qid]; ++ int timeout = 100; ++ ++ while (timeout > 0) { ++ if (!test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags) || ++ !sk_wmem_alloc_get(queue->sock->sk)) ++ return; ++ msleep(2); ++ timeout -= 2; ++ } ++ dev_warn(nctrl->device, ++ "qid %d: timeout draining sock wmem allocation expired\n", ++ qid); ++} ++ ++static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) ++{ ++ nvme_tcp_stop_queue_nowait(nctrl, qid); ++ nvme_tcp_wait_queue(nctrl, qid); ++} ++ ++ + static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue) + { + write_lock_bh(&queue->sock->sk->sk_callback_lock); +@@ -2030,7 +2055,9 @@ static void nvme_tcp_stop_io_queues(struct nvme_ctrl *ctrl) + int i; + + for (i = 1; i < ctrl->queue_count; i++) +- nvme_tcp_stop_queue(ctrl, i); ++ nvme_tcp_stop_queue_nowait(ctrl, i); ++ for (i = 1; i < ctrl->queue_count; i++) ++ nvme_tcp_wait_queue(ctrl, i); + } + + static int nvme_tcp_start_io_queues(struct nvme_ctrl *ctrl, +diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig +index 46be031f91b43b..34438cec32b90b 100644 +--- a/drivers/nvme/target/Kconfig ++++ b/drivers/nvme/target/Kconfig +@@ -98,6 +98,7 @@ config NVME_TARGET_TCP_TLS + bool "NVMe over Fabrics TCP target TLS encryption support" + depends on NVME_TARGET_TCP + select NET_HANDSHAKE ++ select TLS + help + Enables TLS encryption for the NVMe TCP target using the netlink handshake API. + +diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c +index d05c2c478e7950..4e1fe457a608a4 100644 +--- a/drivers/pinctrl/freescale/pinctrl-imx.c ++++ b/drivers/pinctrl/freescale/pinctrl-imx.c +@@ -37,16 +37,16 @@ static inline const struct group_desc *imx_pinctrl_find_group_by_name( + struct pinctrl_dev *pctldev, + const char *name) + { +- const struct group_desc *grp = NULL; ++ const struct group_desc *grp; + int i; + + for (i = 0; i < pctldev->num_groups; i++) { + grp = pinctrl_generic_get_group(pctldev, i); + if (grp && !strcmp(grp->grp.name, name)) +- break; ++ return grp; + } + +- return grp; ++ return NULL; + } + + static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, +diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c +index 4d3acfe849bf4e..dc071b4257d7bf 100644 +--- a/drivers/platform/x86/amd/pmc/pmc.c ++++ b/drivers/platform/x86/amd/pmc/pmc.c +@@ -892,10 +892,9 @@ static void amd_pmc_s2idle_check(void) + struct smu_metrics table; + int rc; + +- /* CZN: Ensure that future s0i3 entry attempts at least 10ms passed */ +- if (pdev->cpu_id == AMD_CPU_ID_CZN && !get_metrics_table(pdev, &table) && +- table.s0i3_last_entry_status) +- usleep_range(10000, 20000); ++ /* Avoid triggering OVP */ ++ if (!get_metrics_table(pdev, &table) && table.s0i3_last_entry_status) ++ msleep(2500); + + /* Dump the IdleMask before we add to the STB */ + amd_pmc_idlemask_read(pdev, pdev->dev, NULL); +diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c +index a450b8a6bcec10..529b19833537ac 100644 +--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c ++++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c +@@ -146,15 +146,13 @@ static int uncore_event_cpu_online(unsigned int cpu) + { + struct uncore_data *data; + int target; ++ int ret; + + /* Check if there is an online cpu in the package for uncore MSR */ + target = cpumask_any_and(&uncore_cpu_mask, topology_die_cpumask(cpu)); + if (target < nr_cpu_ids) + return 0; + +- /* Use this CPU on this die as a control CPU */ +- cpumask_set_cpu(cpu, &uncore_cpu_mask); +- + data = uncore_get_instance(cpu); + if (!data) + return 0; +@@ -163,7 +161,14 @@ static int uncore_event_cpu_online(unsigned int cpu) + data->die_id = topology_die_id(cpu); + data->domain_id = UNCORE_DOMAIN_ID_INVALID; + +- return uncore_freq_add_entry(data, cpu); ++ ret = uncore_freq_add_entry(data, cpu); ++ if (ret) ++ return ret; ++ ++ /* Use this CPU on this die as a control CPU */ ++ cpumask_set_cpu(cpu, &uncore_cpu_mask); ++ ++ return 0; + } + + static int uncore_event_cpu_offline(unsigned int cpu) +diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c +index 0eeb503e06c230..1a936829975e11 100644 +--- a/drivers/ptp/ptp_ocp.c ++++ b/drivers/ptp/ptp_ocp.c +@@ -2574,12 +2574,60 @@ static const struct ocp_sma_op ocp_fb_sma_op = { + .set_output = ptp_ocp_sma_fb_set_output, + }; + ++static int ++ptp_ocp_sma_adva_set_output(struct ptp_ocp *bp, int sma_nr, u32 val) ++{ ++ u32 reg, mask, shift; ++ unsigned long flags; ++ u32 __iomem *gpio; ++ ++ gpio = sma_nr > 2 ? &bp->sma_map1->gpio2 : &bp->sma_map2->gpio2; ++ shift = sma_nr & 1 ? 0 : 16; ++ ++ mask = 0xffff << (16 - shift); ++ ++ spin_lock_irqsave(&bp->lock, flags); ++ ++ reg = ioread32(gpio); ++ reg = (reg & mask) | (val << shift); ++ ++ iowrite32(reg, gpio); ++ ++ spin_unlock_irqrestore(&bp->lock, flags); ++ ++ return 0; ++} ++ ++static int ++ptp_ocp_sma_adva_set_inputs(struct ptp_ocp *bp, int sma_nr, u32 val) ++{ ++ u32 reg, mask, shift; ++ unsigned long flags; ++ u32 __iomem *gpio; ++ ++ gpio = sma_nr > 2 ? &bp->sma_map2->gpio1 : &bp->sma_map1->gpio1; ++ shift = sma_nr & 1 ? 0 : 16; ++ ++ mask = 0xffff << (16 - shift); ++ ++ spin_lock_irqsave(&bp->lock, flags); ++ ++ reg = ioread32(gpio); ++ reg = (reg & mask) | (val << shift); ++ ++ iowrite32(reg, gpio); ++ ++ spin_unlock_irqrestore(&bp->lock, flags); ++ ++ return 0; ++} ++ + static const struct ocp_sma_op ocp_adva_sma_op = { + .tbl = { ptp_ocp_adva_sma_in, ptp_ocp_adva_sma_out }, + .init = ptp_ocp_sma_fb_init, + .get = ptp_ocp_sma_fb_get, +- .set_inputs = ptp_ocp_sma_fb_set_inputs, +- .set_output = ptp_ocp_sma_fb_set_output, ++ .set_inputs = ptp_ocp_sma_adva_set_inputs, ++ .set_output = ptp_ocp_sma_adva_set_output, + }; + + static int +diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c +index bc7cc4088eea0d..5c7eb020943b8c 100644 +--- a/drivers/spi/spi-tegra114.c ++++ b/drivers/spi/spi-tegra114.c +@@ -728,9 +728,9 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi) + u32 inactive_cycles; + u8 cs_state; + +- if (setup->unit != SPI_DELAY_UNIT_SCK || +- hold->unit != SPI_DELAY_UNIT_SCK || +- inactive->unit != SPI_DELAY_UNIT_SCK) { ++ if ((setup->unit && setup->unit != SPI_DELAY_UNIT_SCK) || ++ (hold->unit && hold->unit != SPI_DELAY_UNIT_SCK) || ++ (inactive->unit && inactive->unit != SPI_DELAY_UNIT_SCK)) { + dev_err(&spi->dev, + "Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n", + SPI_DELAY_UNIT_SCK); +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 8d4a5b8371b63d..a9b032d2f4a8db 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -7256,8 +7256,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, + err = -EINVAL; + } + } +- ufshcd_add_query_upiu_trace(hba, err ? UFS_QUERY_ERR : UFS_QUERY_COMP, +- (struct utp_upiu_req *)lrbp->ucd_rsp_ptr); + + return err; + } +diff --git a/fs/bcachefs/xattr_format.h b/fs/bcachefs/xattr_format.h +index c7916011ef34d3..67426e33d04e56 100644 +--- a/fs/bcachefs/xattr_format.h ++++ b/fs/bcachefs/xattr_format.h +@@ -13,7 +13,13 @@ struct bch_xattr { + __u8 x_type; + __u8 x_name_len; + __le16 x_val_len; +- __u8 x_name[] __counted_by(x_name_len); ++ /* ++ * x_name contains the name and value counted by ++ * x_name_len + x_val_len. The introduction of ++ * __counted_by(x_name_len) caused a false positive ++ * detection of an out of bounds write. ++ */ ++ __u8 x_name[]; + } __packed __aligned(8); + + #endif /* _BCACHEFS_XATTR_FORMAT_H */ +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 6551fb003eed25..e263d4b0546fa2 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -1870,7 +1870,7 @@ static int submit_eb_subpage(struct folio *folio, struct writeback_control *wbc) + subpage->bitmaps)) { + spin_unlock_irqrestore(&subpage->lock, flags); + spin_unlock(&folio->mapping->i_private_lock); +- bit_start++; ++ bit_start += sectors_per_node; + continue; + } + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 5b842276573e82..bee8852e81554e 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -2155,12 +2155,13 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, + + /* + * If the found extent starts after requested offset, then +- * adjust extent_end to be right before this extent begins ++ * adjust cur_offset to be right before this extent begins. + */ + if (found_key.offset > cur_offset) { +- extent_end = found_key.offset; +- extent_type = 0; +- goto must_cow; ++ if (cow_start == (u64)-1) ++ cow_start = cur_offset; ++ cur_offset = found_key.offset; ++ goto next_slot; + } + + /* +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 1a7b82664255ab..83022a476e3b3e 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -2938,6 +2938,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, + req->CreateContextsOffset = cpu_to_le32( + sizeof(struct smb2_create_req) + + iov[1].iov_len); ++ le32_add_cpu(&req->CreateContextsLength, iov[n_iov-1].iov_len); + pc_buf = iov[n_iov-1].iov_base; + } + +diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c +index 83caa384974932..b3d121052408cc 100644 +--- a/fs/smb/server/auth.c ++++ b/fs/smb/server/auth.c +@@ -550,7 +550,19 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, + retval = -ENOMEM; + goto out; + } +- sess->user = user; ++ ++ if (!sess->user) { ++ /* First successful authentication */ ++ sess->user = user; ++ } else { ++ if (!ksmbd_compare_user(sess->user, user)) { ++ ksmbd_debug(AUTH, "different user tried to reuse session\n"); ++ retval = -EPERM; ++ ksmbd_free_user(user); ++ goto out; ++ } ++ ksmbd_free_user(user); ++ } + + memcpy(sess->sess_key, resp->payload, resp->session_key_len); + memcpy(out_blob, resp->payload + resp->session_key_len, +diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c +index 3f45f28f6f0f8e..9dec4c2940bc04 100644 +--- a/fs/smb/server/mgmt/user_session.c ++++ b/fs/smb/server/mgmt/user_session.c +@@ -59,10 +59,12 @@ static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess) + struct ksmbd_session_rpc *entry; + long index; + ++ down_write(&sess->rpc_lock); + xa_for_each(&sess->rpc_handle_list, index, entry) { + xa_erase(&sess->rpc_handle_list, index); + __session_rpc_close(sess, entry); + } ++ up_write(&sess->rpc_lock); + + xa_destroy(&sess->rpc_handle_list); + } +@@ -92,7 +94,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) + { + struct ksmbd_session_rpc *entry, *old; + struct ksmbd_rpc_command *resp; +- int method; ++ int method, id; + + method = __rpc_method(rpc_name); + if (!method) +@@ -102,26 +104,29 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) + if (!entry) + return -ENOMEM; + ++ down_read(&sess->rpc_lock); + entry->method = method; +- entry->id = ksmbd_ipc_id_alloc(); +- if (entry->id < 0) ++ entry->id = id = ksmbd_ipc_id_alloc(); ++ if (id < 0) + goto free_entry; +- old = xa_store(&sess->rpc_handle_list, entry->id, entry, KSMBD_DEFAULT_GFP); ++ old = xa_store(&sess->rpc_handle_list, id, entry, KSMBD_DEFAULT_GFP); + if (xa_is_err(old)) + goto free_id; + +- resp = ksmbd_rpc_open(sess, entry->id); ++ resp = ksmbd_rpc_open(sess, id); + if (!resp) + goto erase_xa; + ++ up_read(&sess->rpc_lock); + kvfree(resp); +- return entry->id; ++ return id; + erase_xa: + xa_erase(&sess->rpc_handle_list, entry->id); + free_id: + ksmbd_rpc_id_free(entry->id); + free_entry: + kfree(entry); ++ up_read(&sess->rpc_lock); + return -EINVAL; + } + +@@ -129,9 +134,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id) + { + struct ksmbd_session_rpc *entry; + ++ down_write(&sess->rpc_lock); + entry = xa_erase(&sess->rpc_handle_list, id); + if (entry) + __session_rpc_close(sess, entry); ++ up_write(&sess->rpc_lock); + } + + int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) +@@ -439,6 +446,7 @@ static struct ksmbd_session *__session_create(int protocol) + sess->sequence_number = 1; + rwlock_init(&sess->tree_conns_lock); + atomic_set(&sess->refcnt, 2); ++ init_rwsem(&sess->rpc_lock); + + ret = __init_smb2_session(sess); + if (ret) +diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h +index f21348381d5984..c5749d6ec7151c 100644 +--- a/fs/smb/server/mgmt/user_session.h ++++ b/fs/smb/server/mgmt/user_session.h +@@ -63,6 +63,7 @@ struct ksmbd_session { + rwlock_t tree_conns_lock; + + atomic_t refcnt; ++ struct rw_semaphore rpc_lock; + }; + + static inline int test_session_flag(struct ksmbd_session *sess, int bit) +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index 6b9286c9634391..85348705f2555d 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -1600,11 +1600,6 @@ static int krb5_authenticate(struct ksmbd_work *work, + if (prev_sess_id && prev_sess_id != sess->id) + destroy_previous_session(conn, sess->user, prev_sess_id); + +- if (sess->state == SMB2_SESSION_VALID) { +- ksmbd_free_user(sess->user); +- sess->user = NULL; +- } +- + retval = ksmbd_krb5_authenticate(sess, in_blob, in_len, + out_blob, &out_len); + if (retval) { +@@ -2245,10 +2240,6 @@ int smb2_session_logoff(struct ksmbd_work *work) + sess->state = SMB2_SESSION_EXPIRED; + up_write(&conn->session_lock); + +- if (sess->user) { +- ksmbd_free_user(sess->user); +- sess->user = NULL; +- } + ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_SETUP); + + rsp->StructureSize = cpu_to_le16(4); +diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h +index 7fe0981a7e4674..a604c54ae44dad 100644 +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -770,8 +770,8 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy, + int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy); + + int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, +- unsigned int target_freq, +- unsigned int relation); ++ unsigned int target_freq, unsigned int min, ++ unsigned int max, unsigned int relation); + int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, + unsigned int freq); + +@@ -836,12 +836,12 @@ static inline int cpufreq_table_find_index_dl(struct cpufreq_policy *policy, + return best; + } + +-/* Works only on sorted freq-tables */ +-static inline int cpufreq_table_find_index_l(struct cpufreq_policy *policy, +- unsigned int target_freq, +- bool efficiencies) ++static inline int find_index_l(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ unsigned int min, unsigned int max, ++ bool efficiencies) + { +- target_freq = clamp_val(target_freq, policy->min, policy->max); ++ target_freq = clamp_val(target_freq, min, max); + + if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) + return cpufreq_table_find_index_al(policy, target_freq, +@@ -851,6 +851,14 @@ static inline int cpufreq_table_find_index_l(struct cpufreq_policy *policy, + efficiencies); + } + ++/* Works only on sorted freq-tables */ ++static inline int cpufreq_table_find_index_l(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ bool efficiencies) ++{ ++ return find_index_l(policy, target_freq, policy->min, policy->max, efficiencies); ++} ++ + /* Find highest freq at or below target in a table in ascending order */ + static inline int cpufreq_table_find_index_ah(struct cpufreq_policy *policy, + unsigned int target_freq, +@@ -904,12 +912,12 @@ static inline int cpufreq_table_find_index_dh(struct cpufreq_policy *policy, + return best; + } + +-/* Works only on sorted freq-tables */ +-static inline int cpufreq_table_find_index_h(struct cpufreq_policy *policy, +- unsigned int target_freq, +- bool efficiencies) ++static inline int find_index_h(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ unsigned int min, unsigned int max, ++ bool efficiencies) + { +- target_freq = clamp_val(target_freq, policy->min, policy->max); ++ target_freq = clamp_val(target_freq, min, max); + + if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) + return cpufreq_table_find_index_ah(policy, target_freq, +@@ -919,6 +927,14 @@ static inline int cpufreq_table_find_index_h(struct cpufreq_policy *policy, + efficiencies); + } + ++/* Works only on sorted freq-tables */ ++static inline int cpufreq_table_find_index_h(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ bool efficiencies) ++{ ++ return find_index_h(policy, target_freq, policy->min, policy->max, efficiencies); ++} ++ + /* Find closest freq to target in a table in ascending order */ + static inline int cpufreq_table_find_index_ac(struct cpufreq_policy *policy, + unsigned int target_freq, +@@ -989,12 +1005,12 @@ static inline int cpufreq_table_find_index_dc(struct cpufreq_policy *policy, + return best; + } + +-/* Works only on sorted freq-tables */ +-static inline int cpufreq_table_find_index_c(struct cpufreq_policy *policy, +- unsigned int target_freq, +- bool efficiencies) ++static inline int find_index_c(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ unsigned int min, unsigned int max, ++ bool efficiencies) + { +- target_freq = clamp_val(target_freq, policy->min, policy->max); ++ target_freq = clamp_val(target_freq, min, max); + + if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) + return cpufreq_table_find_index_ac(policy, target_freq, +@@ -1004,7 +1020,17 @@ static inline int cpufreq_table_find_index_c(struct cpufreq_policy *policy, + efficiencies); + } + +-static inline bool cpufreq_is_in_limits(struct cpufreq_policy *policy, int idx) ++/* Works only on sorted freq-tables */ ++static inline int cpufreq_table_find_index_c(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ bool efficiencies) ++{ ++ return find_index_c(policy, target_freq, policy->min, policy->max, efficiencies); ++} ++ ++static inline bool cpufreq_is_in_limits(struct cpufreq_policy *policy, ++ unsigned int min, unsigned int max, ++ int idx) + { + unsigned int freq; + +@@ -1013,11 +1039,13 @@ static inline bool cpufreq_is_in_limits(struct cpufreq_policy *policy, int idx) + + freq = policy->freq_table[idx].frequency; + +- return freq == clamp_val(freq, policy->min, policy->max); ++ return freq == clamp_val(freq, min, max); + } + + static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy, + unsigned int target_freq, ++ unsigned int min, ++ unsigned int max, + unsigned int relation) + { + bool efficiencies = policy->efficiencies_available && +@@ -1028,29 +1056,26 @@ static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy, + relation &= ~CPUFREQ_RELATION_E; + + if (unlikely(policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED)) +- return cpufreq_table_index_unsorted(policy, target_freq, +- relation); ++ return cpufreq_table_index_unsorted(policy, target_freq, min, ++ max, relation); + retry: + switch (relation) { + case CPUFREQ_RELATION_L: +- idx = cpufreq_table_find_index_l(policy, target_freq, +- efficiencies); ++ idx = find_index_l(policy, target_freq, min, max, efficiencies); + break; + case CPUFREQ_RELATION_H: +- idx = cpufreq_table_find_index_h(policy, target_freq, +- efficiencies); ++ idx = find_index_h(policy, target_freq, min, max, efficiencies); + break; + case CPUFREQ_RELATION_C: +- idx = cpufreq_table_find_index_c(policy, target_freq, +- efficiencies); ++ idx = find_index_c(policy, target_freq, min, max, efficiencies); + break; + default: + WARN_ON_ONCE(1); + return 0; + } + +- /* Limit frequency index to honor policy->min/max */ +- if (!cpufreq_is_in_limits(policy, idx) && efficiencies) { ++ /* Limit frequency index to honor min and max */ ++ if (!cpufreq_is_in_limits(policy, min, max, idx) && efficiencies) { + efficiencies = false; + goto retry; + } +diff --git a/include/linux/iommu.h b/include/linux/iommu.h +index bd722f47363520..10f7b1df072361 100644 +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -423,10 +423,10 @@ static inline int __iommu_copy_struct_from_user( + void *dst_data, const struct iommu_user_data *src_data, + unsigned int data_type, size_t data_len, size_t min_len) + { +- if (src_data->type != data_type) +- return -EINVAL; + if (WARN_ON(!dst_data || !src_data)) + return -EINVAL; ++ if (src_data->type != data_type) ++ return -EINVAL; + if (src_data->len < min_len || data_len < src_data->len) + return -EINVAL; + return copy_struct_from_user(dst_data, data_len, src_data->uptr, +@@ -439,8 +439,8 @@ static inline int __iommu_copy_struct_from_user( + * include/uapi/linux/iommufd.h + * @user_data: Pointer to a struct iommu_user_data for user space data info + * @data_type: The data type of the @kdst. Must match with @user_data->type +- * @min_last: The last memember of the data structure @kdst points in the +- * initial version. ++ * @min_last: The last member of the data structure @kdst points in the initial ++ * version. + * Return 0 for success, otherwise -error. + */ + #define iommu_copy_struct_from_user(kdst, user_data, data_type, min_last) \ +diff --git a/include/linux/module.h b/include/linux/module.h +index 88ecc5e9f52307..82a9527d43c768 100644 +--- a/include/linux/module.h ++++ b/include/linux/module.h +@@ -162,6 +162,8 @@ extern void cleanup_module(void); + #define __INITRODATA_OR_MODULE __INITRODATA + #endif /*CONFIG_MODULES*/ + ++struct module_kobject *lookup_or_create_module_kobject(const char *name); ++ + /* Generic info of form tag = "info" */ + #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) + +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index 71d24328764065..40fce4193cc1dd 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -1913,6 +1913,8 @@ struct hci_cp_le_pa_create_sync { + __u8 sync_cte_type; + } __packed; + ++#define HCI_OP_LE_PA_CREATE_SYNC_CANCEL 0x2045 ++ + #define HCI_OP_LE_PA_TERM_SYNC 0x2046 + struct hci_cp_le_pa_term_sync { + __le16 handle; +@@ -2812,7 +2814,7 @@ struct hci_evt_le_create_big_complete { + __le16 bis_handle[]; + } __packed; + +-#define HCI_EVT_LE_BIG_SYNC_ESTABILISHED 0x1d ++#define HCI_EVT_LE_BIG_SYNC_ESTABLISHED 0x1d + struct hci_evt_le_big_sync_estabilished { + __u8 status; + __u8 handle; +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 4245910ffc4a2d..4f3b537476e106 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1105,10 +1105,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev, + return NULL; + } + +-static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev, +- __u8 sid, +- bdaddr_t *dst, +- __u8 dst_type) ++static inline struct hci_conn * ++hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev) + { + struct hci_conn_hash *h = &hdev->conn_hash; + struct hci_conn *c; +@@ -1116,8 +1114,10 @@ static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev, + rcu_read_lock(); + + list_for_each_entry_rcu(c, &h->list, list) { +- if (c->type != ISO_LINK || bacmp(&c->dst, dst) || +- c->dst_type != dst_type || c->sid != sid) ++ if (c->type != ISO_LINK) ++ continue; ++ ++ if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags)) + continue; + + rcu_read_unlock(); +@@ -1506,8 +1506,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle); + void hci_sco_setup(struct hci_conn *conn, __u8 status); + bool hci_iso_setup_path(struct hci_conn *conn); + int hci_le_create_cis_pending(struct hci_dev *hdev); +-int hci_pa_create_sync_pending(struct hci_dev *hdev); +-int hci_le_big_create_sync_pending(struct hci_dev *hdev); + int hci_conn_check_create_cis(struct hci_conn *conn); + + struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, +@@ -1548,9 +1546,9 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst, + __u8 data_len, __u8 *data); + struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + __u8 dst_type, __u8 sid, struct bt_iso_qos *qos); +-int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, +- struct bt_iso_qos *qos, +- __u16 sync_handle, __u8 num_bis, __u8 bis[]); ++int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, ++ struct bt_iso_qos *qos, __u16 sync_handle, ++ __u8 num_bis, __u8 bis[]); + int hci_conn_check_link_mode(struct hci_conn *conn); + int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); + int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, +diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h +index f3052cb252efdd..dbabc17b30cdfa 100644 +--- a/include/net/bluetooth/hci_sync.h ++++ b/include/net/bluetooth/hci_sync.h +@@ -186,3 +186,6 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn); + int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn); + int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn, + struct hci_conn_params *params); ++ ++int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn); ++int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn); +diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h +index bfe625b55d55d7..df3f5f07bc7c2e 100644 +--- a/include/net/xdp_sock.h ++++ b/include/net/xdp_sock.h +@@ -71,9 +71,6 @@ struct xdp_sock { + */ + u32 tx_budget_spent; + +- /* Protects generic receive. */ +- spinlock_t rx_lock; +- + /* Statistics */ + u64 rx_dropped; + u64 rx_queue_full; +diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h +index bacb33f1e3e581..823fd5c7a3b188 100644 +--- a/include/net/xsk_buff_pool.h ++++ b/include/net/xsk_buff_pool.h +@@ -55,6 +55,8 @@ struct xsk_buff_pool { + refcount_t users; + struct xdp_umem *umem; + struct work_struct work; ++ /* Protects generic receive in shared and non-shared umem mode. */ ++ spinlock_t rx_lock; + struct list_head free_list; + struct list_head xskb_list; + u32 heads_cnt; +diff --git a/include/sound/ump_convert.h b/include/sound/ump_convert.h +index d099ae27f8491a..682499b871eac4 100644 +--- a/include/sound/ump_convert.h ++++ b/include/sound/ump_convert.h +@@ -19,7 +19,7 @@ struct ump_cvt_to_ump_bank { + /* context for converting from MIDI1 byte stream to UMP packet */ + struct ump_cvt_to_ump { + /* MIDI1 intermediate buffer */ +- unsigned char buf[4]; ++ unsigned char buf[6]; /* up to 6 bytes for SysEx */ + int len; + int cmd_bytes; + +diff --git a/kernel/params.c b/kernel/params.c +index 2e447f8ae183e7..33b2985b31c7fc 100644 +--- a/kernel/params.c ++++ b/kernel/params.c +@@ -763,7 +763,7 @@ void destroy_params(const struct kernel_param *params, unsigned num) + params[i].ops->free(params[i].arg); + } + +-static struct module_kobject * __init locate_module_kobject(const char *name) ++struct module_kobject __modinit * lookup_or_create_module_kobject(const char *name) + { + struct module_kobject *mk; + struct kobject *kobj; +@@ -805,7 +805,7 @@ static void __init kernel_add_sysfs_param(const char *name, + struct module_kobject *mk; + int err; + +- mk = locate_module_kobject(name); ++ mk = lookup_or_create_module_kobject(name); + if (!mk) + return; + +@@ -876,7 +876,7 @@ static void __init version_sysfs_builtin(void) + int err; + + for (vattr = __start___modver; vattr < __stop___modver; vattr++) { +- mk = locate_module_kobject(vattr->module_name); ++ mk = lookup_or_create_module_kobject(vattr->module_name); + if (mk) { + err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); + WARN_ON_ONCE(err); +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index ffe1422ab03f88..06104c2c66ab2a 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -6703,13 +6703,14 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, + /* Copy the data into the page, so we can start over. */ + ret = trace_seq_to_buffer(&iter->seq, + page_address(spd.pages[i]), +- trace_seq_used(&iter->seq)); ++ min((size_t)trace_seq_used(&iter->seq), ++ PAGE_SIZE)); + if (ret < 0) { + __free_page(spd.pages[i]); + break; + } + spd.partial[i].offset = 0; +- spd.partial[i].len = trace_seq_used(&iter->seq); ++ spd.partial[i].len = ret; + + trace_seq_init(&iter->seq); + } +diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c +index 6e7090e8bf3097..1ecc28a3946a12 100644 +--- a/kernel/trace/trace_output.c ++++ b/kernel/trace/trace_output.c +@@ -950,11 +950,12 @@ enum print_line_t print_event_fields(struct trace_iterator *iter, + struct trace_event_call *call; + struct list_head *head; + ++ lockdep_assert_held_read(&trace_event_sem); ++ + /* ftrace defined events have separate call structures */ + if (event->type <= __TRACE_LAST_TYPE) { + bool found = false; + +- down_read(&trace_event_sem); + list_for_each_entry(call, &ftrace_events, list) { + if (call->event.type == event->type) { + found = true; +@@ -964,7 +965,6 @@ enum print_line_t print_event_fields(struct trace_iterator *iter, + if (call->event.type > __TRACE_LAST_TYPE) + break; + } +- up_read(&trace_event_sem); + if (!found) { + trace_seq_printf(&iter->seq, "UNKNOWN TYPE %d\n", event->type); + goto out; +diff --git a/mm/memblock.c b/mm/memblock.c +index 095c18b5c430da..cc5ee323245e3d 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -2160,11 +2160,14 @@ static void __init memmap_init_reserved_pages(void) + struct memblock_region *region; + phys_addr_t start, end; + int nid; ++ unsigned long max_reserved; + + /* + * set nid on all reserved pages and also treat struct + * pages for the NOMAP regions as PageReserved + */ ++repeat: ++ max_reserved = memblock.reserved.max; + for_each_mem_region(region) { + nid = memblock_get_region_node(region); + start = region->base; +@@ -2173,8 +2176,15 @@ static void __init memmap_init_reserved_pages(void) + if (memblock_is_nomap(region)) + reserve_bootmem_region(start, end, nid); + +- memblock_set_node(start, end, &memblock.reserved, nid); ++ memblock_set_node(start, region->size, &memblock.reserved, nid); + } ++ /* ++ * 'max' is changed means memblock.reserved has been doubled its ++ * array, which may result a new reserved region before current ++ * 'start'. Now we should repeat the procedure to set its node id. ++ */ ++ if (max_reserved != memblock.reserved.max) ++ goto repeat; + + /* + * initialize struct pages for reserved regions that don't have +diff --git a/mm/slub.c b/mm/slub.c +index c26d9cd107ccbc..66f86e5328182d 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -2035,18 +2035,6 @@ static inline void free_slab_obj_exts(struct slab *slab) + slab->obj_exts = 0; + } + +-static inline bool need_slab_obj_ext(void) +-{ +- if (mem_alloc_profiling_enabled()) +- return true; +- +- /* +- * CONFIG_MEMCG creates vector of obj_cgroup objects conditionally +- * inside memcg_slab_post_alloc_hook. No other users for now. +- */ +- return false; +-} +- + #else /* CONFIG_SLAB_OBJ_EXT */ + + static inline void init_slab_obj_exts(struct slab *slab) +@@ -2063,11 +2051,6 @@ static inline void free_slab_obj_exts(struct slab *slab) + { + } + +-static inline bool need_slab_obj_ext(void) +-{ +- return false; +-} +- + #endif /* CONFIG_SLAB_OBJ_EXT */ + + #ifdef CONFIG_MEM_ALLOC_PROFILING +@@ -2099,7 +2082,7 @@ prepare_slab_obj_exts_hook(struct kmem_cache *s, gfp_t flags, void *p) + static inline void + alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags) + { +- if (need_slab_obj_ext()) { ++ if (mem_alloc_profiling_enabled()) { + struct slabobj_ext *obj_exts; + + obj_exts = prepare_slab_obj_exts_hook(s, flags, object); +@@ -2577,8 +2560,12 @@ static __always_inline void account_slab(struct slab *slab, int order, + static __always_inline void unaccount_slab(struct slab *slab, int order, + struct kmem_cache *s) + { +- if (memcg_kmem_online() || need_slab_obj_ext()) +- free_slab_obj_exts(slab); ++ /* ++ * The slab object extensions should now be freed regardless of ++ * whether mem_alloc_profiling_enabled() or not because profiling ++ * might have been disabled after slab->obj_exts got allocated. ++ */ ++ free_slab_obj_exts(slab); + + mod_node_page_state(slab_pgdat(slab), cache_vmstat_idx(s), + -(PAGE_SIZE << order)); +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index e6591f487a5119..ae66fa0a5fb584 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2061,103 +2061,6 @@ static int create_big_sync(struct hci_dev *hdev, void *data) + return hci_le_create_big(conn, &conn->iso_qos); + } + +-static void create_pa_complete(struct hci_dev *hdev, void *data, int err) +-{ +- bt_dev_dbg(hdev, ""); +- +- if (err) +- bt_dev_err(hdev, "Unable to create PA: %d", err); +-} +- +-static bool hci_conn_check_create_pa_sync(struct hci_conn *conn) +-{ +- if (conn->type != ISO_LINK || conn->sid == HCI_SID_INVALID) +- return false; +- +- return true; +-} +- +-static int create_pa_sync(struct hci_dev *hdev, void *data) +-{ +- struct hci_cp_le_pa_create_sync *cp = NULL; +- struct hci_conn *conn; +- int err = 0; +- +- hci_dev_lock(hdev); +- +- rcu_read_lock(); +- +- /* The spec allows only one pending LE Periodic Advertising Create +- * Sync command at a time. If the command is pending now, don't do +- * anything. We check for pending connections after each PA Sync +- * Established event. +- * +- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E +- * page 2493: +- * +- * If the Host issues this command when another HCI_LE_Periodic_ +- * Advertising_Create_Sync command is pending, the Controller shall +- * return the error code Command Disallowed (0x0C). +- */ +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (test_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags)) +- goto unlock; +- } +- +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (hci_conn_check_create_pa_sync(conn)) { +- struct bt_iso_qos *qos = &conn->iso_qos; +- +- cp = kzalloc(sizeof(*cp), GFP_KERNEL); +- if (!cp) { +- err = -ENOMEM; +- goto unlock; +- } +- +- cp->options = qos->bcast.options; +- cp->sid = conn->sid; +- cp->addr_type = conn->dst_type; +- bacpy(&cp->addr, &conn->dst); +- cp->skip = cpu_to_le16(qos->bcast.skip); +- cp->sync_timeout = cpu_to_le16(qos->bcast.sync_timeout); +- cp->sync_cte_type = qos->bcast.sync_cte_type; +- +- break; +- } +- } +- +-unlock: +- rcu_read_unlock(); +- +- hci_dev_unlock(hdev); +- +- if (cp) { +- hci_dev_set_flag(hdev, HCI_PA_SYNC); +- set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); +- +- err = __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC, +- sizeof(*cp), cp, HCI_CMD_TIMEOUT); +- if (!err) +- err = hci_update_passive_scan_sync(hdev); +- +- kfree(cp); +- +- if (err) { +- hci_dev_clear_flag(hdev, HCI_PA_SYNC); +- clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); +- } +- } +- +- return err; +-} +- +-int hci_pa_create_sync_pending(struct hci_dev *hdev) +-{ +- /* Queue start pa_create_sync and scan */ +- return hci_cmd_sync_queue(hdev, create_pa_sync, +- NULL, create_pa_complete); +-} +- + struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + __u8 dst_type, __u8 sid, + struct bt_iso_qos *qos) +@@ -2172,97 +2075,18 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + conn->dst_type = dst_type; + conn->sid = sid; + conn->state = BT_LISTEN; ++ conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10); + + hci_conn_hold(conn); + +- hci_pa_create_sync_pending(hdev); ++ hci_connect_pa_sync(hdev, conn); + + return conn; + } + +-static bool hci_conn_check_create_big_sync(struct hci_conn *conn) +-{ +- if (!conn->num_bis) +- return false; +- +- return true; +-} +- +-static void big_create_sync_complete(struct hci_dev *hdev, void *data, int err) +-{ +- bt_dev_dbg(hdev, ""); +- +- if (err) +- bt_dev_err(hdev, "Unable to create BIG sync: %d", err); +-} +- +-static int big_create_sync(struct hci_dev *hdev, void *data) +-{ +- DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11); +- struct hci_conn *conn; +- +- rcu_read_lock(); +- +- pdu->num_bis = 0; +- +- /* The spec allows only one pending LE BIG Create Sync command at +- * a time. If the command is pending now, don't do anything. We +- * check for pending connections after each BIG Sync Established +- * event. +- * +- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E +- * page 2586: +- * +- * If the Host sends this command when the Controller is in the +- * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_ +- * Established event has not been generated, the Controller shall +- * return the error code Command Disallowed (0x0C). +- */ +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (test_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags)) +- goto unlock; +- } +- +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (hci_conn_check_create_big_sync(conn)) { +- struct bt_iso_qos *qos = &conn->iso_qos; +- +- set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags); +- +- pdu->handle = qos->bcast.big; +- pdu->sync_handle = cpu_to_le16(conn->sync_handle); +- pdu->encryption = qos->bcast.encryption; +- memcpy(pdu->bcode, qos->bcast.bcode, +- sizeof(pdu->bcode)); +- pdu->mse = qos->bcast.mse; +- pdu->timeout = cpu_to_le16(qos->bcast.timeout); +- pdu->num_bis = conn->num_bis; +- memcpy(pdu->bis, conn->bis, conn->num_bis); +- +- break; +- } +- } +- +-unlock: +- rcu_read_unlock(); +- +- if (!pdu->num_bis) +- return 0; +- +- return hci_send_cmd(hdev, HCI_OP_LE_BIG_CREATE_SYNC, +- struct_size(pdu, bis, pdu->num_bis), pdu); +-} +- +-int hci_le_big_create_sync_pending(struct hci_dev *hdev) +-{ +- /* Queue big_create_sync */ +- return hci_cmd_sync_queue_once(hdev, big_create_sync, +- NULL, big_create_sync_complete); +-} +- +-int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, +- struct bt_iso_qos *qos, +- __u16 sync_handle, __u8 num_bis, __u8 bis[]) ++int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, ++ struct bt_iso_qos *qos, __u16 sync_handle, ++ __u8 num_bis, __u8 bis[]) + { + int err; + +@@ -2279,9 +2103,10 @@ int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, + + hcon->num_bis = num_bis; + memcpy(hcon->bis, bis, num_bis); ++ hcon->conn_timeout = msecs_to_jiffies(qos->bcast.timeout * 10); + } + +- return hci_le_big_create_sync_pending(hdev); ++ return hci_connect_big_sync(hdev, hcon); + } + + static void create_big_complete(struct hci_dev *hdev, void *data, int err) +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 96ad1b75d1c4d4..bc5b42fce2b801 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -6368,8 +6368,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + + hci_dev_clear_flag(hdev, HCI_PA_SYNC); + +- conn = hci_conn_hash_lookup_sid(hdev, ev->sid, &ev->bdaddr, +- ev->bdaddr_type); ++ conn = hci_conn_hash_lookup_create_pa_sync(hdev); + if (!conn) { + bt_dev_err(hdev, + "Unable to find connection for dst %pMR sid 0x%2.2x", +@@ -6408,9 +6407,6 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + } + + unlock: +- /* Handle any other pending PA sync command */ +- hci_pa_create_sync_pending(hdev); +- + hci_dev_unlock(hdev); + } + +@@ -6922,7 +6918,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, + + bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); + +- if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED, ++ if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABLISHED, + flex_array_size(ev, bis, ev->num_bis))) + return; + +@@ -6992,9 +6988,6 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, + } + + unlock: +- /* Handle any other pending BIG sync command */ +- hci_le_big_create_sync_pending(hdev); +- + hci_dev_unlock(hdev); + } + +@@ -7116,8 +7109,8 @@ static const struct hci_le_ev { + hci_le_create_big_complete_evt, + sizeof(struct hci_evt_le_create_big_complete), + HCI_MAX_EVENT_SIZE), +- /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */ +- HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED, ++ /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABLISHED] */ ++ HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABLISHED, + hci_le_big_sync_established_evt, + sizeof(struct hci_evt_le_big_sync_estabilished), + HCI_MAX_EVENT_SIZE), +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index cb4d47ae129e8b..6597936fbd51b9 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -2717,16 +2717,16 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) + + /* Force address filtering if PA Sync is in progress */ + if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) { +- struct hci_cp_le_pa_create_sync *sent; ++ struct hci_conn *conn; + +- sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC); +- if (sent) { ++ conn = hci_conn_hash_lookup_create_pa_sync(hdev); ++ if (conn) { + struct conn_params pa; + + memset(&pa, 0, sizeof(pa)); + +- bacpy(&pa.addr, &sent->addr); +- pa.addr_type = sent->addr_type; ++ bacpy(&pa.addr, &conn->dst); ++ pa.addr_type = conn->dst_type; + + /* Clear first since there could be addresses left + * behind. +@@ -6887,3 +6887,143 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn, + return __hci_cmd_sync_status(hdev, HCI_OP_LE_CONN_UPDATE, + sizeof(cp), &cp, HCI_CMD_TIMEOUT); + } ++ ++static void create_pa_complete(struct hci_dev *hdev, void *data, int err) ++{ ++ bt_dev_dbg(hdev, "err %d", err); ++ ++ if (!err) ++ return; ++ ++ hci_dev_clear_flag(hdev, HCI_PA_SYNC); ++ ++ if (err == -ECANCELED) ++ return; ++ ++ hci_dev_lock(hdev); ++ ++ hci_update_passive_scan_sync(hdev); ++ ++ hci_dev_unlock(hdev); ++} ++ ++static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data) ++{ ++ struct hci_cp_le_pa_create_sync cp; ++ struct hci_conn *conn = data; ++ struct bt_iso_qos *qos = &conn->iso_qos; ++ int err; ++ ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; ++ ++ if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC)) ++ return -EBUSY; ++ ++ /* Mark HCI_CONN_CREATE_PA_SYNC so hci_update_passive_scan_sync can ++ * program the address in the allow list so PA advertisements can be ++ * received. ++ */ ++ set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); ++ ++ hci_update_passive_scan_sync(hdev); ++ ++ memset(&cp, 0, sizeof(cp)); ++ cp.options = qos->bcast.options; ++ cp.sid = conn->sid; ++ cp.addr_type = conn->dst_type; ++ bacpy(&cp.addr, &conn->dst); ++ cp.skip = cpu_to_le16(qos->bcast.skip); ++ cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout); ++ cp.sync_cte_type = qos->bcast.sync_cte_type; ++ ++ /* The spec allows only one pending LE Periodic Advertising Create ++ * Sync command at a time so we forcefully wait for PA Sync Established ++ * event since cmd_work can only schedule one command at a time. ++ * ++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E ++ * page 2493: ++ * ++ * If the Host issues this command when another HCI_LE_Periodic_ ++ * Advertising_Create_Sync command is pending, the Controller shall ++ * return the error code Command Disallowed (0x0C). ++ */ ++ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_PA_CREATE_SYNC, ++ sizeof(cp), &cp, ++ HCI_EV_LE_PA_SYNC_ESTABLISHED, ++ conn->conn_timeout, NULL); ++ if (err == -ETIMEDOUT) ++ __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC_CANCEL, ++ 0, NULL, HCI_CMD_TIMEOUT); ++ ++ return err; ++} ++ ++int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn, ++ create_pa_complete); ++} ++ ++static void create_big_complete(struct hci_dev *hdev, void *data, int err) ++{ ++ struct hci_conn *conn = data; ++ ++ bt_dev_dbg(hdev, "err %d", err); ++ ++ if (err == -ECANCELED) ++ return; ++ ++ if (hci_conn_valid(hdev, conn)) ++ clear_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags); ++} ++ ++static int hci_le_big_create_sync(struct hci_dev *hdev, void *data) ++{ ++ DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11); ++ struct hci_conn *conn = data; ++ struct bt_iso_qos *qos = &conn->iso_qos; ++ int err; ++ ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; ++ ++ set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags); ++ ++ memset(cp, 0, sizeof(*cp)); ++ cp->handle = qos->bcast.big; ++ cp->sync_handle = cpu_to_le16(conn->sync_handle); ++ cp->encryption = qos->bcast.encryption; ++ memcpy(cp->bcode, qos->bcast.bcode, sizeof(cp->bcode)); ++ cp->mse = qos->bcast.mse; ++ cp->timeout = cpu_to_le16(qos->bcast.timeout); ++ cp->num_bis = conn->num_bis; ++ memcpy(cp->bis, conn->bis, conn->num_bis); ++ ++ /* The spec allows only one pending LE BIG Create Sync command at ++ * a time, so we forcefully wait for BIG Sync Established event since ++ * cmd_work can only schedule one command at a time. ++ * ++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E ++ * page 2586: ++ * ++ * If the Host sends this command when the Controller is in the ++ * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_ ++ * Established event has not been generated, the Controller shall ++ * return the error code Command Disallowed (0x0C). ++ */ ++ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_BIG_CREATE_SYNC, ++ struct_size(cp, bis, cp->num_bis), cp, ++ HCI_EVT_LE_BIG_SYNC_ESTABLISHED, ++ conn->conn_timeout, NULL); ++ if (err == -ETIMEDOUT) ++ hci_le_big_terminate_sync(hdev, cp->handle); ++ ++ return err; ++} ++ ++int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ return hci_cmd_sync_queue_once(hdev, hci_le_big_create_sync, conn, ++ create_big_complete); ++} +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index 644b606743e212..72bf9b1db22471 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -1414,14 +1414,13 @@ static void iso_conn_big_sync(struct sock *sk) + lock_sock(sk); + + if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) { +- err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon, +- &iso_pi(sk)->qos, +- iso_pi(sk)->sync_handle, +- iso_pi(sk)->bc_num_bis, +- iso_pi(sk)->bc_bis); ++ err = hci_conn_big_create_sync(hdev, iso_pi(sk)->conn->hcon, ++ &iso_pi(sk)->qos, ++ iso_pi(sk)->sync_handle, ++ iso_pi(sk)->bc_num_bis, ++ iso_pi(sk)->bc_bis); + if (err) +- bt_dev_err(hdev, "hci_le_big_create_sync: %d", +- err); ++ bt_dev_err(hdev, "hci_big_create_sync: %d", err); + } + + release_sock(sk); +@@ -1855,7 +1854,7 @@ static void iso_conn_ready(struct iso_conn *conn) + if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags) || + test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) { + ev = hci_recv_event_data(hcon->hdev, +- HCI_EVT_LE_BIG_SYNC_ESTABILISHED); ++ HCI_EVT_LE_BIG_SYNC_ESTABLISHED); + + /* Get reference to PA sync parent socket, if it exists */ + parent = iso_get_sock(&hcon->src, &hcon->dst, +@@ -2047,12 +2046,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + + if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) && + !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) { +- err = hci_le_big_create_sync(hdev, +- hcon, +- &iso_pi(sk)->qos, +- iso_pi(sk)->sync_handle, +- iso_pi(sk)->bc_num_bis, +- iso_pi(sk)->bc_bis); ++ err = hci_conn_big_create_sync(hdev, hcon, ++ &iso_pi(sk)->qos, ++ iso_pi(sk)->sync_handle, ++ iso_pi(sk)->bc_num_bis, ++ iso_pi(sk)->bc_bis); + if (err) { + bt_dev_err(hdev, "hci_le_big_create_sync: %d", + err); +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index a55388fbf07c84..c219a8c596d3e5 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -7380,6 +7380,9 @@ static int l2cap_recv_frag(struct l2cap_conn *conn, struct sk_buff *skb, + return -ENOMEM; + /* Init rx_len */ + conn->rx_len = len; ++ ++ skb_set_delivery_time(conn->rx_skb, skb->tstamp, ++ skb->tstamp_type); + } + + /* Copy as much as the rx_skb can hold */ +diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c +index 2dfac79dc78b8b..e04ebe651c3347 100644 +--- a/net/ipv4/tcp_offload.c ++++ b/net/ipv4/tcp_offload.c +@@ -435,7 +435,7 @@ static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, + iif, sdif); + NAPI_GRO_CB(skb)->is_flist = !sk; + if (sk) +- sock_put(sk); ++ sock_gen_put(sk); + } + + INDIRECT_CALLABLE_SCOPE +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index ecfca59f31f13e..da5d4aea1b5915 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -247,6 +247,62 @@ static struct sk_buff *__udpv4_gso_segment_list_csum(struct sk_buff *segs) + return segs; + } + ++static void __udpv6_gso_segment_csum(struct sk_buff *seg, ++ struct in6_addr *oldip, ++ const struct in6_addr *newip, ++ __be16 *oldport, __be16 newport) ++{ ++ struct udphdr *uh = udp_hdr(seg); ++ ++ if (ipv6_addr_equal(oldip, newip) && *oldport == newport) ++ return; ++ ++ if (uh->check) { ++ inet_proto_csum_replace16(&uh->check, seg, oldip->s6_addr32, ++ newip->s6_addr32, true); ++ ++ inet_proto_csum_replace2(&uh->check, seg, *oldport, newport, ++ false); ++ if (!uh->check) ++ uh->check = CSUM_MANGLED_0; ++ } ++ ++ *oldip = *newip; ++ *oldport = newport; ++} ++ ++static struct sk_buff *__udpv6_gso_segment_list_csum(struct sk_buff *segs) ++{ ++ const struct ipv6hdr *iph; ++ const struct udphdr *uh; ++ struct ipv6hdr *iph2; ++ struct sk_buff *seg; ++ struct udphdr *uh2; ++ ++ seg = segs; ++ uh = udp_hdr(seg); ++ iph = ipv6_hdr(seg); ++ uh2 = udp_hdr(seg->next); ++ iph2 = ipv6_hdr(seg->next); ++ ++ if (!(*(const u32 *)&uh->source ^ *(const u32 *)&uh2->source) && ++ ipv6_addr_equal(&iph->saddr, &iph2->saddr) && ++ ipv6_addr_equal(&iph->daddr, &iph2->daddr)) ++ return segs; ++ ++ while ((seg = seg->next)) { ++ uh2 = udp_hdr(seg); ++ iph2 = ipv6_hdr(seg); ++ ++ __udpv6_gso_segment_csum(seg, &iph2->saddr, &iph->saddr, ++ &uh2->source, uh->source); ++ __udpv6_gso_segment_csum(seg, &iph2->daddr, &iph->daddr, ++ &uh2->dest, uh->dest); ++ } ++ ++ return segs; ++} ++ + static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, + netdev_features_t features, + bool is_ipv6) +@@ -259,7 +315,10 @@ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, + + udp_hdr(skb)->len = htons(sizeof(struct udphdr) + mss); + +- return is_ipv6 ? skb : __udpv4_gso_segment_list_csum(skb); ++ if (is_ipv6) ++ return __udpv6_gso_segment_list_csum(skb); ++ else ++ return __udpv4_gso_segment_list_csum(skb); + } + + struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, +diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c +index ae2da28f9dfb1c..5ab509a5fbdfcf 100644 +--- a/net/ipv6/tcpv6_offload.c ++++ b/net/ipv6/tcpv6_offload.c +@@ -42,7 +42,7 @@ static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, + iif, sdif); + NAPI_GRO_CB(skb)->is_flist = !sk; + if (sk) +- sock_put(sk); ++ sock_gen_put(sk); + #endif /* IS_ENABLED(CONFIG_IPV6) */ + } + +diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c +index c69b999fae171c..9b6d79bd873712 100644 +--- a/net/sched/sch_drr.c ++++ b/net/sched/sch_drr.c +@@ -35,6 +35,11 @@ struct drr_sched { + struct Qdisc_class_hash clhash; + }; + ++static bool cl_is_active(struct drr_class *cl) ++{ ++ return !list_empty(&cl->alist); ++} ++ + static struct drr_class *drr_find_class(struct Qdisc *sch, u32 classid) + { + struct drr_sched *q = qdisc_priv(sch); +@@ -105,6 +110,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + return -ENOBUFS; + + gnet_stats_basic_sync_init(&cl->bstats); ++ INIT_LIST_HEAD(&cl->alist); + cl->common.classid = classid; + cl->quantum = quantum; + cl->qdisc = qdisc_create_dflt(sch->dev_queue, +@@ -229,7 +235,7 @@ static void drr_qlen_notify(struct Qdisc *csh, unsigned long arg) + { + struct drr_class *cl = (struct drr_class *)arg; + +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + } + + static int drr_dump_class(struct Qdisc *sch, unsigned long arg, +@@ -336,7 +342,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct drr_sched *q = qdisc_priv(sch); + struct drr_class *cl; + int err = 0; +- bool first; + + cl = drr_classify(skb, sch, &err); + if (cl == NULL) { +@@ -346,7 +351,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- first = !cl->qdisc->q.qlen; + err = qdisc_enqueue(skb, cl->qdisc, to_free); + if (unlikely(err != NET_XMIT_SUCCESS)) { + if (net_xmit_drop_count(err)) { +@@ -356,7 +360,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- if (first) { ++ if (!cl_is_active(cl)) { + list_add_tail(&cl->alist, &q->active); + cl->deficit = cl->quantum; + } +@@ -390,7 +394,7 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch) + if (unlikely(skb == NULL)) + goto out; + if (cl->qdisc->q.qlen == 0) +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + + bstats_update(&cl->bstats, skb); + qdisc_bstats_update(sch, skb); +@@ -431,7 +435,7 @@ static void drr_reset_qdisc(struct Qdisc *sch) + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) { + if (cl->qdisc->q.qlen) +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + qdisc_reset(cl->qdisc); + } + } +diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c +index 516038a4416380..2c069f0181c62b 100644 +--- a/net/sched/sch_ets.c ++++ b/net/sched/sch_ets.c +@@ -74,6 +74,11 @@ static const struct nla_policy ets_class_policy[TCA_ETS_MAX + 1] = { + [TCA_ETS_QUANTA_BAND] = { .type = NLA_U32 }, + }; + ++static bool cl_is_active(struct ets_class *cl) ++{ ++ return !list_empty(&cl->alist); ++} ++ + static int ets_quantum_parse(struct Qdisc *sch, const struct nlattr *attr, + unsigned int *quantum, + struct netlink_ext_ack *extack) +@@ -293,7 +298,7 @@ static void ets_class_qlen_notify(struct Qdisc *sch, unsigned long arg) + * to remove them. + */ + if (!ets_class_is_strict(q, cl) && sch->q.qlen) +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + } + + static int ets_class_dump(struct Qdisc *sch, unsigned long arg, +@@ -416,7 +421,6 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct ets_sched *q = qdisc_priv(sch); + struct ets_class *cl; + int err = 0; +- bool first; + + cl = ets_classify(skb, sch, &err); + if (!cl) { +@@ -426,7 +430,6 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- first = !cl->qdisc->q.qlen; + err = qdisc_enqueue(skb, cl->qdisc, to_free); + if (unlikely(err != NET_XMIT_SUCCESS)) { + if (net_xmit_drop_count(err)) { +@@ -436,7 +439,7 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- if (first && !ets_class_is_strict(q, cl)) { ++ if (!cl_is_active(cl) && !ets_class_is_strict(q, cl)) { + list_add_tail(&cl->alist, &q->active); + cl->deficit = cl->quantum; + } +@@ -488,7 +491,7 @@ static struct sk_buff *ets_qdisc_dequeue(struct Qdisc *sch) + if (unlikely(!skb)) + goto out; + if (cl->qdisc->q.qlen == 0) +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + return ets_qdisc_dequeue_skb(sch, skb); + } + +@@ -657,7 +660,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, + } + for (i = q->nbands; i < oldbands; i++) { + if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) +- list_del(&q->classes[i].alist); ++ list_del_init(&q->classes[i].alist); + qdisc_tree_flush_backlog(q->classes[i].qdisc); + } + WRITE_ONCE(q->nstrict, nstrict); +@@ -713,7 +716,7 @@ static void ets_qdisc_reset(struct Qdisc *sch) + + for (band = q->nstrict; band < q->nbands; band++) { + if (q->classes[band].qdisc->q.qlen) +- list_del(&q->classes[band].alist); ++ list_del_init(&q->classes[band].alist); + } + for (band = 0; band < q->nbands; band++) + qdisc_reset(q->classes[band].qdisc); +diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c +index 5bb4ab9941d6e9..cb8c525ea20eab 100644 +--- a/net/sched/sch_hfsc.c ++++ b/net/sched/sch_hfsc.c +@@ -203,7 +203,10 @@ eltree_insert(struct hfsc_class *cl) + static inline void + eltree_remove(struct hfsc_class *cl) + { +- rb_erase(&cl->el_node, &cl->sched->eligible); ++ if (!RB_EMPTY_NODE(&cl->el_node)) { ++ rb_erase(&cl->el_node, &cl->sched->eligible); ++ RB_CLEAR_NODE(&cl->el_node); ++ } + } + + static inline void +@@ -1225,7 +1228,8 @@ hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg) + /* vttree is now handled in update_vf() so that update_vf(cl, 0, 0) + * needs to be called explicitly to remove a class from vttree. + */ +- update_vf(cl, 0, 0); ++ if (cl->cl_nactive) ++ update_vf(cl, 0, 0); + if (cl->cl_flags & HFSC_RSC) + eltree_remove(cl); + } +@@ -1565,7 +1569,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + return err; + } + +- if (first) { ++ if (first && !cl->cl_nactive) { + if (cl->cl_flags & HFSC_RSC) + init_ed(cl, len); + if (cl->cl_flags & HFSC_FSC) +diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c +index ff3de37874e4b3..12cccc84d58a0e 100644 +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -1485,6 +1485,8 @@ static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg) + { + struct htb_class *cl = (struct htb_class *)arg; + ++ if (!cl->prio_activity) ++ return; + htb_deactivate(qdisc_priv(sch), cl); + } + +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index d584c0c25899cc..aa4fbd2fae29eb 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -202,6 +202,11 @@ struct qfq_sched { + */ + enum update_reason {enqueue, requeue}; + ++static bool cl_is_active(struct qfq_class *cl) ++{ ++ return !list_empty(&cl->alist); ++} ++ + static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid) + { + struct qfq_sched *q = qdisc_priv(sch); +@@ -347,7 +352,7 @@ static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl) + struct qfq_aggregate *agg = cl->agg; + + +- list_del(&cl->alist); /* remove from RR queue of the aggregate */ ++ list_del_init(&cl->alist); /* remove from RR queue of the aggregate */ + if (list_empty(&agg->active)) /* agg is now inactive */ + qfq_deactivate_agg(q, agg); + } +@@ -477,6 +482,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + gnet_stats_basic_sync_init(&cl->bstats); + cl->common.classid = classid; + cl->deficit = lmax; ++ INIT_LIST_HEAD(&cl->alist); + + cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, + classid, NULL); +@@ -985,7 +991,7 @@ static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg, + cl->deficit -= (int) len; + + if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */ +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) { + cl->deficit += agg->lmax; + list_move_tail(&cl->alist, &agg->active); +@@ -1217,7 +1223,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct qfq_class *cl; + struct qfq_aggregate *agg; + int err = 0; +- bool first; + + cl = qfq_classify(skb, sch, &err); + if (cl == NULL) { +@@ -1239,7 +1244,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + } + + gso_segs = skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; +- first = !cl->qdisc->q.qlen; + err = qdisc_enqueue(skb, cl->qdisc, to_free); + if (unlikely(err != NET_XMIT_SUCCESS)) { + pr_debug("qfq_enqueue: enqueue failed %d\n", err); +@@ -1255,8 +1259,8 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + ++sch->q.qlen; + + agg = cl->agg; +- /* if the queue was not empty, then done here */ +- if (!first) { ++ /* if the class is active, then done here */ ++ if (cl_is_active(cl)) { + if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) && + list_first_entry(&agg->active, struct qfq_class, alist) + == cl && cl->deficit < len) +@@ -1418,6 +1422,8 @@ static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg) + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)arg; + ++ if (list_empty(&cl->alist)) ++ return; + qfq_deactivate_class(q, cl); + } + +diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c +index b57d5d2904eb46..f031b07baa57a9 100644 +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -338,13 +338,14 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) + u32 len = xdp_get_buff_len(xdp); + int err; + +- spin_lock_bh(&xs->rx_lock); + err = xsk_rcv_check(xs, xdp, len); + if (!err) { ++ spin_lock_bh(&xs->pool->rx_lock); + err = __xsk_rcv(xs, xdp, len); + xsk_flush(xs); ++ spin_unlock_bh(&xs->pool->rx_lock); + } +- spin_unlock_bh(&xs->rx_lock); ++ + return err; + } + +@@ -1720,7 +1721,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, + xs = xdp_sk(sk); + xs->state = XSK_READY; + mutex_init(&xs->mutex); +- spin_lock_init(&xs->rx_lock); + + INIT_LIST_HEAD(&xs->map_list); + spin_lock_init(&xs->map_list_lock); +diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c +index 87e865b9b83af9..b69dbd8615fc47 100644 +--- a/net/xdp/xsk_buff_pool.c ++++ b/net/xdp/xsk_buff_pool.c +@@ -87,6 +87,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, + pool->addrs = umem->addrs; + pool->tx_metadata_len = umem->tx_metadata_len; + pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM; ++ spin_lock_init(&pool->rx_lock); + INIT_LIST_HEAD(&pool->free_list); + INIT_LIST_HEAD(&pool->xskb_list); + INIT_LIST_HEAD(&pool->xsk_tx_list); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 4171aa22747c33..db72c5fce9d183 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -440,6 +440,10 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); + fallthrough; + case 0x10ec0215: ++ case 0x10ec0236: ++ case 0x10ec0245: ++ case 0x10ec0256: ++ case 0x10ec0257: + case 0x10ec0285: + case 0x10ec0289: + alc_update_coef_idx(codec, 0x36, 1<<13, 0); +@@ -447,12 +451,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + case 0x10ec0230: + case 0x10ec0233: + case 0x10ec0235: +- case 0x10ec0236: +- case 0x10ec0245: + case 0x10ec0255: +- case 0x10ec0256: + case 0x19e58326: +- case 0x10ec0257: + case 0x10ec0282: + case 0x10ec0283: + case 0x10ec0286: +@@ -10687,8 +10687,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8caf, "HP Elite mt645 G8 Mobile Thin Client", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8cbd, "HP Pavilion Aero Laptop 13-bg0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), +- SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2), +- SND_PCI_QUIRK(0x103c, 0x8cde, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), ++ SND_PCI_QUIRK(0x103c, 0x8cde, "HP OmniBook Ultra Flip Laptop 14t", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), + SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), +@@ -10723,10 +10723,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x12a3, "Asus N7691ZM", ALC269_FIXUP_ASUS_N7601ZM), + SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x12b4, "ASUS B3405CCA / P3405CCA", ALC294_FIXUP_ASUS_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), +- SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), +- SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1460, "Asus VivoBook 15", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), +@@ -10780,7 +10780,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS), + SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS), +- SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1ccf, "ASUS G814JU/JV/JI", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1cdf, "ASUS G814JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1cef, "ASUS G834JY/JZ/JI/JG", ALC285_FIXUP_ASUS_HEADSET_MIC), +diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c +index 92c5ff0deea2cd..607a3eaeb6da8a 100644 +--- a/sound/soc/amd/acp/acp-i2s.c ++++ b/sound/soc/amd/acp/acp-i2s.c +@@ -101,7 +101,7 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas + struct acp_stream *stream; + int slot_len, no_of_slots; + +- chip = dev_get_platdata(dev); ++ chip = dev_get_drvdata(dev->parent); + switch (slot_width) { + case SLOT_WIDTH_8: + slot_len = 8; +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 0d9d1d250f2b5e..6a72561c4189b5 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -746,10 +746,9 @@ config SND_SOC_CS_AMP_LIB + tristate + + config SND_SOC_CS_AMP_LIB_TEST +- tristate "KUnit test for Cirrus Logic cs-amp-lib" +- depends on KUNIT ++ tristate "KUnit test for Cirrus Logic cs-amp-lib" if !KUNIT_ALL_TESTS ++ depends on SND_SOC_CS_AMP_LIB && KUNIT + default KUNIT_ALL_TESTS +- select SND_SOC_CS_AMP_LIB + help + This builds KUnit tests for the Cirrus Logic common + amplifier library. +diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c +index 975ffd2cad292c..809dbb9ded3658 100644 +--- a/sound/soc/generic/simple-card-utils.c ++++ b/sound/soc/generic/simple-card-utils.c +@@ -1150,9 +1150,9 @@ void graph_util_parse_link_direction(struct device_node *np, + bool is_playback_only = of_property_read_bool(np, "playback-only"); + bool is_capture_only = of_property_read_bool(np, "capture-only"); + +- if (is_playback_only) ++ if (playback_only) + *playback_only = is_playback_only; +- if (is_capture_only) ++ if (capture_only) + *capture_only = is_capture_only; + } + EXPORT_SYMBOL_GPL(graph_util_parse_link_direction); +diff --git a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c +index 7f24806d809d9d..74bca3d04e4f1e 100644 +--- a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c ++++ b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c +@@ -29,6 +29,8 @@ int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da + mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "rt715-sdca"); + else + mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s", component->name_prefix); ++ if (!mic_name) ++ return -ENOMEM; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s mic:%s", card->components, +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index 20248a29d1674a..e3c8d4f20b9c13 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -3057,7 +3057,7 @@ int snd_soc_of_parse_pin_switches(struct snd_soc_card *card, const char *prop) + unsigned int i, nb_controls; + int ret; + +- if (!of_property_read_bool(dev->of_node, prop)) ++ if (!of_property_present(dev->of_node, prop)) + return 0; + + strings = devm_kcalloc(dev, nb_controls_max, +@@ -3131,23 +3131,17 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, + if (rx_mask) + snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask); + +- if (of_property_read_bool(np, "dai-tdm-slot-num")) { +- ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); +- if (ret) +- return ret; +- +- if (slots) +- *slots = val; +- } +- +- if (of_property_read_bool(np, "dai-tdm-slot-width")) { +- ret = of_property_read_u32(np, "dai-tdm-slot-width", &val); +- if (ret) +- return ret; ++ ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); ++ if (ret && ret != -EINVAL) ++ return ret; ++ if (!ret && slots) ++ *slots = val; + +- if (slot_width) +- *slot_width = val; +- } ++ ret = of_property_read_u32(np, "dai-tdm-slot-width", &val); ++ if (ret && ret != -EINVAL) ++ return ret; ++ if (!ret && slot_width) ++ *slot_width = val; + + return 0; + } +@@ -3411,12 +3405,12 @@ unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np, + * check "[prefix]frame-master" + */ + snprintf(prop, sizeof(prop), "%sbitclock-master", prefix); +- bit = of_property_read_bool(np, prop); ++ bit = of_property_present(np, prop); + if (bit && bitclkmaster) + *bitclkmaster = of_parse_phandle(np, prop, 0); + + snprintf(prop, sizeof(prop), "%sframe-master", prefix); +- frame = of_property_read_bool(np, prop); ++ frame = of_property_present(np, prop); + if (frame && framemaster) + *framemaster = of_parse_phandle(np, prop, 0); + +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 1102599403c534..0e21ff9f7b74eb 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -1633,10 +1633,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, + /* + * Filter for systems with 'component_chaining' enabled. + * This helps to avoid unnecessary re-configuration of an +- * already active BE on such systems. ++ * already active BE on such systems and ensures the BE DAI ++ * widget is powered ON after hw_params() BE DAI callback. + */ + if (fe->card->component_chaining && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) && ++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) && ++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) + continue; + +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index a29f28eb7d0c64..f36ec98da4601d 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -926,6 +926,8 @@ static int endpoint_set_interface(struct snd_usb_audio *chip, + { + int altset = set ? ep->altsetting : 0; + int err; ++ int retries = 0; ++ const int max_retries = 5; + + if (ep->iface_ref->altset == altset) + return 0; +@@ -935,8 +937,13 @@ static int endpoint_set_interface(struct snd_usb_audio *chip, + + usb_audio_dbg(chip, "Setting usb interface %d:%d for EP 0x%x\n", + ep->iface, altset, ep->ep_num); ++retry: + err = usb_set_interface(chip->dev, ep->iface, altset); + if (err < 0) { ++ if (err == -EPROTO && ++retries <= max_retries) { ++ msleep(5 * (1 << (retries - 1))); ++ goto retry; ++ } + usb_audio_err_ratelimited( + chip, "%d:%d: usb_set_interface failed (%d)\n", + ep->iface, altset, err); +diff --git a/sound/usb/format.c b/sound/usb/format.c +index 6049d957694ca6..a9283b2bd2f4e5 100644 +--- a/sound/usb/format.c ++++ b/sound/usb/format.c +@@ -260,7 +260,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof + } + + /* Jabra Evolve 65 headset */ +- if (chip->usb_id == USB_ID(0x0b0e, 0x030b)) { ++ if (chip->usb_id == USB_ID(0x0b0e, 0x030b) || ++ chip->usb_id == USB_ID(0x0b0e, 0x030c)) { + /* only 48kHz for playback while keeping 16kHz for capture */ + if (fp->nr_rates != 1) + return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);