diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.50-51.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.50-51.patch new file mode 100644 index 000000000000..535938cbe4a3 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.50-51.patch @@ -0,0 +1,12247 @@ +diff --git a/MAINTAINERS b/MAINTAINERS +index f09415b2b3c5c..ae4c0cec50736 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -13702,7 +13702,7 @@ M: Mathieu Desnoyers + M: "Paul E. McKenney" + L: linux-kernel@vger.kernel.org + S: Supported +-F: arch/powerpc/include/asm/membarrier.h ++F: arch/*/include/asm/membarrier.h + F: include/uapi/linux/membarrier.h + F: kernel/sched/membarrier.c + +diff --git a/Makefile b/Makefile +index f7efbb59c9865..6dea0c2163682 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 50 ++SUBLEVEL = 51 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h +index 16b02f44c7d31..d657b84b6bf70 100644 +--- a/arch/arm/include/asm/pgtable.h ++++ b/arch/arm/include/asm/pgtable.h +@@ -151,6 +151,8 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + + extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + ++#define pgdp_get(pgpd) READ_ONCE(*pgdp) ++ + #define pud_page(pud) pmd_page(__pmd(pud_val(pud))) + #define pud_write(pud) pmd_write(__pmd(pud_val(pud))) + +diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h +index 6792a1f83f2ad..a407f9cd549ed 100644 +--- a/arch/arm64/include/asm/acpi.h ++++ b/arch/arm64/include/asm/acpi.h +@@ -119,6 +119,18 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu) + return acpi_cpu_get_madt_gicc(cpu)->uid; + } + ++static inline int get_cpu_for_acpi_id(u32 uid) ++{ ++ int cpu; ++ ++ for (cpu = 0; cpu < nr_cpu_ids; cpu++) ++ if (acpi_cpu_get_madt_gicc(cpu) && ++ uid == get_acpi_id_for_cpu(cpu)) ++ return cpu; ++ ++ return -EINVAL; ++} ++ + static inline void arch_fix_phys_package_id(int num, u32 slot) { } + void __init acpi_init_cpus(void); + int apei_claim_sea(struct pt_regs *regs); +diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c +index ccbff21ce1faf..2465f291c7e17 100644 +--- a/arch/arm64/kernel/acpi_numa.c ++++ b/arch/arm64/kernel/acpi_numa.c +@@ -34,17 +34,6 @@ int __init acpi_numa_get_nid(unsigned int cpu) + return acpi_early_node_map[cpu]; + } + +-static inline int get_cpu_for_acpi_id(u32 uid) +-{ +- int cpu; +- +- for (cpu = 0; cpu < nr_cpu_ids; cpu++) +- if (uid == get_acpi_id_for_cpu(cpu)) +- return cpu; +- +- return -EINVAL; +-} +- + static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header, + const unsigned long end) + { +diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c +index 1acfa704c8d09..0eddd4a66b874 100644 +--- a/arch/loongarch/kernel/relocate.c ++++ b/arch/loongarch/kernel/relocate.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -170,7 +171,7 @@ unsigned long __init relocate_kernel(void) + unsigned long kernel_length; + unsigned long random_offset = 0; + void *location_new = _text; /* Default to original kernel start */ +- char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */ ++ char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */ + + strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE); + +@@ -182,6 +183,7 @@ unsigned long __init relocate_kernel(void) + random_offset = (unsigned long)location_new - (unsigned long)(_text); + #endif + reloc_offset = (unsigned long)_text - VMLINUX_LOAD_ADDRESS; ++ early_memunmap(cmdline, COMMAND_LINE_SIZE); + + if (random_offset) { + kernel_length = (long)(_end) - (long)(_text); +diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c +index 368e8475870f0..5f6e9e2ebbdbb 100644 +--- a/arch/mips/kernel/cevt-r4k.c ++++ b/arch/mips/kernel/cevt-r4k.c +@@ -303,13 +303,6 @@ int r4k_clockevent_init(void) + if (!c0_compare_int_usable()) + return -ENXIO; + +- /* +- * With vectored interrupts things are getting platform specific. +- * get_c0_compare_int is a hook to allow a platform to return the +- * interrupt number of its liking. +- */ +- irq = get_c0_compare_int(); +- + cd = &per_cpu(mips_clockevent_device, cpu); + + cd->name = "MIPS"; +@@ -320,7 +313,6 @@ int r4k_clockevent_init(void) + min_delta = calculate_min_delta(); + + cd->rating = 300; +- cd->irq = irq; + cd->cpumask = cpumask_of(cpu); + cd->set_next_event = mips_next_event; + cd->event_handler = mips_event_handler; +@@ -332,6 +324,13 @@ int r4k_clockevent_init(void) + + cp0_timer_irq_installed = 1; + ++ /* ++ * With vectored interrupts things are getting platform specific. ++ * get_c0_compare_int is a hook to allow a platform to return the ++ * interrupt number of its liking. ++ */ ++ irq = get_c0_compare_int(); ++ + if (request_irq(irq, c0_compare_interrupt, flags, "timer", + c0_compare_interrupt)) + pr_err("Failed to request irq %d (timer)\n", irq); +diff --git a/arch/powerpc/include/asm/nohash/mmu-e500.h b/arch/powerpc/include/asm/nohash/mmu-e500.h +index 6ddced0415cb5..7dc24b8632d7c 100644 +--- a/arch/powerpc/include/asm/nohash/mmu-e500.h ++++ b/arch/powerpc/include/asm/nohash/mmu-e500.h +@@ -303,8 +303,7 @@ extern unsigned long linear_map_top; + extern int book3e_htw_mode; + + #define PPC_HTW_NONE 0 +-#define PPC_HTW_IBM 1 +-#define PPC_HTW_E6500 2 ++#define PPC_HTW_E6500 1 + + /* + * 64-bit booke platforms don't load the tlb in the tlb miss handler code. +diff --git a/arch/powerpc/kernel/vdso/vdso32.lds.S b/arch/powerpc/kernel/vdso/vdso32.lds.S +index 426e1ccc6971a..8f57107000a24 100644 +--- a/arch/powerpc/kernel/vdso/vdso32.lds.S ++++ b/arch/powerpc/kernel/vdso/vdso32.lds.S +@@ -74,6 +74,8 @@ SECTIONS + .got : { *(.got) } :text + .plt : { *(.plt) } + ++ .rela.dyn : { *(.rela .rela*) } ++ + _end = .; + __end = .; + PROVIDE(end = .); +@@ -87,7 +89,7 @@ SECTIONS + *(.branch_lt) + *(.data .data.* .gnu.linkonce.d.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) +- *(.got1 .glink .iplt .rela*) ++ *(.got1 .glink .iplt) + } + } + +diff --git a/arch/powerpc/kernel/vdso/vdso64.lds.S b/arch/powerpc/kernel/vdso/vdso64.lds.S +index bda6c8cdd459c..400819258c06b 100644 +--- a/arch/powerpc/kernel/vdso/vdso64.lds.S ++++ b/arch/powerpc/kernel/vdso/vdso64.lds.S +@@ -69,7 +69,7 @@ SECTIONS + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .gcc_except_table : { *(.gcc_except_table) } +- .rela.dyn ALIGN(8) : { *(.rela.dyn) } ++ .rela.dyn ALIGN(8) : { *(.rela .rela*) } + + .got ALIGN(8) : { *(.got .toc) } + +@@ -86,7 +86,7 @@ SECTIONS + *(.data .data.* .gnu.linkonce.d.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) + *(.opd) +- *(.glink .iplt .plt .rela*) ++ *(.glink .iplt .plt) + } + } + +diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c +index 6dd2f46bd3ef6..8830267789c9c 100644 +--- a/arch/powerpc/lib/qspinlock.c ++++ b/arch/powerpc/lib/qspinlock.c +@@ -715,7 +715,15 @@ static __always_inline void queued_spin_lock_mcs_queue(struct qspinlock *lock, b + } + + release: +- qnodesp->count--; /* release the node */ ++ /* ++ * Clear the lock before releasing the node, as another CPU might see stale ++ * values if an interrupt occurs after we increment qnodesp->count ++ * but before node->lock is initialized. The barrier ensures that ++ * there are no further stores to the node after it has been released. ++ */ ++ node->lock = NULL; ++ barrier(); ++ qnodesp->count--; + } + + void queued_spin_lock_slowpath(struct qspinlock *lock) +diff --git a/arch/powerpc/mm/nohash/Makefile b/arch/powerpc/mm/nohash/Makefile +index f3894e79d5f70..24b445a5fcacc 100644 +--- a/arch/powerpc/mm/nohash/Makefile ++++ b/arch/powerpc/mm/nohash/Makefile +@@ -3,7 +3,7 @@ + ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) + + obj-y += mmu_context.o tlb.o tlb_low.o kup.o +-obj-$(CONFIG_PPC_BOOK3E_64) += tlb_low_64e.o book3e_pgtable.o ++obj-$(CONFIG_PPC_BOOK3E_64) += tlb_64e.o tlb_low_64e.o book3e_pgtable.o + obj-$(CONFIG_40x) += 40x.o + obj-$(CONFIG_44x) += 44x.o + obj-$(CONFIG_PPC_8xx) += 8xx.o +diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c +index 5ffa0af4328af..f57dc721d0636 100644 +--- a/arch/powerpc/mm/nohash/tlb.c ++++ b/arch/powerpc/mm/nohash/tlb.c +@@ -110,28 +110,6 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { + }; + #endif + +-/* The variables below are currently only used on 64-bit Book3E +- * though this will probably be made common with other nohash +- * implementations at some point +- */ +-#ifdef CONFIG_PPC64 +- +-int mmu_pte_psize; /* Page size used for PTE pages */ +-int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ +-int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */ +-unsigned long linear_map_top; /* Top of linear mapping */ +- +- +-/* +- * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug +- * exceptions. This is used for bolted and e6500 TLB miss handlers which +- * do not modify this SPRG in the TLB miss code; for other TLB miss handlers, +- * this is set to zero. +- */ +-int extlb_level_exc; +- +-#endif /* CONFIG_PPC64 */ +- + #ifdef CONFIG_PPC_E500 + /* next_tlbcam_idx is used to round-robin tlbcam entry assignment */ + DEFINE_PER_CPU(int, next_tlbcam_idx); +@@ -358,381 +336,7 @@ void tlb_flush(struct mmu_gather *tlb) + flush_tlb_mm(tlb->mm); + } + +-/* +- * Below are functions specific to the 64-bit variant of Book3E though that +- * may change in the future +- */ +- +-#ifdef CONFIG_PPC64 +- +-/* +- * Handling of virtual linear page tables or indirect TLB entries +- * flushing when PTE pages are freed +- */ +-void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) +-{ +- int tsize = mmu_psize_defs[mmu_pte_psize].enc; +- +- if (book3e_htw_mode != PPC_HTW_NONE) { +- unsigned long start = address & PMD_MASK; +- unsigned long end = address + PMD_SIZE; +- unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift; +- +- /* This isn't the most optimal, ideally we would factor out the +- * while preempt & CPU mask mucking around, or even the IPI but +- * it will do for now +- */ +- while (start < end) { +- __flush_tlb_page(tlb->mm, start, tsize, 1); +- start += size; +- } +- } else { +- unsigned long rmask = 0xf000000000000000ul; +- unsigned long rid = (address & rmask) | 0x1000000000000000ul; +- unsigned long vpte = address & ~rmask; +- +- vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful; +- vpte |= rid; +- __flush_tlb_page(tlb->mm, vpte, tsize, 0); +- } +-} +- +-static void __init setup_page_sizes(void) +-{ +- unsigned int tlb0cfg; +- unsigned int tlb0ps; +- unsigned int eptcfg; +- int i, psize; +- +-#ifdef CONFIG_PPC_E500 +- unsigned int mmucfg = mfspr(SPRN_MMUCFG); +- int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E); +- +- if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { +- unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); +- unsigned int min_pg, max_pg; +- +- min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; +- max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT; +- +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def; +- unsigned int shift; +- +- def = &mmu_psize_defs[psize]; +- shift = def->shift; +- +- if (shift == 0 || shift & 1) +- continue; +- +- /* adjust to be in terms of 4^shift Kb */ +- shift = (shift - 10) >> 1; +- +- if ((shift >= min_pg) && (shift <= max_pg)) +- def->flags |= MMU_PAGE_SIZE_DIRECT; +- } +- +- goto out; +- } +- +- if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { +- u32 tlb1cfg, tlb1ps; +- +- tlb0cfg = mfspr(SPRN_TLB0CFG); +- tlb1cfg = mfspr(SPRN_TLB1CFG); +- tlb1ps = mfspr(SPRN_TLB1PS); +- eptcfg = mfspr(SPRN_EPTCFG); +- +- if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT)) +- book3e_htw_mode = PPC_HTW_E6500; +- +- /* +- * We expect 4K subpage size and unrestricted indirect size. +- * The lack of a restriction on indirect size is a Freescale +- * extension, indicated by PSn = 0 but SPSn != 0. +- */ +- if (eptcfg != 2) +- book3e_htw_mode = PPC_HTW_NONE; +- +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- +- if (!def->shift) +- continue; +- +- if (tlb1ps & (1U << (def->shift - 10))) { +- def->flags |= MMU_PAGE_SIZE_DIRECT; +- +- if (book3e_htw_mode && psize == MMU_PAGE_2M) +- def->flags |= MMU_PAGE_SIZE_INDIRECT; +- } +- } +- +- goto out; +- } +-#endif +- +- tlb0cfg = mfspr(SPRN_TLB0CFG); +- tlb0ps = mfspr(SPRN_TLB0PS); +- eptcfg = mfspr(SPRN_EPTCFG); +- +- /* Look for supported direct sizes */ +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- +- if (tlb0ps & (1U << (def->shift - 10))) +- def->flags |= MMU_PAGE_SIZE_DIRECT; +- } +- +- /* Indirect page sizes supported ? */ +- if ((tlb0cfg & TLBnCFG_IND) == 0 || +- (tlb0cfg & TLBnCFG_PT) == 0) +- goto out; +- +- book3e_htw_mode = PPC_HTW_IBM; +- +- /* Now, we only deal with one IND page size for each +- * direct size. Hopefully all implementations today are +- * unambiguous, but we might want to be careful in the +- * future. +- */ +- for (i = 0; i < 3; i++) { +- unsigned int ps, sps; +- +- sps = eptcfg & 0x1f; +- eptcfg >>= 5; +- ps = eptcfg & 0x1f; +- eptcfg >>= 5; +- if (!ps || !sps) +- continue; +- for (psize = 0; psize < MMU_PAGE_COUNT; psize++) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- +- if (ps == (def->shift - 10)) +- def->flags |= MMU_PAGE_SIZE_INDIRECT; +- if (sps == (def->shift - 10)) +- def->ind = ps + 10; +- } +- } +- +-out: +- /* Cleanup array and print summary */ +- pr_info("MMU: Supported page sizes\n"); +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- const char *__page_type_names[] = { +- "unsupported", +- "direct", +- "indirect", +- "direct & indirect" +- }; +- if (def->flags == 0) { +- def->shift = 0; +- continue; +- } +- pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10), +- __page_type_names[def->flags & 0x3]); +- } +-} +- +-static void __init setup_mmu_htw(void) +-{ +- /* +- * If we want to use HW tablewalk, enable it by patching the TLB miss +- * handlers to branch to the one dedicated to it. +- */ +- +- switch (book3e_htw_mode) { +- case PPC_HTW_IBM: +- patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e); +- patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e); +- break; +-#ifdef CONFIG_PPC_E500 +- case PPC_HTW_E6500: +- extlb_level_exc = EX_TLB_SIZE; +- patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e); +- patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e); +- break; +-#endif +- } +- pr_info("MMU: Book3E HW tablewalk %s\n", +- book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported"); +-} +- +-/* +- * Early initialization of the MMU TLB code +- */ +-static void early_init_this_mmu(void) +-{ +- unsigned int mas4; +- +- /* Set MAS4 based on page table setting */ +- +- mas4 = 0x4 << MAS4_WIMGED_SHIFT; +- switch (book3e_htw_mode) { +- case PPC_HTW_E6500: +- mas4 |= MAS4_INDD; +- mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT; +- mas4 |= MAS4_TLBSELD(1); +- mmu_pte_psize = MMU_PAGE_2M; +- break; +- +- case PPC_HTW_IBM: +- mas4 |= MAS4_INDD; +- mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT; +- mmu_pte_psize = MMU_PAGE_1M; +- break; +- +- case PPC_HTW_NONE: +- mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT; +- mmu_pte_psize = mmu_virtual_psize; +- break; +- } +- mtspr(SPRN_MAS4, mas4); +- +-#ifdef CONFIG_PPC_E500 +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- unsigned int num_cams; +- bool map = true; +- +- /* use a quarter of the TLBCAM for bolted linear map */ +- num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; +- +- /* +- * Only do the mapping once per core, or else the +- * transient mapping would cause problems. +- */ +-#ifdef CONFIG_SMP +- if (hweight32(get_tensr()) > 1) +- map = false; +-#endif +- +- if (map) +- linear_map_top = map_mem_in_cams(linear_map_top, +- num_cams, false, true); +- } +-#endif +- +- /* A sync won't hurt us after mucking around with +- * the MMU configuration +- */ +- mb(); +-} +- +-static void __init early_init_mmu_global(void) +-{ +- /* XXX This should be decided at runtime based on supported +- * page sizes in the TLB, but for now let's assume 16M is +- * always there and a good fit (which it probably is) +- * +- * Freescale booke only supports 4K pages in TLB0, so use that. +- */ +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) +- mmu_vmemmap_psize = MMU_PAGE_4K; +- else +- mmu_vmemmap_psize = MMU_PAGE_16M; +- +- /* XXX This code only checks for TLB 0 capabilities and doesn't +- * check what page size combos are supported by the HW. It +- * also doesn't handle the case where a separate array holds +- * the IND entries from the array loaded by the PT. +- */ +- /* Look for supported page sizes */ +- setup_page_sizes(); +- +- /* Look for HW tablewalk support */ +- setup_mmu_htw(); +- +-#ifdef CONFIG_PPC_E500 +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- if (book3e_htw_mode == PPC_HTW_NONE) { +- extlb_level_exc = EX_TLB_SIZE; +- patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); +- patch_exception(0x1e0, +- exc_instruction_tlb_miss_bolted_book3e); +- } +- } +-#endif +- +- /* Set the global containing the top of the linear mapping +- * for use by the TLB miss code +- */ +- linear_map_top = memblock_end_of_DRAM(); +- +- ioremap_bot = IOREMAP_BASE; +-} +- +-static void __init early_mmu_set_memory_limit(void) +-{ +-#ifdef CONFIG_PPC_E500 +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- /* +- * Limit memory so we dont have linear faults. +- * Unlike memblock_set_current_limit, which limits +- * memory available during early boot, this permanently +- * reduces the memory available to Linux. We need to +- * do this because highmem is not supported on 64-bit. +- */ +- memblock_enforce_memory_limit(linear_map_top); +- } +-#endif +- +- memblock_set_current_limit(linear_map_top); +-} +- +-/* boot cpu only */ +-void __init early_init_mmu(void) +-{ +- early_init_mmu_global(); +- early_init_this_mmu(); +- early_mmu_set_memory_limit(); +-} +- +-void early_init_mmu_secondary(void) +-{ +- early_init_this_mmu(); +-} +- +-void setup_initial_memory_limit(phys_addr_t first_memblock_base, +- phys_addr_t first_memblock_size) +-{ +- /* On non-FSL Embedded 64-bit, we adjust the RMA size to match +- * the bolted TLB entry. We know for now that only 1G +- * entries are supported though that may eventually +- * change. +- * +- * on FSL Embedded 64-bit, usually all RAM is bolted, but with +- * unusual memory sizes it's possible for some RAM to not be mapped +- * (such RAM is not used at all by Linux, since we don't support +- * highmem on 64-bit). We limit ppc64_rma_size to what would be +- * mappable if this memblock is the only one. Additional memblocks +- * can only increase, not decrease, the amount that ends up getting +- * mapped. We still limit max to 1G even if we'll eventually map +- * more. This is due to what the early init code is set up to do. +- * +- * We crop it to the size of the first MEMBLOCK to +- * avoid going over total available memory just in case... +- */ +-#ifdef CONFIG_PPC_E500 +- if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- unsigned long linear_sz; +- unsigned int num_cams; +- +- /* use a quarter of the TLBCAM for bolted linear map */ +- num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; +- +- linear_sz = map_mem_in_cams(first_memblock_size, num_cams, +- true, true); +- +- ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); +- } else +-#endif +- ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); +- +- /* Finally limit subsequent allocations */ +- memblock_set_current_limit(first_memblock_base + ppc64_rma_size); +-} +-#else /* ! CONFIG_PPC64 */ ++#ifndef CONFIG_PPC64 + void __init early_init_mmu(void) + { + unsigned long root = of_get_flat_dt_root(); +diff --git a/arch/powerpc/mm/nohash/tlb_64e.c b/arch/powerpc/mm/nohash/tlb_64e.c +new file mode 100644 +index 0000000000000..b6af3ec4d001d +--- /dev/null ++++ b/arch/powerpc/mm/nohash/tlb_64e.c +@@ -0,0 +1,361 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright 2008,2009 Ben Herrenschmidt ++ * IBM Corp. ++ * ++ * Derived from arch/ppc/mm/init.c: ++ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) ++ * ++ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) ++ * and Cort Dougan (PReP) (cort@cs.nmt.edu) ++ * Copyright (C) 1996 Paul Mackerras ++ * ++ * Derived from "arch/i386/mm/init.c" ++ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* The variables below are currently only used on 64-bit Book3E ++ * though this will probably be made common with other nohash ++ * implementations at some point ++ */ ++static int mmu_pte_psize; /* Page size used for PTE pages */ ++int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ ++int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */ ++unsigned long linear_map_top; /* Top of linear mapping */ ++ ++ ++/* ++ * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug ++ * exceptions. This is used for bolted and e6500 TLB miss handlers which ++ * do not modify this SPRG in the TLB miss code; for other TLB miss handlers, ++ * this is set to zero. ++ */ ++int extlb_level_exc; ++ ++/* ++ * Handling of virtual linear page tables or indirect TLB entries ++ * flushing when PTE pages are freed ++ */ ++void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) ++{ ++ int tsize = mmu_psize_defs[mmu_pte_psize].enc; ++ ++ if (book3e_htw_mode != PPC_HTW_NONE) { ++ unsigned long start = address & PMD_MASK; ++ unsigned long end = address + PMD_SIZE; ++ unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift; ++ ++ /* This isn't the most optimal, ideally we would factor out the ++ * while preempt & CPU mask mucking around, or even the IPI but ++ * it will do for now ++ */ ++ while (start < end) { ++ __flush_tlb_page(tlb->mm, start, tsize, 1); ++ start += size; ++ } ++ } else { ++ unsigned long rmask = 0xf000000000000000ul; ++ unsigned long rid = (address & rmask) | 0x1000000000000000ul; ++ unsigned long vpte = address & ~rmask; ++ ++ vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful; ++ vpte |= rid; ++ __flush_tlb_page(tlb->mm, vpte, tsize, 0); ++ } ++} ++ ++static void __init setup_page_sizes(void) ++{ ++ unsigned int tlb0cfg; ++ unsigned int eptcfg; ++ int psize; ++ ++#ifdef CONFIG_PPC_E500 ++ unsigned int mmucfg = mfspr(SPRN_MMUCFG); ++ int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E); ++ ++ if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { ++ unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); ++ unsigned int min_pg, max_pg; ++ ++ min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; ++ max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT; ++ ++ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { ++ struct mmu_psize_def *def; ++ unsigned int shift; ++ ++ def = &mmu_psize_defs[psize]; ++ shift = def->shift; ++ ++ if (shift == 0 || shift & 1) ++ continue; ++ ++ /* adjust to be in terms of 4^shift Kb */ ++ shift = (shift - 10) >> 1; ++ ++ if ((shift >= min_pg) && (shift <= max_pg)) ++ def->flags |= MMU_PAGE_SIZE_DIRECT; ++ } ++ ++ goto out; ++ } ++ ++ if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { ++ u32 tlb1cfg, tlb1ps; ++ ++ tlb0cfg = mfspr(SPRN_TLB0CFG); ++ tlb1cfg = mfspr(SPRN_TLB1CFG); ++ tlb1ps = mfspr(SPRN_TLB1PS); ++ eptcfg = mfspr(SPRN_EPTCFG); ++ ++ if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT)) ++ book3e_htw_mode = PPC_HTW_E6500; ++ ++ /* ++ * We expect 4K subpage size and unrestricted indirect size. ++ * The lack of a restriction on indirect size is a Freescale ++ * extension, indicated by PSn = 0 but SPSn != 0. ++ */ ++ if (eptcfg != 2) ++ book3e_htw_mode = PPC_HTW_NONE; ++ ++ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { ++ struct mmu_psize_def *def = &mmu_psize_defs[psize]; ++ ++ if (!def->shift) ++ continue; ++ ++ if (tlb1ps & (1U << (def->shift - 10))) { ++ def->flags |= MMU_PAGE_SIZE_DIRECT; ++ ++ if (book3e_htw_mode && psize == MMU_PAGE_2M) ++ def->flags |= MMU_PAGE_SIZE_INDIRECT; ++ } ++ } ++ ++ goto out; ++ } ++#endif ++out: ++ /* Cleanup array and print summary */ ++ pr_info("MMU: Supported page sizes\n"); ++ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { ++ struct mmu_psize_def *def = &mmu_psize_defs[psize]; ++ const char *__page_type_names[] = { ++ "unsupported", ++ "direct", ++ "indirect", ++ "direct & indirect" ++ }; ++ if (def->flags == 0) { ++ def->shift = 0; ++ continue; ++ } ++ pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10), ++ __page_type_names[def->flags & 0x3]); ++ } ++} ++ ++static void __init setup_mmu_htw(void) ++{ ++ /* ++ * If we want to use HW tablewalk, enable it by patching the TLB miss ++ * handlers to branch to the one dedicated to it. ++ */ ++ ++ switch (book3e_htw_mode) { ++#ifdef CONFIG_PPC_E500 ++ case PPC_HTW_E6500: ++ extlb_level_exc = EX_TLB_SIZE; ++ patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e); ++ patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e); ++ break; ++#endif ++ } ++ pr_info("MMU: Book3E HW tablewalk %s\n", ++ book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported"); ++} ++ ++/* ++ * Early initialization of the MMU TLB code ++ */ ++static void early_init_this_mmu(void) ++{ ++ unsigned int mas4; ++ ++ /* Set MAS4 based on page table setting */ ++ ++ mas4 = 0x4 << MAS4_WIMGED_SHIFT; ++ switch (book3e_htw_mode) { ++ case PPC_HTW_E6500: ++ mas4 |= MAS4_INDD; ++ mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT; ++ mas4 |= MAS4_TLBSELD(1); ++ mmu_pte_psize = MMU_PAGE_2M; ++ break; ++ ++ case PPC_HTW_NONE: ++ mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT; ++ mmu_pte_psize = mmu_virtual_psize; ++ break; ++ } ++ mtspr(SPRN_MAS4, mas4); ++ ++#ifdef CONFIG_PPC_E500 ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ unsigned int num_cams; ++ bool map = true; ++ ++ /* use a quarter of the TLBCAM for bolted linear map */ ++ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; ++ ++ /* ++ * Only do the mapping once per core, or else the ++ * transient mapping would cause problems. ++ */ ++#ifdef CONFIG_SMP ++ if (hweight32(get_tensr()) > 1) ++ map = false; ++#endif ++ ++ if (map) ++ linear_map_top = map_mem_in_cams(linear_map_top, ++ num_cams, false, true); ++ } ++#endif ++ ++ /* A sync won't hurt us after mucking around with ++ * the MMU configuration ++ */ ++ mb(); ++} ++ ++static void __init early_init_mmu_global(void) ++{ ++ /* XXX This should be decided at runtime based on supported ++ * page sizes in the TLB, but for now let's assume 16M is ++ * always there and a good fit (which it probably is) ++ * ++ * Freescale booke only supports 4K pages in TLB0, so use that. ++ */ ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) ++ mmu_vmemmap_psize = MMU_PAGE_4K; ++ else ++ mmu_vmemmap_psize = MMU_PAGE_16M; ++ ++ /* XXX This code only checks for TLB 0 capabilities and doesn't ++ * check what page size combos are supported by the HW. It ++ * also doesn't handle the case where a separate array holds ++ * the IND entries from the array loaded by the PT. ++ */ ++ /* Look for supported page sizes */ ++ setup_page_sizes(); ++ ++ /* Look for HW tablewalk support */ ++ setup_mmu_htw(); ++ ++#ifdef CONFIG_PPC_E500 ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ if (book3e_htw_mode == PPC_HTW_NONE) { ++ extlb_level_exc = EX_TLB_SIZE; ++ patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); ++ patch_exception(0x1e0, ++ exc_instruction_tlb_miss_bolted_book3e); ++ } ++ } ++#endif ++ ++ /* Set the global containing the top of the linear mapping ++ * for use by the TLB miss code ++ */ ++ linear_map_top = memblock_end_of_DRAM(); ++ ++ ioremap_bot = IOREMAP_BASE; ++} ++ ++static void __init early_mmu_set_memory_limit(void) ++{ ++#ifdef CONFIG_PPC_E500 ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ /* ++ * Limit memory so we dont have linear faults. ++ * Unlike memblock_set_current_limit, which limits ++ * memory available during early boot, this permanently ++ * reduces the memory available to Linux. We need to ++ * do this because highmem is not supported on 64-bit. ++ */ ++ memblock_enforce_memory_limit(linear_map_top); ++ } ++#endif ++ ++ memblock_set_current_limit(linear_map_top); ++} ++ ++/* boot cpu only */ ++void __init early_init_mmu(void) ++{ ++ early_init_mmu_global(); ++ early_init_this_mmu(); ++ early_mmu_set_memory_limit(); ++} ++ ++void early_init_mmu_secondary(void) ++{ ++ early_init_this_mmu(); ++} ++ ++void setup_initial_memory_limit(phys_addr_t first_memblock_base, ++ phys_addr_t first_memblock_size) ++{ ++ /* On non-FSL Embedded 64-bit, we adjust the RMA size to match ++ * the bolted TLB entry. We know for now that only 1G ++ * entries are supported though that may eventually ++ * change. ++ * ++ * on FSL Embedded 64-bit, usually all RAM is bolted, but with ++ * unusual memory sizes it's possible for some RAM to not be mapped ++ * (such RAM is not used at all by Linux, since we don't support ++ * highmem on 64-bit). We limit ppc64_rma_size to what would be ++ * mappable if this memblock is the only one. Additional memblocks ++ * can only increase, not decrease, the amount that ends up getting ++ * mapped. We still limit max to 1G even if we'll eventually map ++ * more. This is due to what the early init code is set up to do. ++ * ++ * We crop it to the size of the first MEMBLOCK to ++ * avoid going over total available memory just in case... ++ */ ++#ifdef CONFIG_PPC_E500 ++ if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ unsigned long linear_sz; ++ unsigned int num_cams; ++ ++ /* use a quarter of the TLBCAM for bolted linear map */ ++ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; ++ ++ linear_sz = map_mem_in_cams(first_memblock_size, num_cams, ++ true, true); ++ ++ ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); ++ } else ++#endif ++ ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); ++ ++ /* Finally limit subsequent allocations */ ++ memblock_set_current_limit(first_memblock_base + ppc64_rma_size); ++} +diff --git a/arch/powerpc/mm/nohash/tlb_low_64e.S b/arch/powerpc/mm/nohash/tlb_low_64e.S +index 7e0b8fe1c2797..b0eb3f7eaed14 100644 +--- a/arch/powerpc/mm/nohash/tlb_low_64e.S ++++ b/arch/powerpc/mm/nohash/tlb_low_64e.S +@@ -893,201 +893,6 @@ virt_page_table_tlb_miss_whacko_fault: + TLB_MISS_EPILOG_ERROR + b exc_data_storage_book3e + +- +-/************************************************************** +- * * +- * TLB miss handling for Book3E with hw page table support * +- * * +- **************************************************************/ +- +- +-/* Data TLB miss */ +- START_EXCEPTION(data_tlb_miss_htw) +- TLB_MISS_PROLOG +- +- /* Now we handle the fault proper. We only save DEAR in normal +- * fault case since that's the only interesting values here. +- * We could probably also optimize by not saving SRR0/1 in the +- * linear mapping case but I'll leave that for later +- */ +- mfspr r14,SPRN_ESR +- mfspr r16,SPRN_DEAR /* get faulting address */ +- srdi r11,r16,44 /* get region */ +- xoris r11,r11,0xc +- cmpldi cr0,r11,0 /* linear mapping ? */ +- beq tlb_load_linear /* yes -> go to linear map load */ +- cmpldi cr1,r11,1 /* vmalloc mapping ? */ +- +- /* We do the user/kernel test for the PID here along with the RW test +- */ +- srdi. r11,r16,60 /* Check for user region */ +- ld r15,PACAPGD(r13) /* Load user pgdir */ +- beq htw_tlb_miss +- +- /* XXX replace the RMW cycles with immediate loads + writes */ +-1: mfspr r10,SPRN_MAS1 +- rlwinm r10,r10,0,16,1 /* Clear TID */ +- mtspr SPRN_MAS1,r10 +- ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */ +- beq+ cr1,htw_tlb_miss +- +- /* We got a crappy address, just fault with whatever DEAR and ESR +- * are here +- */ +- TLB_MISS_EPILOG_ERROR +- b exc_data_storage_book3e +- +-/* Instruction TLB miss */ +- START_EXCEPTION(instruction_tlb_miss_htw) +- TLB_MISS_PROLOG +- +- /* If we take a recursive fault, the second level handler may need +- * to know whether we are handling a data or instruction fault in +- * order to get to the right store fault handler. We provide that +- * info by keeping a crazy value for ESR in r14 +- */ +- li r14,-1 /* store to exception frame is done later */ +- +- /* Now we handle the fault proper. We only save DEAR in the non +- * linear mapping case since we know the linear mapping case will +- * not re-enter. We could indeed optimize and also not save SRR0/1 +- * in the linear mapping case but I'll leave that for later +- * +- * Faulting address is SRR0 which is already in r16 +- */ +- srdi r11,r16,44 /* get region */ +- xoris r11,r11,0xc +- cmpldi cr0,r11,0 /* linear mapping ? */ +- beq tlb_load_linear /* yes -> go to linear map load */ +- cmpldi cr1,r11,1 /* vmalloc mapping ? */ +- +- /* We do the user/kernel test for the PID here along with the RW test +- */ +- srdi. r11,r16,60 /* Check for user region */ +- ld r15,PACAPGD(r13) /* Load user pgdir */ +- beq htw_tlb_miss +- +- /* XXX replace the RMW cycles with immediate loads + writes */ +-1: mfspr r10,SPRN_MAS1 +- rlwinm r10,r10,0,16,1 /* Clear TID */ +- mtspr SPRN_MAS1,r10 +- ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */ +- beq+ htw_tlb_miss +- +- /* We got a crappy address, just fault */ +- TLB_MISS_EPILOG_ERROR +- b exc_instruction_storage_book3e +- +- +-/* +- * This is the guts of the second-level TLB miss handler for direct +- * misses. We are entered with: +- * +- * r16 = virtual page table faulting address +- * r15 = PGD pointer +- * r14 = ESR +- * r13 = PACA +- * r12 = TLB exception frame in PACA +- * r11 = crap (free to use) +- * r10 = crap (free to use) +- * +- * It can be re-entered by the linear mapping miss handler. However, to +- * avoid too much complication, it will save/restore things for us +- */ +-htw_tlb_miss: +-#ifdef CONFIG_PPC_KUAP +- mfspr r10,SPRN_MAS1 +- rlwinm. r10,r10,0,0x3fff0000 +- beq- htw_tlb_miss_fault /* KUAP fault */ +-#endif +- /* Search if we already have a TLB entry for that virtual address, and +- * if we do, bail out. +- * +- * MAS1:IND should be already set based on MAS4 +- */ +- PPC_TLBSRX_DOT(0,R16) +- beq htw_tlb_miss_done +- +- /* Now, we need to walk the page tables. First check if we are in +- * range. +- */ +- rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4 +- bne- htw_tlb_miss_fault +- +- /* Get the PGD pointer */ +- cmpldi cr0,r15,0 +- beq- htw_tlb_miss_fault +- +- /* Get to PGD entry */ +- rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3 +- clrrdi r10,r11,3 +- ldx r15,r10,r15 +- cmpdi cr0,r15,0 +- bge htw_tlb_miss_fault +- +- /* Get to PUD entry */ +- rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3 +- clrrdi r10,r11,3 +- ldx r15,r10,r15 +- cmpdi cr0,r15,0 +- bge htw_tlb_miss_fault +- +- /* Get to PMD entry */ +- rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3 +- clrrdi r10,r11,3 +- ldx r15,r10,r15 +- cmpdi cr0,r15,0 +- bge htw_tlb_miss_fault +- +- /* Ok, we're all right, we can now create an indirect entry for +- * a 1M or 256M page. +- * +- * The last trick is now that because we use "half" pages for +- * the HTW (1M IND is 2K and 256M IND is 32K) we need to account +- * for an added LSB bit to the RPN. For 64K pages, there is no +- * problem as we already use 32K arrays (half PTE pages), but for +- * 4K page we need to extract a bit from the virtual address and +- * insert it into the "PA52" bit of the RPN. +- */ +- rlwimi r15,r16,32-9,20,20 +- /* Now we build the MAS: +- * +- * MAS 0 : Fully setup with defaults in MAS4 and TLBnCFG +- * MAS 1 : Almost fully setup +- * - PID already updated by caller if necessary +- * - TSIZE for now is base ind page size always +- * MAS 2 : Use defaults +- * MAS 3+7 : Needs to be done +- */ +- ori r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT) +- +- srdi r16,r10,32 +- mtspr SPRN_MAS3,r10 +- mtspr SPRN_MAS7,r16 +- +- tlbwe +- +-htw_tlb_miss_done: +- /* We don't bother with restoring DEAR or ESR since we know we are +- * level 0 and just going back to userland. They are only needed +- * if you are going to take an access fault +- */ +- TLB_MISS_EPILOG_SUCCESS +- rfi +- +-htw_tlb_miss_fault: +- /* We need to check if it was an instruction miss. We know this +- * though because r14 would contain -1 +- */ +- cmpdi cr0,r14,-1 +- beq 1f +- mtspr SPRN_DEAR,r16 +- mtspr SPRN_ESR,r14 +- TLB_MISS_EPILOG_ERROR +- b exc_data_storage_book3e +-1: TLB_MISS_EPILOG_ERROR +- b exc_instruction_storage_book3e +- + /* + * This is the guts of "any" level TLB miss handler for kernel linear + * mapping misses. We are entered with: +diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig +index c785a02005738..fe30b24d52e18 100644 +--- a/arch/riscv/Kconfig ++++ b/arch/riscv/Kconfig +@@ -27,6 +27,7 @@ config RISCV + select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_GIGANTIC_PAGE + select ARCH_HAS_KCOV ++ select ARCH_HAS_MEMBARRIER_CALLBACKS + select ARCH_HAS_MMIOWB + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + select ARCH_HAS_PMEM_API +@@ -489,8 +490,8 @@ config RISCV_ISA_SVPBMT + config TOOLCHAIN_HAS_V + bool + default y +- depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv) +- depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv) ++ depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64imv) ++ depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv) + depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800 + depends on AS_HAS_OPTION_ARCH + +diff --git a/arch/riscv/include/asm/kfence.h b/arch/riscv/include/asm/kfence.h +index 0bbffd528096d..7388edd88986f 100644 +--- a/arch/riscv/include/asm/kfence.h ++++ b/arch/riscv/include/asm/kfence.h +@@ -18,9 +18,9 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) + pte_t *pte = virt_to_kpte(addr); + + if (protect) +- set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); ++ set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT)); + else +- set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); ++ set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT)); + + flush_tlb_kernel_range(addr, addr + PAGE_SIZE); + +diff --git a/arch/riscv/include/asm/membarrier.h b/arch/riscv/include/asm/membarrier.h +new file mode 100644 +index 0000000000000..6c016ebb5020a +--- /dev/null ++++ b/arch/riscv/include/asm/membarrier.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++#ifndef _ASM_RISCV_MEMBARRIER_H ++#define _ASM_RISCV_MEMBARRIER_H ++ ++static inline void membarrier_arch_switch_mm(struct mm_struct *prev, ++ struct mm_struct *next, ++ struct task_struct *tsk) ++{ ++ /* ++ * Only need the full barrier when switching between processes. ++ * Barrier when switching from kernel to userspace is not ++ * required here, given that it is implied by mmdrop(). Barrier ++ * when switching from userspace to kernel is not needed after ++ * store to rq->curr. ++ */ ++ if (IS_ENABLED(CONFIG_SMP) && ++ likely(!(atomic_read(&next->membarrier_state) & ++ (MEMBARRIER_STATE_PRIVATE_EXPEDITED | ++ MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev)) ++ return; ++ ++ /* ++ * The membarrier system call requires a full memory barrier ++ * after storing to rq->curr, before going back to user-space. ++ * Matches a full barrier in the proximity of the membarrier ++ * system call entry. ++ */ ++ smp_mb(); ++} ++ ++#endif /* _ASM_RISCV_MEMBARRIER_H */ +diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h +index 7a5097202e157..3272ca7a5270b 100644 +--- a/arch/riscv/include/asm/pgtable-64.h ++++ b/arch/riscv/include/asm/pgtable-64.h +@@ -198,7 +198,7 @@ static inline int pud_user(pud_t pud) + + static inline void set_pud(pud_t *pudp, pud_t pud) + { +- *pudp = pud; ++ WRITE_ONCE(*pudp, pud); + } + + static inline void pud_clear(pud_t *pudp) +@@ -274,7 +274,7 @@ static inline unsigned long _pmd_pfn(pmd_t pmd) + static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) + { + if (pgtable_l4_enabled) +- *p4dp = p4d; ++ WRITE_ONCE(*p4dp, p4d); + else + set_pud((pud_t *)p4dp, (pud_t){ p4d_val(p4d) }); + } +@@ -336,18 +336,12 @@ static inline struct page *p4d_page(p4d_t p4d) + #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) + + #define pud_offset pud_offset +-static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) +-{ +- if (pgtable_l4_enabled) +- return p4d_pgtable(*p4d) + pud_index(address); +- +- return (pud_t *)p4d; +-} ++pud_t *pud_offset(p4d_t *p4d, unsigned long address); + + static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) + { + if (pgtable_l5_enabled) +- *pgdp = pgd; ++ WRITE_ONCE(*pgdp, pgd); + else + set_p4d((p4d_t *)pgdp, (p4d_t){ pgd_val(pgd) }); + } +@@ -400,12 +394,6 @@ static inline struct page *pgd_page(pgd_t pgd) + #define p4d_index(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1)) + + #define p4d_offset p4d_offset +-static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) +-{ +- if (pgtable_l5_enabled) +- return pgd_pgtable(*pgd) + p4d_index(address); +- +- return (p4d_t *)pgd; +-} ++p4d_t *p4d_offset(pgd_t *pgd, unsigned long address); + + #endif /* _ASM_RISCV_PGTABLE_64_H */ +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index 719c3041ae1c2..37829dab4a0a4 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -248,7 +248,7 @@ static inline int pmd_leaf(pmd_t pmd) + + static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) + { +- *pmdp = pmd; ++ WRITE_ONCE(*pmdp, pmd); + } + + static inline void pmd_clear(pmd_t *pmdp) +@@ -515,7 +515,7 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b) + */ + static inline void set_pte(pte_t *ptep, pte_t pteval) + { +- *ptep = pteval; ++ WRITE_ONCE(*ptep, pteval); + } + + void flush_icache_pte(pte_t pte); +@@ -549,19 +549,12 @@ static inline void pte_clear(struct mm_struct *mm, + __set_pte_at(ptep, __pte(0)); + } + +-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +-static inline int ptep_set_access_flags(struct vm_area_struct *vma, +- unsigned long address, pte_t *ptep, +- pte_t entry, int dirty) +-{ +- if (!pte_same(*ptep, entry)) +- __set_pte_at(ptep, entry); +- /* +- * update_mmu_cache will unconditionally execute, handling both +- * the case that the PTE changed and the spurious fault case. +- */ +- return true; +-} ++#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS /* defined in mm/pgtable.c */ ++extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, ++ pte_t *ptep, pte_t entry, int dirty); ++#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG /* defined in mm/pgtable.c */ ++extern int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long address, ++ pte_t *ptep); + + #define __HAVE_ARCH_PTEP_GET_AND_CLEAR + static inline pte_t ptep_get_and_clear(struct mm_struct *mm, +@@ -574,16 +567,6 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, + return pte; + } + +-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, +- unsigned long address, +- pte_t *ptep) +-{ +- if (!pte_young(*ptep)) +- return 0; +- return test_and_clear_bit(_PAGE_ACCESSED_OFFSET, &pte_val(*ptep)); +-} +- + #define __HAVE_ARCH_PTEP_SET_WRPROTECT + static inline void ptep_set_wrprotect(struct mm_struct *mm, + unsigned long address, pte_t *ptep) +diff --git a/arch/riscv/kernel/efi.c b/arch/riscv/kernel/efi.c +index aa6209a74c83f..b64bf1624a052 100644 +--- a/arch/riscv/kernel/efi.c ++++ b/arch/riscv/kernel/efi.c +@@ -60,7 +60,7 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) + static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) + { + efi_memory_desc_t *md = data; +- pte_t pte = READ_ONCE(*ptep); ++ pte_t pte = ptep_get(ptep); + unsigned long val; + + if (md->attribute & EFI_MEMORY_RO) { +diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S +index 0097c145385f6..9691fa8f2faa7 100644 +--- a/arch/riscv/kernel/head.S ++++ b/arch/riscv/kernel/head.S +@@ -305,6 +305,9 @@ clear_bss_done: + #else + mv a0, a1 + #endif /* CONFIG_BUILTIN_DTB */ ++ /* Set trap vector to spin forever to help debug */ ++ la a3, .Lsecondary_park ++ csrw CSR_TVEC, a3 + call setup_vm + #ifdef CONFIG_MMU + la a0, early_pg_dir +diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c +index 2f08c14a933d0..fecbbcf40ac3f 100644 +--- a/arch/riscv/kernel/probes/kprobes.c ++++ b/arch/riscv/kernel/probes/kprobes.c +@@ -28,9 +28,8 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p) + + p->ainsn.api.restore = (unsigned long)p->addr + offset; + +- patch_text(p->ainsn.api.insn, &p->opcode, 1); +- patch_text((void *)((unsigned long)(p->ainsn.api.insn) + offset), +- &insn, 1); ++ patch_text_nosync(p->ainsn.api.insn, &p->opcode, 1); ++ patch_text_nosync(p->ainsn.api.insn + offset, &insn, 1); + } + + static void __kprobes arch_prepare_simulate(struct kprobe *p) +diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c +index 068c745938710..a9e2fd7245e1e 100644 +--- a/arch/riscv/kvm/mmu.c ++++ b/arch/riscv/kvm/mmu.c +@@ -103,7 +103,7 @@ static bool gstage_get_leaf_entry(struct kvm *kvm, gpa_t addr, + *ptep_level = current_level; + ptep = (pte_t *)kvm->arch.pgd; + ptep = &ptep[gstage_pte_index(addr, current_level)]; +- while (ptep && pte_val(*ptep)) { ++ while (ptep && pte_val(ptep_get(ptep))) { + if (gstage_pte_leaf(ptep)) { + *ptep_level = current_level; + *ptepp = ptep; +@@ -113,7 +113,7 @@ static bool gstage_get_leaf_entry(struct kvm *kvm, gpa_t addr, + if (current_level) { + current_level--; + *ptep_level = current_level; +- ptep = (pte_t *)gstage_pte_page_vaddr(*ptep); ++ ptep = (pte_t *)gstage_pte_page_vaddr(ptep_get(ptep)); + ptep = &ptep[gstage_pte_index(addr, current_level)]; + } else { + ptep = NULL; +@@ -149,25 +149,25 @@ static int gstage_set_pte(struct kvm *kvm, u32 level, + if (gstage_pte_leaf(ptep)) + return -EEXIST; + +- if (!pte_val(*ptep)) { ++ if (!pte_val(ptep_get(ptep))) { + if (!pcache) + return -ENOMEM; + next_ptep = kvm_mmu_memory_cache_alloc(pcache); + if (!next_ptep) + return -ENOMEM; +- *ptep = pfn_pte(PFN_DOWN(__pa(next_ptep)), +- __pgprot(_PAGE_TABLE)); ++ set_pte(ptep, pfn_pte(PFN_DOWN(__pa(next_ptep)), ++ __pgprot(_PAGE_TABLE))); + } else { + if (gstage_pte_leaf(ptep)) + return -EEXIST; +- next_ptep = (pte_t *)gstage_pte_page_vaddr(*ptep); ++ next_ptep = (pte_t *)gstage_pte_page_vaddr(ptep_get(ptep)); + } + + current_level--; + ptep = &next_ptep[gstage_pte_index(addr, current_level)]; + } + +- *ptep = *new_pte; ++ set_pte(ptep, *new_pte); + if (gstage_pte_leaf(ptep)) + gstage_remote_tlb_flush(kvm, current_level, addr); + +@@ -239,11 +239,11 @@ static void gstage_op_pte(struct kvm *kvm, gpa_t addr, + + BUG_ON(addr & (page_size - 1)); + +- if (!pte_val(*ptep)) ++ if (!pte_val(ptep_get(ptep))) + return; + + if (ptep_level && !gstage_pte_leaf(ptep)) { +- next_ptep = (pte_t *)gstage_pte_page_vaddr(*ptep); ++ next_ptep = (pte_t *)gstage_pte_page_vaddr(ptep_get(ptep)); + next_ptep_level = ptep_level - 1; + ret = gstage_level_to_page_size(next_ptep_level, + &next_page_size); +@@ -261,7 +261,7 @@ static void gstage_op_pte(struct kvm *kvm, gpa_t addr, + if (op == GSTAGE_OP_CLEAR) + set_pte(ptep, __pte(0)); + else if (op == GSTAGE_OP_WP) +- set_pte(ptep, __pte(pte_val(*ptep) & ~_PAGE_WRITE)); ++ set_pte(ptep, __pte(pte_val(ptep_get(ptep)) & ~_PAGE_WRITE)); + gstage_remote_tlb_flush(kvm, ptep_level, addr); + } + } +@@ -603,7 +603,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) + &ptep, &ptep_level)) + return false; + +- return pte_young(*ptep); ++ return pte_young(ptep_get(ptep)); + } + + int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu, +diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile +index 3a4dfc8babcf8..2c869f8026a88 100644 +--- a/arch/riscv/mm/Makefile ++++ b/arch/riscv/mm/Makefile +@@ -13,10 +13,9 @@ endif + KCOV_INSTRUMENT_init.o := n + + obj-y += init.o +-obj-$(CONFIG_MMU) += extable.o fault.o pageattr.o ++obj-$(CONFIG_MMU) += extable.o fault.o pageattr.o pgtable.o + obj-y += cacheflush.o + obj-y += context.o +-obj-y += pgtable.o + obj-y += pmem.o + + ifeq ($(CONFIG_MMU),y) +diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c +index 217fd4de61342..ba8eb3944687c 100644 +--- a/arch/riscv/mm/context.c ++++ b/arch/riscv/mm/context.c +@@ -323,6 +323,8 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next, + if (unlikely(prev == next)) + return; + ++ membarrier_arch_switch_mm(prev, next, task); ++ + /* + * Mark the current MM context as inactive, and the next as + * active. This is at least used by the icache flushing +diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c +index 655b2b1bb529f..8960f4c844976 100644 +--- a/arch/riscv/mm/fault.c ++++ b/arch/riscv/mm/fault.c +@@ -137,24 +137,24 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a + pgd = (pgd_t *)pfn_to_virt(pfn) + index; + pgd_k = init_mm.pgd + index; + +- if (!pgd_present(*pgd_k)) { ++ if (!pgd_present(pgdp_get(pgd_k))) { + no_context(regs, addr); + return; + } +- set_pgd(pgd, *pgd_k); ++ set_pgd(pgd, pgdp_get(pgd_k)); + + p4d_k = p4d_offset(pgd_k, addr); +- if (!p4d_present(*p4d_k)) { ++ if (!p4d_present(p4dp_get(p4d_k))) { + no_context(regs, addr); + return; + } + + pud_k = pud_offset(p4d_k, addr); +- if (!pud_present(*pud_k)) { ++ if (!pud_present(pudp_get(pud_k))) { + no_context(regs, addr); + return; + } +- if (pud_leaf(*pud_k)) ++ if (pud_leaf(pudp_get(pud_k))) + goto flush_tlb; + + /* +@@ -162,11 +162,11 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a + * to copy individual PTEs + */ + pmd_k = pmd_offset(pud_k, addr); +- if (!pmd_present(*pmd_k)) { ++ if (!pmd_present(pmdp_get(pmd_k))) { + no_context(regs, addr); + return; + } +- if (pmd_leaf(*pmd_k)) ++ if (pmd_leaf(pmdp_get(pmd_k))) + goto flush_tlb; + + /* +@@ -176,7 +176,7 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a + * silently loop forever. + */ + pte_k = pte_offset_kernel(pmd_k, addr); +- if (!pte_present(*pte_k)) { ++ if (!pte_present(ptep_get(pte_k))) { + no_context(regs, addr); + return; + } +diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c +index fbe918801667d..5ef2a6891158a 100644 +--- a/arch/riscv/mm/hugetlbpage.c ++++ b/arch/riscv/mm/hugetlbpage.c +@@ -54,7 +54,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, + } + + if (sz == PMD_SIZE) { +- if (want_pmd_share(vma, addr) && pud_none(*pud)) ++ if (want_pmd_share(vma, addr) && pud_none(pudp_get(pud))) + pte = huge_pmd_share(mm, vma, addr, pud); + else + pte = (pte_t *)pmd_alloc(mm, pud, addr); +@@ -93,11 +93,11 @@ pte_t *huge_pte_offset(struct mm_struct *mm, + pmd_t *pmd; + + pgd = pgd_offset(mm, addr); +- if (!pgd_present(*pgd)) ++ if (!pgd_present(pgdp_get(pgd))) + return NULL; + + p4d = p4d_offset(pgd, addr); +- if (!p4d_present(*p4d)) ++ if (!p4d_present(p4dp_get(p4d))) + return NULL; + + pud = pud_offset(p4d, addr); +@@ -105,7 +105,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, + /* must be pud huge, non-present or none */ + return (pte_t *)pud; + +- if (!pud_present(*pud)) ++ if (!pud_present(pudp_get(pud))) + return NULL; + + pmd = pmd_offset(pud, addr); +@@ -113,7 +113,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, + /* must be pmd huge, non-present or none */ + return (pte_t *)pmd; + +- if (!pmd_present(*pmd)) ++ if (!pmd_present(pmdp_get(pmd))) + return NULL; + + for_each_napot_order(order) { +@@ -351,7 +351,7 @@ void huge_pte_clear(struct mm_struct *mm, + pte_t *ptep, + unsigned long sz) + { +- pte_t pte = READ_ONCE(*ptep); ++ pte_t pte = ptep_get(ptep); + int i, pte_num; + + if (!pte_napot(pte)) { +diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c +index abe7a7a7686c1..3245bb525212e 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -235,7 +235,7 @@ static void __init setup_bootmem(void) + * The size of the linear page mapping may restrict the amount of + * usable RAM. + */ +- if (IS_ENABLED(CONFIG_64BIT)) { ++ if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) { + max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE; + memblock_cap_memory_range(phys_ram_base, + max_mapped_addr - phys_ram_base); +diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c +index 5e39dcf23fdbc..e962518530373 100644 +--- a/arch/riscv/mm/kasan_init.c ++++ b/arch/riscv/mm/kasan_init.c +@@ -31,7 +31,7 @@ static void __init kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned + phys_addr_t phys_addr; + pte_t *ptep, *p; + +- if (pmd_none(*pmd)) { ++ if (pmd_none(pmdp_get(pmd))) { + p = memblock_alloc(PTRS_PER_PTE * sizeof(pte_t), PAGE_SIZE); + set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa(p)), PAGE_TABLE)); + } +@@ -39,7 +39,7 @@ static void __init kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned + ptep = pte_offset_kernel(pmd, vaddr); + + do { +- if (pte_none(*ptep)) { ++ if (pte_none(ptep_get(ptep))) { + phys_addr = memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); + set_pte(ptep, pfn_pte(PFN_DOWN(phys_addr), PAGE_KERNEL)); + memset(__va(phys_addr), KASAN_SHADOW_INIT, PAGE_SIZE); +@@ -53,7 +53,7 @@ static void __init kasan_populate_pmd(pud_t *pud, unsigned long vaddr, unsigned + pmd_t *pmdp, *p; + unsigned long next; + +- if (pud_none(*pud)) { ++ if (pud_none(pudp_get(pud))) { + p = memblock_alloc(PTRS_PER_PMD * sizeof(pmd_t), PAGE_SIZE); + set_pud(pud, pfn_pud(PFN_DOWN(__pa(p)), PAGE_TABLE)); + } +@@ -63,7 +63,8 @@ static void __init kasan_populate_pmd(pud_t *pud, unsigned long vaddr, unsigned + do { + next = pmd_addr_end(vaddr, end); + +- if (pmd_none(*pmdp) && IS_ALIGNED(vaddr, PMD_SIZE) && (next - vaddr) >= PMD_SIZE) { ++ if (pmd_none(pmdp_get(pmdp)) && IS_ALIGNED(vaddr, PMD_SIZE) && ++ (next - vaddr) >= PMD_SIZE) { + phys_addr = memblock_phys_alloc(PMD_SIZE, PMD_SIZE); + if (phys_addr) { + set_pmd(pmdp, pfn_pmd(PFN_DOWN(phys_addr), PAGE_KERNEL)); +@@ -83,7 +84,7 @@ static void __init kasan_populate_pud(p4d_t *p4d, + pud_t *pudp, *p; + unsigned long next; + +- if (p4d_none(*p4d)) { ++ if (p4d_none(p4dp_get(p4d))) { + p = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE); + set_p4d(p4d, pfn_p4d(PFN_DOWN(__pa(p)), PAGE_TABLE)); + } +@@ -93,7 +94,8 @@ static void __init kasan_populate_pud(p4d_t *p4d, + do { + next = pud_addr_end(vaddr, end); + +- if (pud_none(*pudp) && IS_ALIGNED(vaddr, PUD_SIZE) && (next - vaddr) >= PUD_SIZE) { ++ if (pud_none(pudp_get(pudp)) && IS_ALIGNED(vaddr, PUD_SIZE) && ++ (next - vaddr) >= PUD_SIZE) { + phys_addr = memblock_phys_alloc(PUD_SIZE, PUD_SIZE); + if (phys_addr) { + set_pud(pudp, pfn_pud(PFN_DOWN(phys_addr), PAGE_KERNEL)); +@@ -113,7 +115,7 @@ static void __init kasan_populate_p4d(pgd_t *pgd, + p4d_t *p4dp, *p; + unsigned long next; + +- if (pgd_none(*pgd)) { ++ if (pgd_none(pgdp_get(pgd))) { + p = memblock_alloc(PTRS_PER_P4D * sizeof(p4d_t), PAGE_SIZE); + set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(p)), PAGE_TABLE)); + } +@@ -123,7 +125,8 @@ static void __init kasan_populate_p4d(pgd_t *pgd, + do { + next = p4d_addr_end(vaddr, end); + +- if (p4d_none(*p4dp) && IS_ALIGNED(vaddr, P4D_SIZE) && (next - vaddr) >= P4D_SIZE) { ++ if (p4d_none(p4dp_get(p4dp)) && IS_ALIGNED(vaddr, P4D_SIZE) && ++ (next - vaddr) >= P4D_SIZE) { + phys_addr = memblock_phys_alloc(P4D_SIZE, P4D_SIZE); + if (phys_addr) { + set_p4d(p4dp, pfn_p4d(PFN_DOWN(phys_addr), PAGE_KERNEL)); +@@ -145,7 +148,7 @@ static void __init kasan_populate_pgd(pgd_t *pgdp, + do { + next = pgd_addr_end(vaddr, end); + +- if (pgd_none(*pgdp) && IS_ALIGNED(vaddr, PGDIR_SIZE) && ++ if (pgd_none(pgdp_get(pgdp)) && IS_ALIGNED(vaddr, PGDIR_SIZE) && + (next - vaddr) >= PGDIR_SIZE) { + phys_addr = memblock_phys_alloc(PGDIR_SIZE, PGDIR_SIZE); + if (phys_addr) { +@@ -168,7 +171,7 @@ static void __init kasan_early_clear_pud(p4d_t *p4dp, + if (!pgtable_l4_enabled) { + pudp = (pud_t *)p4dp; + } else { +- base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(*p4dp))); ++ base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(p4dp_get(p4dp)))); + pudp = base_pud + pud_index(vaddr); + } + +@@ -193,7 +196,7 @@ static void __init kasan_early_clear_p4d(pgd_t *pgdp, + if (!pgtable_l5_enabled) { + p4dp = (p4d_t *)pgdp; + } else { +- base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgdp))); ++ base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(pgdp_get(pgdp)))); + p4dp = base_p4d + p4d_index(vaddr); + } + +@@ -239,14 +242,14 @@ static void __init kasan_early_populate_pud(p4d_t *p4dp, + if (!pgtable_l4_enabled) { + pudp = (pud_t *)p4dp; + } else { +- base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(*p4dp))); ++ base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(p4dp_get(p4dp)))); + pudp = base_pud + pud_index(vaddr); + } + + do { + next = pud_addr_end(vaddr, end); + +- if (pud_none(*pudp) && IS_ALIGNED(vaddr, PUD_SIZE) && ++ if (pud_none(pudp_get(pudp)) && IS_ALIGNED(vaddr, PUD_SIZE) && + (next - vaddr) >= PUD_SIZE) { + phys_addr = __pa((uintptr_t)kasan_early_shadow_pmd); + set_pud(pudp, pfn_pud(PFN_DOWN(phys_addr), PAGE_TABLE)); +@@ -277,14 +280,14 @@ static void __init kasan_early_populate_p4d(pgd_t *pgdp, + if (!pgtable_l5_enabled) { + p4dp = (p4d_t *)pgdp; + } else { +- base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgdp))); ++ base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(pgdp_get(pgdp)))); + p4dp = base_p4d + p4d_index(vaddr); + } + + do { + next = p4d_addr_end(vaddr, end); + +- if (p4d_none(*p4dp) && IS_ALIGNED(vaddr, P4D_SIZE) && ++ if (p4d_none(p4dp_get(p4dp)) && IS_ALIGNED(vaddr, P4D_SIZE) && + (next - vaddr) >= P4D_SIZE) { + phys_addr = __pa((uintptr_t)kasan_early_shadow_pud); + set_p4d(p4dp, pfn_p4d(PFN_DOWN(phys_addr), PAGE_TABLE)); +@@ -305,7 +308,7 @@ static void __init kasan_early_populate_pgd(pgd_t *pgdp, + do { + next = pgd_addr_end(vaddr, end); + +- if (pgd_none(*pgdp) && IS_ALIGNED(vaddr, PGDIR_SIZE) && ++ if (pgd_none(pgdp_get(pgdp)) && IS_ALIGNED(vaddr, PGDIR_SIZE) && + (next - vaddr) >= PGDIR_SIZE) { + phys_addr = __pa((uintptr_t)kasan_early_shadow_p4d); + set_pgd(pgdp, pfn_pgd(PFN_DOWN(phys_addr), PAGE_TABLE)); +@@ -381,7 +384,7 @@ static void __init kasan_shallow_populate_pud(p4d_t *p4d, + do { + next = pud_addr_end(vaddr, end); + +- if (pud_none(*pud_k)) { ++ if (pud_none(pudp_get(pud_k))) { + p = memblock_alloc(PAGE_SIZE, PAGE_SIZE); + set_pud(pud_k, pfn_pud(PFN_DOWN(__pa(p)), PAGE_TABLE)); + continue; +@@ -401,7 +404,7 @@ static void __init kasan_shallow_populate_p4d(pgd_t *pgd, + do { + next = p4d_addr_end(vaddr, end); + +- if (p4d_none(*p4d_k)) { ++ if (p4d_none(p4dp_get(p4d_k))) { + p = memblock_alloc(PAGE_SIZE, PAGE_SIZE); + set_p4d(p4d_k, pfn_p4d(PFN_DOWN(__pa(p)), PAGE_TABLE)); + continue; +@@ -420,7 +423,7 @@ static void __init kasan_shallow_populate_pgd(unsigned long vaddr, unsigned long + do { + next = pgd_addr_end(vaddr, end); + +- if (pgd_none(*pgd_k)) { ++ if (pgd_none(pgdp_get(pgd_k))) { + p = memblock_alloc(PAGE_SIZE, PAGE_SIZE); + set_pgd(pgd_k, pfn_pgd(PFN_DOWN(__pa(p)), PAGE_TABLE)); + continue; +@@ -451,7 +454,7 @@ static void __init create_tmp_mapping(void) + + /* Copy the last p4d since it is shared with the kernel mapping. */ + if (pgtable_l5_enabled) { +- ptr = (p4d_t *)pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_END)); ++ ptr = (p4d_t *)pgd_page_vaddr(pgdp_get(pgd_offset_k(KASAN_SHADOW_END))); + memcpy(tmp_p4d, ptr, sizeof(p4d_t) * PTRS_PER_P4D); + set_pgd(&tmp_pg_dir[pgd_index(KASAN_SHADOW_END)], + pfn_pgd(PFN_DOWN(__pa(tmp_p4d)), PAGE_TABLE)); +@@ -462,7 +465,7 @@ static void __init create_tmp_mapping(void) + + /* Copy the last pud since it is shared with the kernel mapping. */ + if (pgtable_l4_enabled) { +- ptr = (pud_t *)p4d_page_vaddr(*(base_p4d + p4d_index(KASAN_SHADOW_END))); ++ ptr = (pud_t *)p4d_page_vaddr(p4dp_get(base_p4d + p4d_index(KASAN_SHADOW_END))); + memcpy(tmp_pud, ptr, sizeof(pud_t) * PTRS_PER_PUD); + set_p4d(&base_p4d[p4d_index(KASAN_SHADOW_END)], + pfn_p4d(PFN_DOWN(__pa(tmp_pud)), PAGE_TABLE)); +diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c +index f61b2f8291e35..271d01a5ba4da 100644 +--- a/arch/riscv/mm/pageattr.c ++++ b/arch/riscv/mm/pageattr.c +@@ -29,7 +29,7 @@ static unsigned long set_pageattr_masks(unsigned long val, struct mm_walk *walk) + static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, + unsigned long next, struct mm_walk *walk) + { +- p4d_t val = READ_ONCE(*p4d); ++ p4d_t val = p4dp_get(p4d); + + if (p4d_leaf(val)) { + val = __p4d(set_pageattr_masks(p4d_val(val), walk)); +@@ -42,7 +42,7 @@ static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, + static int pageattr_pud_entry(pud_t *pud, unsigned long addr, + unsigned long next, struct mm_walk *walk) + { +- pud_t val = READ_ONCE(*pud); ++ pud_t val = pudp_get(pud); + + if (pud_leaf(val)) { + val = __pud(set_pageattr_masks(pud_val(val), walk)); +@@ -55,7 +55,7 @@ static int pageattr_pud_entry(pud_t *pud, unsigned long addr, + static int pageattr_pmd_entry(pmd_t *pmd, unsigned long addr, + unsigned long next, struct mm_walk *walk) + { +- pmd_t val = READ_ONCE(*pmd); ++ pmd_t val = pmdp_get(pmd); + + if (pmd_leaf(val)) { + val = __pmd(set_pageattr_masks(pmd_val(val), walk)); +@@ -68,7 +68,7 @@ static int pageattr_pmd_entry(pmd_t *pmd, unsigned long addr, + static int pageattr_pte_entry(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk) + { +- pte_t val = READ_ONCE(*pte); ++ pte_t val = ptep_get(pte); + + val = __pte(set_pageattr_masks(pte_val(val), walk)); + set_pte(pte, val); +@@ -108,10 +108,10 @@ static int __split_linear_mapping_pmd(pud_t *pudp, + vaddr <= (vaddr & PMD_MASK) && end >= next) + continue; + +- if (pmd_leaf(*pmdp)) { ++ if (pmd_leaf(pmdp_get(pmdp))) { + struct page *pte_page; +- unsigned long pfn = _pmd_pfn(*pmdp); +- pgprot_t prot = __pgprot(pmd_val(*pmdp) & ~_PAGE_PFN_MASK); ++ unsigned long pfn = _pmd_pfn(pmdp_get(pmdp)); ++ pgprot_t prot = __pgprot(pmd_val(pmdp_get(pmdp)) & ~_PAGE_PFN_MASK); + pte_t *ptep_new; + int i; + +@@ -148,10 +148,10 @@ static int __split_linear_mapping_pud(p4d_t *p4dp, + vaddr <= (vaddr & PUD_MASK) && end >= next) + continue; + +- if (pud_leaf(*pudp)) { ++ if (pud_leaf(pudp_get(pudp))) { + struct page *pmd_page; +- unsigned long pfn = _pud_pfn(*pudp); +- pgprot_t prot = __pgprot(pud_val(*pudp) & ~_PAGE_PFN_MASK); ++ unsigned long pfn = _pud_pfn(pudp_get(pudp)); ++ pgprot_t prot = __pgprot(pud_val(pudp_get(pudp)) & ~_PAGE_PFN_MASK); + pmd_t *pmdp_new; + int i; + +@@ -197,10 +197,10 @@ static int __split_linear_mapping_p4d(pgd_t *pgdp, + vaddr <= (vaddr & P4D_MASK) && end >= next) + continue; + +- if (p4d_leaf(*p4dp)) { ++ if (p4d_leaf(p4dp_get(p4dp))) { + struct page *pud_page; +- unsigned long pfn = _p4d_pfn(*p4dp); +- pgprot_t prot = __pgprot(p4d_val(*p4dp) & ~_PAGE_PFN_MASK); ++ unsigned long pfn = _p4d_pfn(p4dp_get(p4dp)); ++ pgprot_t prot = __pgprot(p4d_val(p4dp_get(p4dp)) & ~_PAGE_PFN_MASK); + pud_t *pudp_new; + int i; + +@@ -427,29 +427,29 @@ bool kernel_page_present(struct page *page) + pte_t *pte; + + pgd = pgd_offset_k(addr); +- if (!pgd_present(*pgd)) ++ if (!pgd_present(pgdp_get(pgd))) + return false; +- if (pgd_leaf(*pgd)) ++ if (pgd_leaf(pgdp_get(pgd))) + return true; + + p4d = p4d_offset(pgd, addr); +- if (!p4d_present(*p4d)) ++ if (!p4d_present(p4dp_get(p4d))) + return false; +- if (p4d_leaf(*p4d)) ++ if (p4d_leaf(p4dp_get(p4d))) + return true; + + pud = pud_offset(p4d, addr); +- if (!pud_present(*pud)) ++ if (!pud_present(pudp_get(pud))) + return false; +- if (pud_leaf(*pud)) ++ if (pud_leaf(pudp_get(pud))) + return true; + + pmd = pmd_offset(pud, addr); +- if (!pmd_present(*pmd)) ++ if (!pmd_present(pmdp_get(pmd))) + return false; +- if (pmd_leaf(*pmd)) ++ if (pmd_leaf(pmdp_get(pmd))) + return true; + + pte = pte_offset_kernel(pmd, addr); +- return pte_present(*pte); ++ return pte_present(ptep_get(pte)); + } +diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c +index fef4e7328e490..ef887efcb6790 100644 +--- a/arch/riscv/mm/pgtable.c ++++ b/arch/riscv/mm/pgtable.c +@@ -5,6 +5,47 @@ + #include + #include + ++int ptep_set_access_flags(struct vm_area_struct *vma, ++ unsigned long address, pte_t *ptep, ++ pte_t entry, int dirty) ++{ ++ if (!pte_same(ptep_get(ptep), entry)) ++ __set_pte_at(ptep, entry); ++ /* ++ * update_mmu_cache will unconditionally execute, handling both ++ * the case that the PTE changed and the spurious fault case. ++ */ ++ return true; ++} ++ ++int ptep_test_and_clear_young(struct vm_area_struct *vma, ++ unsigned long address, ++ pte_t *ptep) ++{ ++ if (!pte_young(ptep_get(ptep))) ++ return 0; ++ return test_and_clear_bit(_PAGE_ACCESSED_OFFSET, &pte_val(*ptep)); ++} ++EXPORT_SYMBOL_GPL(ptep_test_and_clear_young); ++ ++#ifdef CONFIG_64BIT ++pud_t *pud_offset(p4d_t *p4d, unsigned long address) ++{ ++ if (pgtable_l4_enabled) ++ return p4d_pgtable(p4dp_get(p4d)) + pud_index(address); ++ ++ return (pud_t *)p4d; ++} ++ ++p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) ++{ ++ if (pgtable_l5_enabled) ++ return pgd_pgtable(pgdp_get(pgd)) + p4d_index(address); ++ ++ return (p4d_t *)pgd; ++} ++#endif ++ + #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP + int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) + { +@@ -25,7 +66,7 @@ int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot) + + int pud_clear_huge(pud_t *pud) + { +- if (!pud_leaf(READ_ONCE(*pud))) ++ if (!pud_leaf(pudp_get(pud))) + return 0; + pud_clear(pud); + return 1; +@@ -33,7 +74,7 @@ int pud_clear_huge(pud_t *pud) + + int pud_free_pmd_page(pud_t *pud, unsigned long addr) + { +- pmd_t *pmd = pud_pgtable(*pud); ++ pmd_t *pmd = pud_pgtable(pudp_get(pud)); + int i; + + pud_clear(pud); +@@ -63,7 +104,7 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot) + + int pmd_clear_huge(pmd_t *pmd) + { +- if (!pmd_leaf(READ_ONCE(*pmd))) ++ if (!pmd_leaf(pmdp_get(pmd))) + return 0; + pmd_clear(pmd); + return 1; +@@ -71,7 +112,7 @@ int pmd_clear_huge(pmd_t *pmd) + + int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) + { +- pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd); ++ pte_t *pte = (pte_t *)pmd_page_vaddr(pmdp_get(pmd)); + + pmd_clear(pmd); + +@@ -88,7 +129,7 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, + pmd_t pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp); + + VM_BUG_ON(address & ~HPAGE_PMD_MASK); +- VM_BUG_ON(pmd_trans_huge(*pmdp)); ++ VM_BUG_ON(pmd_trans_huge(pmdp_get(pmdp))); + /* + * When leaf PTE entries (regular pages) are collapsed into a leaf + * PMD entry (huge page), a valid non-leaf PTE is converted into a +diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S +index 2ae201ebf90b9..de5f9f623f5b2 100644 +--- a/arch/s390/kernel/vmlinux.lds.S ++++ b/arch/s390/kernel/vmlinux.lds.S +@@ -71,6 +71,15 @@ SECTIONS + . = ALIGN(PAGE_SIZE); + __end_ro_after_init = .; + ++ .data.rel.ro : { ++ *(.data.rel.ro .data.rel.ro.*) ++ } ++ .got : { ++ __got_start = .; ++ *(.got) ++ __got_end = .; ++ } ++ + RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE) + BOOT_DATA_PRESERVED + +diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c +index 375200e9aba9a..2ba4e0d4e26b0 100644 +--- a/arch/um/drivers/line.c ++++ b/arch/um/drivers/line.c +@@ -383,6 +383,7 @@ int setup_one_line(struct line *lines, int n, char *init, + parse_chan_pair(NULL, line, n, opts, error_out); + err = 0; + } ++ *error_out = "configured as 'none'"; + } else { + char *new = kstrdup(init, GFP_KERNEL); + if (!new) { +@@ -406,6 +407,7 @@ int setup_one_line(struct line *lines, int n, char *init, + } + } + if (err) { ++ *error_out = "failed to parse channel pair"; + line->init_str = NULL; + line->valid = 0; + kfree(new); +diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c +index f3c75809fed26..006041fbb65f8 100644 +--- a/arch/x86/coco/tdx/tdx.c ++++ b/arch/x86/coco/tdx/tdx.c +@@ -362,7 +362,6 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val) + .r12 = size, + .r13 = EPT_READ, + .r14 = addr, +- .r15 = *val, + }; + + if (__tdx_hypercall_ret(&args)) +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index bc4fcf0d94056..688550e336ce1 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4465,6 +4465,25 @@ static u8 adl_get_hybrid_cpu_type(void) + return hybrid_big; + } + ++static inline bool erratum_hsw11(struct perf_event *event) ++{ ++ return (event->hw.config & INTEL_ARCH_EVENT_MASK) == ++ X86_CONFIG(.event=0xc0, .umask=0x01); ++} ++ ++/* ++ * The HSW11 requires a period larger than 100 which is the same as the BDM11. ++ * A minimum period of 128 is enforced as well for the INST_RETIRED.ALL. ++ * ++ * The message 'interrupt took too long' can be observed on any counter which ++ * was armed with a period < 32 and two events expired in the same NMI. ++ * A minimum period of 32 is enforced for the rest of the events. ++ */ ++static void hsw_limit_period(struct perf_event *event, s64 *left) ++{ ++ *left = max(*left, erratum_hsw11(event) ? 128 : 32); ++} ++ + /* + * Broadwell: + * +@@ -4482,8 +4501,7 @@ static u8 adl_get_hybrid_cpu_type(void) + */ + static void bdw_limit_period(struct perf_event *event, s64 *left) + { +- if ((event->hw.config & INTEL_ARCH_EVENT_MASK) == +- X86_CONFIG(.event=0xc0, .umask=0x01)) { ++ if (erratum_hsw11(event)) { + if (*left < 128) + *left = 128; + *left &= ~0x3fULL; +@@ -6392,6 +6410,7 @@ __init int intel_pmu_init(void) + + x86_pmu.hw_config = hsw_hw_config; + x86_pmu.get_event_constraints = hsw_get_event_constraints; ++ x86_pmu.limit_period = hsw_limit_period; + x86_pmu.lbr_double_abort = true; + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; +diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h +index eb810074f1e74..fd5fb43d920b4 100644 +--- a/arch/x86/include/asm/fpu/types.h ++++ b/arch/x86/include/asm/fpu/types.h +@@ -589,6 +589,13 @@ struct fpu_state_config { + * even without XSAVE support, i.e. legacy features FP + SSE + */ + u64 legacy_features; ++ /* ++ * @independent_features: ++ * ++ * Features that are supported by XSAVES, but not managed as part of ++ * the FPU core, such as LBR ++ */ ++ u64 independent_features; + }; + + /* FPU state configuration information */ +diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h +index cc6b8e087192e..9dab85aba7afd 100644 +--- a/arch/x86/include/asm/page_64.h ++++ b/arch/x86/include/asm/page_64.h +@@ -17,6 +17,7 @@ extern unsigned long phys_base; + extern unsigned long page_offset_base; + extern unsigned long vmalloc_base; + extern unsigned long vmemmap_base; ++extern unsigned long physmem_end; + + static __always_inline unsigned long __phys_addr_nodebug(unsigned long x) + { +diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h +index 38b54b992f32e..35c416f061552 100644 +--- a/arch/x86/include/asm/pgtable_64_types.h ++++ b/arch/x86/include/asm/pgtable_64_types.h +@@ -140,6 +140,10 @@ extern unsigned int ptrs_per_p4d; + # define VMEMMAP_START __VMEMMAP_BASE_L4 + #endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */ + ++#ifdef CONFIG_RANDOMIZE_MEMORY ++# define PHYSMEM_END physmem_end ++#endif ++ + /* + * End of the region for which vmalloc page tables are pre-allocated. + * For non-KMSAN builds, this is the same as VMALLOC_END. +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 06d5a7eeee81a..f2e605ee75d96 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -1812,12 +1812,9 @@ static __init void apic_set_fixmap(bool read_apic); + + static __init void x2apic_disable(void) + { +- u32 x2apic_id, state = x2apic_state; ++ u32 x2apic_id; + +- x2apic_mode = 0; +- x2apic_state = X2APIC_DISABLED; +- +- if (state != X2APIC_ON) ++ if (x2apic_state < X2APIC_ON) + return; + + x2apic_id = read_apic_id(); +@@ -1830,6 +1827,10 @@ static __init void x2apic_disable(void) + } + + __x2apic_disable(); ++ ++ x2apic_mode = 0; ++ x2apic_state = X2APIC_DISABLED; ++ + /* + * Don't reread the APIC ID as it was already done from + * check_x2apic() and the APIC driver still is a x2APIC variant, +diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c +index 571a43b3105df..255ff8f6c5270 100644 +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -788,6 +788,9 @@ void __init fpu__init_system_xstate(unsigned int legacy_size) + goto out_disable; + } + ++ fpu_kernel_cfg.independent_features = fpu_kernel_cfg.max_features & ++ XFEATURE_MASK_INDEPENDENT; ++ + /* + * Clear XSAVE features that are disabled in the normal CPUID. + */ +diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h +index 19ca623ffa2ac..544224611e23c 100644 +--- a/arch/x86/kernel/fpu/xstate.h ++++ b/arch/x86/kernel/fpu/xstate.h +@@ -64,9 +64,9 @@ static inline u64 xfeatures_mask_supervisor(void) + static inline u64 xfeatures_mask_independent(void) + { + if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) +- return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR; ++ return fpu_kernel_cfg.independent_features & ~XFEATURE_MASK_LBR; + +- return XFEATURE_MASK_INDEPENDENT; ++ return fpu_kernel_cfg.independent_features; + } + + /* XSAVE/XRSTOR wrapper functions */ +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index e3c2acc1adc73..413f1f2aadd1a 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -2869,6 +2869,12 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + case MSR_CSTAR: + msr_info->data = svm->vmcb01.ptr->save.cstar; + break; ++ case MSR_GS_BASE: ++ msr_info->data = svm->vmcb01.ptr->save.gs.base; ++ break; ++ case MSR_FS_BASE: ++ msr_info->data = svm->vmcb01.ptr->save.fs.base; ++ break; + case MSR_KERNEL_GS_BASE: + msr_info->data = svm->vmcb01.ptr->save.kernel_gs_base; + break; +@@ -3090,6 +3096,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) + case MSR_CSTAR: + svm->vmcb01.ptr->save.cstar = data; + break; ++ case MSR_GS_BASE: ++ svm->vmcb01.ptr->save.gs.base = data; ++ break; ++ case MSR_FS_BASE: ++ svm->vmcb01.ptr->save.fs.base = data; ++ break; + case MSR_KERNEL_GS_BASE: + svm->vmcb01.ptr->save.kernel_gs_base = data; + break; +@@ -5166,6 +5178,9 @@ static __init void svm_set_cpu_caps(void) + + /* CPUID 0x8000001F (SME/SEV features) */ + sev_set_cpu_caps(); ++ ++ /* Don't advertise Bus Lock Detect to guest if SVM support is absent */ ++ kvm_cpu_cap_clear(X86_FEATURE_BUS_LOCK_DETECT); + } + + static __init int svm_hardware_setup(void) +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index c7e7ab1593d5b..50cc822e12900 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -5829,7 +5829,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, + if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events))) + break; + ++ kvm_vcpu_srcu_read_lock(vcpu); + r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events); ++ kvm_vcpu_srcu_read_unlock(vcpu); + break; + } + case KVM_GET_DEBUGREGS: { +diff --git a/arch/x86/lib/iomem.c b/arch/x86/lib/iomem.c +index e0411a3774d49..5eecb45d05d5d 100644 +--- a/arch/x86/lib/iomem.c ++++ b/arch/x86/lib/iomem.c +@@ -25,6 +25,9 @@ static __always_inline void rep_movs(void *to, const void *from, size_t n) + + static void string_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) + { ++ const void *orig_to = to; ++ const size_t orig_n = n; ++ + if (unlikely(!n)) + return; + +@@ -39,7 +42,7 @@ static void string_memcpy_fromio(void *to, const volatile void __iomem *from, si + } + rep_movs(to, (const void *)from, n); + /* KMSAN must treat values read from devices as initialized. */ +- kmsan_unpoison_memory(to, n); ++ kmsan_unpoison_memory(orig_to, orig_n); + } + + static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n) +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index 19d209b412d7a..aa69353da49f2 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -950,8 +950,12 @@ static void update_end_of_memory_vars(u64 start, u64 size) + int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, + struct mhp_params *params) + { ++ unsigned long end = ((start_pfn + nr_pages) << PAGE_SHIFT) - 1; + int ret; + ++ if (WARN_ON_ONCE(end > PHYSMEM_END)) ++ return -ERANGE; ++ + ret = __add_pages(nid, start_pfn, nr_pages, params); + WARN_ON_ONCE(ret); + +diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c +index 37db264866b64..230f1dee4f095 100644 +--- a/arch/x86/mm/kaslr.c ++++ b/arch/x86/mm/kaslr.c +@@ -47,13 +47,24 @@ static const unsigned long vaddr_end = CPU_ENTRY_AREA_BASE; + */ + static __initdata struct kaslr_memory_region { + unsigned long *base; ++ unsigned long *end; + unsigned long size_tb; + } kaslr_regions[] = { +- { &page_offset_base, 0 }, +- { &vmalloc_base, 0 }, +- { &vmemmap_base, 0 }, ++ { ++ .base = &page_offset_base, ++ .end = &physmem_end, ++ }, ++ { ++ .base = &vmalloc_base, ++ }, ++ { ++ .base = &vmemmap_base, ++ }, + }; + ++/* The end of the possible address space for physical memory */ ++unsigned long physmem_end __ro_after_init; ++ + /* Get size in bytes used by the memory region */ + static inline unsigned long get_padding(struct kaslr_memory_region *region) + { +@@ -82,6 +93,8 @@ void __init kernel_randomize_memory(void) + BUILD_BUG_ON(vaddr_end != CPU_ENTRY_AREA_BASE); + BUILD_BUG_ON(vaddr_end > __START_KERNEL_map); + ++ /* Preset the end of the possible address space for physical memory */ ++ physmem_end = ((1ULL << MAX_PHYSMEM_BITS) - 1); + if (!kaslr_memory_enabled()) + return; + +@@ -128,11 +141,18 @@ void __init kernel_randomize_memory(void) + vaddr += entropy; + *kaslr_regions[i].base = vaddr; + ++ /* Calculate the end of the region */ ++ vaddr += get_padding(&kaslr_regions[i]); + /* +- * Jump the region and add a minimum padding based on +- * randomization alignment. ++ * KASLR trims the maximum possible size of the ++ * direct-map. Update the physmem_end boundary. ++ * No rounding required as the region starts ++ * PUD aligned and size is in units of TB. + */ +- vaddr += get_padding(&kaslr_regions[i]); ++ if (kaslr_regions[i].end) ++ *kaslr_regions[i].end = __pa_nodebug(vaddr - 1); ++ ++ /* Add a minimum padding based on randomization alignment. */ + vaddr = round_up(vaddr + 1, PUD_SIZE); + remain_entropy -= entropy; + } +diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c +index 41d8c8f475a7c..83a6bdf0b498e 100644 +--- a/arch/x86/mm/pti.c ++++ b/arch/x86/mm/pti.c +@@ -241,7 +241,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) + * + * Returns a pointer to a PTE on success, or NULL on failure. + */ +-static pte_t *pti_user_pagetable_walk_pte(unsigned long address) ++static pte_t *pti_user_pagetable_walk_pte(unsigned long address, bool late_text) + { + gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); + pmd_t *pmd; +@@ -251,10 +251,15 @@ static pte_t *pti_user_pagetable_walk_pte(unsigned long address) + if (!pmd) + return NULL; + +- /* We can't do anything sensible if we hit a large mapping. */ ++ /* Large PMD mapping found */ + if (pmd_large(*pmd)) { +- WARN_ON(1); +- return NULL; ++ /* Clear the PMD if we hit a large mapping from the first round */ ++ if (late_text) { ++ set_pmd(pmd, __pmd(0)); ++ } else { ++ WARN_ON_ONCE(1); ++ return NULL; ++ } + } + + if (pmd_none(*pmd)) { +@@ -283,7 +288,7 @@ static void __init pti_setup_vsyscall(void) + if (!pte || WARN_ON(level != PG_LEVEL_4K) || pte_none(*pte)) + return; + +- target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR); ++ target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR, false); + if (WARN_ON(!target_pte)) + return; + +@@ -301,7 +306,7 @@ enum pti_clone_level { + + static void + pti_clone_pgtable(unsigned long start, unsigned long end, +- enum pti_clone_level level) ++ enum pti_clone_level level, bool late_text) + { + unsigned long addr; + +@@ -390,7 +395,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + return; + + /* Allocate PTE in the user page-table */ +- target_pte = pti_user_pagetable_walk_pte(addr); ++ target_pte = pti_user_pagetable_walk_pte(addr, late_text); + if (WARN_ON(!target_pte)) + return; + +@@ -452,7 +457,7 @@ static void __init pti_clone_user_shared(void) + phys_addr_t pa = per_cpu_ptr_to_phys((void *)va); + pte_t *target_pte; + +- target_pte = pti_user_pagetable_walk_pte(va); ++ target_pte = pti_user_pagetable_walk_pte(va, false); + if (WARN_ON(!target_pte)) + return; + +@@ -475,7 +480,7 @@ static void __init pti_clone_user_shared(void) + start = CPU_ENTRY_AREA_BASE; + end = start + (PAGE_SIZE * CPU_ENTRY_AREA_PAGES); + +- pti_clone_pgtable(start, end, PTI_CLONE_PMD); ++ pti_clone_pgtable(start, end, PTI_CLONE_PMD, false); + } + #endif /* CONFIG_X86_64 */ + +@@ -492,11 +497,11 @@ static void __init pti_setup_espfix64(void) + /* + * Clone the populated PMDs of the entry text and force it RO. + */ +-static void pti_clone_entry_text(void) ++static void pti_clone_entry_text(bool late) + { + pti_clone_pgtable((unsigned long) __entry_text_start, + (unsigned long) __entry_text_end, +- PTI_LEVEL_KERNEL_IMAGE); ++ PTI_LEVEL_KERNEL_IMAGE, late); + } + + /* +@@ -571,7 +576,7 @@ static void pti_clone_kernel_text(void) + * pti_set_kernel_image_nonglobal() did to clear the + * global bit. + */ +- pti_clone_pgtable(start, end_clone, PTI_LEVEL_KERNEL_IMAGE); ++ pti_clone_pgtable(start, end_clone, PTI_LEVEL_KERNEL_IMAGE, false); + + /* + * pti_clone_pgtable() will set the global bit in any PMDs +@@ -638,8 +643,15 @@ void __init pti_init(void) + + /* Undo all global bits from the init pagetables in head_64.S: */ + pti_set_kernel_image_nonglobal(); ++ + /* Replace some of the global bits just for shared entry text: */ +- pti_clone_entry_text(); ++ /* ++ * This is very early in boot. Device and Late initcalls can do ++ * modprobe before free_initmem() and mark_readonly(). This ++ * pti_clone_entry_text() allows those user-mode-helpers to function, ++ * but notably the text is still RW. ++ */ ++ pti_clone_entry_text(false); + pti_setup_espfix64(); + pti_setup_vsyscall(); + } +@@ -656,10 +668,11 @@ void pti_finalize(void) + if (!boot_cpu_has(X86_FEATURE_PTI)) + return; + /* +- * We need to clone everything (again) that maps parts of the +- * kernel image. ++ * This is after free_initmem() (all initcalls are done) and we've done ++ * mark_readonly(). Text is now NX which might've split some PMDs ++ * relative to the early clone. + */ +- pti_clone_entry_text(); ++ pti_clone_entry_text(true); + pti_clone_kernel_text(); + + debug_checkwx_user(); +diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2_security.c b/drivers/accel/habanalabs/gaudi2/gaudi2_security.c +index 908710524dc9e..493e556cd31b7 100644 +--- a/drivers/accel/habanalabs/gaudi2/gaudi2_security.c ++++ b/drivers/accel/habanalabs/gaudi2/gaudi2_security.c +@@ -479,6 +479,7 @@ static const u32 gaudi2_pb_dcr0_edma0_unsecured_regs[] = { + mmDCORE0_EDMA0_CORE_CTX_TE_NUMROWS, + mmDCORE0_EDMA0_CORE_CTX_IDX, + mmDCORE0_EDMA0_CORE_CTX_IDX_INC, ++ mmDCORE0_EDMA0_CORE_WR_COMP_MAX_OUTSTAND, + mmDCORE0_EDMA0_CORE_RD_LBW_RATE_LIM_CFG, + mmDCORE0_EDMA0_QM_CQ_CFG0_0, + mmDCORE0_EDMA0_QM_CQ_CFG0_1, +diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c +index 0f5218e361df5..7053f1b9fc1dd 100644 +--- a/drivers/acpi/acpi_processor.c ++++ b/drivers/acpi/acpi_processor.c +@@ -415,7 +415,7 @@ static int acpi_processor_add(struct acpi_device *device, + + result = acpi_processor_get_info(device); + if (result) /* Processor is not physically present or unavailable */ +- return 0; ++ goto err_clear_driver_data; + + BUG_ON(pr->id >= nr_cpu_ids); + +@@ -430,7 +430,7 @@ static int acpi_processor_add(struct acpi_device *device, + "BIOS reported wrong ACPI id %d for the processor\n", + pr->id); + /* Give up, but do not abort the namespace scan. */ +- goto err; ++ goto err_clear_driver_data; + } + /* + * processor_device_array is not cleared on errors to allow buggy BIOS +@@ -442,12 +442,12 @@ static int acpi_processor_add(struct acpi_device *device, + dev = get_cpu_device(pr->id); + if (!dev) { + result = -ENODEV; +- goto err; ++ goto err_clear_per_cpu; + } + + result = acpi_bind_one(dev, device); + if (result) +- goto err; ++ goto err_clear_per_cpu; + + pr->dev = dev; + +@@ -458,10 +458,11 @@ static int acpi_processor_add(struct acpi_device *device, + dev_err(dev, "Processor driver could not be attached\n"); + acpi_unbind_one(dev); + +- err: +- free_cpumask_var(pr->throttling.shared_cpu_map); +- device->driver_data = NULL; ++ err_clear_per_cpu: + per_cpu(processors, pr->id) = NULL; ++ err_clear_driver_data: ++ device->driver_data = NULL; ++ free_cpumask_var(pr->throttling.shared_cpu_map); + err_free_pr: + kfree(pr); + return result; +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index d3b9da75a8155..d6934ba7a3154 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -1196,6 +1196,19 @@ int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf) + return cppc_get_perf(cpunum, NOMINAL_PERF, nominal_perf); + } + ++/** ++ * cppc_get_highest_perf - Get the highest performance register value. ++ * @cpunum: CPU from which to get highest performance. ++ * @highest_perf: Return address. ++ * ++ * Return: 0 for success, -EIO otherwise. ++ */ ++int cppc_get_highest_perf(int cpunum, u64 *highest_perf) ++{ ++ return cppc_get_perf(cpunum, HIGHEST_PERF, highest_perf); ++} ++EXPORT_SYMBOL_GPL(cppc_get_highest_perf); ++ + /** + * cppc_get_epp_perf - Get the epp register value. + * @cpunum: CPU from which to get epp preference value. +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index ccaceedbc2c01..94f10c6eb336a 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -3342,6 +3342,7 @@ static void binder_transaction(struct binder_proc *proc, + */ + copy_size = object_offset - user_offset; + if (copy_size && (user_offset > object_offset || ++ object_offset > tr->data_size || + binder_alloc_copy_user_to_buffer( + &target_proc->alloc, + t->buffer, user_offset, +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 373d23af1d9ac..4ed90d46a017a 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5593,8 +5593,10 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) + } + + dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); +- if (!dr) ++ if (!dr) { ++ kfree(host); + goto err_out; ++ } + + devres_add(dev, dr); + dev_set_drvdata(dev, host); +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index 277bf0e8ed091..c91f8746289f4 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -242,10 +242,17 @@ void ata_scsi_set_sense_information(struct ata_device *dev, + */ + static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc) + { ++ struct ata_device *dev = qc->dev; + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; + unsigned char *sb = cmd->sense_buffer; + ++ if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ++ ata_dev_dbg(dev, ++ "missing result TF: can't set ATA PT sense fields\n"); ++ return; ++ } ++ + if ((sb[0] & 0x7f) >= 0x72) { + unsigned char *desc; + u8 len; +@@ -924,12 +931,16 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, + */ + static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) + { ++ struct ata_device *dev = qc->dev; + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; +- unsigned char *sb = cmd->sense_buffer; + u8 sense_key, asc, ascq; + +- memset(sb, 0, SCSI_SENSE_BUFFERSIZE); ++ if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ++ ata_dev_dbg(dev, ++ "missing result TF: can't generate ATA PT sense data\n"); ++ return; ++ } + + /* + * Use ata_to_sense_error() to map status register bits +@@ -976,14 +987,19 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) + u64 block; + u8 sense_key, asc, ascq; + +- memset(sb, 0, SCSI_SENSE_BUFFERSIZE); +- + if (ata_dev_disabled(dev)) { + /* Device disabled after error recovery */ + /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */ + ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21); + return; + } ++ ++ if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ++ ata_dev_dbg(dev, ++ "missing result TF: can't generate sense data\n"); ++ return; ++ } ++ + /* Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. + */ +diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c +index 17f6ccee53c7c..ffbb2e8591cef 100644 +--- a/drivers/ata/pata_macio.c ++++ b/drivers/ata/pata_macio.c +@@ -541,7 +541,8 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc) + + while (sg_len) { + /* table overflow should never happen */ +- BUG_ON (pi++ >= MAX_DCMDS); ++ if (WARN_ON_ONCE(pi >= MAX_DCMDS)) ++ return AC_ERR_SYSTEM; + + len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG; + table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE); +@@ -553,11 +554,13 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc) + addr += len; + sg_len -= len; + ++table; ++ ++pi; + } + } + + /* Should never happen according to Tejun */ +- BUG_ON(!pi); ++ if (WARN_ON_ONCE(!pi)) ++ return AC_ERR_SYSTEM; + + /* Convert the last command to an input/output */ + table--; +diff --git a/drivers/base/devres.c b/drivers/base/devres.c +index 8d709dbd4e0c1..e9b0d94aeabd9 100644 +--- a/drivers/base/devres.c ++++ b/drivers/base/devres.c +@@ -567,6 +567,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) + grp->id = grp; + if (id) + grp->id = id; ++ grp->color = 0; + + spin_lock_irqsave(&dev->devres_lock, flags); + add_dr(dev, &grp->node[0]); +diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c +index 55999a50ccc0b..0b6c2277128b4 100644 +--- a/drivers/base/regmap/regcache-maple.c ++++ b/drivers/base/regmap/regcache-maple.c +@@ -110,7 +110,8 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min, + struct maple_tree *mt = map->cache; + MA_STATE(mas, mt, min, max); + unsigned long *entry, *lower, *upper; +- unsigned long lower_index, lower_last; ++ /* initialized to work around false-positive -Wuninitialized warning */ ++ unsigned long lower_index = 0, lower_last = 0; + unsigned long upper_index, upper_last; + int ret = 0; + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index f4e0573c47114..bf7f68e90953b 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -2603,6 +2603,8 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub, + mutex_lock(&ub->mutex); + if (!ublk_can_use_recovery(ub)) + goto out_unlock; ++ if (!ub->nr_queues_ready) ++ goto out_unlock; + /* + * START_RECOVERY is only allowd after: + * +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index 814dd966b1a45..5ee9a8b8dcfdb 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -1326,8 +1326,10 @@ static int btnxpuart_close(struct hci_dev *hdev) + + serdev_device_close(nxpdev->serdev); + skb_queue_purge(&nxpdev->txq); +- kfree_skb(nxpdev->rx_skb); +- nxpdev->rx_skb = NULL; ++ if (!IS_ERR_OR_NULL(nxpdev->rx_skb)) { ++ kfree_skb(nxpdev->rx_skb); ++ nxpdev->rx_skb = NULL; ++ } + clear_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state); + return 0; + } +@@ -1342,8 +1344,10 @@ static int btnxpuart_flush(struct hci_dev *hdev) + + cancel_work_sync(&nxpdev->tx_work); + +- kfree_skb(nxpdev->rx_skb); +- nxpdev->rx_skb = NULL; ++ if (!IS_ERR_OR_NULL(nxpdev->rx_skb)) { ++ kfree_skb(nxpdev->rx_skb); ++ nxpdev->rx_skb = NULL; ++ } + + return 0; + } +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 9082456d80fbf..7a552387129ef 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -1090,6 +1090,7 @@ static void qca_controller_memdump(struct work_struct *work) + qca->memdump_state = QCA_MEMDUMP_COLLECTED; + cancel_delayed_work(&qca->ctrl_memdump_timeout); + clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); ++ clear_bit(QCA_IBS_DISABLED, &qca->flags); + mutex_unlock(&qca->hci_memdump_lock); + return; + } +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index 85aa089650eaa..1701cce74df79 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -40,7 +40,7 @@ + + #define PLL_USER_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL]) + # define PLL_POST_DIV_SHIFT 8 +-# define PLL_POST_DIV_MASK(p) GENMASK((p)->width, 0) ++# define PLL_POST_DIV_MASK(p) GENMASK((p)->width - 1, 0) + # define PLL_ALPHA_EN BIT(24) + # define PLL_ALPHA_MODE BIT(25) + # define PLL_VCO_SHIFT 20 +@@ -1478,8 +1478,8 @@ clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + } + + return regmap_update_bits(regmap, PLL_USER_CTL(pll), +- PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT, +- val << PLL_POST_DIV_SHIFT); ++ PLL_POST_DIV_MASK(pll) << pll->post_div_shift, ++ val << pll->post_div_shift); + } + + const struct clk_ops clk_alpha_pll_postdiv_trion_ops = { +diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h +index e6d84c8c7989c..84c497f361bc6 100644 +--- a/drivers/clk/qcom/clk-rcg.h ++++ b/drivers/clk/qcom/clk-rcg.h +@@ -176,6 +176,7 @@ extern const struct clk_ops clk_byte2_ops; + extern const struct clk_ops clk_pixel_ops; + extern const struct clk_ops clk_gfx3d_ops; + extern const struct clk_ops clk_rcg2_shared_ops; ++extern const struct clk_ops clk_rcg2_shared_no_init_park_ops; + extern const struct clk_ops clk_dp_ops; + + struct clk_rcg_dfs_data { +diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c +index b9f2a29be927c..461f54fe5e4f1 100644 +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -1182,6 +1182,36 @@ const struct clk_ops clk_rcg2_shared_ops = { + }; + EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + ++static int clk_rcg2_shared_no_init_park(struct clk_hw *hw) ++{ ++ struct clk_rcg2 *rcg = to_clk_rcg2(hw); ++ ++ /* ++ * Read the config register so that the parent is properly mapped at ++ * registration time. ++ */ ++ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &rcg->parked_cfg); ++ ++ return 0; ++} ++ ++/* ++ * Like clk_rcg2_shared_ops but skip the init so that the clk frequency is left ++ * unchanged at registration time. ++ */ ++const struct clk_ops clk_rcg2_shared_no_init_park_ops = { ++ .init = clk_rcg2_shared_no_init_park, ++ .enable = clk_rcg2_shared_enable, ++ .disable = clk_rcg2_shared_disable, ++ .get_parent = clk_rcg2_shared_get_parent, ++ .set_parent = clk_rcg2_shared_set_parent, ++ .recalc_rate = clk_rcg2_shared_recalc_rate, ++ .determine_rate = clk_rcg2_determine_rate, ++ .set_rate = clk_rcg2_shared_set_rate, ++ .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, ++}; ++EXPORT_SYMBOL_GPL(clk_rcg2_shared_no_init_park_ops); ++ + /* Common APIs to be used for DFS based RCGR */ + static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l, + struct freq_tbl *f) +diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c +index f8b9a1e93bef2..cdbbf2cc9c5d1 100644 +--- a/drivers/clk/qcom/gcc-ipq9574.c ++++ b/drivers/clk/qcom/gcc-ipq9574.c +@@ -65,7 +65,7 @@ static const struct clk_parent_data gcc_sleep_clk_data[] = { + + static struct clk_alpha_pll gpll0_main = { + .offset = 0x20000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(0), +@@ -93,7 +93,7 @@ static struct clk_fixed_factor gpll0_out_main_div2 = { + + static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x20000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0", +@@ -107,7 +107,7 @@ static struct clk_alpha_pll_postdiv gpll0 = { + + static struct clk_alpha_pll gpll4_main = { + .offset = 0x22000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(2), +@@ -122,7 +122,7 @@ static struct clk_alpha_pll gpll4_main = { + + static struct clk_alpha_pll_postdiv gpll4 = { + .offset = 0x22000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll4", +@@ -136,7 +136,7 @@ static struct clk_alpha_pll_postdiv gpll4 = { + + static struct clk_alpha_pll gpll2_main = { + .offset = 0x21000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(1), +@@ -151,7 +151,7 @@ static struct clk_alpha_pll gpll2_main = { + + static struct clk_alpha_pll_postdiv gpll2 = { + .offset = 0x21000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll2", +diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c +index b883dffe5f7aa..eb3765c57b650 100644 +--- a/drivers/clk/qcom/gcc-sm8550.c ++++ b/drivers/clk/qcom/gcc-sm8550.c +@@ -536,7 +536,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -551,7 +551,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -566,7 +566,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -581,7 +581,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -596,7 +596,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -611,7 +611,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s5_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -626,7 +626,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s6_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -641,7 +641,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s7_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -656,7 +656,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s8_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -671,7 +671,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s9_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -700,7 +700,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { +@@ -717,7 +717,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { +@@ -750,7 +750,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { +@@ -767,7 +767,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { +@@ -784,7 +784,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { +@@ -801,7 +801,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { +@@ -818,7 +818,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { +@@ -835,7 +835,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { +@@ -852,7 +852,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { +@@ -869,7 +869,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { +@@ -886,7 +886,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { +@@ -903,7 +903,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { +@@ -920,7 +920,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { +@@ -937,7 +937,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { +@@ -975,7 +975,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = { + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = { +@@ -992,7 +992,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { +@@ -1159,7 +1159,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_shared_no_init_park_ops, + }, + }; + +diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c +index 3884eff9fe931..58ef7c6d69cce 100644 +--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c ++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c +@@ -385,6 +385,32 @@ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv, + } + EXPORT_SYMBOL_GPL(jh7110_reset_controller_register); + ++/* ++ * This clock notifier is called when the rate of PLL0 clock is to be changed. ++ * The cpu_root clock should save the curent parent clock and switch its parent ++ * clock to osc before PLL0 rate will be changed. Then switch its parent clock ++ * back after the PLL0 rate is completed. ++ */ ++static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ struct jh71x0_clk_priv *priv = container_of(nb, struct jh71x0_clk_priv, pll_clk_nb); ++ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk; ++ int ret = 0; ++ ++ if (action == PRE_RATE_CHANGE) { ++ struct clk *osc = clk_get(priv->dev, "osc"); ++ ++ priv->original_clk = clk_get_parent(cpu_root); ++ ret = clk_set_parent(cpu_root, osc); ++ clk_put(osc); ++ } else if (action == POST_RATE_CHANGE) { ++ ret = clk_set_parent(cpu_root, priv->original_clk); ++ } ++ ++ return notifier_from_errno(ret); ++} ++ + static int __init jh7110_syscrg_probe(struct platform_device *pdev) + { + struct jh71x0_clk_priv *priv; +@@ -413,7 +439,10 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev) + if (IS_ERR(priv->pll[0])) + return PTR_ERR(priv->pll[0]); + } else { +- clk_put(pllclk); ++ priv->pll_clk_nb.notifier_call = jh7110_pll0_clk_notifier_cb; ++ ret = clk_notifier_register(pllclk, &priv->pll_clk_nb); ++ if (ret) ++ return ret; + priv->pll[0] = NULL; + } + +diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h +index 34bb11c72eb73..ebc55b9ef8370 100644 +--- a/drivers/clk/starfive/clk-starfive-jh71x0.h ++++ b/drivers/clk/starfive/clk-starfive-jh71x0.h +@@ -114,6 +114,8 @@ struct jh71x0_clk_priv { + spinlock_t rmw_lock; + struct device *dev; + void __iomem *base; ++ struct clk *original_clk; ++ struct notifier_block pll_clk_nb; + struct clk_hw *pll[3]; + struct jh71x0_clk reg[]; + }; +diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c +index bd64a8a8427f3..92c025b70eb62 100644 +--- a/drivers/clocksource/timer-imx-tpm.c ++++ b/drivers/clocksource/timer-imx-tpm.c +@@ -83,20 +83,28 @@ static u64 notrace tpm_read_sched_clock(void) + static int tpm_set_next_event(unsigned long delta, + struct clock_event_device *evt) + { +- unsigned long next, now; ++ unsigned long next, prev, now; + +- next = tpm_read_counter(); +- next += delta; ++ prev = tpm_read_counter(); ++ next = prev + delta; + writel(next, timer_base + TPM_C0V); + now = tpm_read_counter(); + ++ /* ++ * Need to wait CNT increase at least 1 cycle to make sure ++ * the C0V has been updated into HW. ++ */ ++ if ((next & 0xffffffff) != readl(timer_base + TPM_C0V)) ++ while (now == tpm_read_counter()) ++ ; ++ + /* + * NOTE: We observed in a very small probability, the bus fabric + * contention between GPU and A7 may results a few cycles delay + * of writing CNT registers which may cause the min_delta event got + * missed, so we need add a ETIME check here in case it happened. + */ +- return (int)(next - now) <= 0 ? -ETIME : 0; ++ return (now - prev) >= delta ? -ETIME : 0; + } + + static int tpm_set_state_oneshot(struct clock_event_device *evt) +diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c +index c3f54d9912be7..420202bf76e42 100644 +--- a/drivers/clocksource/timer-of.c ++++ b/drivers/clocksource/timer-of.c +@@ -25,10 +25,7 @@ static __init void timer_of_irq_exit(struct of_timer_irq *of_irq) + + struct clock_event_device *clkevt = &to->clkevt; + +- if (of_irq->percpu) +- free_percpu_irq(of_irq->irq, clkevt); +- else +- free_irq(of_irq->irq, clkevt); ++ free_irq(of_irq->irq, clkevt); + } + + /** +@@ -42,9 +39,6 @@ static __init void timer_of_irq_exit(struct of_timer_irq *of_irq) + * - Get interrupt number by name + * - Get interrupt number by index + * +- * When the interrupt is per CPU, 'request_percpu_irq()' is called, +- * otherwise 'request_irq()' is used. +- * + * Returns 0 on success, < 0 otherwise + */ + static __init int timer_of_irq_init(struct device_node *np, +@@ -69,12 +63,9 @@ static __init int timer_of_irq_init(struct device_node *np, + return -EINVAL; + } + +- ret = of_irq->percpu ? +- request_percpu_irq(of_irq->irq, of_irq->handler, +- np->full_name, clkevt) : +- request_irq(of_irq->irq, of_irq->handler, +- of_irq->flags ? of_irq->flags : IRQF_TIMER, +- np->full_name, clkevt); ++ ret = request_irq(of_irq->irq, of_irq->handler, ++ of_irq->flags ? of_irq->flags : IRQF_TIMER, ++ np->full_name, clkevt); + if (ret) { + pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np); + return ret; +diff --git a/drivers/clocksource/timer-of.h b/drivers/clocksource/timer-of.h +index a5478f3e8589d..01a2c6b7db065 100644 +--- a/drivers/clocksource/timer-of.h ++++ b/drivers/clocksource/timer-of.h +@@ -11,7 +11,6 @@ + struct of_timer_irq { + int irq; + int index; +- int percpu; + const char *name; + unsigned long flags; + irq_handler_t handler; +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index 23c74e9f04c48..f461f99eb040c 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -49,6 +50,8 @@ + + #define AMD_PSTATE_TRANSITION_LATENCY 20000 + #define AMD_PSTATE_TRANSITION_DELAY 1000 ++#define CPPC_HIGHEST_PERF_PERFORMANCE 196 ++#define CPPC_HIGHEST_PERF_DEFAULT 166 + + /* + * TODO: We need more time to fine tune processors with shared memory solution +@@ -64,6 +67,7 @@ static struct cpufreq_driver amd_pstate_driver; + static struct cpufreq_driver amd_pstate_epp_driver; + static int cppc_state = AMD_PSTATE_UNDEFINED; + static bool cppc_enabled; ++static bool amd_pstate_prefcore = true; + + /* + * AMD Energy Preference Performance (EPP) +@@ -310,6 +314,21 @@ static inline int amd_pstate_enable(bool enable) + return static_call(amd_pstate_enable)(enable); + } + ++static u32 amd_pstate_highest_perf_set(struct amd_cpudata *cpudata) ++{ ++ struct cpuinfo_x86 *c = &cpu_data(0); ++ ++ /* ++ * For AMD CPUs with Family ID 19H and Model ID range 0x70 to 0x7f, ++ * the highest performance level is set to 196. ++ * https://bugzilla.kernel.org/show_bug.cgi?id=218759 ++ */ ++ if (c->x86 == 0x19 && (c->x86_model >= 0x70 && c->x86_model <= 0x7f)) ++ return CPPC_HIGHEST_PERF_PERFORMANCE; ++ ++ return CPPC_HIGHEST_PERF_DEFAULT; ++} ++ + static int pstate_init_perf(struct amd_cpudata *cpudata) + { + u64 cap1; +@@ -320,13 +339,14 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) + if (ret) + return ret; + +- /* +- * TODO: Introduce AMD specific power feature. +- * +- * CPPC entry doesn't indicate the highest performance in some ASICs. ++ /* For platforms that do not support the preferred core feature, the ++ * highest_pef may be configured with 166 or 255, to avoid max frequency ++ * calculated wrongly. we take the AMD_CPPC_HIGHEST_PERF(cap1) value as ++ * the default max perf. + */ +- highest_perf = amd_get_highest_perf(); +- if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) ++ if (cpudata->hw_prefcore) ++ highest_perf = amd_pstate_highest_perf_set(cpudata); ++ else + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); + + WRITE_ONCE(cpudata->highest_perf, highest_perf); +@@ -347,8 +367,9 @@ static int cppc_init_perf(struct amd_cpudata *cpudata) + if (ret) + return ret; + +- highest_perf = amd_get_highest_perf(); +- if (highest_perf > cppc_perf.highest_perf) ++ if (cpudata->hw_prefcore) ++ highest_perf = amd_pstate_highest_perf_set(cpudata); ++ else + highest_perf = cppc_perf.highest_perf; + + WRITE_ONCE(cpudata->highest_perf, highest_perf); +@@ -709,6 +730,80 @@ static void amd_perf_ctl_reset(unsigned int cpu) + wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); + } + ++/* ++ * Set amd-pstate preferred core enable can't be done directly from cpufreq callbacks ++ * due to locking, so queue the work for later. ++ */ ++static void amd_pstste_sched_prefcore_workfn(struct work_struct *work) ++{ ++ sched_set_itmt_support(); ++} ++static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn); ++ ++/* ++ * Get the highest performance register value. ++ * @cpu: CPU from which to get highest performance. ++ * @highest_perf: Return address. ++ * ++ * Return: 0 for success, -EIO otherwise. ++ */ ++static int amd_pstate_get_highest_perf(int cpu, u32 *highest_perf) ++{ ++ int ret; ++ ++ if (boot_cpu_has(X86_FEATURE_CPPC)) { ++ u64 cap1; ++ ++ ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1); ++ if (ret) ++ return ret; ++ WRITE_ONCE(*highest_perf, AMD_CPPC_HIGHEST_PERF(cap1)); ++ } else { ++ u64 cppc_highest_perf; ++ ++ ret = cppc_get_highest_perf(cpu, &cppc_highest_perf); ++ if (ret) ++ return ret; ++ WRITE_ONCE(*highest_perf, cppc_highest_perf); ++ } ++ ++ return (ret); ++} ++ ++#define CPPC_MAX_PERF U8_MAX ++ ++static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata) ++{ ++ int ret, prio; ++ u32 highest_perf; ++ ++ ret = amd_pstate_get_highest_perf(cpudata->cpu, &highest_perf); ++ if (ret) ++ return; ++ ++ cpudata->hw_prefcore = true; ++ /* check if CPPC preferred core feature is enabled*/ ++ if (highest_perf < CPPC_MAX_PERF) ++ prio = (int)highest_perf; ++ else { ++ pr_debug("AMD CPPC preferred core is unsupported!\n"); ++ cpudata->hw_prefcore = false; ++ return; ++ } ++ ++ if (!amd_pstate_prefcore) ++ return; ++ ++ /* ++ * The priorities can be set regardless of whether or not ++ * sched_set_itmt_support(true) has been called and it is valid to ++ * update them at any time after it has been called. ++ */ ++ sched_set_itmt_core_prio(prio, cpudata->cpu); ++ ++ schedule_work(&sched_prefcore_work); ++} ++ + static int amd_pstate_cpu_init(struct cpufreq_policy *policy) + { + int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; +@@ -730,6 +825,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) + + cpudata->cpu = policy->cpu; + ++ amd_pstate_init_prefcore(cpudata); ++ + ret = amd_pstate_init_perf(cpudata); + if (ret) + goto free_cpudata1; +@@ -880,6 +977,17 @@ static ssize_t show_amd_pstate_highest_perf(struct cpufreq_policy *policy, + return sysfs_emit(buf, "%u\n", perf); + } + ++static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy, ++ char *buf) ++{ ++ bool hw_prefcore; ++ struct amd_cpudata *cpudata = policy->driver_data; ++ ++ hw_prefcore = READ_ONCE(cpudata->hw_prefcore); ++ ++ return sysfs_emit(buf, "%s\n", str_enabled_disabled(hw_prefcore)); ++} ++ + static ssize_t show_energy_performance_available_preferences( + struct cpufreq_policy *policy, char *buf) + { +@@ -1077,18 +1185,27 @@ static ssize_t status_store(struct device *a, struct device_attribute *b, + return ret < 0 ? ret : count; + } + ++static ssize_t prefcore_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore)); ++} ++ + cpufreq_freq_attr_ro(amd_pstate_max_freq); + cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); + + cpufreq_freq_attr_ro(amd_pstate_highest_perf); ++cpufreq_freq_attr_ro(amd_pstate_hw_prefcore); + cpufreq_freq_attr_rw(energy_performance_preference); + cpufreq_freq_attr_ro(energy_performance_available_preferences); + static DEVICE_ATTR_RW(status); ++static DEVICE_ATTR_RO(prefcore); + + static struct freq_attr *amd_pstate_attr[] = { + &amd_pstate_max_freq, + &amd_pstate_lowest_nonlinear_freq, + &amd_pstate_highest_perf, ++ &amd_pstate_hw_prefcore, + NULL, + }; + +@@ -1096,6 +1213,7 @@ static struct freq_attr *amd_pstate_epp_attr[] = { + &amd_pstate_max_freq, + &amd_pstate_lowest_nonlinear_freq, + &amd_pstate_highest_perf, ++ &amd_pstate_hw_prefcore, + &energy_performance_preference, + &energy_performance_available_preferences, + NULL, +@@ -1103,6 +1221,7 @@ static struct freq_attr *amd_pstate_epp_attr[] = { + + static struct attribute *pstate_global_attributes[] = { + &dev_attr_status.attr, ++ &dev_attr_prefcore.attr, + NULL + }; + +@@ -1154,6 +1273,8 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) + cpudata->cpu = policy->cpu; + cpudata->epp_policy = 0; + ++ amd_pstate_init_prefcore(cpudata); ++ + ret = amd_pstate_init_perf(cpudata); + if (ret) + goto free_cpudata1; +@@ -1577,7 +1698,17 @@ static int __init amd_pstate_param(char *str) + + return amd_pstate_set_driver(mode_idx); + } ++ ++static int __init amd_prefcore_param(char *str) ++{ ++ if (!strcmp(str, "disable")) ++ amd_pstate_prefcore = false; ++ ++ return 0; ++} ++ + early_param("amd_pstate", amd_pstate_param); ++early_param("amd_prefcore", amd_prefcore_param); + + MODULE_AUTHOR("Huang Rui "); + MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver"); +diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c +index 70ef119639381..43af81fcab868 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c +@@ -100,7 +100,9 @@ static u32 adf_gen2_disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr) + errmsk3 |= ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK); + ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3); + +- errmsk3 &= ADF_GEN2_ERR_MSK_VF2PF(sources | disabled); ++ /* Update only section of errmsk3 related to VF2PF */ ++ errmsk3 &= ~ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK); ++ errmsk3 |= ADF_GEN2_ERR_MSK_VF2PF(sources | disabled); + ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3); + + /* Return the sources of the (new) interrupt(s) */ +diff --git a/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +index 09551f9491265..0e40897cc983a 100644 +--- a/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c ++++ b/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +@@ -191,8 +191,12 @@ static u32 disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr) + ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3); + ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5); + +- errmsk3 &= ADF_DH895XCC_ERR_MSK_VF2PF_L(sources | disabled); +- errmsk5 &= ADF_DH895XCC_ERR_MSK_VF2PF_U(sources | disabled); ++ /* Update only section of errmsk3 and errmsk5 related to VF2PF */ ++ errmsk3 &= ~ADF_DH895XCC_ERR_MSK_VF2PF_L(ADF_DH895XCC_VF_MSK); ++ errmsk5 &= ~ADF_DH895XCC_ERR_MSK_VF2PF_U(ADF_DH895XCC_VF_MSK); ++ ++ errmsk3 |= ADF_DH895XCC_ERR_MSK_VF2PF_L(sources | disabled); ++ errmsk5 |= ADF_DH895XCC_ERR_MSK_VF2PF_U(sources | disabled); + ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3); + ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5); + +diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h +index fe011d50473d7..607f70292b215 100644 +--- a/drivers/crypto/starfive/jh7110-cryp.h ++++ b/drivers/crypto/starfive/jh7110-cryp.h +@@ -30,6 +30,7 @@ + #define MAX_KEY_SIZE SHA512_BLOCK_SIZE + #define STARFIVE_AES_IV_LEN AES_BLOCK_SIZE + #define STARFIVE_AES_CTR_LEN AES_BLOCK_SIZE ++#define STARFIVE_RSA_MAX_KEYSZ 256 + + union starfive_aes_csr { + u32 v; +@@ -212,12 +213,11 @@ struct starfive_cryp_request_ctx { + struct scatterlist *out_sg; + struct ahash_request ahash_fbk_req; + size_t total; +- size_t nents; + unsigned int blksize; + unsigned int digsize; + unsigned long in_sg_len; + unsigned char *adata; +- u8 rsa_data[] __aligned(sizeof(u32)); ++ u8 rsa_data[STARFIVE_RSA_MAX_KEYSZ] __aligned(sizeof(u32)); + }; + + struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); +diff --git a/drivers/crypto/starfive/jh7110-rsa.c b/drivers/crypto/starfive/jh7110-rsa.c +index f31bbd825f883..1db9a3d02848b 100644 +--- a/drivers/crypto/starfive/jh7110-rsa.c ++++ b/drivers/crypto/starfive/jh7110-rsa.c +@@ -37,7 +37,6 @@ + // A * A * R mod N ==> A + #define CRYPTO_CMD_AARN 0x7 + +-#define STARFIVE_RSA_MAX_KEYSZ 256 + #define STARFIVE_RSA_RESET 0x2 + + static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx) +@@ -91,7 +90,7 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx, + { + struct starfive_cryp_dev *cryp = ctx->cryp; + struct starfive_cryp_request_ctx *rctx = ctx->rctx; +- int count = rctx->total / sizeof(u32) - 1; ++ int count = (ALIGN(rctx->total, 4) / 4) - 1; + int loop; + u32 temp; + u8 opsize; +@@ -274,12 +273,17 @@ static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc) + struct starfive_cryp_dev *cryp = ctx->cryp; + struct starfive_cryp_request_ctx *rctx = ctx->rctx; + struct starfive_rsa_key *key = &ctx->rsa_key; +- int ret = 0; ++ int ret = 0, shift = 0; + + writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET); + +- rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents, +- rctx->rsa_data, rctx->total); ++ if (!IS_ALIGNED(rctx->total, sizeof(u32))) { ++ shift = sizeof(u32) - (rctx->total & 0x3); ++ memset(rctx->rsa_data, 0, shift); ++ } ++ ++ rctx->total = sg_copy_to_buffer(rctx->in_sg, sg_nents(rctx->in_sg), ++ rctx->rsa_data + shift, rctx->total); + + if (enc) { + key->bitlen = key->e_bitlen; +@@ -329,7 +333,6 @@ static int starfive_rsa_enc(struct akcipher_request *req) + rctx->in_sg = req->src; + rctx->out_sg = req->dst; + rctx->total = req->src_len; +- rctx->nents = sg_nents(rctx->in_sg); + ctx->rctx = rctx; + + return starfive_rsa_enc_core(ctx, 1); +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index bc5a43897d578..5060d9802795e 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1528,10 +1528,13 @@ static int cxl_region_attach_position(struct cxl_region *cxlr, + const struct cxl_dport *dport, int pos) + { + struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); ++ struct cxl_switch_decoder *cxlsd = &cxlrd->cxlsd; ++ struct cxl_decoder *cxld = &cxlsd->cxld; ++ int iw = cxld->interleave_ways; + struct cxl_port *iter; + int rc; + +- if (cxlrd->calc_hb(cxlrd, pos) != dport) { ++ if (dport != cxlrd->cxlsd.target[pos % iw]) { + dev_dbg(&cxlr->dev, "%s:%s invalid target position for %s\n", + dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), + dev_name(&cxlrd->cxlsd.cxld.dev)); +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index a1da7581adb03..e62ffffe5fb8d 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -796,6 +796,9 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, + + lockdep_assert_held(&ctl->dsp->pwr_lock); + ++ if (ctl->flags && !(ctl->flags & WMFW_CTL_FLAG_WRITEABLE)) ++ return -EPERM; ++ + if (len + off * sizeof(u32) > ctl->len) + return -EINVAL; + +diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c +index b35b9604413f0..caeb3bdc78f8d 100644 +--- a/drivers/gpio/gpio-rockchip.c ++++ b/drivers/gpio/gpio-rockchip.c +@@ -713,6 +713,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev) + return -ENODEV; + + pctldev = of_pinctrl_get(pctlnp); ++ of_node_put(pctlnp); + if (!pctldev) + return -EPROBE_DEFER; + +diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c +index a0d69387c1532..2f3c9ebfa78d1 100644 +--- a/drivers/gpio/gpio-zynqmp-modepin.c ++++ b/drivers/gpio/gpio-zynqmp-modepin.c +@@ -146,6 +146,7 @@ static const struct of_device_id modepin_platform_id[] = { + { .compatible = "xlnx,zynqmp-gpio-modepin", }, + { } + }; ++MODULE_DEVICE_TABLE(of, modepin_platform_id); + + static struct platform_driver modepin_platform_driver = { + .driver = { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index 61668a784315f..e361dc37a0890 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -1096,6 +1096,21 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p) + unsigned int i; + int r; + ++ /* ++ * We can't use gang submit on with reserved VMIDs when the VM changes ++ * can't be invalidated by more than one engine at the same time. ++ */ ++ if (p->gang_size > 1 && !p->adev->vm_manager.concurrent_flush) { ++ for (i = 0; i < p->gang_size; ++i) { ++ struct drm_sched_entity *entity = p->entities[i]; ++ struct drm_gpu_scheduler *sched = entity->rq->sched; ++ struct amdgpu_ring *ring = to_amdgpu_ring(sched); ++ ++ if (amdgpu_vmid_uses_reserved(vm, ring->vm_hub)) ++ return -EINVAL; ++ } ++ } ++ + r = amdgpu_vm_clear_freed(adev, vm, NULL); + if (r) + return r; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index 578aeba49ea8e..5fbb9caa7415f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -909,8 +909,7 @@ static int check_tiling_flags_gfx6(struct amdgpu_framebuffer *afb) + { + u64 micro_tile_mode; + +- /* Zero swizzle mode means linear */ +- if (AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE) == 0) ++ if (AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) == 1) /* LINEAR_ALIGNED */ + return 0; + + micro_tile_mode = AMDGPU_TILING_GET(afb->tiling_flags, MICRO_TILE_MODE); +@@ -1034,6 +1033,30 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) + block_width = 256 / format_info->cpp[i]; + block_height = 1; + block_size_log2 = 8; ++ } else if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12) { ++ int swizzle = AMD_FMT_MOD_GET(TILE, modifier); ++ ++ switch (swizzle) { ++ case AMD_FMT_MOD_TILE_GFX12_256B_2D: ++ block_size_log2 = 8; ++ break; ++ case AMD_FMT_MOD_TILE_GFX12_4K_2D: ++ block_size_log2 = 12; ++ break; ++ case AMD_FMT_MOD_TILE_GFX12_64K_2D: ++ block_size_log2 = 16; ++ break; ++ case AMD_FMT_MOD_TILE_GFX12_256K_2D: ++ block_size_log2 = 18; ++ break; ++ default: ++ drm_dbg_kms(rfb->base.dev, ++ "Gfx12 swizzle mode with unknown block size: %d\n", swizzle); ++ return -EINVAL; ++ } ++ ++ get_block_dimensions(block_size_log2, format_info->cpp[i], ++ &block_width, &block_height); + } else { + int swizzle = AMD_FMT_MOD_GET(TILE, modifier); + +@@ -1069,7 +1092,8 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) + return ret; + } + +- if (AMD_FMT_MOD_GET(DCC, modifier)) { ++ if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11 && ++ AMD_FMT_MOD_GET(DCC, modifier)) { + if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) { + block_size_log2 = get_dcc_block_size(modifier, false, false); + get_block_dimensions(block_size_log2 + 8, format_info->cpp[0], +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +index ff1ea99292fbf..69dfc699d78b0 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +@@ -409,7 +409,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring, + if (r || !idle) + goto error; + +- if (vm->reserved_vmid[vmhub] || (enforce_isolation && (vmhub == AMDGPU_GFXHUB(0)))) { ++ if (amdgpu_vmid_uses_reserved(vm, vmhub)) { + r = amdgpu_vmid_grab_reserved(vm, ring, job, &id, fence); + if (r || !id) + goto error; +@@ -459,6 +459,19 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring, + return r; + } + ++/* ++ * amdgpu_vmid_uses_reserved - check if a VM will use a reserved VMID ++ * @vm: the VM to check ++ * @vmhub: the VMHUB which will be used ++ * ++ * Returns: True if the VM will use a reserved VMID. ++ */ ++bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub) ++{ ++ return vm->reserved_vmid[vmhub] || ++ (enforce_isolation && (vmhub == AMDGPU_GFXHUB(0))); ++} ++ + int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, + unsigned vmhub) + { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h +index fa8c42c83d5d2..240fa67512602 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h +@@ -78,6 +78,7 @@ void amdgpu_pasid_free_delayed(struct dma_resv *resv, + + bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev, + struct amdgpu_vmid *id); ++bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub); + int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, + unsigned vmhub); + void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index d9dc675b46aed..22575422ca7ec 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -137,8 +137,10 @@ int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init) + + if (virt->ops && virt->ops->req_full_gpu) { + r = virt->ops->req_full_gpu(adev, init); +- if (r) ++ if (r) { ++ adev->no_hw_access = true; + return r; ++ } + + adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +index c81e98f0d17ff..c813cd7b015e1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -4269,11 +4269,11 @@ static int gfx_v11_0_hw_init(void *handle) + /* RLC autoload sequence 1: Program rlc ram */ + if (adev->gfx.imu.funcs->program_rlc_ram) + adev->gfx.imu.funcs->program_rlc_ram(adev); ++ /* rlc autoload firmware */ ++ r = gfx_v11_0_rlc_backdoor_autoload_enable(adev); ++ if (r) ++ return r; + } +- /* rlc autoload firmware */ +- r = gfx_v11_0_rlc_backdoor_autoload_enable(adev); +- if (r) +- return r; + } else { + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { + if (adev->gfx.imu.funcs && (amdgpu_dpm > 0)) { +diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +index f432dc72df6a9..725b1a585088d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +@@ -135,6 +135,34 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev, + + tmp = RREG32(ih_regs->ih_rb_cntl); + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0)); ++ ++ if (enable) { ++ /* Unset the CLEAR_OVERFLOW bit to make sure the next step ++ * is switching the bit from 0 to 1 ++ */ ++ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); ++ if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) { ++ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) ++ return -ETIMEDOUT; ++ } else { ++ WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); ++ } ++ ++ /* Clear RB_OVERFLOW bit */ ++ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); ++ if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) { ++ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) ++ return -ETIMEDOUT; ++ } else { ++ WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); ++ } ++ ++ /* Unset the CLEAR_OVERFLOW bit immediately so new overflows ++ * can be detected. ++ */ ++ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); ++ } ++ + /* enable_intr field is only valid in ring0 */ + if (ih == &adev->irq.ih) + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0)); +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 44c1556838240..f0ebf686b06f2 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -6937,7 +6937,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, + } + } + +- if (j == dc_state->stream_count) ++ if (j == dc_state->stream_count || pbn_div == 0) + continue; + + slot_num = DIV_ROUND_UP(pbn, pbn_div); +diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c +index 2c366866f5700..33bb96f770b86 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c ++++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c +@@ -629,14 +629,14 @@ static bool construct_phy(struct dc_link *link, + link->link_enc = + link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data); + +- DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); +- DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); +- + if (!link->link_enc) { + DC_ERROR("Failed to create link encoder!\n"); + goto link_enc_create_fail; + } + ++ DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); ++ DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); ++ + /* Update link encoder tracking variables. These are used for the dynamic + * assignment of link encoders to streams. + */ +diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +index 1ddb4f5eac8e5..93c0455766ddb 100644 +--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c ++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +@@ -433,17 +433,20 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp, + } + + if (status == MOD_HDCP_STATUS_SUCCESS) +- mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, ++ if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, + &input->bstatus_read, &status, +- hdcp, "bstatus_read"); ++ hdcp, "bstatus_read")) ++ goto out; + if (status == MOD_HDCP_STATUS_SUCCESS) +- mod_hdcp_execute_and_set(check_link_integrity_dp, ++ if (!mod_hdcp_execute_and_set(check_link_integrity_dp, + &input->link_integrity_check, &status, +- hdcp, "link_integrity_check"); ++ hdcp, "link_integrity_check")) ++ goto out; + if (status == MOD_HDCP_STATUS_SUCCESS) +- mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, ++ if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, + &input->reauth_request_check, &status, +- hdcp, "reauth_request_check"); ++ hdcp, "reauth_request_check")) ++ goto out; + out: + return status; + } +diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +index c9a9c758531bc..c0d7fe5102e6d 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -1883,7 +1883,8 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, + smu_dpm_ctx->dpm_level = level; + } + +- if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { ++ if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && ++ smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { + index = fls(smu->workload_mask); + index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; + workload[0] = smu->workload_setting[index]; +@@ -1962,7 +1963,8 @@ static int smu_switch_power_profile(void *handle, + workload[0] = smu->workload_setting[index]; + } + +- if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) ++ if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && ++ smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) + smu_bump_power_profile_mode(smu, workload, 0); + + return 0; +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c +index 0d3b22a743659..e251e061d1adb 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c +@@ -304,7 +304,7 @@ void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc) + { + struct intel_gt *gt = gsc_uc_to_gt(gsc); + +- if (!intel_uc_fw_is_loadable(&gsc->fw)) ++ if (!intel_uc_fw_is_loadable(&gsc->fw) || intel_uc_fw_is_in_error(&gsc->fw)) + return; + + if (intel_gsc_uc_fw_init_done(gsc)) +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h +index 9a431726c8d5b..ac7b3aad2222e 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h +@@ -258,6 +258,11 @@ static inline bool intel_uc_fw_is_running(struct intel_uc_fw *uc_fw) + return __intel_uc_fw_status(uc_fw) == INTEL_UC_FIRMWARE_RUNNING; + } + ++static inline bool intel_uc_fw_is_in_error(struct intel_uc_fw *uc_fw) ++{ ++ return intel_uc_fw_status_to_error(__intel_uc_fw_status(uc_fw)) != 0; ++} ++ + static inline bool intel_uc_fw_is_overridden(const struct intel_uc_fw *uc_fw) + { + return uc_fw->user_overridden; +diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c +index 8a9aad523eec2..1d4cc91c0e40d 100644 +--- a/drivers/gpu/drm/i915/i915_sw_fence.c ++++ b/drivers/gpu/drm/i915/i915_sw_fence.c +@@ -51,7 +51,7 @@ static inline void debug_fence_init(struct i915_sw_fence *fence) + debug_object_init(fence, &i915_sw_fence_debug_descr); + } + +-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence) + { + debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr); + } +@@ -77,7 +77,7 @@ static inline void debug_fence_destroy(struct i915_sw_fence *fence) + debug_object_destroy(fence, &i915_sw_fence_debug_descr); + } + +-static inline void debug_fence_free(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence) + { + debug_object_free(fence, &i915_sw_fence_debug_descr); + smp_wmb(); /* flush the change in state before reallocation */ +@@ -94,7 +94,7 @@ static inline void debug_fence_init(struct i915_sw_fence *fence) + { + } + +-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence) + { + } + +@@ -115,7 +115,7 @@ static inline void debug_fence_destroy(struct i915_sw_fence *fence) + { + } + +-static inline void debug_fence_free(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence) + { + } + +diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +index 705b523370684..81f3024b7b1b5 100644 +--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c ++++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +@@ -171,11 +171,13 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data) + void amdtp_hid_remove(struct amdtp_cl_data *cli_data) + { + int i; ++ struct amdtp_hid_data *hid_data; + + for (i = 0; i < cli_data->num_hid_devices; ++i) { + if (cli_data->hid_sensor_hubs[i]) { +- kfree(cli_data->hid_sensor_hubs[i]->driver_data); ++ hid_data = cli_data->hid_sensor_hubs[i]->driver_data; + hid_destroy_device(cli_data->hid_sensor_hubs[i]); ++ kfree(hid_data); + cli_data->hid_sensor_hubs[i] = NULL; + } + } +diff --git a/drivers/hid/hid-cougar.c b/drivers/hid/hid-cougar.c +index cb8bd8aae15b5..0fa785f52707a 100644 +--- a/drivers/hid/hid-cougar.c ++++ b/drivers/hid/hid-cougar.c +@@ -106,7 +106,7 @@ static void cougar_fix_g6_mapping(void) + static __u8 *cougar_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) + { +- if (rdesc[2] == 0x09 && rdesc[3] == 0x02 && ++ if (*rsize >= 117 && rdesc[2] == 0x09 && rdesc[3] == 0x02 && + (rdesc[115] | rdesc[116] << 8) >= HID_MAX_USAGES) { + hid_info(hdev, + "usage count exceeds max: fixing up report descriptor\n"); +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index edbb38f6956b9..756aebf324735 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -1962,6 +1962,7 @@ void vmbus_device_unregister(struct hv_device *device_obj) + */ + device_unregister(&device_obj->device); + } ++EXPORT_SYMBOL_GPL(vmbus_device_unregister); + + #ifdef CONFIG_ACPI + /* +diff --git a/drivers/hwmon/adc128d818.c b/drivers/hwmon/adc128d818.c +index 46e3c8c507657..73fd967998472 100644 +--- a/drivers/hwmon/adc128d818.c ++++ b/drivers/hwmon/adc128d818.c +@@ -176,7 +176,7 @@ static ssize_t adc128_in_store(struct device *dev, + + mutex_lock(&data->update_lock); + /* 10 mV LSB on limit registers */ +- regval = clamp_val(DIV_ROUND_CLOSEST(val, 10), 0, 255); ++ regval = DIV_ROUND_CLOSEST(clamp_val(val, 0, 2550), 10); + data->in[index][nr] = regval << 4; + reg = index == 1 ? ADC128_REG_IN_MIN(nr) : ADC128_REG_IN_MAX(nr); + i2c_smbus_write_byte_data(data->client, reg, regval); +@@ -214,7 +214,7 @@ static ssize_t adc128_temp_store(struct device *dev, + return err; + + mutex_lock(&data->update_lock); +- regval = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); ++ regval = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); + data->temp[index] = regval << 1; + i2c_smbus_write_byte_data(data->client, + index == 1 ? ADC128_REG_TEMP_MAX +diff --git a/drivers/hwmon/hp-wmi-sensors.c b/drivers/hwmon/hp-wmi-sensors.c +index b5325d0e72b9c..dfa1d6926deac 100644 +--- a/drivers/hwmon/hp-wmi-sensors.c ++++ b/drivers/hwmon/hp-wmi-sensors.c +@@ -1637,6 +1637,8 @@ static void hp_wmi_notify(u32 value, void *context) + goto out_unlock; + + wobj = out.pointer; ++ if (!wobj) ++ goto out_unlock; + + err = populate_event_from_wobj(dev, &event, wobj); + if (err) { +diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c +index 67b9d7636ee42..37e8e9679aeb6 100644 +--- a/drivers/hwmon/lm95234.c ++++ b/drivers/hwmon/lm95234.c +@@ -301,7 +301,8 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr, + if (ret < 0) + return ret; + +- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, index ? 255 : 127); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, (index ? 255 : 127) * 1000), ++ 1000); + + mutex_lock(&data->update_lock); + data->tcrit2[index] = val; +@@ -350,7 +351,7 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr, + if (ret < 0) + return ret; + +- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000); + + mutex_lock(&data->update_lock); + data->tcrit1[index] = val; +@@ -391,7 +392,7 @@ static ssize_t tcrit1_hyst_store(struct device *dev, + if (ret < 0) + return ret; + +- val = DIV_ROUND_CLOSEST(val, 1000); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, -255000, 255000), 1000); + val = clamp_val((int)data->tcrit1[index] - val, 0, 31); + + mutex_lock(&data->update_lock); +@@ -431,7 +432,7 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr, + return ret; + + /* Accuracy is 1/2 degrees C */ +- val = clamp_val(DIV_ROUND_CLOSEST(val, 500), -128, 127); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, -64000, 63500), 500); + + mutex_lock(&data->update_lock); + data->toffset[index] = val; +diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c +index f3bf2e4701c38..8da7aa1614d7d 100644 +--- a/drivers/hwmon/nct6775-core.c ++++ b/drivers/hwmon/nct6775-core.c +@@ -2262,7 +2262,7 @@ store_temp_offset(struct device *dev, struct device_attribute *attr, + if (err < 0) + return err; + +- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); + + mutex_lock(&data->update_lock); + data->temp_offset[nr] = val; +diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c +index fe960c0a624f7..7d7d70afde655 100644 +--- a/drivers/hwmon/w83627ehf.c ++++ b/drivers/hwmon/w83627ehf.c +@@ -895,7 +895,7 @@ store_target_temp(struct device *dev, struct device_attribute *attr, + if (err < 0) + return err; + +- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 127); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 127000), 1000); + + mutex_lock(&data->update_lock); + data->target_temp[nr] = val; +@@ -920,7 +920,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr, + return err; + + /* Limit the temp to 0C - 15C */ +- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 15); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 15000), 1000); + + mutex_lock(&data->update_lock); + reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]); +diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c +index 337c95d43f3f6..edc3a69bfe31f 100644 +--- a/drivers/i3c/master/mipi-i3c-hci/dma.c ++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c +@@ -291,7 +291,10 @@ static int hci_dma_init(struct i3c_hci *hci) + + rh->ibi_chunk_sz = dma_get_cache_alignment(); + rh->ibi_chunk_sz *= IBI_CHUNK_CACHELINES; +- BUG_ON(rh->ibi_chunk_sz > 256); ++ if (rh->ibi_chunk_sz > 256) { ++ ret = -EINVAL; ++ goto err_out; ++ } + + ibi_status_ring_sz = rh->ibi_status_sz * rh->ibi_status_entries; + ibi_data_ring_sz = rh->ibi_chunk_sz * rh->ibi_chunks_total; +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index ccd0c4680be29..acc937275c184 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -1037,29 +1037,59 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, + u8 *in, const u8 *out, unsigned int xfer_len, + unsigned int *actual_len, bool continued) + { ++ int retry = 2; + u32 reg; + int ret; + + /* clean SVC_I3C_MINT_IBIWON w1c bits */ + writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS); + +- writel(SVC_I3C_MCTRL_REQUEST_START_ADDR | +- xfer_type | +- SVC_I3C_MCTRL_IBIRESP_NACK | +- SVC_I3C_MCTRL_DIR(rnw) | +- SVC_I3C_MCTRL_ADDR(addr) | +- SVC_I3C_MCTRL_RDTERM(*actual_len), +- master->regs + SVC_I3C_MCTRL); + +- ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, ++ while (retry--) { ++ writel(SVC_I3C_MCTRL_REQUEST_START_ADDR | ++ xfer_type | ++ SVC_I3C_MCTRL_IBIRESP_NACK | ++ SVC_I3C_MCTRL_DIR(rnw) | ++ SVC_I3C_MCTRL_ADDR(addr) | ++ SVC_I3C_MCTRL_RDTERM(*actual_len), ++ master->regs + SVC_I3C_MCTRL); ++ ++ ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, + SVC_I3C_MSTATUS_MCTRLDONE(reg), 0, 1000); +- if (ret) +- goto emit_stop; ++ if (ret) ++ goto emit_stop; + +- if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) { +- ret = -ENXIO; +- *actual_len = 0; +- goto emit_stop; ++ if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) { ++ /* ++ * According to I3C Spec 1.1.1, 11-Jun-2021, section: 5.1.2.2.3. ++ * If the Controller chooses to start an I3C Message with an I3C Dynamic ++ * Address, then special provisions shall be made because that same I3C ++ * Target may be initiating an IBI or a Controller Role Request. So, one of ++ * three things may happen: (skip 1, 2) ++ * ++ * 3. The Addresses match and the RnW bits also match, and so neither ++ * Controller nor Target will ACK since both are expecting the other side to ++ * provide ACK. As a result, each side might think it had "won" arbitration, ++ * but neither side would continue, as each would subsequently see that the ++ * other did not provide ACK. ++ * ... ++ * For either value of RnW: Due to the NACK, the Controller shall defer the ++ * Private Write or Private Read, and should typically transmit the Target ++ * Address again after a Repeated START (i.e., the next one or any one prior ++ * to a STOP in the Frame). Since the Address Header following a Repeated ++ * START is not arbitrated, the Controller will always win (see Section ++ * 5.1.2.2.4). ++ */ ++ if (retry && addr != 0x7e) { ++ writel(SVC_I3C_MERRWARN_NACK, master->regs + SVC_I3C_MERRWARN); ++ } else { ++ ret = -ENXIO; ++ *actual_len = 0; ++ goto emit_stop; ++ } ++ } else { ++ break; ++ } + } + + /* +diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c +index b9b206fcd748f..2976c62b58c07 100644 +--- a/drivers/iio/adc/ad7124.c ++++ b/drivers/iio/adc/ad7124.c +@@ -146,15 +146,18 @@ struct ad7124_chip_info { + struct ad7124_channel_config { + bool live; + unsigned int cfg_slot; +- enum ad7124_ref_sel refsel; +- bool bipolar; +- bool buf_positive; +- bool buf_negative; +- unsigned int vref_mv; +- unsigned int pga_bits; +- unsigned int odr; +- unsigned int odr_sel_bits; +- unsigned int filter_type; ++ /* Following fields are used to compare equality. */ ++ struct_group(config_props, ++ enum ad7124_ref_sel refsel; ++ bool bipolar; ++ bool buf_positive; ++ bool buf_negative; ++ unsigned int vref_mv; ++ unsigned int pga_bits; ++ unsigned int odr; ++ unsigned int odr_sel_bits; ++ unsigned int filter_type; ++ ); + }; + + struct ad7124_channel { +@@ -333,11 +336,12 @@ static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_ + ptrdiff_t cmp_size; + int i; + +- cmp_size = (u8 *)&cfg->live - (u8 *)cfg; ++ cmp_size = sizeof_field(struct ad7124_channel_config, config_props); + for (i = 0; i < st->num_channels; i++) { + cfg_aux = &st->channels[i].cfg; + +- if (cfg_aux->live && !memcmp(cfg, cfg_aux, cmp_size)) ++ if (cfg_aux->live && ++ !memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size)) + return cfg_aux; + } + +@@ -761,6 +765,7 @@ static int ad7124_soft_reset(struct ad7124_state *st) + if (ret < 0) + return ret; + ++ fsleep(200); + timeout = 100; + do { + ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval); +diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c +index 1928d9ae5bcff..1c08c0921ee71 100644 +--- a/drivers/iio/adc/ad7606.c ++++ b/drivers/iio/adc/ad7606.c +@@ -49,7 +49,7 @@ static const unsigned int ad7616_oversampling_avail[8] = { + 1, 2, 4, 8, 16, 32, 64, 128, + }; + +-static int ad7606_reset(struct ad7606_state *st) ++int ad7606_reset(struct ad7606_state *st) + { + if (st->gpio_reset) { + gpiod_set_value(st->gpio_reset, 1); +@@ -60,6 +60,7 @@ static int ad7606_reset(struct ad7606_state *st) + + return -ENODEV; + } ++EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606); + + static int ad7606_reg_access(struct iio_dev *indio_dev, + unsigned int reg, +@@ -88,31 +89,6 @@ static int ad7606_read_samples(struct ad7606_state *st) + { + unsigned int num = st->chip_info->num_channels - 1; + u16 *data = st->data; +- int ret; +- +- /* +- * The frstdata signal is set to high while and after reading the sample +- * of the first channel and low for all other channels. This can be used +- * to check that the incoming data is correctly aligned. During normal +- * operation the data should never become unaligned, but some glitch or +- * electrostatic discharge might cause an extra read or clock cycle. +- * Monitoring the frstdata signal allows to recover from such failure +- * situations. +- */ +- +- if (st->gpio_frstdata) { +- ret = st->bops->read_block(st->dev, 1, data); +- if (ret) +- return ret; +- +- if (!gpiod_get_value(st->gpio_frstdata)) { +- ad7606_reset(st); +- return -EIO; +- } +- +- data++; +- num--; +- } + + return st->bops->read_block(st->dev, num, data); + } +diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h +index 0c6a88cc46958..6649e84d25de6 100644 +--- a/drivers/iio/adc/ad7606.h ++++ b/drivers/iio/adc/ad7606.h +@@ -151,6 +151,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, + const char *name, unsigned int id, + const struct ad7606_bus_ops *bops); + ++int ad7606_reset(struct ad7606_state *st); ++ + enum ad7606_supported_device_ids { + ID_AD7605_4, + ID_AD7606_8, +diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c +index d8408052262e4..6bc587b20f05d 100644 +--- a/drivers/iio/adc/ad7606_par.c ++++ b/drivers/iio/adc/ad7606_par.c +@@ -7,6 +7,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -21,8 +22,29 @@ static int ad7606_par16_read_block(struct device *dev, + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7606_state *st = iio_priv(indio_dev); + +- insw((unsigned long)st->base_address, buf, count); + ++ /* ++ * On the parallel interface, the frstdata signal is set to high while ++ * and after reading the sample of the first channel and low for all ++ * other channels. This can be used to check that the incoming data is ++ * correctly aligned. During normal operation the data should never ++ * become unaligned, but some glitch or electrostatic discharge might ++ * cause an extra read or clock cycle. Monitoring the frstdata signal ++ * allows to recover from such failure situations. ++ */ ++ int num = count; ++ u16 *_buf = buf; ++ ++ if (st->gpio_frstdata) { ++ insw((unsigned long)st->base_address, _buf, 1); ++ if (!gpiod_get_value(st->gpio_frstdata)) { ++ ad7606_reset(st); ++ return -EIO; ++ } ++ _buf++; ++ num--; ++ } ++ insw((unsigned long)st->base_address, _buf, num); + return 0; + } + +@@ -35,8 +57,28 @@ static int ad7606_par8_read_block(struct device *dev, + { + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7606_state *st = iio_priv(indio_dev); +- +- insb((unsigned long)st->base_address, buf, count * 2); ++ /* ++ * On the parallel interface, the frstdata signal is set to high while ++ * and after reading the sample of the first channel and low for all ++ * other channels. This can be used to check that the incoming data is ++ * correctly aligned. During normal operation the data should never ++ * become unaligned, but some glitch or electrostatic discharge might ++ * cause an extra read or clock cycle. Monitoring the frstdata signal ++ * allows to recover from such failure situations. ++ */ ++ int num = count; ++ u16 *_buf = buf; ++ ++ if (st->gpio_frstdata) { ++ insb((unsigned long)st->base_address, _buf, 2); ++ if (!gpiod_get_value(st->gpio_frstdata)) { ++ ad7606_reset(st); ++ return -EIO; ++ } ++ _buf++; ++ num--; ++ } ++ insb((unsigned long)st->base_address, _buf, num * 2); + + return 0; + } +diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c +index 0d53c0a07b0d6..db5dbd60cf675 100644 +--- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c ++++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c +@@ -180,7 +180,7 @@ struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, + + ret = dma_get_slave_caps(chan, &caps); + if (ret < 0) +- goto err_free; ++ goto err_release; + + /* Needs to be aligned to the maximum of the minimums */ + if (caps.src_addr_widths) +@@ -206,6 +206,8 @@ struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, + + return &dmaengine_buffer->queue.buffer; + ++err_release: ++ dma_release_channel(chan); + err_free: + kfree(dmaengine_buffer); + return ERR_PTR(ret); +diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c +index b855565384757..80e1c45485c9b 100644 +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -680,17 +680,17 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, + break; + case IIO_VAL_INT_PLUS_MICRO: + if (scale_val2 < 0) +- *processed = -raw64 * scale_val; ++ *processed = -raw64 * scale_val * scale; + else +- *processed = raw64 * scale_val; ++ *processed = raw64 * scale_val * scale; + *processed += div_s64(raw64 * (s64)scale_val2 * scale, + 1000000LL); + break; + case IIO_VAL_INT_PLUS_NANO: + if (scale_val2 < 0) +- *processed = -raw64 * scale_val; ++ *processed = -raw64 * scale_val * scale; + else +- *processed = raw64 * scale_val; ++ *processed = raw64 * scale_val * scale; + *processed += div_s64(raw64 * (s64)scale_val2 * scale, + 1000000000LL); + break; +diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c +index d98212d55108c..2c973f15cab7d 100644 +--- a/drivers/input/misc/uinput.c ++++ b/drivers/input/misc/uinput.c +@@ -417,6 +417,20 @@ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code, + return -EINVAL; + } + ++ /* ++ * Limit number of contacts to a reasonable value (100). This ++ * ensures that we need less than 2 pages for struct input_mt ++ * (we are not using in-kernel slot assignment so not going to ++ * allocate memory for the "red" table), and we should have no ++ * trouble getting this much memory. ++ */ ++ if (code == ABS_MT_SLOT && max > 99) { ++ printk(KERN_DEBUG ++ "%s: unreasonably large number of slots requested: %d\n", ++ UINPUT_NAME, max); ++ return -EINVAL; ++ } ++ + return 0; + } + +diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c +index ae7ba0c419f5a..6a77babcf7228 100644 +--- a/drivers/input/touchscreen/ili210x.c ++++ b/drivers/input/touchscreen/ili210x.c +@@ -597,7 +597,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, + * once, copy them all into this buffer at the right locations, and then + * do all operations on this linear buffer. + */ +- fw_buf = kzalloc(SZ_64K, GFP_KERNEL); ++ fw_buf = kvmalloc(SZ_64K, GFP_KERNEL); + if (!fw_buf) + return -ENOMEM; + +@@ -627,7 +627,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, + return 0; + + err_big: +- kfree(fw_buf); ++ kvfree(fw_buf); + return error; + } + +@@ -870,7 +870,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, + ili210x_hardware_reset(priv->reset_gpio); + dev_dbg(dev, "Firmware update ended, error=%i\n", error); + enable_irq(client->irq); +- kfree(fwbuf); ++ kvfree(fwbuf); + return error; + } + +diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c +index 23cb80d62a9ab..84f0459e503cf 100644 +--- a/drivers/iommu/intel/dmar.c ++++ b/drivers/iommu/intel/dmar.c +@@ -1422,7 +1422,7 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc, + */ + writel(qi->free_head << shift, iommu->reg + DMAR_IQT_REG); + +- while (qi->desc_status[wait_index] != QI_DONE) { ++ while (READ_ONCE(qi->desc_status[wait_index]) != QI_DONE) { + /* + * We will leave the interrupts disabled, to prevent interrupt + * context to queue another cmd while a cmd is already submitted +diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c +index 74c5cb93e9002..94bd7f25f6f26 100644 +--- a/drivers/iommu/sun50i-iommu.c ++++ b/drivers/iommu/sun50i-iommu.c +@@ -449,6 +449,7 @@ static int sun50i_iommu_enable(struct sun50i_iommu *iommu) + IOMMU_TLB_PREFETCH_MASTER_ENABLE(3) | + IOMMU_TLB_PREFETCH_MASTER_ENABLE(4) | + IOMMU_TLB_PREFETCH_MASTER_ENABLE(5)); ++ iommu_write(iommu, IOMMU_BYPASS_REG, 0); + iommu_write(iommu, IOMMU_INT_ENABLE_REG, IOMMU_INT_MASK); + iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_NONE), + IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) | +diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c +index a55528469278c..91a42e2d7a131 100644 +--- a/drivers/irqchip/irq-armada-370-xp.c ++++ b/drivers/irqchip/irq-armada-370-xp.c +@@ -566,6 +566,10 @@ static struct irq_chip armada_370_xp_irq_chip = { + static int armada_370_xp_mpic_irq_map(struct irq_domain *h, + unsigned int virq, irq_hw_number_t hw) + { ++ /* IRQs 0 and 1 cannot be mapped, they are handled internally */ ++ if (hw <= 1) ++ return -EINVAL; ++ + armada_370_xp_irq_mask(irq_get_irq_data(virq)); + if (!is_percpu_irq(hw)) + writel(hw, per_cpu_int_base + +diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c +index f2ff4387870d6..d83c2c85962c3 100644 +--- a/drivers/irqchip/irq-gic-v2m.c ++++ b/drivers/irqchip/irq-gic-v2m.c +@@ -438,12 +438,12 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle, + + ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, + &res, 0); +- if (ret) { +- of_node_put(child); ++ if (ret) + break; +- } + } + ++ if (ret && child) ++ of_node_put(child); + if (!ret) + ret = gicv2m_allocate_domains(parent); + if (ret) +diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c +index 9d91f21842f2b..afe9bff7c7c16 100644 +--- a/drivers/leds/leds-spi-byte.c ++++ b/drivers/leds/leds-spi-byte.c +@@ -91,7 +91,6 @@ static int spi_byte_probe(struct spi_device *spi) + dev_err(dev, "Device must have exactly one LED sub-node."); + return -EINVAL; + } +- child = of_get_next_available_child(dev_of_node(dev), NULL); + + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); + if (!led) +@@ -107,11 +106,13 @@ static int spi_byte_probe(struct spi_device *spi) + led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value; + led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking; + ++ child = of_get_next_available_child(dev_of_node(dev), NULL); + state = of_get_property(child, "default-state", NULL); + if (state) { + if (!strcmp(state, "on")) { + led->ldev.brightness = led->ldev.max_brightness; + } else if (strcmp(state, "off")) { ++ of_node_put(child); + /* all other cases except "off" */ + dev_err(dev, "default-state can only be 'on' or 'off'"); + return -EINVAL; +@@ -122,9 +123,12 @@ static int spi_byte_probe(struct spi_device *spi) + + ret = devm_led_classdev_register(&spi->dev, &led->ldev); + if (ret) { ++ of_node_put(child); + mutex_destroy(&led->mutex); + return ret; + } ++ ++ of_node_put(child); + spi_set_drvdata(spi, led); + + return 0; +diff --git a/drivers/md/dm-init.c b/drivers/md/dm-init.c +index 2a71bcdba92d1..b37bbe7625003 100644 +--- a/drivers/md/dm-init.c ++++ b/drivers/md/dm-init.c +@@ -212,8 +212,10 @@ static char __init *dm_parse_device_entry(struct dm_device *dev, char *str) + strscpy(dev->dmi.uuid, field[1], sizeof(dev->dmi.uuid)); + /* minor */ + if (strlen(field[2])) { +- if (kstrtoull(field[2], 0, &dev->dmi.dev)) ++ if (kstrtoull(field[2], 0, &dev->dmi.dev) || ++ dev->dmi.dev >= (1 << MINORBITS)) + return ERR_PTR(-EINVAL); ++ dev->dmi.dev = huge_encode_dev((dev_t)dev->dmi.dev); + dev->dmi.flags |= DM_PERSISTENT_DEV_FLAG; + } + /* flags */ +diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c +index c6df862c79e39..8fa6750b5b421 100644 +--- a/drivers/media/platform/qcom/camss/camss.c ++++ b/drivers/media/platform/qcom/camss/camss.c +@@ -1038,8 +1038,11 @@ static int camss_of_parse_endpoint_node(struct device *dev, + struct v4l2_mbus_config_mipi_csi2 *mipi_csi2; + struct v4l2_fwnode_endpoint vep = { { 0 } }; + unsigned int i; ++ int ret; + +- v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); ++ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); ++ if (ret) ++ return ret; + + csd->interface.csiphy_id = vep.base.port; + +diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c +index 3a06df35a2d7c..99325bfed6431 100644 +--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c ++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c +@@ -106,8 +106,9 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, + if (*nplanes != buffers) + return -EINVAL; + for (p = 0; p < buffers; p++) { +- if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h + +- dev->fmt_cap->data_offset[p]) ++ if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h / ++ dev->fmt_cap->vdownsampling[p] + ++ dev->fmt_cap->data_offset[p]) + return -EINVAL; + } + } else { +@@ -1556,8 +1557,10 @@ int vidioc_s_edid(struct file *file, void *_fh, + return -EINVAL; + if (edid->blocks == 0) { + dev->edid_blocks = 0; +- v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); +- v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); ++ if (dev->num_outputs) { ++ v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); ++ v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); ++ } + phys_addr = CEC_PHYS_ADDR_INVALID; + goto set_phys_addr; + } +@@ -1581,8 +1584,10 @@ int vidioc_s_edid(struct file *file, void *_fh, + display_present |= + dev->display_present[i] << j++; + +- v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); +- v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); ++ if (dev->num_outputs) { ++ v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); ++ v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); ++ } + + set_phys_addr: + /* TODO: a proper hotplug detect cycle should be emulated here */ +diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c +index 184a6df2c29fe..d05f547a587cd 100644 +--- a/drivers/media/test-drivers/vivid/vivid-vid-out.c ++++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c +@@ -63,14 +63,16 @@ static int vid_out_queue_setup(struct vb2_queue *vq, + if (sizes[0] < size) + return -EINVAL; + for (p = 1; p < planes; p++) { +- if (sizes[p] < dev->bytesperline_out[p] * h + +- vfmt->data_offset[p]) ++ if (sizes[p] < dev->bytesperline_out[p] * h / ++ vfmt->vdownsampling[p] + ++ vfmt->data_offset[p]) + return -EINVAL; + } + } else { + for (p = 0; p < planes; p++) +- sizes[p] = p ? dev->bytesperline_out[p] * h + +- vfmt->data_offset[p] : size; ++ sizes[p] = p ? dev->bytesperline_out[p] * h / ++ vfmt->vdownsampling[p] + ++ vfmt->data_offset[p] : size; + } + + if (vq->num_buffers + *nbuffers < 2) +@@ -127,7 +129,7 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb) + + for (p = 0; p < planes; p++) { + if (p) +- size = dev->bytesperline_out[p] * h; ++ size = dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; + size += vb->planes[p].data_offset; + + if (vb2_get_plane_payload(vb, p) < size) { +@@ -334,8 +336,8 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv, + for (p = 0; p < mp->num_planes; p++) { + mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; + mp->plane_fmt[p].sizeimage = +- mp->plane_fmt[p].bytesperline * mp->height + +- fmt->data_offset[p]; ++ mp->plane_fmt[p].bytesperline * mp->height / ++ fmt->vdownsampling[p] + fmt->data_offset[p]; + } + for (p = fmt->buffers; p < fmt->planes; p++) { + unsigned stride = dev->bytesperline_out[p]; +diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c +index f0626814d56b9..4df0d7a0cd118 100644 +--- a/drivers/misc/fastrpc.c ++++ b/drivers/misc/fastrpc.c +@@ -1912,7 +1912,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) + &args[0]); + if (err) { + dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size); +- goto err_invoke; ++ fastrpc_buf_free(buf); ++ return err; + } + + /* update the buffer to be able to deallocate the memory on the DSP */ +@@ -1950,8 +1951,6 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) + + err_assign: + fastrpc_req_munmap_impl(fl, buf); +-err_invoke: +- fastrpc_buf_free(buf); + + return err; + } +diff --git a/drivers/misc/vmw_vmci/vmci_resource.c b/drivers/misc/vmw_vmci/vmci_resource.c +index 692daa9eff341..19c9d2cdd277b 100644 +--- a/drivers/misc/vmw_vmci/vmci_resource.c ++++ b/drivers/misc/vmw_vmci/vmci_resource.c +@@ -144,7 +144,8 @@ void vmci_resource_remove(struct vmci_resource *resource) + spin_lock(&vmci_resource_table.lock); + + hlist_for_each_entry(r, &vmci_resource_table.entries[idx], node) { +- if (vmci_handle_is_equal(r->handle, resource->handle)) { ++ if (vmci_handle_is_equal(r->handle, resource->handle) && ++ resource->type == r->type) { + hlist_del_init_rcu(&r->node); + break; + } +diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h +index cca71867bc4ad..92905fc46436d 100644 +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -15,6 +15,19 @@ + + #include "card.h" + ++static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = { ++ /* ++ * Kingston Canvas Go! Plus microSD cards never finish SD cache flush. ++ * This has so far only been observed on cards from 11/2019, while new ++ * cards from 2023/05 do not exhibit this behavior. ++ */ ++ _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11, ++ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, ++ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), ++ ++ END_FIXUP ++}; ++ + static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { + #define INAND_CMD38_ARG_EXT_CSD 113 + #define INAND_CMD38_ARG_ERASE 0x00 +@@ -53,15 +66,6 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { + MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_BLK_NO_CMD23), + +- /* +- * Kingston Canvas Go! Plus microSD cards never finish SD cache flush. +- * This has so far only been observed on cards from 11/2019, while new +- * cards from 2023/05 do not exhibit this behavior. +- */ +- _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11, +- 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, +- MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), +- + /* + * Some SD cards lockup while using CMD23 multiblock transfers. + */ +diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c +index c3e554344c99f..240469a881a27 100644 +--- a/drivers/mmc/core/sd.c ++++ b/drivers/mmc/core/sd.c +@@ -26,6 +26,7 @@ + #include "host.h" + #include "bus.h" + #include "mmc_ops.h" ++#include "quirks.h" + #include "sd.h" + #include "sd_ops.h" + +@@ -1475,6 +1476,9 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, + goto free_card; + } + ++ /* Apply quirks prior to card setup */ ++ mmc_fixup_device(card, mmc_sd_fixups); ++ + err = mmc_sd_setup_card(host, card, oldcard != NULL); + if (err) + goto free_card; +diff --git a/drivers/mmc/host/cqhci-core.c b/drivers/mmc/host/cqhci-core.c +index 41e94cd141098..fe7a4eac9595c 100644 +--- a/drivers/mmc/host/cqhci-core.c ++++ b/drivers/mmc/host/cqhci-core.c +@@ -612,7 +612,7 @@ static int cqhci_request(struct mmc_host *mmc, struct mmc_request *mrq) + cqhci_writel(cq_host, 0, CQHCI_CTL); + mmc->cqe_on = true; + pr_debug("%s: cqhci: CQE on\n", mmc_hostname(mmc)); +- if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) { ++ if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) { + pr_err("%s: cqhci: CQE failed to exit halt state\n", + mmc_hostname(mmc)); + } +diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c +index 02bee7afab37e..2f0bc79ef856a 100644 +--- a/drivers/mmc/host/dw_mmc.c ++++ b/drivers/mmc/host/dw_mmc.c +@@ -2952,8 +2952,8 @@ static int dw_mci_init_slot(struct dw_mci *host) + if (host->use_dma == TRANS_MODE_IDMAC) { + mmc->max_segs = host->ring_size; + mmc->max_blk_size = 65535; +- mmc->max_seg_size = 0x1000; +- mmc->max_req_size = mmc->max_seg_size * host->ring_size; ++ mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size; ++ mmc->max_seg_size = mmc->max_req_size; + mmc->max_blk_count = mmc->max_req_size / 512; + } else if (host->use_dma == TRANS_MODE_EDMAC) { + mmc->max_segs = 64; +diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c +index 42d54532cabe6..8379a0620c8fe 100644 +--- a/drivers/mmc/host/sdhci-of-aspeed.c ++++ b/drivers/mmc/host/sdhci-of-aspeed.c +@@ -510,6 +510,7 @@ static const struct of_device_id aspeed_sdhci_of_match[] = { + { .compatible = "aspeed,ast2600-sdhci", .data = &ast2600_sdhci_pdata, }, + { } + }; ++MODULE_DEVICE_TABLE(of, aspeed_sdhci_of_match); + + static struct platform_driver aspeed_sdhci_driver = { + .driver = { +diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c +index 683203f87ae2b..277493e41b072 100644 +--- a/drivers/net/bareudp.c ++++ b/drivers/net/bareudp.c +@@ -82,7 +82,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) + + if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, &ipversion, + sizeof(ipversion))) { +- bareudp->dev->stats.rx_dropped++; ++ DEV_STATS_INC(bareudp->dev, rx_dropped); + goto drop; + } + ipversion >>= 4; +@@ -92,7 +92,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) + } else if (ipversion == 6 && bareudp->multi_proto_mode) { + proto = htons(ETH_P_IPV6); + } else { +- bareudp->dev->stats.rx_dropped++; ++ DEV_STATS_INC(bareudp->dev, rx_dropped); + goto drop; + } + } else if (bareudp->ethertype == htons(ETH_P_MPLS_UC)) { +@@ -106,7 +106,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) + ipv4_is_multicast(tunnel_hdr->daddr)) { + proto = htons(ETH_P_MPLS_MC); + } else { +- bareudp->dev->stats.rx_dropped++; ++ DEV_STATS_INC(bareudp->dev, rx_dropped); + goto drop; + } + } else { +@@ -122,7 +122,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) + (addr_type & IPV6_ADDR_MULTICAST)) { + proto = htons(ETH_P_MPLS_MC); + } else { +- bareudp->dev->stats.rx_dropped++; ++ DEV_STATS_INC(bareudp->dev, rx_dropped); + goto drop; + } + } +@@ -134,12 +134,12 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) + proto, + !net_eq(bareudp->net, + dev_net(bareudp->dev)))) { +- bareudp->dev->stats.rx_dropped++; ++ DEV_STATS_INC(bareudp->dev, rx_dropped); + goto drop; + } + tun_dst = udp_tun_rx_dst(skb, family, TUNNEL_KEY, 0, 0); + if (!tun_dst) { +- bareudp->dev->stats.rx_dropped++; ++ DEV_STATS_INC(bareudp->dev, rx_dropped); + goto drop; + } + skb_dst_set(skb, &tun_dst->dst); +@@ -165,8 +165,8 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) + &((struct ipv6hdr *)oiph)->saddr); + } + if (err > 1) { +- ++bareudp->dev->stats.rx_frame_errors; +- ++bareudp->dev->stats.rx_errors; ++ DEV_STATS_INC(bareudp->dev, rx_frame_errors); ++ DEV_STATS_INC(bareudp->dev, rx_errors); + goto drop; + } + } +@@ -462,11 +462,11 @@ static netdev_tx_t bareudp_xmit(struct sk_buff *skb, struct net_device *dev) + dev_kfree_skb(skb); + + if (err == -ELOOP) +- dev->stats.collisions++; ++ DEV_STATS_INC(dev, collisions); + else if (err == -ENETUNREACH) +- dev->stats.tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + return NETDEV_TX_OK; + } + +diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c +index a57005faa04f5..c490b4ba065ba 100644 +--- a/drivers/net/can/kvaser_pciefd.c ++++ b/drivers/net/can/kvaser_pciefd.c +@@ -1580,23 +1580,15 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf) + return res; + } + +-static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie) ++static u32 kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie) + { + u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG); + +- if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) { ++ if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) + kvaser_pciefd_read_buffer(pcie, 0); +- /* Reset DMA buffer 0 */ +- iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0, +- KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG); +- } + +- if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) { ++ if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) + kvaser_pciefd_read_buffer(pcie, 1); +- /* Reset DMA buffer 1 */ +- iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1, +- KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG); +- } + + if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 || + irq & KVASER_PCIEFD_SRB_IRQ_DOF1 || +@@ -1605,6 +1597,7 @@ static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie) + dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq); + + iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG); ++ return irq; + } + + static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can) +@@ -1631,27 +1624,31 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev) + { + struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev; + const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask; +- u32 board_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie)); ++ u32 pci_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie)); ++ u32 srb_irq = 0; ++ u32 srb_release = 0; + int i; + +- if (!(board_irq & irq_mask->all)) ++ if (!(pci_irq & irq_mask->all)) + return IRQ_NONE; + +- if (board_irq & irq_mask->kcan_rx0) +- kvaser_pciefd_receive_irq(pcie); ++ if (pci_irq & irq_mask->kcan_rx0) ++ srb_irq = kvaser_pciefd_receive_irq(pcie); + + for (i = 0; i < pcie->nr_channels; i++) { +- if (!pcie->can[i]) { +- dev_err(&pcie->pci->dev, +- "IRQ mask points to unallocated controller\n"); +- break; +- } +- +- /* Check that mask matches channel (i) IRQ mask */ +- if (board_irq & irq_mask->kcan_tx[i]) ++ if (pci_irq & irq_mask->kcan_tx[i]) + kvaser_pciefd_transmit_irq(pcie->can[i]); + } + ++ if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD0) ++ srb_release |= KVASER_PCIEFD_SRB_CMD_RDB0; ++ ++ if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD1) ++ srb_release |= KVASER_PCIEFD_SRB_CMD_RDB1; ++ ++ if (srb_release) ++ iowrite32(srb_release, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG); ++ + return IRQ_HANDLED; + } + +diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c +index 2395b1225cc8a..fb77fd74de27f 100644 +--- a/drivers/net/can/m_can/m_can.c ++++ b/drivers/net/can/m_can/m_can.c +@@ -1871,7 +1871,7 @@ static int m_can_open(struct net_device *dev) + /* start the m_can controller */ + err = m_can_start(dev); + if (err) +- goto exit_irq_fail; ++ goto exit_start_fail; + + if (!cdev->is_peripheral) + napi_enable(&cdev->napi); +@@ -1880,6 +1880,9 @@ static int m_can_open(struct net_device *dev) + + return 0; + ++exit_start_fail: ++ if (cdev->is_peripheral || dev->irq) ++ free_irq(dev->irq, dev); + exit_irq_fail: + if (cdev->is_peripheral) + destroy_workqueue(cdev->tx_wq); +diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c +index 79c4bab5f7246..8c56f85e87c1a 100644 +--- a/drivers/net/can/spi/mcp251x.c ++++ b/drivers/net/can/spi/mcp251x.c +@@ -753,7 +753,7 @@ static int mcp251x_hw_wake(struct spi_device *spi) + int ret; + + /* Force wakeup interrupt to wake device, but don't execute IST */ +- disable_irq(spi->irq); ++ disable_irq_nosync(spi->irq); + mcp251x_write_2regs(spi, CANINTE, CANINTE_WAKIE, CANINTF_WAKIF); + + /* Wait for oscillator startup timer after wake up */ +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +index 1665f78abb5c9..a9bafa96e2f92 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2019, 2020, 2021 Pengutronix, ++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + // Based on: +@@ -867,18 +867,18 @@ static int mcp251xfd_get_berr_counter(const struct net_device *ndev, + + static struct sk_buff * + mcp251xfd_alloc_can_err_skb(struct mcp251xfd_priv *priv, +- struct can_frame **cf, u32 *timestamp) ++ struct can_frame **cf, u32 *ts_raw) + { + struct sk_buff *skb; + int err; + +- err = mcp251xfd_get_timestamp(priv, timestamp); ++ err = mcp251xfd_get_timestamp_raw(priv, ts_raw); + if (err) + return NULL; + + skb = alloc_can_err_skb(priv->ndev, cf); + if (skb) +- mcp251xfd_skb_set_timestamp(priv, skb, *timestamp); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, *ts_raw); + + return skb; + } +@@ -889,7 +889,7 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) + struct mcp251xfd_rx_ring *ring; + struct sk_buff *skb; + struct can_frame *cf; +- u32 timestamp, rxovif; ++ u32 ts_raw, rxovif; + int err, i; + + stats->rx_over_errors++; +@@ -924,14 +924,14 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) + return err; + } + +- skb = mcp251xfd_alloc_can_err_skb(priv, &cf, ×tamp); ++ skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); + if (!skb) + return 0; + + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + +- err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); ++ err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); + if (err) + stats->rx_fifo_errors++; + +@@ -948,12 +948,12 @@ static int mcp251xfd_handle_txatif(struct mcp251xfd_priv *priv) + static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) + { + struct net_device_stats *stats = &priv->ndev->stats; +- u32 bdiag1, timestamp; ++ u32 bdiag1, ts_raw; + struct sk_buff *skb; + struct can_frame *cf = NULL; + int err; + +- err = mcp251xfd_get_timestamp(priv, ×tamp); ++ err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); + if (err) + return err; + +@@ -1035,8 +1035,8 @@ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) + if (!cf) + return 0; + +- mcp251xfd_skb_set_timestamp(priv, skb, timestamp); +- err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, ts_raw); ++ err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); + if (err) + stats->rx_fifo_errors++; + +@@ -1049,7 +1049,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) + struct sk_buff *skb; + struct can_frame *cf = NULL; + enum can_state new_state, rx_state, tx_state; +- u32 trec, timestamp; ++ u32 trec, ts_raw; + int err; + + err = regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec); +@@ -1079,7 +1079,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) + /* The skb allocation might fail, but can_change_state() + * handles cf == NULL. + */ +- skb = mcp251xfd_alloc_can_err_skb(priv, &cf, ×tamp); ++ skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); + can_change_state(priv->ndev, cf, tx_state, rx_state); + + if (new_state == CAN_STATE_BUS_OFF) { +@@ -1110,7 +1110,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) + cf->data[7] = bec.rxerr; + } + +- err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); ++ err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); + if (err) + stats->rx_fifo_errors++; + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c +index 9e8e82cdba461..61b0d6fa52dd8 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c +@@ -97,7 +97,16 @@ void can_ram_get_layout(struct can_ram_layout *layout, + if (ring) { + u8 num_rx_coalesce = 0, num_tx_coalesce = 0; + +- num_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, ring->rx_pending); ++ /* If the ring parameters have been configured in ++ * CAN-CC mode, but and we are in CAN-FD mode now, ++ * they might be to big. Use the default CAN-FD values ++ * in this case. ++ */ ++ num_rx = ring->rx_pending; ++ if (num_rx > layout->max_rx) ++ num_rx = layout->default_rx; ++ ++ num_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, num_rx); + + /* The ethtool doc says: + * To disable coalescing, set usecs = 0 and max_frames = 1. +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +index 4cb79a4f24612..f72582d4d3e8e 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +@@ -206,6 +206,7 @@ mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr) + int i, j; + + mcp251xfd_for_each_rx_ring(priv, rx_ring, i) { ++ rx_ring->last_valid = timecounter_read(&priv->tc); + rx_ring->head = 0; + rx_ring->tail = 0; + rx_ring->base = *base; +@@ -468,11 +469,25 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) + + /* switching from CAN-2.0 to CAN-FD mode or vice versa */ + if (fd_mode != test_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags)) { ++ const struct ethtool_ringparam ring = { ++ .rx_pending = priv->rx_obj_num, ++ .tx_pending = priv->tx->obj_num, ++ }; ++ const struct ethtool_coalesce ec = { ++ .rx_coalesce_usecs_irq = priv->rx_coalesce_usecs_irq, ++ .rx_max_coalesced_frames_irq = priv->rx_obj_num_coalesce_irq, ++ .tx_coalesce_usecs_irq = priv->tx_coalesce_usecs_irq, ++ .tx_max_coalesced_frames_irq = priv->tx_obj_num_coalesce_irq, ++ }; + struct can_ram_layout layout; + +- can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode); +- priv->rx_obj_num = layout.default_rx; +- tx_ring->obj_num = layout.default_tx; ++ can_ram_get_layout(&layout, &mcp251xfd_ram_config, &ring, &ec, fd_mode); ++ ++ priv->rx_obj_num = layout.cur_rx; ++ priv->rx_obj_num_coalesce_irq = layout.rx_coalesce; ++ ++ tx_ring->obj_num = layout.cur_tx; ++ priv->tx_obj_num_coalesce_irq = layout.tx_coalesce; + } + + if (fd_mode) { +@@ -509,6 +524,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) + } + + rx_ring->obj_num = rx_obj_num; ++ rx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(rx_ring->obj_num_shift_to_u8) - ++ ilog2(rx_obj_num); + rx_ring->obj_size = rx_obj_size; + priv->rx[i] = rx_ring; + } +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +index ced8d9c81f8c6..fe897f3e4c12a 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2019, 2020, 2021 Pengutronix, ++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + // Based on: +@@ -16,23 +16,14 @@ + + #include "mcp251xfd.h" + +-static inline int +-mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv *priv, +- const struct mcp251xfd_rx_ring *ring, +- u8 *rx_head, bool *fifo_empty) ++static inline bool mcp251xfd_rx_fifo_sta_empty(const u32 fifo_sta) + { +- u32 fifo_sta; +- int err; +- +- err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), +- &fifo_sta); +- if (err) +- return err; +- +- *rx_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); +- *fifo_empty = !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); ++ return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); ++} + +- return 0; ++static inline bool mcp251xfd_rx_fifo_sta_full(const u32 fifo_sta) ++{ ++ return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF; + } + + static inline int +@@ -80,29 +71,49 @@ mcp251xfd_check_rx_tail(const struct mcp251xfd_priv *priv, + } + + static int +-mcp251xfd_rx_ring_update(const struct mcp251xfd_priv *priv, +- struct mcp251xfd_rx_ring *ring) ++mcp251xfd_get_rx_len(const struct mcp251xfd_priv *priv, ++ const struct mcp251xfd_rx_ring *ring, ++ u8 *len_p) + { +- u32 new_head; +- u8 chip_rx_head; +- bool fifo_empty; ++ const u8 shift = ring->obj_num_shift_to_u8; ++ u8 chip_head, tail, len; ++ u32 fifo_sta; + int err; + +- err = mcp251xfd_rx_head_get_from_chip(priv, ring, &chip_rx_head, +- &fifo_empty); +- if (err || fifo_empty) ++ err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), ++ &fifo_sta); ++ if (err) ++ return err; ++ ++ if (mcp251xfd_rx_fifo_sta_empty(fifo_sta)) { ++ *len_p = 0; ++ return 0; ++ } ++ ++ if (mcp251xfd_rx_fifo_sta_full(fifo_sta)) { ++ *len_p = ring->obj_num; ++ return 0; ++ } ++ ++ chip_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); ++ ++ err = mcp251xfd_check_rx_tail(priv, ring); ++ if (err) + return err; ++ tail = mcp251xfd_get_rx_tail(ring); + +- /* chip_rx_head, is the next RX-Object filled by the HW. +- * The new RX head must be >= the old head. ++ /* First shift to full u8. The subtraction works on signed ++ * values, that keeps the difference steady around the u8 ++ * overflow. The right shift acts on len, which is an u8. + */ +- new_head = round_down(ring->head, ring->obj_num) + chip_rx_head; +- if (new_head <= ring->head) +- new_head += ring->obj_num; ++ BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(chip_head)); ++ BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(tail)); ++ BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(len)); + +- ring->head = new_head; ++ len = (chip_head << shift) - (tail << shift); ++ *len_p = len >> shift; + +- return mcp251xfd_check_rx_tail(priv, ring); ++ return 0; + } + + static void +@@ -148,8 +159,6 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, + + if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) + memcpy(cfd->data, hw_rx_obj->data, cfd->len); +- +- mcp251xfd_skb_set_timestamp(priv, skb, hw_rx_obj->ts); + } + + static int +@@ -160,8 +169,26 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, + struct net_device_stats *stats = &priv->ndev->stats; + struct sk_buff *skb; + struct canfd_frame *cfd; ++ u64 timestamp; + int err; + ++ /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI ++ * bits of a FIFOSTA register, here the RX FIFO head index ++ * might be corrupted and we might process past the RX FIFO's ++ * head into old CAN frames. ++ * ++ * Compare the timestamp of currently processed CAN frame with ++ * last valid frame received. Abort with -EBADMSG if an old ++ * CAN frame is detected. ++ */ ++ timestamp = timecounter_cyc2time(&priv->tc, hw_rx_obj->ts); ++ if (timestamp <= ring->last_valid) { ++ stats->rx_fifo_errors++; ++ ++ return -EBADMSG; ++ } ++ ring->last_valid = timestamp; ++ + if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) + skb = alloc_canfd_skb(priv->ndev, &cfd); + else +@@ -172,6 +199,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, + return 0; + } + ++ mcp251xfd_skb_set_timestamp(skb, timestamp); + mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb); + err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts); + if (err) +@@ -197,52 +225,81 @@ mcp251xfd_rx_obj_read(const struct mcp251xfd_priv *priv, + return err; + } + ++static int ++mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv, ++ struct mcp251xfd_rx_ring *ring, ++ u8 len) ++{ ++ int offset; ++ int err; ++ ++ if (!len) ++ return 0; ++ ++ ring->head += len; ++ ++ /* Increment the RX FIFO tail pointer 'len' times in a ++ * single SPI message. ++ * ++ * Note: ++ * Calculate offset, so that the SPI transfer ends on ++ * the last message of the uinc_xfer array, which has ++ * "cs_change == 0", to properly deactivate the chip ++ * select. ++ */ ++ offset = ARRAY_SIZE(ring->uinc_xfer) - len; ++ err = spi_sync_transfer(priv->spi, ++ ring->uinc_xfer + offset, len); ++ if (err) ++ return err; ++ ++ ring->tail += len; ++ ++ return 0; ++} ++ + static int + mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + struct mcp251xfd_rx_ring *ring) + { + struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj; +- u8 rx_tail, len; ++ u8 rx_tail, len, l; + int err, i; + +- err = mcp251xfd_rx_ring_update(priv, ring); ++ err = mcp251xfd_get_rx_len(priv, ring, &len); + if (err) + return err; + +- while ((len = mcp251xfd_get_rx_linear_len(ring))) { +- int offset; +- ++ while ((l = mcp251xfd_get_rx_linear_len(ring, len))) { + rx_tail = mcp251xfd_get_rx_tail(ring); + + err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj, +- rx_tail, len); ++ rx_tail, l); + if (err) + return err; + +- for (i = 0; i < len; i++) { ++ for (i = 0; i < l; i++) { + err = mcp251xfd_handle_rxif_one(priv, ring, + (void *)hw_rx_obj + + i * ring->obj_size); +- if (err) ++ ++ /* -EBADMSG means we're affected by mcp2518fd ++ * erratum DS80000789E 6., i.e. the timestamp ++ * in the RX object is older that the last ++ * valid received CAN frame. Don't process any ++ * further and mark processed frames as good. ++ */ ++ if (err == -EBADMSG) ++ return mcp251xfd_handle_rxif_ring_uinc(priv, ring, i); ++ else if (err) + return err; + } + +- /* Increment the RX FIFO tail pointer 'len' times in a +- * single SPI message. +- * +- * Note: +- * Calculate offset, so that the SPI transfer ends on +- * the last message of the uinc_xfer array, which has +- * "cs_change == 0", to properly deactivate the chip +- * select. +- */ +- offset = ARRAY_SIZE(ring->uinc_xfer) - len; +- err = spi_sync_transfer(priv->spi, +- ring->uinc_xfer + offset, len); ++ err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, l); + if (err) + return err; + +- ring->tail += len; ++ len -= l; + } + + return 0; +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +index 5b0c7890d4b44..3886476a8f8ef 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +@@ -97,7 +97,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, + tef_tail = mcp251xfd_get_tef_tail(priv); + skb = priv->can.echo_skb[tef_tail]; + if (skb) +- mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_tef_obj->ts); + stats->tx_bytes += + can_rx_offload_get_echo_skb_queue_timestamp(&priv->offload, + tef_tail, hw_tef_obj->ts, +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c +index 712e091869870..1db99aabe85c5 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2021 Pengutronix, ++// Copyright (c) 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + +@@ -11,20 +11,20 @@ + + #include "mcp251xfd.h" + +-static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc) ++static u64 mcp251xfd_timestamp_raw_read(const struct cyclecounter *cc) + { + const struct mcp251xfd_priv *priv; +- u32 timestamp = 0; ++ u32 ts_raw = 0; + int err; + + priv = container_of(cc, struct mcp251xfd_priv, cc); +- err = mcp251xfd_get_timestamp(priv, ×tamp); ++ err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); + if (err) + netdev_err(priv->ndev, + "Error %d while reading timestamp. HW timestamps may be inaccurate.", + err); + +- return timestamp; ++ return ts_raw; + } + + static void mcp251xfd_timestamp_work(struct work_struct *work) +@@ -39,21 +39,11 @@ static void mcp251xfd_timestamp_work(struct work_struct *work) + MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); + } + +-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, +- struct sk_buff *skb, u32 timestamp) +-{ +- struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); +- u64 ns; +- +- ns = timecounter_cyc2time(&priv->tc, timestamp); +- hwtstamps->hwtstamp = ns_to_ktime(ns); +-} +- + void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv) + { + struct cyclecounter *cc = &priv->cc; + +- cc->read = mcp251xfd_timestamp_read; ++ cc->read = mcp251xfd_timestamp_raw_read; + cc->mask = CYCLECOUNTER_MASK(32); + cc->shift = 1; + cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift); +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +index 4628bf847bc9b..991662fbba42e 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -2,7 +2,7 @@ + * + * mcp251xfd - Microchip MCP251xFD Family CAN controller driver + * +- * Copyright (c) 2019, 2020, 2021 Pengutronix, ++ * Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + * Marc Kleine-Budde + * Copyright (c) 2019 Martin Sperl + */ +@@ -554,10 +554,14 @@ struct mcp251xfd_rx_ring { + unsigned int head; + unsigned int tail; + ++ /* timestamp of the last valid received CAN frame */ ++ u64 last_valid; ++ + u16 base; + u8 nr; + u8 fifo_nr; + u8 obj_num; ++ u8 obj_num_shift_to_u8; + u8 obj_size; + + union mcp251xfd_write_reg_buf irq_enable_buf; +@@ -811,10 +815,27 @@ mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, + return data; + } + +-static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv, +- u32 *timestamp) ++static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv, ++ u32 *ts_raw) ++{ ++ return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw); ++} ++ ++static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns) ++{ ++ struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); ++ ++ hwtstamps->hwtstamp = ns_to_ktime(ns); ++} ++ ++static inline ++void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv, ++ struct sk_buff *skb, u32 ts_raw) + { +- return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp); ++ u64 ns; ++ ++ ns = timecounter_cyc2time(&priv->tc, ts_raw); ++ mcp251xfd_skb_set_timestamp(skb, ns); + } + + static inline u16 mcp251xfd_get_tef_obj_addr(u8 n) +@@ -907,18 +928,9 @@ static inline u8 mcp251xfd_get_rx_tail(const struct mcp251xfd_rx_ring *ring) + return ring->tail & (ring->obj_num - 1); + } + +-static inline u8 mcp251xfd_get_rx_len(const struct mcp251xfd_rx_ring *ring) +-{ +- return ring->head - ring->tail; +-} +- + static inline u8 +-mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring) ++mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring, u8 len) + { +- u8 len; +- +- len = mcp251xfd_get_rx_len(ring); +- + return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring)); + } + +@@ -944,8 +956,6 @@ void mcp251xfd_ring_free(struct mcp251xfd_priv *priv); + int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv); + int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv); + int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv); +-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, +- struct sk_buff *skb, u32 timestamp); + void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); + void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); + +diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c +index 23bd8b3f89931..a28bf5433ea72 100644 +--- a/drivers/net/dsa/vitesse-vsc73xx-core.c ++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c +@@ -34,7 +34,7 @@ + #define VSC73XX_BLOCK_ANALYZER 0x2 /* Only subblock 0 */ + #define VSC73XX_BLOCK_MII 0x3 /* Subblocks 0 and 1 */ + #define VSC73XX_BLOCK_MEMINIT 0x3 /* Only subblock 2 */ +-#define VSC73XX_BLOCK_CAPTURE 0x4 /* Only subblock 2 */ ++#define VSC73XX_BLOCK_CAPTURE 0x4 /* Subblocks 0-4, 6, 7 */ + #define VSC73XX_BLOCK_ARBITER 0x5 /* Only subblock 0 */ + #define VSC73XX_BLOCK_SYSTEM 0x7 /* Only subblock 0 */ + +@@ -370,13 +370,19 @@ int vsc73xx_is_addr_valid(u8 block, u8 subblock) + break; + + case VSC73XX_BLOCK_MII: +- case VSC73XX_BLOCK_CAPTURE: + case VSC73XX_BLOCK_ARBITER: + switch (subblock) { + case 0 ... 1: + return 1; + } + break; ++ case VSC73XX_BLOCK_CAPTURE: ++ switch (subblock) { ++ case 0 ... 4: ++ case 6 ... 7: ++ return 1; ++ } ++ break; + } + + return 0; +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index dcbc598b11c6c..c6a3eefd83bff 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -931,14 +931,18 @@ static inline void dpaa_setup_egress(const struct dpaa_priv *priv, + } + } + +-static void dpaa_fq_setup(struct dpaa_priv *priv, +- const struct dpaa_fq_cbs *fq_cbs, +- struct fman_port *tx_port) ++static int dpaa_fq_setup(struct dpaa_priv *priv, ++ const struct dpaa_fq_cbs *fq_cbs, ++ struct fman_port *tx_port) + { + int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu; + const cpumask_t *affine_cpus = qman_affine_cpus(); +- u16 channels[NR_CPUS]; + struct dpaa_fq *fq; ++ u16 *channels; ++ ++ channels = kcalloc(num_possible_cpus(), sizeof(u16), GFP_KERNEL); ++ if (!channels) ++ return -ENOMEM; + + for_each_cpu_and(cpu, affine_cpus, cpu_online_mask) + channels[num_portals++] = qman_affine_channel(cpu); +@@ -997,6 +1001,10 @@ static void dpaa_fq_setup(struct dpaa_priv *priv, + break; + } + } ++ ++ kfree(channels); ++ ++ return 0; + } + + static inline int dpaa_tx_fq_to_id(const struct dpaa_priv *priv, +@@ -3416,7 +3424,9 @@ static int dpaa_eth_probe(struct platform_device *pdev) + */ + dpaa_eth_add_channel(priv->channel, &pdev->dev); + +- dpaa_fq_setup(priv, &dpaa_fq_cbs, priv->mac_dev->port[TX]); ++ err = dpaa_fq_setup(priv, &dpaa_fq_cbs, priv->mac_dev->port[TX]); ++ if (err) ++ goto free_dpaa_bps; + + /* Create a congestion group for this netdev, with + * dynamically-allocated CGR ID. +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +index 5bd0b36d1feb5..3f8cd4a7d8457 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +@@ -457,12 +457,16 @@ static int dpaa_set_coalesce(struct net_device *dev, + struct netlink_ext_ack *extack) + { + const cpumask_t *cpus = qman_affine_cpus(); +- bool needs_revert[NR_CPUS] = {false}; + struct qman_portal *portal; + u32 period, prev_period; + u8 thresh, prev_thresh; ++ bool *needs_revert; + int cpu, res; + ++ needs_revert = kcalloc(num_possible_cpus(), sizeof(bool), GFP_KERNEL); ++ if (!needs_revert) ++ return -ENOMEM; ++ + period = c->rx_coalesce_usecs; + thresh = c->rx_max_coalesced_frames; + +@@ -485,6 +489,8 @@ static int dpaa_set_coalesce(struct net_device *dev, + needs_revert[cpu] = true; + } + ++ kfree(needs_revert); ++ + return 0; + + revert_values: +@@ -498,6 +504,8 @@ static int dpaa_set_coalesce(struct net_device *dev, + qman_dqrr_set_ithresh(portal, prev_thresh); + } + ++ kfree(needs_revert); ++ + return res; + } + +diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c +index 4d83c9a0c023a..f9e94be36e97f 100644 +--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c ++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c +@@ -2573,7 +2573,7 @@ void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) + hw->phy.ops.write_reg_page(hw, BM_RAR_H(i), + (u16)(mac_reg & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_RAR_CTRL(i), +- FIELD_GET(E1000_RAH_AV, mac_reg)); ++ (u16)((mac_reg & E1000_RAH_AV) >> 16)); + } + + e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index c7962f322db2d..7b3ce30ba38fa 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -313,6 +313,7 @@ enum ice_vsi_state { + ICE_VSI_UMAC_FLTR_CHANGED, + ICE_VSI_MMAC_FLTR_CHANGED, + ICE_VSI_PROMISC_CHANGED, ++ ICE_VSI_REBUILD_PENDING, + ICE_VSI_STATE_NBITS /* must be last */ + }; + +@@ -409,6 +410,7 @@ struct ice_vsi { + struct ice_tx_ring **xdp_rings; /* XDP ring array */ + u16 num_xdp_txq; /* Used XDP queues */ + u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */ ++ struct mutex xdp_state_lock; + + struct net_device **target_netdevs; + +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 13ca3342a0cea..b3010a53f1b45 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -459,6 +459,7 @@ static void ice_vsi_free(struct ice_vsi *vsi) + + ice_vsi_free_stats(vsi); + ice_vsi_free_arrays(vsi); ++ mutex_destroy(&vsi->xdp_state_lock); + mutex_unlock(&pf->sw_mutex); + devm_kfree(dev, vsi); + } +@@ -660,6 +661,8 @@ static struct ice_vsi *ice_vsi_alloc(struct ice_pf *pf) + pf->next_vsi = ice_get_free_slot(pf->vsi, pf->num_alloc_vsi, + pf->next_vsi); + ++ mutex_init(&vsi->xdp_state_lock); ++ + unlock_pf: + mutex_unlock(&pf->sw_mutex); + return vsi; +@@ -3164,19 +3167,23 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags) + if (WARN_ON(vsi->type == ICE_VSI_VF && !vsi->vf)) + return -EINVAL; + ++ mutex_lock(&vsi->xdp_state_lock); ++ + ret = ice_vsi_realloc_stat_arrays(vsi); + if (ret) +- goto err_vsi_cfg; ++ goto unlock; + + ice_vsi_decfg(vsi); + ret = ice_vsi_cfg_def(vsi, ¶ms); + if (ret) +- goto err_vsi_cfg; ++ goto unlock; + + coalesce = kcalloc(vsi->num_q_vectors, + sizeof(struct ice_coalesce_stored), GFP_KERNEL); +- if (!coalesce) +- return -ENOMEM; ++ if (!coalesce) { ++ ret = -ENOMEM; ++ goto decfg; ++ } + + prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce); + +@@ -3184,22 +3191,23 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags) + if (ret) { + if (vsi_flags & ICE_VSI_FLAG_INIT) { + ret = -EIO; +- goto err_vsi_cfg_tc_lan; ++ goto free_coalesce; + } + +- kfree(coalesce); +- return ice_schedule_reset(pf, ICE_RESET_PFR); ++ ret = ice_schedule_reset(pf, ICE_RESET_PFR); ++ goto free_coalesce; + } + + ice_vsi_rebuild_set_coalesce(vsi, coalesce, prev_num_q_vectors); +- kfree(coalesce); ++ clear_bit(ICE_VSI_REBUILD_PENDING, vsi->state); + +- return 0; +- +-err_vsi_cfg_tc_lan: +- ice_vsi_decfg(vsi); ++free_coalesce: + kfree(coalesce); +-err_vsi_cfg: ++decfg: ++ if (ret) ++ ice_vsi_decfg(vsi); ++unlock: ++ mutex_unlock(&vsi->xdp_state_lock); + return ret; + } + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index b168a37a5dfff..4d3a9fc79a6c1 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -606,11 +606,15 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) + memset(&vsi->mqprio_qopt, 0, sizeof(vsi->mqprio_qopt)); + } + } ++ ++ if (vsi->netdev) ++ netif_device_detach(vsi->netdev); + skip: + + /* clear SW filtering DB */ + ice_clear_hw_tbls(hw); + /* disable the VSIs and their queues that are not already DOWN */ ++ set_bit(ICE_VSI_REBUILD_PENDING, ice_get_main_vsi(pf)->state); + ice_pf_dis_all_vsi(pf, false); + + if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) +@@ -2927,8 +2931,8 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, + struct netlink_ext_ack *extack) + { + unsigned int frame_size = vsi->netdev->mtu + ICE_ETH_PKT_HDR_PAD; +- bool if_running = netif_running(vsi->netdev); + int ret = 0, xdp_ring_err = 0; ++ bool if_running; + + if (prog && !prog->aux->xdp_has_frags) { + if (frame_size > ice_max_xdp_frame_size(vsi)) { +@@ -2939,13 +2943,17 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, + } + + /* hot swap progs and avoid toggling link */ +- if (ice_is_xdp_ena_vsi(vsi) == !!prog) { ++ if (ice_is_xdp_ena_vsi(vsi) == !!prog || ++ test_bit(ICE_VSI_REBUILD_PENDING, vsi->state)) { + ice_vsi_assign_bpf_prog(vsi, prog); + return 0; + } + ++ if_running = netif_running(vsi->netdev) && ++ !test_and_set_bit(ICE_VSI_DOWN, vsi->state); ++ + /* need to stop netdev while setting up the program for Rx rings */ +- if (if_running && !test_and_set_bit(ICE_VSI_DOWN, vsi->state)) { ++ if (if_running) { + ret = ice_down(vsi); + if (ret) { + NL_SET_ERR_MSG_MOD(extack, "Preparing device for XDP attach failed"); +@@ -3011,21 +3019,28 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp) + { + struct ice_netdev_priv *np = netdev_priv(dev); + struct ice_vsi *vsi = np->vsi; ++ int ret; + + if (vsi->type != ICE_VSI_PF) { + NL_SET_ERR_MSG_MOD(xdp->extack, "XDP can be loaded only on PF VSI"); + return -EINVAL; + } + ++ mutex_lock(&vsi->xdp_state_lock); ++ + switch (xdp->command) { + case XDP_SETUP_PROG: +- return ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack); ++ ret = ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack); ++ break; + case XDP_SETUP_XSK_POOL: +- return ice_xsk_pool_setup(vsi, xdp->xsk.pool, +- xdp->xsk.queue_id); ++ ret = ice_xsk_pool_setup(vsi, xdp->xsk.pool, xdp->xsk.queue_id); ++ break; + default: +- return -EINVAL; ++ ret = -EINVAL; + } ++ ++ mutex_unlock(&vsi->xdp_state_lock); ++ return ret; + } + + /** +@@ -3979,13 +3994,17 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked) + + /* set for the next time the netdev is started */ + if (!netif_running(vsi->netdev)) { +- ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); ++ err = ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); ++ if (err) ++ goto rebuild_err; + dev_dbg(ice_pf_to_dev(pf), "Link is down, queue count change happens when link is brought up\n"); + goto done; + } + + ice_vsi_close(vsi); +- ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); ++ err = ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); ++ if (err) ++ goto rebuild_err; + + ice_for_each_traffic_class(i) { + if (vsi->tc_cfg.ena_tc & BIT(i)) +@@ -3996,6 +4015,11 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked) + } + ice_pf_dcb_recfg(pf, locked); + ice_vsi_open(vsi); ++ goto done; ++ ++rebuild_err: ++ dev_err(ice_pf_to_dev(pf), "Error during VSI rebuild: %d. Unload and reload the driver.\n", ++ err); + done: + clear_bit(ICE_CFG_BUSY, pf->state); + return err; +@@ -7286,6 +7310,7 @@ static void ice_update_pf_netdev_link(struct ice_pf *pf) + */ + static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) + { ++ struct ice_vsi *vsi = ice_get_main_vsi(pf); + struct device *dev = ice_pf_to_dev(pf); + struct ice_hw *hw = &pf->hw; + bool dvm; +@@ -7438,6 +7463,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) + ice_rebuild_arfs(pf); + } + ++ if (vsi && vsi->netdev) ++ netif_device_attach(vsi->netdev); ++ + ice_update_pf_netdev_link(pf); + + /* tell the firmware we are up */ +diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c +index 67511153081ae..9a9b8698881b4 100644 +--- a/drivers/net/ethernet/intel/ice/ice_xsk.c ++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c +@@ -396,7 +396,8 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid) + goto failure; + } + +- if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi); ++ if_running = !test_bit(ICE_VSI_DOWN, vsi->state) && ++ ice_is_xdp_ena_vsi(vsi); + + if (if_running) { + struct ice_rx_ring *rx_ring = vsi->rx_rings[qid]; +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index 8c8894ef33886..fa268d7bd1bc3 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -6985,10 +6985,20 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt) + + static void igb_tsync_interrupt(struct igb_adapter *adapter) + { ++ const u32 mask = (TSINTR_SYS_WRAP | E1000_TSICR_TXTS | ++ TSINTR_TT0 | TSINTR_TT1 | ++ TSINTR_AUTT0 | TSINTR_AUTT1); + struct e1000_hw *hw = &adapter->hw; + u32 tsicr = rd32(E1000_TSICR); + struct ptp_clock_event event; + ++ if (hw->mac.type == e1000_82580) { ++ /* 82580 has a hardware bug that requires an explicit ++ * write to clear the TimeSync interrupt cause. ++ */ ++ wr32(E1000_TSICR, tsicr & mask); ++ } ++ + if (tsicr & TSINTR_SYS_WRAP) { + event.type = PTP_CLOCK_PPS; + if (adapter->ptp_caps.pps) +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index 21fb1a98ebca6..da1018d832622 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -7288,6 +7288,7 @@ static void igc_io_resume(struct pci_dev *pdev) + rtnl_lock(); + if (netif_running(netdev)) { + if (igc_open(netdev)) { ++ rtnl_unlock(); + netdev_err(netdev, "igc_open failed after reset\n"); + return; + } +diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +index fe4e166de8a04..79276bc3d4951 100644 +--- a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c ++++ b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +@@ -1442,18 +1442,8 @@ static void vcap_api_encode_rule_test(struct kunit *test) + vcap_enable_lookups(&test_vctrl, &test_netdev, 0, 0, + rule->cookie, false); + +- vcap_free_rule(rule); +- +- /* Check that the rule has been freed: tricky to access since this +- * memory should not be accessible anymore +- */ +- KUNIT_EXPECT_PTR_NE(test, NULL, rule); +- ret = list_empty(&rule->keyfields); +- KUNIT_EXPECT_EQ(test, true, ret); +- ret = list_empty(&rule->actionfields); +- KUNIT_EXPECT_EQ(test, true, ret); +- +- vcap_del_rule(&test_vctrl, &test_netdev, id); ++ ret = vcap_del_rule(&test_vctrl, &test_netdev, id); ++ KUNIT_EXPECT_EQ(test, 0, ret); + } + + static void vcap_api_set_rule_counter_test(struct kunit *test) +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 765c5fc158f8f..d8cce3771af21 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1858,10 +1858,12 @@ static void mana_destroy_txq(struct mana_port_context *apc) + + for (i = 0; i < apc->num_queues; i++) { + napi = &apc->tx_qp[i].tx_cq.napi; +- napi_synchronize(napi); +- napi_disable(napi); +- netif_napi_del(napi); +- ++ if (apc->tx_qp[i].txq.napi_initialized) { ++ napi_synchronize(napi); ++ napi_disable(napi); ++ netif_napi_del(napi); ++ apc->tx_qp[i].txq.napi_initialized = false; ++ } + mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i].tx_object); + + mana_deinit_cq(apc, &apc->tx_qp[i].tx_cq); +@@ -1917,6 +1919,7 @@ static int mana_create_txq(struct mana_port_context *apc, + txq->ndev = net; + txq->net_txq = netdev_get_tx_queue(net, i); + txq->vp_offset = apc->tx_vp_offset; ++ txq->napi_initialized = false; + skb_queue_head_init(&txq->pending_skbs); + + memset(&spec, 0, sizeof(spec)); +@@ -1983,6 +1986,7 @@ static int mana_create_txq(struct mana_port_context *apc, + + netif_napi_add_tx(net, &cq->napi, mana_poll); + napi_enable(&cq->napi); ++ txq->napi_initialized = true; + + mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT); + } +@@ -1994,7 +1998,7 @@ static int mana_create_txq(struct mana_port_context *apc, + } + + static void mana_destroy_rxq(struct mana_port_context *apc, +- struct mana_rxq *rxq, bool validate_state) ++ struct mana_rxq *rxq, bool napi_initialized) + + { + struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; +@@ -2009,15 +2013,15 @@ static void mana_destroy_rxq(struct mana_port_context *apc, + + napi = &rxq->rx_cq.napi; + +- if (validate_state) ++ if (napi_initialized) { + napi_synchronize(napi); + +- napi_disable(napi); ++ napi_disable(napi); + ++ netif_napi_del(napi); ++ } + xdp_rxq_info_unreg(&rxq->xdp_rxq); + +- netif_napi_del(napi); +- + mana_destroy_wq_obj(apc, GDMA_RQ, rxq->rxobj); + + mana_deinit_cq(apc, &rxq->rx_cq); +diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c +index 5bf6fdff701cd..346e6ad36054e 100644 +--- a/drivers/net/mctp/mctp-serial.c ++++ b/drivers/net/mctp/mctp-serial.c +@@ -91,8 +91,8 @@ static int next_chunk_len(struct mctp_serial *dev) + * will be those non-escaped bytes, and does not include the escaped + * byte. + */ +- for (i = 1; i + dev->txpos + 1 < dev->txlen; i++) { +- if (needs_escape(dev->txbuf[dev->txpos + i + 1])) ++ for (i = 1; i + dev->txpos < dev->txlen; i++) { ++ if (needs_escape(dev->txbuf[dev->txpos + i])) + break; + } + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index c895cd178e6a1..2e4bff6055e22 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -3164,11 +3164,13 @@ static int of_phy_leds(struct phy_device *phydev) + err = of_phy_led(phydev, led); + if (err) { + of_node_put(led); ++ of_node_put(leds); + phy_leds_unregister(phydev); + return err; + } + } + ++ of_node_put(leds); + return 0; + } + +diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c +index 687d70cfc5563..6eeef10edadad 100644 +--- a/drivers/net/usb/ipheth.c ++++ b/drivers/net/usb/ipheth.c +@@ -475,8 +475,8 @@ static int ipheth_close(struct net_device *net) + { + struct ipheth_device *dev = netdev_priv(net); + +- cancel_delayed_work_sync(&dev->carrier_work); + netif_stop_queue(net); ++ cancel_delayed_work_sync(&dev->carrier_work); + return 0; + } + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 127b34dcc5b37..ce19ebd180f12 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -5143,14 +5143,23 @@ static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac) + data = (u8 *)mac; + data += __le16_to_cpu(mac->fw_offset); + +- generic_ocp_write(tp, __le16_to_cpu(mac->fw_reg), 0xff, length, data, +- type); ++ if (generic_ocp_write(tp, __le16_to_cpu(mac->fw_reg), 0xff, length, ++ data, type) < 0) { ++ dev_err(&tp->intf->dev, "Write %s fw fail\n", ++ type ? "PLA" : "USB"); ++ return; ++ } + + ocp_write_word(tp, type, __le16_to_cpu(mac->bp_ba_addr), + __le16_to_cpu(mac->bp_ba_value)); + +- generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD, +- __le16_to_cpu(mac->bp_num) << 1, mac->bp, type); ++ if (generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD, ++ ALIGN(__le16_to_cpu(mac->bp_num) << 1, 4), ++ mac->bp, type) < 0) { ++ dev_err(&tp->intf->dev, "Write %s bp fail\n", ++ type ? "PLA" : "USB"); ++ return; ++ } + + bp_en_addr = __le16_to_cpu(mac->bp_en_addr); + if (bp_en_addr) +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index 2d14b0d78541a..6cc1b56ddde2f 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -61,9 +61,6 @@ + + /*-------------------------------------------------------------------------*/ + +-// randomly generated ethernet address +-static u8 node_id [ETH_ALEN]; +- + /* use ethtool to change the level for any given device */ + static int msg_level = -1; + module_param (msg_level, int, 0); +@@ -1731,7 +1728,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) + + dev->net = net; + strscpy(net->name, "usb%d", sizeof(net->name)); +- eth_hw_addr_set(net, node_id); + + /* rx and tx sides can use different message sizes; + * bind() should set rx_urb_size in that case. +@@ -1805,9 +1801,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) + goto out4; + } + +- /* let userspace know we have a random address */ +- if (ether_addr_equal(net->dev_addr, node_id)) +- net->addr_assign_type = NET_ADDR_RANDOM; ++ /* this flags the device for user space */ ++ if (!is_valid_ether_addr(net->dev_addr)) ++ eth_hw_addr_random(net); + + if ((dev->driver_info->flags & FLAG_WLAN) != 0) + SET_NETDEV_DEVTYPE(net, &wlan_type); +@@ -2217,7 +2213,6 @@ static int __init usbnet_init(void) + BUILD_BUG_ON( + sizeof_field(struct sk_buff, cb) < sizeof(struct skb_data)); + +- eth_random_addr(node_id); + return 0; + } + module_init(usbnet_init); +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index ba6fc27f4a1a1..dd2a7c95517be 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -1614,7 +1614,9 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, + { + const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; + int i; +- u8 ampdu_factor, rx_mcs_80, rx_mcs_160, max_nss; ++ u8 ampdu_factor, max_nss; ++ u8 rx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; ++ u8 rx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; + u16 mcs_160_map, mcs_80_map; + bool support_160; + u16 v; +@@ -3355,6 +3357,11 @@ static int ath12k_station_assoc(struct ath12k *ar, + + ath12k_peer_assoc_prepare(ar, vif, sta, &peer_arg, reassoc); + ++ if (peer_arg.peer_nss < 1) { ++ ath12k_warn(ar->ab, ++ "invalid peer NSS %d\n", peer_arg.peer_nss); ++ return -EINVAL; ++ } + ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg); + if (ret) { + ath12k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n", +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +index 543e93ec49d22..9ab669487de4d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +@@ -1086,6 +1086,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); ++ ieee80211_hw_set(hw, MFP_CAPABLE); + + hw->extra_tx_headroom = brcms_c_get_header_len(); + hw->queues = N_TX_QUEUES; +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +index c780e5ffcd596..bace9d01fd583 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +@@ -1318,7 +1318,8 @@ iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu) + static inline struct ieee80211_bss_conf * + iwl_mvm_rcu_fw_link_id_to_link_conf(struct iwl_mvm *mvm, u8 link_id, bool rcu) + { +- if (WARN_ON(link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf))) ++ if (IWL_FW_CHECK(mvm, link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf), ++ "erroneous FW link ID: %d\n", link_id)) + return NULL; + + if (rcu) +diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h +index 7bdec6c622481..dc6b4cf616bea 100644 +--- a/drivers/net/wireless/marvell/mwifiex/main.h ++++ b/drivers/net/wireless/marvell/mwifiex/main.h +@@ -1290,6 +1290,9 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, + + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { ++ if (adapter->priv[i]->bss_mode == NL80211_IFTYPE_UNSPECIFIED) ++ continue; ++ + if ((adapter->priv[i]->bss_num == bss_num) && + (adapter->priv[i]->bss_type == bss_type)) + break; +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index efd0c2915a051..04a64afcbf8a2 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -742,7 +742,6 @@ static struct rtw_hci_ops rtw_usb_ops = { + static int rtw_usb_init_rx(struct rtw_dev *rtwdev) + { + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); +- int i; + + rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq"); + if (!rtwusb->rxwq) { +@@ -754,13 +753,19 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev) + + INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler); + ++ return 0; ++} ++ ++static void rtw_usb_setup_rx(struct rtw_dev *rtwdev) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ int i; ++ + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i]; + + rtw_usb_rx_resubmit(rtwusb, rxcb); + } +- +- return 0; + } + + static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev) +@@ -897,6 +902,8 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) + goto err_destroy_rxwq; + } + ++ rtw_usb_setup_rx(rtwdev); ++ + return 0; + + err_destroy_rxwq: +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 2c3f55877a113..7fc1ab4d9e7d8 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2471,6 +2471,12 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev) + + static void nvme_pci_update_nr_queues(struct nvme_dev *dev) + { ++ if (!dev->ctrl.tagset) { ++ nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, ++ nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); ++ return; ++ } ++ + blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); + /* free previously allocated queues that are no longer usable */ + nvme_free_queues(dev, dev->online_queues); +@@ -2929,6 +2935,17 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + dmi_match(DMI_BOARD_NAME, "NS5x_7xPU") || + dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1")) + return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; ++ } else if (pdev->vendor == 0x144d && pdev->device == 0xa80d) { ++ /* ++ * Exclude Samsung 990 Evo from NVME_QUIRK_SIMPLE_SUSPEND ++ * because of high power consumption (> 2 Watt) in s2idle ++ * sleep. Only some boards with Intel CPU are affected. ++ */ ++ if (dmi_match(DMI_BOARD_NAME, "GMxPXxx") || ++ dmi_match(DMI_BOARD_NAME, "PH4PG31") || ++ dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || ++ dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71")) ++ return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; + } + + /* +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index c65a1f4421f60..bd142aed20f45 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -1859,8 +1859,10 @@ static u16 nvmet_tcp_install_queue(struct nvmet_sq *sq) + } + + queue->nr_cmds = sq->size * 2; +- if (nvmet_tcp_alloc_cmds(queue)) ++ if (nvmet_tcp_alloc_cmds(queue)) { ++ queue->nr_cmds = 0; + return NVME_SC_INTERNAL; ++ } + return 0; + } + +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index 040dfa01fa12e..e7fd1315d7edc 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -1253,13 +1253,13 @@ void nvmem_device_put(struct nvmem_device *nvmem) + EXPORT_SYMBOL_GPL(nvmem_device_put); + + /** +- * devm_nvmem_device_get() - Get nvmem cell of device form a given id ++ * devm_nvmem_device_get() - Get nvmem device of device form a given id + * + * @dev: Device that requests the nvmem device. + * @id: name id for the requested nvmem device. + * +- * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell +- * on success. The nvmem_cell will be freed by the automatically once the ++ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device ++ * on success. The nvmem_device will be freed by the automatically once the + * device is freed. + */ + struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id) +diff --git a/drivers/of/irq.c b/drivers/of/irq.c +index c94203ce65bb3..8fd63100ba8f0 100644 +--- a/drivers/of/irq.c ++++ b/drivers/of/irq.c +@@ -344,7 +344,8 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar + struct device_node *p; + const __be32 *addr; + u32 intsize; +- int i, res; ++ int i, res, addr_len; ++ __be32 addr_buf[3] = { 0 }; + + pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index); + +@@ -353,13 +354,19 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar + return of_irq_parse_oldworld(device, index, out_irq); + + /* Get the reg property (if any) */ +- addr = of_get_property(device, "reg", NULL); ++ addr = of_get_property(device, "reg", &addr_len); ++ ++ /* Prevent out-of-bounds read in case of longer interrupt parent address size */ ++ if (addr_len > (3 * sizeof(__be32))) ++ addr_len = 3 * sizeof(__be32); ++ if (addr) ++ memcpy(addr_buf, addr, addr_len); + + /* Try the new-style interrupts-extended first */ + res = of_parse_phandle_with_args(device, "interrupts-extended", + "#interrupt-cells", index, out_irq); + if (!res) +- return of_irq_parse_raw(addr, out_irq); ++ return of_irq_parse_raw(addr_buf, out_irq); + + /* Look for the interrupt parent. */ + p = of_irq_find_parent(device); +@@ -389,7 +396,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar + + + /* Check if there are any interrupt-map translations to process */ +- res = of_irq_parse_raw(addr, out_irq); ++ res = of_irq_parse_raw(addr_buf, out_irq); + out: + of_node_put(p); + return res; +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index 54a3c7f29f78a..c1dedc83759c6 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -34,6 +34,11 @@ + #define PCIE_DEVICEID_SHIFT 16 + + /* Application registers */ ++#define PID 0x000 ++#define RTL GENMASK(15, 11) ++#define RTL_SHIFT 11 ++#define AM6_PCI_PG1_RTL_VER 0x15 ++ + #define CMD_STATUS 0x004 + #define LTSSM_EN_VAL BIT(0) + #define OB_XLAT_EN_VAL BIT(1) +@@ -104,6 +109,8 @@ + + #define to_keystone_pcie(x) dev_get_drvdata((x)->dev) + ++#define PCI_DEVICE_ID_TI_AM654X 0xb00c ++ + struct ks_pcie_of_data { + enum dw_pcie_device_mode mode; + const struct dw_pcie_host_ops *host_ops; +@@ -518,7 +525,11 @@ static int ks_pcie_start_link(struct dw_pcie *pci) + static void ks_pcie_quirk(struct pci_dev *dev) + { + struct pci_bus *bus = dev->bus; ++ struct keystone_pcie *ks_pcie; ++ struct device *bridge_dev; + struct pci_dev *bridge; ++ u32 val; ++ + static const struct pci_device_id rc_pci_devids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2HK), + .class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, }, +@@ -530,6 +541,11 @@ static void ks_pcie_quirk(struct pci_dev *dev) + .class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, }, + { 0, }, + }; ++ static const struct pci_device_id am6_pci_devids[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654X), ++ .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, ++ { 0, }, ++ }; + + if (pci_is_root_bus(bus)) + bridge = dev; +@@ -551,10 +567,36 @@ static void ks_pcie_quirk(struct pci_dev *dev) + */ + if (pci_match_id(rc_pci_devids, bridge)) { + if (pcie_get_readrq(dev) > 256) { +- dev_info(&dev->dev, "limiting MRRS to 256\n"); ++ dev_info(&dev->dev, "limiting MRRS to 256 bytes\n"); + pcie_set_readrq(dev, 256); + } + } ++ ++ /* ++ * Memory transactions fail with PCI controller in AM654 PG1.0 ++ * when MRRS is set to more than 128 bytes. Force the MRRS to ++ * 128 bytes in all downstream devices. ++ */ ++ if (pci_match_id(am6_pci_devids, bridge)) { ++ bridge_dev = pci_get_host_bridge_device(dev); ++ if (!bridge_dev && !bridge_dev->parent) ++ return; ++ ++ ks_pcie = dev_get_drvdata(bridge_dev->parent); ++ if (!ks_pcie) ++ return; ++ ++ val = ks_pcie_app_readl(ks_pcie, PID); ++ val &= RTL; ++ val >>= RTL_SHIFT; ++ if (val != AM6_PCI_PG1_RTL_VER) ++ return; ++ ++ if (pcie_get_readrq(dev) > 128) { ++ dev_info(&dev->dev, "limiting MRRS to 128 bytes\n"); ++ pcie_set_readrq(dev, 128); ++ } ++ } + } + DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, ks_pcie_quirk); + +diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c +index 881d420637bf1..092c9ac0d26d2 100644 +--- a/drivers/pci/hotplug/pnv_php.c ++++ b/drivers/pci/hotplug/pnv_php.c +@@ -39,7 +39,6 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, + bool disable_device) + { + struct pci_dev *pdev = php_slot->pdev; +- int irq = php_slot->irq; + u16 ctrl; + + if (php_slot->irq > 0) { +@@ -58,7 +57,7 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, + php_slot->wq = NULL; + } + +- if (disable_device || irq > 0) { ++ if (disable_device) { + if (pdev->msix_enabled) + pci_disable_msix(pdev); + else if (pdev->msi_enabled) +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index a0f961a380fa9..53e9e9788bd54 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -5718,10 +5718,12 @@ static void pci_bus_lock(struct pci_bus *bus) + { + struct pci_dev *dev; + ++ pci_dev_lock(bus->self); + list_for_each_entry(dev, &bus->devices, bus_list) { +- pci_dev_lock(dev); + if (dev->subordinate) + pci_bus_lock(dev->subordinate); ++ else ++ pci_dev_lock(dev); + } + } + +@@ -5733,8 +5735,10 @@ static void pci_bus_unlock(struct pci_bus *bus) + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->subordinate) + pci_bus_unlock(dev->subordinate); +- pci_dev_unlock(dev); ++ else ++ pci_dev_unlock(dev); + } ++ pci_dev_unlock(bus->self); + } + + /* Return 1 on successful lock, 0 on contention */ +@@ -5742,15 +5746,15 @@ static int pci_bus_trylock(struct pci_bus *bus) + { + struct pci_dev *dev; + ++ if (!pci_dev_trylock(bus->self)) ++ return 0; ++ + list_for_each_entry(dev, &bus->devices, bus_list) { +- if (!pci_dev_trylock(dev)) +- goto unlock; + if (dev->subordinate) { +- if (!pci_bus_trylock(dev->subordinate)) { +- pci_dev_unlock(dev); ++ if (!pci_bus_trylock(dev->subordinate)) + goto unlock; +- } +- } ++ } else if (!pci_dev_trylock(dev)) ++ goto unlock; + } + return 1; + +@@ -5758,8 +5762,10 @@ static int pci_bus_trylock(struct pci_bus *bus) + list_for_each_entry_continue_reverse(dev, &bus->devices, bus_list) { + if (dev->subordinate) + pci_bus_unlock(dev->subordinate); +- pci_dev_unlock(dev); ++ else ++ pci_dev_unlock(dev); + } ++ pci_dev_unlock(bus->self); + return 0; + } + +@@ -5791,9 +5797,10 @@ static void pci_slot_lock(struct pci_slot *slot) + list_for_each_entry(dev, &slot->bus->devices, bus_list) { + if (!dev->slot || dev->slot != slot) + continue; +- pci_dev_lock(dev); + if (dev->subordinate) + pci_bus_lock(dev->subordinate); ++ else ++ pci_dev_lock(dev); + } + } + +@@ -5819,14 +5826,13 @@ static int pci_slot_trylock(struct pci_slot *slot) + list_for_each_entry(dev, &slot->bus->devices, bus_list) { + if (!dev->slot || dev->slot != slot) + continue; +- if (!pci_dev_trylock(dev)) +- goto unlock; + if (dev->subordinate) { + if (!pci_bus_trylock(dev->subordinate)) { + pci_dev_unlock(dev); + goto unlock; + } +- } ++ } else if (!pci_dev_trylock(dev)) ++ goto unlock; + } + return 1; + +@@ -5837,7 +5843,8 @@ static int pci_slot_trylock(struct pci_slot *slot) + continue; + if (dev->subordinate) + pci_bus_unlock(dev->subordinate); +- pci_dev_unlock(dev); ++ else ++ pci_dev_unlock(dev); + } + return 0; + } +diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c +index 1365eaa20ff49..ff169124929cc 100644 +--- a/drivers/pcmcia/yenta_socket.c ++++ b/drivers/pcmcia/yenta_socket.c +@@ -638,11 +638,11 @@ static int yenta_search_one_res(struct resource *root, struct resource *res, + start = PCIBIOS_MIN_CARDBUS_IO; + end = ~0U; + } else { +- unsigned long avail = root->end - root->start; ++ unsigned long avail = resource_size(root); + int i; + size = BRIDGE_MEM_MAX; +- if (size > avail/8) { +- size = (avail+1)/8; ++ if (size > (avail - 1) / 8) { ++ size = avail / 8; + /* round size down to next power of 2 */ + i = 0; + while ((size /= 2) != 0) +diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c +index 8c8b1ca31e4c4..c72b52955a867 100644 +--- a/drivers/phy/xilinx/phy-zynqmp.c ++++ b/drivers/phy/xilinx/phy-zynqmp.c +@@ -846,6 +846,7 @@ static struct phy *xpsgtr_xlate(struct device *dev, + phy_type = args->args[1]; + phy_instance = args->args[2]; + ++ guard(mutex)(>r_phy->phy->mutex); + ret = xpsgtr_set_lane_type(gtr_phy, phy_type, phy_instance); + if (ret < 0) { + dev_err(gtr_dev->dev, "Invalid PHY type and/or instance\n"); +diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c +index 86b95206cb1bd..6fb538a138689 100644 +--- a/drivers/platform/x86/dell/dell-smbios-base.c ++++ b/drivers/platform/x86/dell/dell-smbios-base.c +@@ -590,7 +590,10 @@ static int __init dell_smbios_init(void) + return 0; + + fail_sysfs: +- free_group(platform_device); ++ if (!wmi) ++ exit_dell_smbios_wmi(); ++ if (!smm) ++ exit_dell_smbios_smm(); + + fail_create_group: + platform_device_del(platform_device); +diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c +index a5a31dfa45122..ee2da8e49d4cf 100644 +--- a/drivers/scsi/pm8001/pm8001_sas.c ++++ b/drivers/scsi/pm8001/pm8001_sas.c +@@ -166,7 +166,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + unsigned long flags; + pm8001_ha = sas_phy->ha->lldd_ha; + phy = &pm8001_ha->phy[phy_id]; +- pm8001_ha->phy[phy_id].enable_completion = &completion; + + if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) { + /* +@@ -190,6 +189,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + rates->maximum_linkrate; + } + if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { ++ pm8001_ha->phy[phy_id].enable_completion = &completion; + PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); + wait_for_completion(&completion); + } +@@ -198,6 +198,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + break; + case PHY_FUNC_HARD_RESET: + if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { ++ pm8001_ha->phy[phy_id].enable_completion = &completion; + PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); + wait_for_completion(&completion); + } +@@ -206,6 +207,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + break; + case PHY_FUNC_LINK_RESET: + if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { ++ pm8001_ha->phy[phy_id].enable_completion = &completion; + PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); + wait_for_completion(&completion); + } +diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c +index 3c0f7dc9614d1..f7e268cf90850 100644 +--- a/drivers/spi/spi-fsl-lpspi.c ++++ b/drivers/spi/spi-fsl-lpspi.c +@@ -82,6 +82,10 @@ + #define TCR_RXMSK BIT(19) + #define TCR_TXMSK BIT(18) + ++struct fsl_lpspi_devtype_data { ++ u8 prescale_max; ++}; ++ + struct lpspi_config { + u8 bpw; + u8 chip_select; +@@ -119,10 +123,25 @@ struct fsl_lpspi_data { + bool usedma; + struct completion dma_rx_completion; + struct completion dma_tx_completion; ++ ++ const struct fsl_lpspi_devtype_data *devtype_data; ++}; ++ ++/* ++ * ERR051608 fixed or not: ++ * https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf ++ */ ++static struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = { ++ .prescale_max = 1, ++}; ++ ++static struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = { ++ .prescale_max = 7, + }; + + static const struct of_device_id fsl_lpspi_dt_ids[] = { +- { .compatible = "fsl,imx7ulp-spi", }, ++ { .compatible = "fsl,imx7ulp-spi", .data = &imx7ulp_lpspi_devtype_data,}, ++ { .compatible = "fsl,imx93-spi", .data = &imx93_lpspi_devtype_data,}, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids); +@@ -297,9 +316,11 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) + { + struct lpspi_config config = fsl_lpspi->config; + unsigned int perclk_rate, scldiv, div; ++ u8 prescale_max; + u8 prescale; + + perclk_rate = clk_get_rate(fsl_lpspi->clk_per); ++ prescale_max = fsl_lpspi->devtype_data->prescale_max; + + if (!config.speed_hz) { + dev_err(fsl_lpspi->dev, +@@ -315,7 +336,7 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) + + div = DIV_ROUND_UP(perclk_rate, config.speed_hz); + +- for (prescale = 0; prescale < 8; prescale++) { ++ for (prescale = 0; prescale <= prescale_max; prescale++) { + scldiv = div / (1 << prescale) - 2; + if (scldiv < 256) { + fsl_lpspi->config.prescale = prescale; +@@ -822,6 +843,7 @@ static int fsl_lpspi_init_rpm(struct fsl_lpspi_data *fsl_lpspi) + + static int fsl_lpspi_probe(struct platform_device *pdev) + { ++ const struct fsl_lpspi_devtype_data *devtype_data; + struct fsl_lpspi_data *fsl_lpspi; + struct spi_controller *controller; + struct resource *res; +@@ -830,6 +852,10 @@ static int fsl_lpspi_probe(struct platform_device *pdev) + u32 temp; + bool is_target; + ++ devtype_data = of_device_get_match_data(&pdev->dev); ++ if (!devtype_data) ++ return -ENODEV; ++ + is_target = of_property_read_bool((&pdev->dev)->of_node, "spi-slave"); + if (is_target) + controller = devm_spi_alloc_target(&pdev->dev, +@@ -848,6 +874,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) + fsl_lpspi->is_target = is_target; + fsl_lpspi->is_only_cs1 = of_property_read_bool((&pdev->dev)->of_node, + "fsl,spi-only-use-cs1-sel"); ++ fsl_lpspi->devtype_data = devtype_data; + + init_completion(&fsl_lpspi->xfer_done); + +diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c +index 6910b4d4c427b..16054695bdb04 100644 +--- a/drivers/spi/spi-hisi-kunpeng.c ++++ b/drivers/spi/spi-hisi-kunpeng.c +@@ -481,6 +481,9 @@ static int hisi_spi_probe(struct platform_device *pdev) + return -EINVAL; + } + ++ if (host->max_speed_hz == 0) ++ return dev_err_probe(dev, -EINVAL, "spi-max-frequency can't be 0\n"); ++ + ret = device_property_read_u16(dev, "num-cs", + &host->num_chipselect); + if (ret) +diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c +index 5b010094dace5..1f374cf4d6f65 100644 +--- a/drivers/spi/spi-rockchip.c ++++ b/drivers/spi/spi-rockchip.c +@@ -974,14 +974,16 @@ static int rockchip_spi_suspend(struct device *dev) + { + int ret; + struct spi_controller *ctlr = dev_get_drvdata(dev); +- struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); + + ret = spi_controller_suspend(ctlr); + if (ret < 0) + return ret; + +- clk_disable_unprepare(rs->spiclk); +- clk_disable_unprepare(rs->apb_pclk); ++ ret = pm_runtime_force_suspend(dev); ++ if (ret < 0) { ++ spi_controller_resume(ctlr); ++ return ret; ++ } + + pinctrl_pm_select_sleep_state(dev); + +@@ -992,25 +994,14 @@ static int rockchip_spi_resume(struct device *dev) + { + int ret; + struct spi_controller *ctlr = dev_get_drvdata(dev); +- struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); + + pinctrl_pm_select_default_state(dev); + +- ret = clk_prepare_enable(rs->apb_pclk); ++ ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret; + +- ret = clk_prepare_enable(rs->spiclk); +- if (ret < 0) +- clk_disable_unprepare(rs->apb_pclk); +- +- ret = spi_controller_resume(ctlr); +- if (ret < 0) { +- clk_disable_unprepare(rs->spiclk); +- clk_disable_unprepare(rs->apb_pclk); +- } +- +- return 0; ++ return spi_controller_resume(ctlr); + } + #endif /* CONFIG_PM_SLEEP */ + +diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c +index 285df0e489a62..cfdfe66d74f17 100644 +--- a/drivers/staging/iio/frequency/ad9834.c ++++ b/drivers/staging/iio/frequency/ad9834.c +@@ -114,7 +114,7 @@ static int ad9834_write_frequency(struct ad9834_state *st, + + clk_freq = clk_get_rate(st->mclk); + +- if (fout > (clk_freq / 2)) ++ if (!clk_freq || fout > (clk_freq / 2)) + return -EINVAL; + + regval = ad9834_calc_freqreg(clk_freq, fout); +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index ad0ef5b6b8cf9..ed59d2367a4e7 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -10130,7 +10130,8 @@ void ufshcd_remove(struct ufs_hba *hba) + blk_mq_destroy_queue(hba->tmf_queue); + blk_put_queue(hba->tmf_queue); + blk_mq_free_tag_set(&hba->tmf_tag_set); +- scsi_remove_host(hba->host); ++ if (hba->scsi_host_added) ++ scsi_remove_host(hba->host); + /* disable interrupts */ + ufshcd_disable_intr(hba, hba->intr_mask); + ufshcd_hba_stop(hba); +@@ -10408,6 +10409,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + dev_err(hba->dev, "scsi_add_host failed\n"); + goto out_disable; + } ++ hba->scsi_host_added = true; + } + + hba->tmf_tag_set = (struct blk_mq_tag_set) { +@@ -10489,7 +10491,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + free_tmf_tag_set: + blk_mq_free_tag_set(&hba->tmf_tag_set); + out_remove_scsi_host: +- scsi_remove_host(hba->host); ++ if (hba->scsi_host_added) ++ scsi_remove_host(hba->host); + out_disable: + hba->is_irq_enabled = false; + ufshcd_hba_exit(hba); +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index 6be3462b109ff..a2c7abf8c289e 100644 +--- a/drivers/uio/uio_hv_generic.c ++++ b/drivers/uio/uio_hv_generic.c +@@ -104,10 +104,11 @@ static void hv_uio_channel_cb(void *context) + + /* + * Callback from vmbus_event when channel is rescinded. ++ * It is meant for rescind of primary channels only. + */ + static void hv_uio_rescind(struct vmbus_channel *channel) + { +- struct hv_device *hv_dev = channel->primary_channel->device_obj; ++ struct hv_device *hv_dev = channel->device_obj; + struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev); + + /* +@@ -118,6 +119,14 @@ static void hv_uio_rescind(struct vmbus_channel *channel) + + /* Wake up reader */ + uio_event_notify(&pdata->info); ++ ++ /* ++ * With rescind callback registered, rescind path will not unregister the device ++ * from vmbus when the primary channel is rescinded. ++ * Without it, rescind handling is incomplete and next onoffer msg does not come. ++ * Unregister the device from vmbus here. ++ */ ++ vmbus_device_unregister(channel->device_obj); + } + + /* Sysfs API to allow mmap of the ring buffers +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 21ff6cbe5e49f..9955091c53360 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1288,6 +1288,21 @@ static int dwc3_core_init(struct dwc3 *dwc) + dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); + } + ++ /* ++ * STAR 9001285599: This issue affects DWC_usb3 version 3.20a ++ * only. If the PM TIMER ECM is enabled through GUCTL2[19], the ++ * link compliance test (TD7.21) may fail. If the ECN is not ++ * enabled (GUCTL2[19] = 0), the controller will use the old timer ++ * value (5us), which is still acceptable for the link compliance ++ * test. Therefore, do not enable PM TIMER ECM in 3.20a by ++ * setting GUCTL2[19] by default; instead, use GUCTL2[19] = 0. ++ */ ++ if (DWC3_VER_IS(DWC3, 320A)) { ++ reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); ++ reg &= ~DWC3_GUCTL2_LC_TIMER; ++ dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); ++ } ++ + /* + * When configured in HOST mode, after issuing U3/L2 exit controller + * fails to send proper CRC checksum in CRC5 feild. Because of this +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index 07b062c2f6479..db1a793a9b13f 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -408,6 +408,7 @@ + + /* Global User Control Register 2 */ + #define DWC3_GUCTL2_RST_ACTBITLATER BIT(14) ++#define DWC3_GUCTL2_LC_TIMER BIT(19) + + /* Global User Control Register 3 */ + #define DWC3_GUCTL3_SPLITDISABLE BIT(14) +@@ -1238,6 +1239,7 @@ struct dwc3 { + #define DWC3_REVISION_290A 0x5533290a + #define DWC3_REVISION_300A 0x5533300a + #define DWC3_REVISION_310A 0x5533310a ++#define DWC3_REVISION_320A 0x5533320a + #define DWC3_REVISION_330A 0x5533330a + + #define DWC31_REVISION_ANY 0x0 +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 579d90efc281a..1a1da4a057019 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -287,6 +287,23 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc, bool async); + * + * Caller should handle locking. This function will issue @cmd with given + * @params to @dep and wait for its completion. ++ * ++ * According to the programming guide, if the link state is in L1/L2/U3, ++ * then sending the Start Transfer command may not complete. The ++ * programming guide suggested to bring the link state back to ON/U0 by ++ * performing remote wakeup prior to sending the command. However, don't ++ * initiate remote wakeup when the user/function does not send wakeup ++ * request via wakeup ops. Send the command when it's allowed. ++ * ++ * Notes: ++ * For L1 link state, issuing a command requires the clearing of ++ * GUSB2PHYCFG.SUSPENDUSB2, which turns on the signal required to complete ++ * the given command (usually within 50us). This should happen within the ++ * command timeout set by driver. No additional step is needed. ++ * ++ * For L2 or U3 link state, the gadget is in USB suspend. Care should be ++ * taken when sending Start Transfer command to ensure that it's done after ++ * USB resume. + */ + int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, + struct dwc3_gadget_ep_cmd_params *params) +@@ -327,30 +344,6 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + } + +- if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { +- int link_state; +- +- /* +- * Initiate remote wakeup if the link state is in U3 when +- * operating in SS/SSP or L1/L2 when operating in HS/FS. If the +- * link state is in U1/U2, no remote wakeup is needed. The Start +- * Transfer command will initiate the link recovery. +- */ +- link_state = dwc3_gadget_get_link_state(dwc); +- switch (link_state) { +- case DWC3_LINK_STATE_U2: +- if (dwc->gadget->speed >= USB_SPEED_SUPER) +- break; +- +- fallthrough; +- case DWC3_LINK_STATE_U3: +- ret = __dwc3_gadget_wakeup(dwc, false); +- dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n", +- ret); +- break; +- } +- } +- + /* + * For some commands such as Update Transfer command, DEPCMDPARn + * registers are reserved. Since the driver often sends Update Transfer +diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c +index fc2ead0fe6217..4868286574a1c 100644 +--- a/drivers/usb/gadget/udc/aspeed_udc.c ++++ b/drivers/usb/gadget/udc/aspeed_udc.c +@@ -1009,6 +1009,8 @@ static void ast_udc_getstatus(struct ast_udc_dev *udc) + break; + case USB_RECIP_ENDPOINT: + epnum = crq.wIndex & USB_ENDPOINT_NUMBER_MASK; ++ if (epnum >= AST_UDC_NUM_ENDPOINTS) ++ goto stall; + status = udc->ep[epnum].stopped; + break; + default: +diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c +index 0eed0e03842cf..d394affb70723 100644 +--- a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c ++++ b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c +@@ -2251,7 +2251,6 @@ static int cdns2_gadget_start(struct cdns2_device *pdev) + { + u32 max_speed; + void *buf; +- int val; + int ret; + + pdev->usb_regs = pdev->regs; +@@ -2261,14 +2260,9 @@ static int cdns2_gadget_start(struct cdns2_device *pdev) + pdev->adma_regs = pdev->regs + CDNS2_ADMA_REGS_OFFSET; + + /* Reset controller. */ +- set_reg_bit_8(&pdev->usb_regs->cpuctrl, CPUCTRL_SW_RST); +- +- ret = readl_poll_timeout_atomic(&pdev->usb_regs->cpuctrl, val, +- !(val & CPUCTRL_SW_RST), 1, 10000); +- if (ret) { +- dev_err(pdev->dev, "Error: reset controller timeout\n"); +- return -EINVAL; +- } ++ writeb(CPUCTRL_SW_RST | CPUCTRL_UPCLK | CPUCTRL_WUEN, ++ &pdev->usb_regs->cpuctrl); ++ usleep_range(5, 10); + + usb_initialize_gadget(pdev->dev, &pdev->gadget, NULL); + +diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.h b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.h +index 71e2f62d653a5..b5d5ec12e986e 100644 +--- a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.h ++++ b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.h +@@ -292,8 +292,17 @@ struct cdns2_usb_regs { + #define SPEEDCTRL_HSDISABLE BIT(7) + + /* CPUCTRL- bitmasks. */ ++/* UP clock enable */ ++#define CPUCTRL_UPCLK BIT(0) + /* Controller reset bit. */ + #define CPUCTRL_SW_RST BIT(1) ++/** ++ * If the wuen bit is ‘1’, the upclken is automatically set to ‘1’ after ++ * detecting rising edge of wuintereq interrupt. If the wuen bit is ‘0’, ++ * the wuintereq interrupt is ignored. ++ */ ++#define CPUCTRL_WUEN BIT(7) ++ + + /** + * struct cdns2_adma_regs - ADMA controller registers. +diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c +index 451d9569163a7..f794cb39cc313 100644 +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -422,6 +422,7 @@ static void uas_data_cmplt(struct urb *urb) + uas_log_cmd_state(cmnd, "data cmplt err", status); + /* error: no data transfered */ + scsi_set_resid(cmnd, sdb->length); ++ set_host_byte(cmnd, DID_ERROR); + } else { + scsi_set_resid(cmnd, sdb->length - urb->actual_length); + } +diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c +index a94ec6225d31a..5f9e7e4770783 100644 +--- a/drivers/vfio/vfio_iommu_spapr_tce.c ++++ b/drivers/vfio/vfio_iommu_spapr_tce.c +@@ -364,7 +364,6 @@ static void tce_iommu_release(void *iommu_data) + if (!tbl) + continue; + +- tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); + tce_iommu_free_table(container, tbl); + } + +@@ -720,6 +719,8 @@ static long tce_iommu_remove_window(struct tce_container *container, + + BUG_ON(!tbl->it_size); + ++ tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); ++ + /* Detach groups from IOMMUs */ + list_for_each_entry(tcegrp, &container->group_list, next) { + table_group = iommu_group_get_iommudata(tcegrp->grp); +@@ -738,7 +739,6 @@ static long tce_iommu_remove_window(struct tce_container *container, + } + + /* Free table */ +- tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); + tce_iommu_free_table(container, tbl); + container->tables[num] = NULL; + +@@ -1197,9 +1197,14 @@ static void tce_iommu_release_ownership(struct tce_container *container, + return; + } + +- for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) +- if (container->tables[i]) ++ for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { ++ if (container->tables[i]) { ++ tce_iommu_clear(container, container->tables[i], ++ container->tables[i]->it_offset, ++ container->tables[i]->it_size); + table_group->ops->unset_window(table_group, i); ++ } ++ } + } + + static long tce_iommu_take_ownership(struct tce_container *container, +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 6f7e5010a6735..80669e05bf0ee 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -3126,8 +3126,10 @@ dma_addr_t virtqueue_dma_map_single_attrs(struct virtqueue *_vq, void *ptr, + { + struct vring_virtqueue *vq = to_vvq(_vq); + +- if (!vq->use_dma_api) ++ if (!vq->use_dma_api) { ++ kmsan_handle_dma(virt_to_page(ptr), offset_in_page(ptr), size, dir); + return (dma_addr_t)virt_to_phys(ptr); ++ } + + return dma_map_single_attrs(vring_dma_dev(vq), ptr, size, dir, attrs); + } +diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c +index 923f064c7e3e9..61aaded483e1d 100644 +--- a/drivers/xen/privcmd.c ++++ b/drivers/xen/privcmd.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -842,6 +843,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, + /* Irqfd support */ + static struct workqueue_struct *irqfd_cleanup_wq; + static DEFINE_SPINLOCK(irqfds_lock); ++DEFINE_STATIC_SRCU(irqfds_srcu); + static LIST_HEAD(irqfds_list); + + struct privcmd_kernel_irqfd { +@@ -869,6 +871,9 @@ static void irqfd_shutdown(struct work_struct *work) + container_of(work, struct privcmd_kernel_irqfd, shutdown); + u64 cnt; + ++ /* Make sure irqfd has been initialized in assign path */ ++ synchronize_srcu(&irqfds_srcu); ++ + eventfd_ctx_remove_wait_queue(kirqfd->eventfd, &kirqfd->wait, &cnt); + eventfd_ctx_put(kirqfd->eventfd); + kfree(kirqfd); +@@ -931,7 +936,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) + __poll_t events; + struct fd f; + void *dm_op; +- int ret; ++ int ret, idx; + + kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL); + if (!kirqfd) +@@ -977,6 +982,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) + } + } + ++ idx = srcu_read_lock(&irqfds_srcu); + list_add_tail(&kirqfd->list, &irqfds_list); + spin_unlock_irqrestore(&irqfds_lock, flags); + +@@ -988,6 +994,8 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) + if (events & EPOLLIN) + irqfd_inject(kirqfd); + ++ srcu_read_unlock(&irqfds_srcu, idx); ++ + /* + * Do not drop the file until the kirqfd is fully initialized, otherwise + * we might race against the EPOLLHUP. +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 7b3d2d4914073..fb2c8d14327ae 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1008,7 +1008,8 @@ static int load_elf_binary(struct linux_binprm *bprm) + if (elf_read_implies_exec(*elf_ex, executable_stack)) + current->personality |= READ_IMPLIES_EXEC; + +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) ++ const int snapshot_randomize_va_space = READ_ONCE(randomize_va_space); ++ if (!(current->personality & ADDR_NO_RANDOMIZE) && snapshot_randomize_va_space) + current->flags |= PF_RANDOMIZE; + + setup_new_exec(bprm); +@@ -1300,7 +1301,7 @@ static int load_elf_binary(struct linux_binprm *bprm) + mm->end_data = end_data; + mm->start_stack = bprm->p; + +- if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { ++ if ((current->flags & PF_RANDOMIZE) && (snapshot_randomize_va_space > 1)) { + /* + * For architectures with ELF randomization, when executing + * a loader directly (i.e. no interpreter listed in ELF +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 118ad4d2cbbe2..2eb4e03080ac9 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -451,8 +451,16 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, + } + + owner = btrfs_header_owner(buf); +- BUG_ON(owner == BTRFS_TREE_RELOC_OBJECTID && +- !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)); ++ if (unlikely(owner == BTRFS_TREE_RELOC_OBJECTID && ++ !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF))) { ++ btrfs_crit(fs_info, ++"found tree block at bytenr %llu level %d root %llu refs %llu flags %llx without full backref flag set", ++ buf->start, btrfs_header_level(buf), ++ btrfs_root_id(root), refs, flags); ++ ret = -EUCLEAN; ++ btrfs_abort_transaction(trans, ret); ++ return ret; ++ } + + if (refs > 1) { + if ((owner == root->root_key.objectid || +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index 86c7f8ce1715e..06333a74d6c4c 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -445,7 +445,6 @@ struct btrfs_file_private { + void *filldir_buf; + u64 last_index; + struct extent_state *llseek_cached_state; +- bool fsync_skip_inode_lock; + }; + + static inline u32 BTRFS_LEAF_DATA_SIZE(const struct btrfs_fs_info *info) +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index c6ecfd05e1db9..72851adc1feeb 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -5085,7 +5085,15 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, + /* We don't care about errors in readahead. */ + if (ret < 0) + continue; +- BUG_ON(refs == 0); ++ ++ /* ++ * This could be racey, it's conceivable that we raced and end ++ * up with a bogus refs count, if that's the case just skip, if ++ * we are actually corrupt we will notice when we look up ++ * everything again with our locks. ++ */ ++ if (refs == 0) ++ continue; + + if (wc->stage == DROP_REFERENCE) { + if (refs == 1) +@@ -5144,7 +5152,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, + if (lookup_info && + ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) || + (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) { +- BUG_ON(!path->locks[level]); ++ ASSERT(path->locks[level]); + ret = btrfs_lookup_extent_info(trans, fs_info, + eb->start, level, 1, + &wc->refs[level], +@@ -5152,7 +5160,11 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, + BUG_ON(ret == -ENOMEM); + if (ret) + return ret; +- BUG_ON(wc->refs[level] == 0); ++ if (unlikely(wc->refs[level] == 0)) { ++ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0", ++ eb->start); ++ return -EUCLEAN; ++ } + } + + if (wc->stage == DROP_REFERENCE) { +@@ -5168,7 +5180,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, + + /* wc->stage == UPDATE_BACKREF */ + if (!(wc->flags[level] & flag)) { +- BUG_ON(!path->locks[level]); ++ ASSERT(path->locks[level]); + ret = btrfs_inc_ref(trans, root, eb, 1); + BUG_ON(ret); /* -ENOMEM */ + ret = btrfs_dec_ref(trans, root, eb, 0); +@@ -5286,8 +5298,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, + goto out_unlock; + + if (unlikely(wc->refs[level - 1] == 0)) { +- btrfs_err(fs_info, "Missing references."); +- ret = -EIO; ++ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0", ++ bytenr); ++ ret = -EUCLEAN; + goto out_unlock; + } + *lookup_info = 0; +@@ -5487,7 +5500,12 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, + path->locks[level] = 0; + return ret; + } +- BUG_ON(wc->refs[level] == 0); ++ if (unlikely(wc->refs[level] == 0)) { ++ btrfs_tree_unlock_rw(eb, path->locks[level]); ++ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0", ++ eb->start); ++ return -EUCLEAN; ++ } + if (wc->refs[level] == 1) { + btrfs_tree_unlock_rw(eb, path->locks[level]); + path->locks[level] = 0; +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index 952cf145c6295..15fd8c00f4c08 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1543,13 +1543,6 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) + if (IS_ERR_OR_NULL(dio)) { + err = PTR_ERR_OR_ZERO(dio); + } else { +- struct btrfs_file_private stack_private = { 0 }; +- struct btrfs_file_private *private; +- const bool have_private = (file->private_data != NULL); +- +- if (!have_private) +- file->private_data = &stack_private; +- + /* + * If we have a synchoronous write, we must make sure the fsync + * triggered by the iomap_dio_complete() call below doesn't +@@ -1558,13 +1551,10 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) + * partial writes due to the input buffer (or parts of it) not + * being already faulted in. + */ +- private = file->private_data; +- private->fsync_skip_inode_lock = true; ++ ASSERT(current->journal_info == NULL); ++ current->journal_info = BTRFS_TRANS_DIO_WRITE_STUB; + err = iomap_dio_complete(dio); +- private->fsync_skip_inode_lock = false; +- +- if (!have_private) +- file->private_data = NULL; ++ current->journal_info = NULL; + } + + /* No increment (+=) because iomap returns a cumulative value. */ +@@ -1796,7 +1786,6 @@ static inline bool skip_inode_logging(const struct btrfs_log_ctx *ctx) + */ + int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + { +- struct btrfs_file_private *private = file->private_data; + struct dentry *dentry = file_dentry(file); + struct inode *inode = d_inode(dentry); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); +@@ -1806,7 +1795,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + int ret = 0, err; + u64 len; + bool full_sync; +- const bool skip_ilock = (private ? private->fsync_skip_inode_lock : false); ++ bool skip_ilock = false; ++ ++ if (current->journal_info == BTRFS_TRANS_DIO_WRITE_STUB) { ++ skip_ilock = true; ++ current->journal_info = NULL; ++ lockdep_assert_held(&inode->i_rwsem); ++ } + + trace_btrfs_sync_file(file, datasync); + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 18ce5353092d7..a422382118878 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -5668,7 +5668,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) + struct inode *inode; + struct btrfs_root *root = BTRFS_I(dir)->root; + struct btrfs_root *sub_root = root; +- struct btrfs_key location; ++ struct btrfs_key location = { 0 }; + u8 di_type = 0; + int ret = 0; + +diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h +index 238a0ab85df9b..7623db359881e 100644 +--- a/fs/btrfs/transaction.h ++++ b/fs/btrfs/transaction.h +@@ -12,6 +12,12 @@ + #include "ctree.h" + #include "misc.h" + ++/* ++ * Signal that a direct IO write is in progress, to avoid deadlock for sync ++ * direct IO writes when fsync is called during the direct IO write path. ++ */ ++#define BTRFS_TRANS_DIO_WRITE_STUB ((void *) 1) ++ + /* Radix-tree tag for roots that are part of the trasaction. */ + #define BTRFS_ROOT_TRANS_TAG 0 + +diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c +index 5d473e50598f9..f32a91d7c05d9 100644 +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -353,7 +353,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handl + read_unlock(&sbi->s_journal->j_state_lock); + } + spin_lock(&sbi->s_fc_lock); +- if (sbi->s_fc_ineligible_tid < tid) ++ if (tid_gt(tid, sbi->s_fc_ineligible_tid)) + sbi->s_fc_ineligible_tid = tid; + spin_unlock(&sbi->s_fc_lock); + WARN_ON(reason >= EXT4_FC_REASON_MAX); +@@ -1213,7 +1213,7 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid) + if (ret == -EALREADY) { + /* There was an ongoing commit, check if we need to restart */ + if (atomic_read(&sbi->s_fc_subtid) <= subtid && +- commit_tid > journal->j_commit_sequence) ++ tid_gt(commit_tid, journal->j_commit_sequence)) + goto restart_fc; + ext4_fc_update_stats(sb, EXT4_FC_STATUS_SKIPPED, 0, 0, + commit_tid); +@@ -1288,7 +1288,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid) + list_del_init(&iter->i_fc_list); + ext4_clear_inode_state(&iter->vfs_inode, + EXT4_STATE_FC_COMMITTING); +- if (iter->i_sync_tid <= tid) ++ if (tid_geq(tid, iter->i_sync_tid)) + ext4_fc_reset_inode(&iter->vfs_inode); + /* Make sure EXT4_STATE_FC_COMMITTING bit is clear */ + smp_mb(); +@@ -1319,7 +1319,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid) + list_splice_init(&sbi->s_fc_q[FC_Q_STAGING], + &sbi->s_fc_q[FC_Q_MAIN]); + +- if (tid >= sbi->s_fc_ineligible_tid) { ++ if (tid_geq(tid, sbi->s_fc_ineligible_tid)) { + sbi->s_fc_ineligible_tid = 0; + ext4_clear_mount_flag(sb, EXT4_MF_FC_INELIGIBLE); + } +diff --git a/fs/fscache/main.c b/fs/fscache/main.c +index dad85fd84f6f9..7a60cd96e87ea 100644 +--- a/fs/fscache/main.c ++++ b/fs/fscache/main.c +@@ -114,6 +114,7 @@ static void __exit fscache_exit(void) + + kmem_cache_destroy(fscache_cookie_jar); + fscache_proc_cleanup(); ++ timer_shutdown_sync(&fscache_cookie_lru_timer); + destroy_workqueue(fscache_wq); + pr_notice("Unloaded\n"); + } +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index c1703d2c4bf9a..95f9913a35373 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -668,7 +668,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, + + err = get_create_ext(&args, dir, entry, mode); + if (err) +- goto out_put_forget_req; ++ goto out_free_ff; + + err = fuse_simple_request(fm, &args); + free_ext_value(&args); +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index cc9651a01351c..ceb9f7d230388 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -1735,10 +1735,16 @@ __acquires(fi->lock) + fuse_writepage_finish(fm, wpa); + spin_unlock(&fi->lock); + +- /* After fuse_writepage_finish() aux request list is private */ ++ /* After rb_erase() aux request list is private */ + for (aux = wpa->next; aux; aux = next) { ++ struct backing_dev_info *bdi = inode_to_bdi(aux->inode); ++ + next = aux->next; + aux->next = NULL; ++ ++ dec_wb_stat(&bdi->wb, WB_WRITEBACK); ++ dec_node_page_state(aux->ia.ap.pages[0], NR_WRITEBACK_TEMP); ++ wb_writeout_inc(&bdi->wb); + fuse_writepage_free(aux); + } + +diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c +index 49c01559580f4..690b9aadceaa8 100644 +--- a/fs/fuse/xattr.c ++++ b/fs/fuse/xattr.c +@@ -81,7 +81,7 @@ ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, + } + ret = fuse_simple_request(fm, &args); + if (!ret && !size) +- ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX); ++ ret = min_t(size_t, outarg.size, XATTR_SIZE_MAX); + if (ret == -ENOSYS) { + fm->fc->no_getxattr = 1; + ret = -EOPNOTSUPP; +@@ -143,7 +143,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) + } + ret = fuse_simple_request(fm, &args); + if (!ret && !size) +- ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX); ++ ret = min_t(size_t, outarg.size, XATTR_LIST_MAX); + if (ret > 0 && size) + ret = fuse_verify_xattr_list(list, ret); + if (ret == -ENOSYS) { +diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c +index 5b771a3d8d9ae..421c0d360836e 100644 +--- a/fs/jbd2/recovery.c ++++ b/fs/jbd2/recovery.c +@@ -448,6 +448,27 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf) + return provided == cpu_to_be32(calculated); + } + ++static bool jbd2_commit_block_csum_verify_partial(journal_t *j, void *buf) ++{ ++ struct commit_header *h; ++ __be32 provided; ++ __u32 calculated; ++ void *tmpbuf; ++ ++ tmpbuf = kzalloc(j->j_blocksize, GFP_KERNEL); ++ if (!tmpbuf) ++ return false; ++ ++ memcpy(tmpbuf, buf, sizeof(struct commit_header)); ++ h = tmpbuf; ++ provided = h->h_chksum[0]; ++ h->h_chksum[0] = 0; ++ calculated = jbd2_chksum(j, j->j_csum_seed, tmpbuf, j->j_blocksize); ++ kfree(tmpbuf); ++ ++ return provided == cpu_to_be32(calculated); ++} ++ + static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag, + journal_block_tag3_t *tag3, + void *buf, __u32 sequence) +@@ -814,6 +835,13 @@ static int do_one_pass(journal_t *journal, + if (pass == PASS_SCAN && + !jbd2_commit_block_csum_verify(journal, + bh->b_data)) { ++ if (jbd2_commit_block_csum_verify_partial( ++ journal, ++ bh->b_data)) { ++ pr_notice("JBD2: Find incomplete commit block in transaction %u block %lu\n", ++ next_commit_ID, next_log_block); ++ goto chksum_ok; ++ } + chksum_error: + if (commit_time < last_trans_commit_time) + goto ignore_crc_mismatch; +@@ -828,6 +856,7 @@ static int do_one_pass(journal_t *journal, + } + } + if (pass == PASS_SCAN) { ++ chksum_ok: + last_trans_commit_time = commit_time; + head_block = next_log_block; + } +@@ -847,6 +876,7 @@ static int do_one_pass(journal_t *journal, + next_log_block); + need_check_commit_time = true; + } ++ + /* If we aren't in the REVOKE pass, then we can + * just skip over this block. */ + if (pass != PASS_REVOKE) { +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index 0d6473cb00cb3..f63513e477c50 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -223,6 +224,7 @@ static int __nfs_list_for_each_server(struct list_head *head, + ret = fn(server, data); + if (ret) + goto out; ++ cond_resched(); + rcu_read_lock(); + } + rcu_read_unlock(); +diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c +index a9b8d77c8c1d5..ce30b51ac593c 100644 +--- a/fs/nilfs2/recovery.c ++++ b/fs/nilfs2/recovery.c +@@ -708,6 +708,33 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, + brelse(bh); + } + ++/** ++ * nilfs_abort_roll_forward - cleaning up after a failed rollforward recovery ++ * @nilfs: nilfs object ++ */ ++static void nilfs_abort_roll_forward(struct the_nilfs *nilfs) ++{ ++ struct nilfs_inode_info *ii, *n; ++ LIST_HEAD(head); ++ ++ /* Abandon inodes that have read recovery data */ ++ spin_lock(&nilfs->ns_inode_lock); ++ list_splice_init(&nilfs->ns_dirty_files, &head); ++ spin_unlock(&nilfs->ns_inode_lock); ++ if (list_empty(&head)) ++ return; ++ ++ set_nilfs_purging(nilfs); ++ list_for_each_entry_safe(ii, n, &head, i_dirty) { ++ spin_lock(&nilfs->ns_inode_lock); ++ list_del_init(&ii->i_dirty); ++ spin_unlock(&nilfs->ns_inode_lock); ++ ++ iput(&ii->vfs_inode); ++ } ++ clear_nilfs_purging(nilfs); ++} ++ + /** + * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint + * @nilfs: nilfs object +@@ -766,15 +793,19 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, + if (unlikely(err)) { + nilfs_err(sb, "error %d writing segment for recovery", + err); +- goto failed; ++ goto put_root; + } + + nilfs_finish_roll_forward(nilfs, ri); + } + +- failed: ++put_root: + nilfs_put_root(root); + return err; ++ ++failed: ++ nilfs_abort_roll_forward(nilfs); ++ goto put_root; + } + + /** +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index e10f8a777ab06..0610cb12c11ca 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -1835,6 +1835,9 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci, + nilfs_abort_logs(&logs, ret ? : err); + + list_splice_tail_init(&sci->sc_segbufs, &logs); ++ if (list_empty(&logs)) ++ return; /* if the first segment buffer preparation failed */ ++ + nilfs_cancel_segusage(&logs, nilfs->ns_sufile); + nilfs_free_incomplete_logs(&logs, nilfs); + +@@ -2079,7 +2082,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) + + err = nilfs_segctor_begin_construction(sci, nilfs); + if (unlikely(err)) +- goto out; ++ goto failed; + + /* Update time stamp */ + sci->sc_seg_ctime = ktime_get_real_seconds(); +@@ -2142,10 +2145,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) + return err; + + failed_to_write: +- if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) +- nilfs_redirty_inodes(&sci->sc_dirty_files); +- + failed: ++ if (mode == SC_LSEG_SR && nilfs_sc_cstage_get(sci) >= NILFS_ST_IFILE) ++ nilfs_redirty_inodes(&sci->sc_dirty_files); + if (nilfs_doing_gc()) + nilfs_redirty_inodes(&sci->sc_gc_inodes); + nilfs_segctor_abort_construction(sci, nilfs, err); +diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c +index 379d22e28ed62..905c7eadf9676 100644 +--- a/fs/nilfs2/sysfs.c ++++ b/fs/nilfs2/sysfs.c +@@ -836,9 +836,15 @@ ssize_t nilfs_dev_revision_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; +- u32 major = le32_to_cpu(sbp[0]->s_rev_level); +- u16 minor = le16_to_cpu(sbp[0]->s_minor_rev_level); ++ struct nilfs_super_block *raw_sb; ++ u32 major; ++ u16 minor; ++ ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ major = le32_to_cpu(raw_sb->s_rev_level); ++ minor = le16_to_cpu(raw_sb->s_minor_rev_level); ++ up_read(&nilfs->ns_sem); + + return sysfs_emit(buf, "%d.%d\n", major, minor); + } +@@ -856,8 +862,13 @@ ssize_t nilfs_dev_device_size_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; +- u64 dev_size = le64_to_cpu(sbp[0]->s_dev_size); ++ struct nilfs_super_block *raw_sb; ++ u64 dev_size; ++ ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ dev_size = le64_to_cpu(raw_sb->s_dev_size); ++ up_read(&nilfs->ns_sem); + + return sysfs_emit(buf, "%llu\n", dev_size); + } +@@ -879,9 +890,15 @@ ssize_t nilfs_dev_uuid_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; ++ struct nilfs_super_block *raw_sb; ++ ssize_t len; + +- return sysfs_emit(buf, "%pUb\n", sbp[0]->s_uuid); ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ len = sysfs_emit(buf, "%pUb\n", raw_sb->s_uuid); ++ up_read(&nilfs->ns_sem); ++ ++ return len; + } + + static +@@ -889,10 +906,16 @@ ssize_t nilfs_dev_volume_name_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; ++ struct nilfs_super_block *raw_sb; ++ ssize_t len; ++ ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ len = scnprintf(buf, sizeof(raw_sb->s_volume_name), "%s\n", ++ raw_sb->s_volume_name); ++ up_read(&nilfs->ns_sem); + +- return scnprintf(buf, sizeof(sbp[0]->s_volume_name), "%s\n", +- sbp[0]->s_volume_name); ++ return len; + } + + static const char dev_readme_str[] = +diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c +index 9d0a09f00b384..e1b856ecce61d 100644 +--- a/fs/ntfs3/dir.c ++++ b/fs/ntfs3/dir.c +@@ -272,9 +272,12 @@ struct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni, + return err == -ENOENT ? NULL : err ? ERR_PTR(err) : inode; + } + +-static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, +- const struct NTFS_DE *e, u8 *name, +- struct dir_context *ctx) ++/* ++ * returns false if 'ctx' if full ++ */ ++static inline bool ntfs_dir_emit(struct ntfs_sb_info *sbi, ++ struct ntfs_inode *ni, const struct NTFS_DE *e, ++ u8 *name, struct dir_context *ctx) + { + const struct ATTR_FILE_NAME *fname; + unsigned long ino; +@@ -284,29 +287,29 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + fname = Add2Ptr(e, sizeof(struct NTFS_DE)); + + if (fname->type == FILE_NAME_DOS) +- return 0; ++ return true; + + if (!mi_is_ref(&ni->mi, &fname->home)) +- return 0; ++ return true; + + ino = ino_get(&e->ref); + + if (ino == MFT_REC_ROOT) +- return 0; ++ return true; + + /* Skip meta files. Unless option to show metafiles is set. */ + if (!sbi->options->showmeta && ntfs_is_meta_file(sbi, ino)) +- return 0; ++ return true; + + if (sbi->options->nohidden && (fname->dup.fa & FILE_ATTRIBUTE_HIDDEN)) +- return 0; ++ return true; + + name_len = ntfs_utf16_to_nls(sbi, fname->name, fname->name_len, name, + PATH_MAX); + if (name_len <= 0) { + ntfs_warn(sbi->sb, "failed to convert name for inode %lx.", + ino); +- return 0; ++ return true; + } + + /* +@@ -336,17 +339,20 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + } + } + +- return !dir_emit(ctx, (s8 *)name, name_len, ino, dt_type); ++ return dir_emit(ctx, (s8 *)name, name_len, ino, dt_type); + } + + /* + * ntfs_read_hdr - Helper function for ntfs_readdir(). ++ * ++ * returns 0 if ok. ++ * returns -EINVAL if directory is corrupted. ++ * returns +1 if 'ctx' is full. + */ + static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + const struct INDEX_HDR *hdr, u64 vbo, u64 pos, + u8 *name, struct dir_context *ctx) + { +- int err; + const struct NTFS_DE *e; + u32 e_size; + u32 end = le32_to_cpu(hdr->used); +@@ -354,12 +360,12 @@ static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + + for (;; off += e_size) { + if (off + sizeof(struct NTFS_DE) > end) +- return -1; ++ return -EINVAL; + + e = Add2Ptr(hdr, off); + e_size = le16_to_cpu(e->size); + if (e_size < sizeof(struct NTFS_DE) || off + e_size > end) +- return -1; ++ return -EINVAL; + + if (de_is_last(e)) + return 0; +@@ -369,14 +375,15 @@ static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + continue; + + if (le16_to_cpu(e->key_size) < SIZEOF_ATTRIBUTE_FILENAME) +- return -1; ++ return -EINVAL; + + ctx->pos = vbo + off; + + /* Submit the name to the filldir callback. */ +- err = ntfs_filldir(sbi, ni, e, name, ctx); +- if (err) +- return err; ++ if (!ntfs_dir_emit(sbi, ni, e, name, ctx)) { ++ /* ctx is full. */ ++ return +1; ++ } + } + } + +@@ -475,8 +482,6 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx) + + vbo = (u64)bit << index_bits; + if (vbo >= i_size) { +- ntfs_inode_err(dir, "Looks like your dir is corrupt"); +- ctx->pos = eod; + err = -EINVAL; + goto out; + } +@@ -499,9 +504,16 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx) + __putname(name); + put_indx_node(node); + +- if (err == -ENOENT) { ++ if (err == 1) { ++ /* 'ctx' is full. */ ++ err = 0; ++ } else if (err == -ENOENT) { + err = 0; + ctx->pos = pos; ++ } else if (err < 0) { ++ if (err == -EINVAL) ++ ntfs_inode_err(dir, "directory corrupted"); ++ ctx->pos = eod; + } + + return err; +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 45b687aff700b..f7c381730b396 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1601,8 +1601,10 @@ int ni_delete_all(struct ntfs_inode *ni) + asize = le32_to_cpu(attr->size); + roff = le16_to_cpu(attr->nres.run_off); + +- if (roff > asize) ++ if (roff > asize) { ++ _ntfs_bad_inode(&ni->vfs_inode); + return -EINVAL; ++ } + + /* run==1 means unpack and deallocate. */ + run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn, +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 15cbfec4c28c7..dd8acd2077521 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -1106,6 +1106,8 @@ int smb2_rename_path(const unsigned int xid, + co, DELETE, SMB2_OP_RENAME, cfile, source_dentry); + if (rc == -EINVAL) { + cifs_dbg(FYI, "invalid lease key, resending request without lease"); ++ cifs_get_writable_path(tcon, from_name, ++ FIND_WR_WITH_DELETE, &cfile); + rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, + co, DELETE, SMB2_OP_RENAME, cfile, NULL); + } +@@ -1149,6 +1151,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, + cfile, NULL, NULL, dentry); + if (rc == -EINVAL) { + cifs_dbg(FYI, "invalid lease key, resending request without lease"); ++ cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + rc = smb2_compound_op(xid, tcon, cifs_sb, + full_path, &oparms, &in_iov, + &(int){SMB2_OP_SET_EOF}, 1, +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index 012d6ec12a691..acd5d7d793525 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -3186,13 +3186,15 @@ static long smb3_zero_data(struct file *file, struct cifs_tcon *tcon, + } + + static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, +- loff_t offset, loff_t len, bool keep_size) ++ unsigned long long offset, unsigned long long len, ++ bool keep_size) + { + struct cifs_ses *ses = tcon->ses; + struct inode *inode = file_inode(file); + struct cifsInodeInfo *cifsi = CIFS_I(inode); + struct cifsFileInfo *cfile = file->private_data; +- unsigned long long new_size; ++ struct netfs_inode *ictx = netfs_inode(inode); ++ unsigned long long i_size, new_size, remote_size; + long rc; + unsigned int xid; + +@@ -3204,6 +3206,16 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, + inode_lock(inode); + filemap_invalidate_lock(inode->i_mapping); + ++ i_size = i_size_read(inode); ++ remote_size = ictx->remote_i_size; ++ if (offset + len >= remote_size && offset < i_size) { ++ unsigned long long top = umin(offset + len, i_size); ++ ++ rc = filemap_write_and_wait_range(inode->i_mapping, offset, top - 1); ++ if (rc < 0) ++ goto zero_range_exit; ++ } ++ + /* + * We zero the range through ioctl, so we need remove the page caches + * first, otherwise the data may be inconsistent with the server. +diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c +index a8f52c4ebbdad..e546ffa57b55a 100644 +--- a/fs/smb/server/oplock.c ++++ b/fs/smb/server/oplock.c +@@ -1510,7 +1510,7 @@ void create_lease_buf(u8 *rbuf, struct lease *lease) + * parse_lease_state() - parse lease context containted in file open request + * @open_req: buffer containing smb2 file open(create) request + * +- * Return: oplock state, -ENOENT if create lease context not found ++ * Return: allocated lease context object on success, otherwise NULL + */ + struct lease_ctx_info *parse_lease_state(void *open_req) + { +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index da57adc2bd689..458cc736286aa 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -1687,6 +1687,8 @@ int smb2_sess_setup(struct ksmbd_work *work) + rc = ksmbd_session_register(conn, sess); + if (rc) + goto out_err; ++ ++ conn->binding = false; + } else if (conn->dialect >= SMB30_PROT_ID && + (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) && + req->Flags & SMB2_SESSION_REQ_FLAG_BINDING) { +@@ -1765,6 +1767,8 @@ int smb2_sess_setup(struct ksmbd_work *work) + sess = NULL; + goto out_err; + } ++ ++ conn->binding = false; + } + work->sess = sess; + +@@ -2767,8 +2771,8 @@ static int parse_durable_handle_context(struct ksmbd_work *work, + } + } + +- if (((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) || +- req_op_level == SMB2_OPLOCK_LEVEL_BATCH)) { ++ if ((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) || ++ req_op_level == SMB2_OPLOCK_LEVEL_BATCH) { + dh_info->CreateGuid = + durable_v2_blob->CreateGuid; + dh_info->persistent = +@@ -2788,8 +2792,8 @@ static int parse_durable_handle_context(struct ksmbd_work *work, + goto out; + } + +- if (((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) || +- req_op_level == SMB2_OPLOCK_LEVEL_BATCH)) { ++ if ((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) || ++ req_op_level == SMB2_OPLOCK_LEVEL_BATCH) { + ksmbd_debug(SMB, "Request for durable open\n"); + dh_info->type = dh_idx; + } +@@ -3411,7 +3415,7 @@ int smb2_open(struct ksmbd_work *work) + goto err_out1; + } + } else { +- if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) { ++ if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE && lc) { + if (S_ISDIR(file_inode(filp)->i_mode)) { + lc->req_state &= ~SMB2_LEASE_WRITE_CACHING_LE; + lc->is_dir = true; +diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c +index 6633fa78e9b96..2ce7f75059cb3 100644 +--- a/fs/smb/server/transport_tcp.c ++++ b/fs/smb/server/transport_tcp.c +@@ -624,8 +624,10 @@ int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz) + for_each_netdev(&init_net, netdev) { + if (netif_is_bridge_port(netdev)) + continue; +- if (!alloc_iface(kstrdup(netdev->name, GFP_KERNEL))) ++ if (!alloc_iface(kstrdup(netdev->name, GFP_KERNEL))) { ++ rtnl_unlock(); + return -ENOMEM; ++ } + } + rtnl_unlock(); + bind_additional_ifaces = 1; +diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c +index 16bd693d0b3aa..d5918eba27e37 100644 +--- a/fs/squashfs/inode.c ++++ b/fs/squashfs/inode.c +@@ -279,8 +279,13 @@ int squashfs_read_inode(struct inode *inode, long long ino) + if (err < 0) + goto failed_read; + +- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); ++ if (inode->i_size > PAGE_SIZE) { ++ ERROR("Corrupted symlink\n"); ++ return -EINVAL; ++ } ++ ++ set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + inode->i_op = &squashfs_symlink_inode_ops; + inode_nohighmem(inode); + inode->i_data.a_ops = &squashfs_symlink_aops; +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index aa54be1ce1242..73a08db3b7a85 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -935,7 +935,7 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, int level) + list_for_each_entry(ei_child, &ei->children, list) + eventfs_remove_rec(ei_child, level + 1); + +- list_del(&ei->list); ++ list_del_rcu(&ei->list); + free_ei(ei); + } + +diff --git a/fs/udf/super.c b/fs/udf/super.c +index e0080fda2526b..3c78535f406b0 100644 +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -1080,12 +1080,19 @@ static int udf_fill_partdesc_info(struct super_block *sb, + struct udf_part_map *map; + struct udf_sb_info *sbi = UDF_SB(sb); + struct partitionHeaderDesc *phd; ++ u32 sum; + int err; + + map = &sbi->s_partmaps[p_index]; + + map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ + map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); ++ if (check_add_overflow(map->s_partition_root, map->s_partition_len, ++ &sum)) { ++ udf_err(sb, "Partition %d has invalid location %u + %u\n", ++ p_index, map->s_partition_root, map->s_partition_len); ++ return -EFSCORRUPTED; ++ } + + if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) + map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY; +@@ -1141,6 +1148,14 @@ static int udf_fill_partdesc_info(struct super_block *sb, + bitmap->s_extPosition = le32_to_cpu( + phd->unallocSpaceBitmap.extPosition); + map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; ++ /* Check whether math over bitmap won't overflow. */ ++ if (check_add_overflow(map->s_partition_len, ++ sizeof(struct spaceBitmapDesc) << 3, ++ &sum)) { ++ udf_err(sb, "Partition %d is too long (%u)\n", p_index, ++ map->s_partition_len); ++ return -EFSCORRUPTED; ++ } + udf_debug("unallocSpaceBitmap (part %d) @ %u\n", + p_index, bitmap->s_extPosition); + } +diff --git a/fs/xattr.c b/fs/xattr.c +index efd4736bc94b0..c20046548f218 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -631,10 +631,9 @@ int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, + ctx->kvalue, ctx->size, ctx->flags); + } + +-static long +-setxattr(struct mnt_idmap *idmap, struct dentry *d, +- const char __user *name, const void __user *value, size_t size, +- int flags) ++static int path_setxattr(const char __user *pathname, ++ const char __user *name, const void __user *value, ++ size_t size, int flags, unsigned int lookup_flags) + { + struct xattr_name kname; + struct xattr_ctx ctx = { +@@ -644,33 +643,20 @@ setxattr(struct mnt_idmap *idmap, struct dentry *d, + .kname = &kname, + .flags = flags, + }; ++ struct path path; + int error; + + error = setxattr_copy(name, &ctx); + if (error) + return error; + +- error = do_setxattr(idmap, d, &ctx); +- +- kvfree(ctx.kvalue); +- return error; +-} +- +-static int path_setxattr(const char __user *pathname, +- const char __user *name, const void __user *value, +- size_t size, int flags, unsigned int lookup_flags) +-{ +- struct path path; +- int error; +- + retry: + error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); + if (error) +- return error; ++ goto out; + error = mnt_want_write(path.mnt); + if (!error) { +- error = setxattr(mnt_idmap(path.mnt), path.dentry, name, +- value, size, flags); ++ error = do_setxattr(mnt_idmap(path.mnt), path.dentry, &ctx); + mnt_drop_write(path.mnt); + } + path_put(&path); +@@ -678,6 +664,9 @@ static int path_setxattr(const char __user *pathname, + lookup_flags |= LOOKUP_REVAL; + goto retry; + } ++ ++out: ++ kvfree(ctx.kvalue); + return error; + } + +@@ -698,20 +687,32 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, + SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, + const void __user *,value, size_t, size, int, flags) + { +- struct fd f = fdget(fd); +- int error = -EBADF; ++ struct xattr_name kname; ++ struct xattr_ctx ctx = { ++ .cvalue = value, ++ .kvalue = NULL, ++ .size = size, ++ .kname = &kname, ++ .flags = flags, ++ }; ++ int error; + ++ CLASS(fd, f)(fd); + if (!f.file) +- return error; ++ return -EBADF; ++ + audit_file(f.file); ++ error = setxattr_copy(name, &ctx); ++ if (error) ++ return error; ++ + error = mnt_want_write_file(f.file); + if (!error) { +- error = setxattr(file_mnt_idmap(f.file), +- f.file->f_path.dentry, name, +- value, size, flags); ++ error = do_setxattr(file_mnt_idmap(f.file), ++ f.file->f_path.dentry, &ctx); + mnt_drop_write_file(f.file); + } +- fdput(f); ++ kvfree(ctx.kvalue); + return error; + } + +@@ -900,9 +901,17 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) + * Extended attribute REMOVE operations + */ + static long +-removexattr(struct mnt_idmap *idmap, struct dentry *d, +- const char __user *name) ++removexattr(struct mnt_idmap *idmap, struct dentry *d, const char *name) + { ++ if (is_posix_acl_xattr(name)) ++ return vfs_remove_acl(idmap, d, name); ++ return vfs_removexattr(idmap, d, name); ++} ++ ++static int path_removexattr(const char __user *pathname, ++ const char __user *name, unsigned int lookup_flags) ++{ ++ struct path path; + int error; + char kname[XATTR_NAME_MAX + 1]; + +@@ -911,25 +920,13 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d, + error = -ERANGE; + if (error < 0) + return error; +- +- if (is_posix_acl_xattr(kname)) +- return vfs_remove_acl(idmap, d, kname); +- +- return vfs_removexattr(idmap, d, kname); +-} +- +-static int path_removexattr(const char __user *pathname, +- const char __user *name, unsigned int lookup_flags) +-{ +- struct path path; +- int error; + retry: + error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); + if (error) + return error; + error = mnt_want_write(path.mnt); + if (!error) { +- error = removexattr(mnt_idmap(path.mnt), path.dentry, name); ++ error = removexattr(mnt_idmap(path.mnt), path.dentry, kname); + mnt_drop_write(path.mnt); + } + path_put(&path); +@@ -955,15 +952,23 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, + SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) + { + struct fd f = fdget(fd); ++ char kname[XATTR_NAME_MAX + 1]; + int error = -EBADF; + + if (!f.file) + return error; + audit_file(f.file); ++ ++ error = strncpy_from_user(kname, name, sizeof(kname)); ++ if (error == 0 || error == sizeof(kname)) ++ error = -ERANGE; ++ if (error < 0) ++ return error; ++ + error = mnt_want_write_file(f.file); + if (!error) { + error = removexattr(file_mnt_idmap(f.file), +- f.file->f_path.dentry, name); ++ f.file->f_path.dentry, kname); + mnt_drop_write_file(f.file); + } + fdput(f); +diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h +index 6126c977ece04..c0b69ffe7bdb4 100644 +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -139,6 +139,7 @@ struct cppc_cpudata { + #ifdef CONFIG_ACPI_CPPC_LIB + extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); + extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf); ++extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf); + extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); + extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); + extern int cppc_set_enable(int cpu, bool enable); +@@ -165,6 +166,10 @@ static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf) + { + return -ENOTSUPP; + } ++static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf) ++{ ++ return -ENOTSUPP; ++} + static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs) + { + return -ENOTSUPP; +diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h +index 6ad02ad9c7b42..68fc1bd8d851e 100644 +--- a/include/linux/amd-pstate.h ++++ b/include/linux/amd-pstate.h +@@ -52,6 +52,9 @@ struct amd_aperf_mperf { + * @prev: Last Aperf/Mperf/tsc count value read from register + * @freq: current cpu frequency value + * @boost_supported: check whether the Processor or SBIOS supports boost mode ++ * @hw_prefcore: check whether HW supports preferred core featue. ++ * Only when hw_prefcore and early prefcore param are true, ++ * AMD P-State driver supports preferred core featue. + * @epp_policy: Last saved policy used to set energy-performance preference + * @epp_cached: Cached CPPC energy-performance preference value + * @policy: Cpufreq policy value +@@ -85,6 +88,7 @@ struct amd_cpudata { + + u64 freq; + bool boost_supported; ++ bool hw_prefcore; + + /* EPP feature related attributes*/ + s16 epp_policy; +diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h +index 31561e7897157..d4f2c8706042c 100644 +--- a/include/linux/bpf-cgroup.h ++++ b/include/linux/bpf-cgroup.h +@@ -138,11 +138,12 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head, + enum cgroup_bpf_attach_type atype); + + int __cgroup_bpf_run_filter_setsockopt(struct sock *sock, int *level, +- int *optname, char __user *optval, ++ int *optname, sockptr_t optval, + int *optlen, char **kernel_optval); ++ + int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, +- int optname, char __user *optval, +- int __user *optlen, int max_optlen, ++ int optname, sockptr_t optval, ++ sockptr_t optlen, int max_optlen, + int retval); + + int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level, +@@ -374,14 +375,6 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk, + __ret; \ + }) + +-#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen) \ +-({ \ +- int __ret = 0; \ +- if (cgroup_bpf_enabled(CGROUP_GETSOCKOPT)) \ +- get_user(__ret, optlen); \ +- __ret; \ +-}) +- + #define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, optlen, \ + max_optlen, retval) \ + ({ \ +@@ -499,7 +492,6 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map, + #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) + #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; }) + #define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; }) +-#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen) ({ 0; }) + #define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \ + optlen, max_optlen, retval) ({ retval; }) + #define BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sock, level, optname, optval, \ +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 3d617d0d69675..830b925c2d005 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -95,6 +95,10 @@ extern const int mmap_rnd_compat_bits_max; + extern int mmap_rnd_compat_bits __read_mostly; + #endif + ++#ifndef PHYSMEM_END ++# define PHYSMEM_END ((1ULL << MAX_PHYSMEM_BITS) - 1) ++#endif ++ + #include + #include + +diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h +index af7639c3b0a3a..8b7daccd11bef 100644 +--- a/include/linux/pgtable.h ++++ b/include/linux/pgtable.h +@@ -292,6 +292,27 @@ static inline pmd_t pmdp_get(pmd_t *pmdp) + } + #endif + ++#ifndef pudp_get ++static inline pud_t pudp_get(pud_t *pudp) ++{ ++ return READ_ONCE(*pudp); ++} ++#endif ++ ++#ifndef p4dp_get ++static inline p4d_t p4dp_get(p4d_t *p4dp) ++{ ++ return READ_ONCE(*p4dp); ++} ++#endif ++ ++#ifndef pgdp_get ++static inline pgd_t pgdp_get(pgd_t *pgdp) ++{ ++ return READ_ONCE(*pgdp); ++} ++#endif ++ + #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG + static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, + unsigned long address, +diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h +index 2c526c8d10cc4..25d0684d37b3e 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -489,6 +489,14 @@ static inline int of_regulator_bulk_get_all(struct device *dev, struct device_no + return 0; + } + ++static inline int devm_regulator_bulk_get_const( ++ struct device *dev, int num_consumers, ++ const struct regulator_bulk_data *in_consumers, ++ struct regulator_bulk_data **out_consumers) ++{ ++ return 0; ++} ++ + static inline int regulator_bulk_enable(int num_consumers, + struct regulator_bulk_data *consumers) + { +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index d2a280a42f3b8..2129d071c3725 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -430,6 +430,7 @@ enum { + #define HCI_NCMD_TIMEOUT msecs_to_jiffies(4000) /* 4 seconds */ + #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ + #define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ ++#define HCI_ACL_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */ + #define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */ + #define HCI_LE_AUTOCONN_TIMEOUT msecs_to_jiffies(4000) /* 4 seconds */ + +@@ -644,6 +645,7 @@ enum { + #define HCI_ERROR_PIN_OR_KEY_MISSING 0x06 + #define HCI_ERROR_MEMORY_EXCEEDED 0x07 + #define HCI_ERROR_CONNECTION_TIMEOUT 0x08 ++#define HCI_ERROR_COMMAND_DISALLOWED 0x0c + #define HCI_ERROR_REJ_LIMITED_RESOURCES 0x0d + #define HCI_ERROR_REJ_BAD_ADDR 0x0f + #define HCI_ERROR_INVALID_PARAMETERS 0x12 +@@ -652,6 +654,7 @@ enum { + #define HCI_ERROR_REMOTE_POWER_OFF 0x15 + #define HCI_ERROR_LOCAL_HOST_TERM 0x16 + #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 ++#define HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE 0x1e + #define HCI_ERROR_INVALID_LL_PARAMS 0x1e + #define HCI_ERROR_UNSPECIFIED 0x1f + #define HCI_ERROR_ADVERTISING_TIMEOUT 0x3c +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index f89d6d43ba8f1..29f1549ee1114 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -188,7 +188,6 @@ struct blocked_key { + struct smp_csrk { + bdaddr_t bdaddr; + u8 bdaddr_type; +- u8 link_type; + u8 type; + u8 val[16]; + }; +@@ -198,7 +197,6 @@ struct smp_ltk { + struct rcu_head rcu; + bdaddr_t bdaddr; + u8 bdaddr_type; +- u8 link_type; + u8 authenticated; + u8 type; + u8 enc_size; +@@ -213,7 +211,6 @@ struct smp_irk { + bdaddr_t rpa; + bdaddr_t bdaddr; + u8 addr_type; +- u8 link_type; + u8 val[16]; + }; + +@@ -221,8 +218,6 @@ struct link_key { + struct list_head list; + struct rcu_head rcu; + bdaddr_t bdaddr; +- u8 bdaddr_type; +- u8 link_type; + u8 type; + u8 val[HCI_LINK_KEY_SIZE]; + u8 pin_len; +@@ -1046,6 +1041,24 @@ static inline unsigned int hci_conn_count(struct hci_dev *hdev) + return c->acl_num + c->sco_num + c->le_num + c->iso_num; + } + ++static inline bool hci_conn_valid(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ struct hci_conn_hash *h = &hdev->conn_hash; ++ struct hci_conn *c; ++ ++ rcu_read_lock(); ++ ++ list_for_each_entry_rcu(c, &h->list, list) { ++ if (c == conn) { ++ rcu_read_unlock(); ++ return true; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return false; ++} ++ + static inline __u8 hci_conn_lookup_type(struct hci_dev *hdev, __u16 handle) + { + struct hci_conn_hash *h = &hdev->conn_hash; +@@ -1422,7 +1435,6 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type, + bdaddr_t *dst, u8 role); + void hci_conn_del(struct hci_conn *conn); + void hci_conn_hash_flush(struct hci_dev *hdev); +-void hci_conn_check_pending(struct hci_dev *hdev); + + struct hci_chan *hci_chan_create(struct hci_conn *conn); + void hci_chan_del(struct hci_chan *chan); +@@ -1436,6 +1448,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst, + struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, + u8 dst_type, bool dst_resolved, u8 sec_level, + u16 conn_timeout, u8 role); ++void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status); + struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, + u8 sec_level, u8 auth_type, + enum conn_reasons conn_reason); +diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h +index 4cb048bdcb1e4..3cb2d10cac930 100644 +--- a/include/net/bluetooth/hci_sync.h ++++ b/include/net/bluetooth/hci_sync.h +@@ -50,6 +50,22 @@ int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, + void *data, hci_cmd_sync_work_destroy_t destroy); + int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, + void *data, hci_cmd_sync_work_destroy_t destroy); ++int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy); ++int hci_cmd_sync_run(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy); ++int hci_cmd_sync_run_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy); ++struct hci_cmd_sync_work_entry * ++hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy); ++void hci_cmd_sync_cancel_entry(struct hci_dev *hdev, ++ struct hci_cmd_sync_work_entry *entry); ++bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy); ++bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev, ++ hci_cmd_sync_work_func_t func, void *data, ++ hci_cmd_sync_work_destroy_t destroy); + + int hci_update_eir_sync(struct hci_dev *hdev); + int hci_update_class_sync(struct hci_dev *hdev); +@@ -129,8 +145,6 @@ struct hci_conn; + + int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason); + +-int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn); +- + int hci_le_create_cis_sync(struct hci_dev *hdev); + + int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle); +@@ -140,3 +154,9 @@ int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason); + int hci_le_big_terminate_sync(struct hci_dev *hdev, u8 handle); + + int hci_le_pa_terminate_sync(struct hci_dev *hdev, u16 handle); ++ ++int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn); ++ ++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); +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 37ccce56a73e8..28e110f733ffd 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -97,6 +97,8 @@ struct mana_txq { + + atomic_t pending_sends; + ++ bool napi_initialized; ++ + struct mana_stats_tx stats; + }; + +diff --git a/include/net/sock.h b/include/net/sock.h +index 5942b5ff4c786..2a1aee5038482 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1875,11 +1875,13 @@ int sk_setsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen); + int sock_setsockopt(struct socket *sock, int level, int op, + sockptr_t optval, unsigned int optlen); ++int do_sock_setsockopt(struct socket *sock, bool compat, int level, ++ int optname, sockptr_t optval, int optlen); ++int do_sock_getsockopt(struct socket *sock, bool compat, int level, ++ int optname, sockptr_t optval, sockptr_t optlen); + + int sk_getsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, sockptr_t optlen); +-int sock_getsockopt(struct socket *sock, int level, int op, +- char __user *optval, int __user *optlen); + int sock_gettstamp(struct socket *sock, void __user *userstamp, + bool timeval, bool time32); + struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, +diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h +index 8db7fd3f743e4..5eed091d4c291 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -1474,6 +1474,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + #define AMD_FMT_MOD_TILE_VER_GFX10 2 + #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 + #define AMD_FMT_MOD_TILE_VER_GFX11 4 ++#define AMD_FMT_MOD_TILE_VER_GFX12 5 + + /* + * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical +@@ -1484,6 +1485,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + /* + * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has + * GFX9 as canonical version. ++ * ++ * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. + */ + #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 + #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 +@@ -1491,6 +1494,21 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 + #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 + ++/* Gfx12 swizzle modes: ++ * 0 - LINEAR ++ * 1 - 256B_2D - 2D block dimensions ++ * 2 - 4KB_2D ++ * 3 - 64KB_2D ++ * 4 - 256KB_2D ++ * 5 - 4KB_3D - 3D block dimensions ++ * 6 - 64KB_3D ++ * 7 - 256KB_3D ++ */ ++#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1 ++#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2 ++#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 ++#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 ++ + #define AMD_FMT_MOD_DCC_BLOCK_64B 0 + #define AMD_FMT_MOD_DCC_BLOCK_128B 1 + #define AMD_FMT_MOD_DCC_BLOCK_256B 2 +diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c +index ac37bd53aee03..913a6a7e62ca6 100644 +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -1799,7 +1799,7 @@ static bool sockopt_buf_allocated(struct bpf_sockopt_kern *ctx, + } + + int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, +- int *optname, char __user *optval, ++ int *optname, sockptr_t optval, + int *optlen, char **kernel_optval) + { + struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); +@@ -1822,7 +1822,8 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, + + ctx.optlen = *optlen; + +- if (copy_from_user(ctx.optval, optval, min(*optlen, max_optlen)) != 0) { ++ if (copy_from_sockptr(ctx.optval, optval, ++ min(*optlen, max_optlen))) { + ret = -EFAULT; + goto out; + } +@@ -1889,8 +1890,8 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, + } + + int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, +- int optname, char __user *optval, +- int __user *optlen, int max_optlen, ++ int optname, sockptr_t optval, ++ sockptr_t optlen, int max_optlen, + int retval) + { + struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); +@@ -1917,8 +1918,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, + * one that kernel returned as well to let + * BPF programs inspect the value. + */ +- +- if (get_user(ctx.optlen, optlen)) { ++ if (copy_from_sockptr(&ctx.optlen, optlen, ++ sizeof(ctx.optlen))) { + ret = -EFAULT; + goto out; + } +@@ -1929,8 +1930,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, + } + orig_optlen = ctx.optlen; + +- if (copy_from_user(ctx.optval, optval, +- min(ctx.optlen, max_optlen)) != 0) { ++ if (copy_from_sockptr(ctx.optval, optval, ++ min(ctx.optlen, max_optlen))) { + ret = -EFAULT; + goto out; + } +@@ -1944,7 +1945,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, + if (ret < 0) + goto out; + +- if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) { ++ if (!sockptr_is_null(optval) && ++ (ctx.optlen > max_optlen || ctx.optlen < 0)) { + if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); +@@ -1956,11 +1958,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, + } + + if (ctx.optlen != 0) { +- if (optval && copy_to_user(optval, ctx.optval, ctx.optlen)) { ++ if (!sockptr_is_null(optval) && ++ copy_to_sockptr(optval, ctx.optval, ctx.optlen)) { + ret = -EFAULT; + goto out; + } +- if (put_user(ctx.optlen, optlen)) { ++ if (copy_to_sockptr(optlen, &ctx.optlen, sizeof(ctx.optlen))) { + ret = -EFAULT; + goto out; + } +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 3f1a9cd7fc9ec..9d5699942273e 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3064,8 +3064,10 @@ static int check_subprogs(struct bpf_verifier_env *env) + + if (code == (BPF_JMP | BPF_CALL) && + insn[i].src_reg == 0 && +- insn[i].imm == BPF_FUNC_tail_call) ++ insn[i].imm == BPF_FUNC_tail_call) { + subprog[cur_subprog].has_tail_call = true; ++ subprog[cur_subprog].tail_call_reachable = true; ++ } + if (BPF_CLASS(code) == BPF_LD && + (BPF_MODE(code) == BPF_ABS || BPF_MODE(code) == BPF_IND)) + subprog[cur_subprog].has_ld_abs = true; +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 5eca6281d1aa6..660817c125e73 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -1829,9 +1829,9 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) + RCU_INIT_POINTER(scgrp->subsys[ssid], NULL); + rcu_assign_pointer(dcgrp->subsys[ssid], css); + ss->root = dst_root; +- css->cgroup = dcgrp; + + spin_lock_irq(&css_set_lock); ++ css->cgroup = dcgrp; + WARN_ON(!list_empty(&dcgrp->e_csets[ss->id])); + list_for_each_entry_safe(cset, cset_pos, &scgrp->e_csets[ss->id], + e_cset_node[ss->id]) { +diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c +index 4950e0b622b1f..cc19a3efea896 100644 +--- a/kernel/dma/map_benchmark.c ++++ b/kernel/dma/map_benchmark.c +@@ -89,6 +89,22 @@ static int map_benchmark_thread(void *data) + atomic64_add(map_sq, &map->sum_sq_map); + atomic64_add(unmap_sq, &map->sum_sq_unmap); + atomic64_inc(&map->loops); ++ ++ /* ++ * We may test for a long time so periodically check whether ++ * we need to schedule to avoid starving the others. Otherwise ++ * we may hangup the kernel in a non-preemptible kernel when ++ * the test kthreads number >= CPU number, the test kthreads ++ * will run endless on every CPU since the thread resposible ++ * for notifying the kthread stop (in do_map_benchmark()) ++ * could not be scheduled. ++ * ++ * Note this may degrade the test concurrency since the test ++ * threads may need to share the CPU time with other load ++ * in the system. So it's recommended to run this benchmark ++ * on an idle system. ++ */ ++ cond_resched(); + } + + out: +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 0f2b5610933d7..4d0abdace4e7c 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1255,8 +1255,9 @@ static void put_ctx(struct perf_event_context *ctx) + * perf_event_context::mutex + * perf_event::child_mutex; + * perf_event_context::lock +- * perf_event::mmap_mutex + * mmap_lock ++ * perf_event::mmap_mutex ++ * perf_buffer::aux_mutex + * perf_addr_filters_head::lock + * + * cpu_hotplug_lock +@@ -6352,12 +6353,11 @@ static void perf_mmap_close(struct vm_area_struct *vma) + event->pmu->event_unmapped(event, vma->vm_mm); + + /* +- * rb->aux_mmap_count will always drop before rb->mmap_count and +- * event->mmap_count, so it is ok to use event->mmap_mutex to +- * serialize with perf_mmap here. ++ * The AUX buffer is strictly a sub-buffer, serialize using aux_mutex ++ * to avoid complications. + */ + if (rb_has_aux(rb) && vma->vm_pgoff == rb->aux_pgoff && +- atomic_dec_and_mutex_lock(&rb->aux_mmap_count, &event->mmap_mutex)) { ++ atomic_dec_and_mutex_lock(&rb->aux_mmap_count, &rb->aux_mutex)) { + /* + * Stop all AUX events that are writing to this buffer, + * so that we can free its AUX pages and corresponding PMU +@@ -6374,7 +6374,7 @@ static void perf_mmap_close(struct vm_area_struct *vma) + rb_free_aux(rb); + WARN_ON_ONCE(refcount_read(&rb->aux_refcount)); + +- mutex_unlock(&event->mmap_mutex); ++ mutex_unlock(&rb->aux_mutex); + } + + if (atomic_dec_and_test(&rb->mmap_count)) +@@ -6462,6 +6462,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + struct perf_event *event = file->private_data; + unsigned long user_locked, user_lock_limit; + struct user_struct *user = current_user(); ++ struct mutex *aux_mutex = NULL; + struct perf_buffer *rb = NULL; + unsigned long locked, lock_limit; + unsigned long vma_size; +@@ -6510,6 +6511,9 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + if (!rb) + goto aux_unlock; + ++ aux_mutex = &rb->aux_mutex; ++ mutex_lock(aux_mutex); ++ + aux_offset = READ_ONCE(rb->user_page->aux_offset); + aux_size = READ_ONCE(rb->user_page->aux_size); + +@@ -6660,6 +6664,8 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + atomic_dec(&rb->mmap_count); + } + aux_unlock: ++ if (aux_mutex) ++ mutex_unlock(aux_mutex); + mutex_unlock(&event->mmap_mutex); + + /* +diff --git a/kernel/events/internal.h b/kernel/events/internal.h +index 386d21c7edfa0..f376b057320ce 100644 +--- a/kernel/events/internal.h ++++ b/kernel/events/internal.h +@@ -40,6 +40,7 @@ struct perf_buffer { + struct user_struct *mmap_user; + + /* AUX area */ ++ struct mutex aux_mutex; + long aux_head; + unsigned int aux_nest; + long aux_wakeup; /* last aux_watermark boundary crossed by aux_head */ +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index f1f4a627f93db..b0930b4185527 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -333,6 +333,8 @@ ring_buffer_init(struct perf_buffer *rb, long watermark, int flags) + */ + if (!rb->nr_pages) + rb->paused = 1; ++ ++ mutex_init(&rb->aux_mutex); + } + + void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags) +diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c +index 3048589e2e851..4705571f80345 100644 +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -1480,7 +1480,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) + uprobe_opcode_t insn = UPROBE_SWBP_INSN; + struct xol_area *area; + +- area = kmalloc(sizeof(*area), GFP_KERNEL); ++ area = kzalloc(sizeof(*area), GFP_KERNEL); + if (unlikely(!area)) + goto out; + +@@ -1490,7 +1490,6 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) + goto free_area; + + area->xol_mapping.name = "[uprobes]"; +- area->xol_mapping.fault = NULL; + area->xol_mapping.pages = area->pages; + area->pages[0] = alloc_page(GFP_HIGHUSER); + if (!area->pages[0]) +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index f9a419cd22d4c..830344627e9f2 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -728,7 +728,7 @@ static int kexec_calculate_store_digests(struct kimage *image) + + #ifdef CONFIG_CRASH_HOTPLUG + /* Exclude elfcorehdr segment to allow future changes via hotplug */ +- if (j == image->elfcorehdr_index) ++ if (i == image->elfcorehdr_index) + continue; + #endif + +diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c +index 21db0df0eb000..bf3a28ee7d8f4 100644 +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -1624,6 +1624,7 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock, + } + + static void __sched rt_mutex_handle_deadlock(int res, int detect_deadlock, ++ struct rt_mutex_base *lock, + struct rt_mutex_waiter *w) + { + /* +@@ -1636,10 +1637,10 @@ static void __sched rt_mutex_handle_deadlock(int res, int detect_deadlock, + if (build_ww_mutex() && w->ww_ctx) + return; + +- /* +- * Yell loudly and stop the task right here. +- */ ++ raw_spin_unlock_irq(&lock->wait_lock); ++ + WARN(1, "rtmutex deadlock detected\n"); ++ + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); +@@ -1693,7 +1694,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock, + } else { + __set_current_state(TASK_RUNNING); + remove_waiter(lock, waiter); +- rt_mutex_handle_deadlock(ret, chwalk, waiter); ++ rt_mutex_handle_deadlock(ret, chwalk, lock, waiter); + } + + /* +diff --git a/kernel/resource.c b/kernel/resource.c +index e3f5680a564cf..ce127a829ead7 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -1778,8 +1778,7 @@ static resource_size_t gfr_start(struct resource *base, resource_size_t size, + if (flags & GFR_DESCENDING) { + resource_size_t end; + +- end = min_t(resource_size_t, base->end, +- (1ULL << MAX_PHYSMEM_BITS) - 1); ++ end = min_t(resource_size_t, base->end, PHYSMEM_END); + return end - size + 1; + } + +@@ -1796,8 +1795,7 @@ static bool gfr_continue(struct resource *base, resource_size_t addr, + * @size did not wrap 0. + */ + return addr > addr - size && +- addr <= min_t(resource_size_t, base->end, +- (1ULL << MAX_PHYSMEM_BITS) - 1); ++ addr <= min_t(resource_size_t, base->end, PHYSMEM_END); + } + + static resource_size_t gfr_next(resource_size_t addr, resource_size_t size, +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 97571d390f184..9b406d9886541 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -6679,8 +6679,9 @@ static void __sched notrace __schedule(unsigned int sched_mode) + * + * Here are the schemes providing that barrier on the + * various architectures: +- * - mm ? switch_mm() : mmdrop() for x86, s390, sparc, PowerPC. +- * switch_mm() rely on membarrier_arch_switch_mm() on PowerPC. ++ * - mm ? switch_mm() : mmdrop() for x86, s390, sparc, PowerPC, ++ * RISC-V. switch_mm() relies on membarrier_arch_switch_mm() ++ * on PowerPC and on RISC-V. + * - finish_lock_switch() for weakly-ordered + * architectures where spin_unlock is a full barrier, + * - switch_to() for arm64 (weakly-ordered, spin_unlock +diff --git a/kernel/smp.c b/kernel/smp.c +index 695eb13a276d2..3eeffeaf5450c 100644 +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -1119,6 +1119,7 @@ int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys) + + queue_work_on(cpu, system_wq, &sscs.work); + wait_for_completion(&sscs.done); ++ destroy_work_on_stack(&sscs.work); + + return sscs.ret; + } +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index fd398af792b4a..be878005e3449 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4156,6 +4156,8 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu) + break; + entries++; + ring_buffer_iter_advance(buf_iter); ++ /* This could be a big loop */ ++ cond_resched(); + } + + per_cpu_ptr(iter->array_buffer->data, cpu)->skipped_entries = entries; +diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c +index a8e28f9b9271c..5b06f67879f5f 100644 +--- a/kernel/trace/trace_osnoise.c ++++ b/kernel/trace/trace_osnoise.c +@@ -252,6 +252,11 @@ static inline struct timerlat_variables *this_cpu_tmr_var(void) + return this_cpu_ptr(&per_cpu_timerlat_var); + } + ++/* ++ * Protect the interface. ++ */ ++static struct mutex interface_lock; ++ + /* + * tlat_var_reset - Reset the values of the given timerlat_variables + */ +@@ -259,14 +264,20 @@ static inline void tlat_var_reset(void) + { + struct timerlat_variables *tlat_var; + int cpu; ++ ++ /* Synchronize with the timerlat interfaces */ ++ mutex_lock(&interface_lock); + /* + * So far, all the values are initialized as 0, so + * zeroing the structure is perfect. + */ + for_each_cpu(cpu, cpu_online_mask) { + tlat_var = per_cpu_ptr(&per_cpu_timerlat_var, cpu); ++ if (tlat_var->kthread) ++ hrtimer_cancel(&tlat_var->timer); + memset(tlat_var, 0, sizeof(*tlat_var)); + } ++ mutex_unlock(&interface_lock); + } + #else /* CONFIG_TIMERLAT_TRACER */ + #define tlat_var_reset() do {} while (0) +@@ -331,11 +342,6 @@ struct timerlat_sample { + }; + #endif + +-/* +- * Protect the interface. +- */ +-static struct mutex interface_lock; +- + /* + * Tracer data. + */ +@@ -1612,6 +1618,7 @@ static int run_osnoise(void) + + static struct cpumask osnoise_cpumask; + static struct cpumask save_cpumask; ++static struct cpumask kthread_cpumask; + + /* + * osnoise_sleep - sleep until the next period +@@ -1675,6 +1682,7 @@ static inline int osnoise_migration_pending(void) + */ + mutex_lock(&interface_lock); + this_cpu_osn_var()->kthread = NULL; ++ cpumask_clear_cpu(smp_processor_id(), &kthread_cpumask); + mutex_unlock(&interface_lock); + + return 1; +@@ -1945,11 +1953,16 @@ static void stop_kthread(unsigned int cpu) + { + struct task_struct *kthread; + ++ mutex_lock(&interface_lock); + kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; + if (kthread) { +- if (test_bit(OSN_WORKLOAD, &osnoise_options)) { ++ per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; ++ mutex_unlock(&interface_lock); ++ ++ if (cpumask_test_and_clear_cpu(cpu, &kthread_cpumask) && ++ !WARN_ON(!test_bit(OSN_WORKLOAD, &osnoise_options))) { + kthread_stop(kthread); +- } else { ++ } else if (!WARN_ON(test_bit(OSN_WORKLOAD, &osnoise_options))) { + /* + * This is a user thread waiting on the timerlat_fd. We need + * to close all users, and the best way to guarantee this is +@@ -1958,8 +1971,8 @@ static void stop_kthread(unsigned int cpu) + kill_pid(kthread->thread_pid, SIGKILL, 1); + put_task_struct(kthread); + } +- per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; + } else { ++ mutex_unlock(&interface_lock); + /* if no workload, just return */ + if (!test_bit(OSN_WORKLOAD, &osnoise_options)) { + /* +@@ -1967,7 +1980,6 @@ static void stop_kthread(unsigned int cpu) + */ + per_cpu(per_cpu_osnoise_var, cpu).sampling = false; + barrier(); +- return; + } + } + } +@@ -1982,12 +1994,8 @@ static void stop_per_cpu_kthreads(void) + { + int cpu; + +- cpus_read_lock(); +- +- for_each_online_cpu(cpu) ++ for_each_possible_cpu(cpu) + stop_kthread(cpu); +- +- cpus_read_unlock(); + } + + /* +@@ -2021,6 +2029,7 @@ static int start_kthread(unsigned int cpu) + } + + per_cpu(per_cpu_osnoise_var, cpu).kthread = kthread; ++ cpumask_set_cpu(cpu, &kthread_cpumask); + + return 0; + } +@@ -2048,8 +2057,16 @@ static int start_per_cpu_kthreads(void) + */ + cpumask_and(current_mask, cpu_online_mask, &osnoise_cpumask); + +- for_each_possible_cpu(cpu) ++ for_each_possible_cpu(cpu) { ++ if (cpumask_test_and_clear_cpu(cpu, &kthread_cpumask)) { ++ struct task_struct *kthread; ++ ++ kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; ++ if (!WARN_ON(!kthread)) ++ kthread_stop(kthread); ++ } + per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; ++ } + + for_each_cpu(cpu, current_mask) { + retval = start_kthread(cpu); +@@ -2579,7 +2596,8 @@ static int timerlat_fd_release(struct inode *inode, struct file *file) + osn_var = per_cpu_ptr(&per_cpu_osnoise_var, cpu); + tlat_var = per_cpu_ptr(&per_cpu_timerlat_var, cpu); + +- hrtimer_cancel(&tlat_var->timer); ++ if (tlat_var->kthread) ++ hrtimer_cancel(&tlat_var->timer); + memset(tlat_var, 0, sizeof(*tlat_var)); + + osn_var->sampling = 0; +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 8c7bafbee1b13..7fa1c7c9151ae 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -6456,10 +6456,18 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) + + notrace void wq_watchdog_touch(int cpu) + { ++ unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; ++ unsigned long touch_ts = READ_ONCE(wq_watchdog_touched); ++ unsigned long now = jiffies; ++ + if (cpu >= 0) +- per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies; ++ per_cpu(wq_watchdog_touched_cpu, cpu) = now; ++ else ++ WARN_ONCE(1, "%s should be called with valid CPU", __func__); + +- wq_watchdog_touched = jiffies; ++ /* Don't unnecessarily store to global cacheline */ ++ if (time_after(now, touch_ts + thresh / 4)) ++ WRITE_ONCE(wq_watchdog_touched, jiffies); + } + + static void wq_watchdog_set_thresh(unsigned long thresh) +diff --git a/lib/generic-radix-tree.c b/lib/generic-radix-tree.c +index 7dfa88282b006..78f081d695d0b 100644 +--- a/lib/generic-radix-tree.c ++++ b/lib/generic-radix-tree.c +@@ -131,6 +131,8 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, + if ((v = cmpxchg_release(&radix->root, r, new_root)) == r) { + v = new_root; + new_node = NULL; ++ } else { ++ new_node->children[0] = NULL; + } + } + +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index f36525a595a93..9beed7c71a8e9 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1610,7 +1610,7 @@ struct range __weak arch_get_mappable_range(void) + + struct range mhp_get_pluggable_range(bool need_mapping) + { +- const u64 max_phys = (1ULL << MAX_PHYSMEM_BITS) - 1; ++ const u64 max_phys = PHYSMEM_END; + struct range mhp_range; + + if (need_mapping) { +diff --git a/mm/sparse.c b/mm/sparse.c +index 338cf946dee8d..0706113c4c843 100644 +--- a/mm/sparse.c ++++ b/mm/sparse.c +@@ -129,7 +129,7 @@ static inline int sparse_early_nid(struct mem_section *section) + static void __meminit mminit_validate_memmodel_limits(unsigned long *start_pfn, + unsigned long *end_pfn) + { +- unsigned long max_sparsemem_pfn = 1UL << (MAX_PHYSMEM_BITS-PAGE_SHIFT); ++ unsigned long max_sparsemem_pfn = (PHYSMEM_END + 1) >> PAGE_SHIFT; + + /* + * Sanity checks - do not allow an architecture to pass +diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c +index e76faba102797..92fe2a76f4b51 100644 +--- a/mm/userfaultfd.c ++++ b/mm/userfaultfd.c +@@ -699,27 +699,30 @@ static __always_inline ssize_t mfill_atomic(struct mm_struct *dst_mm, + } + + dst_pmdval = pmdp_get_lockless(dst_pmd); +- /* +- * If the dst_pmd is mapped as THP don't +- * override it and just be strict. +- */ +- if (unlikely(pmd_trans_huge(dst_pmdval))) { +- err = -EEXIST; +- break; +- } + if (unlikely(pmd_none(dst_pmdval)) && + unlikely(__pte_alloc(dst_mm, dst_pmd))) { + err = -ENOMEM; + break; + } +- /* If an huge pmd materialized from under us fail */ +- if (unlikely(pmd_trans_huge(*dst_pmd))) { ++ dst_pmdval = pmdp_get_lockless(dst_pmd); ++ /* ++ * If the dst_pmd is THP don't override it and just be strict. ++ * (This includes the case where the PMD used to be THP and ++ * changed back to none after __pte_alloc().) ++ */ ++ if (unlikely(!pmd_present(dst_pmdval) || pmd_trans_huge(dst_pmdval) || ++ pmd_devmap(dst_pmdval))) { ++ err = -EEXIST; ++ break; ++ } ++ if (unlikely(pmd_bad(dst_pmdval))) { + err = -EFAULT; + break; + } +- +- BUG_ON(pmd_none(*dst_pmd)); +- BUG_ON(pmd_trans_huge(*dst_pmd)); ++ /* ++ * For shmem mappings, khugepaged is allowed to remove page ++ * tables under us; pte_offset_map_lock() will deal with that. ++ */ + + err = mfill_atomic_pte(dst_pmd, dst_vma, dst_addr, + src_addr, flags, &folio); +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 732ff66d1b513..0148be0814af7 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -2066,6 +2066,7 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask) + vb->dirty_max = 0; + bitmap_set(vb->used_map, 0, (1UL << order)); + INIT_LIST_HEAD(&vb->free_list); ++ vb->cpu = raw_smp_processor_id(); + + xa = addr_to_vb_xa(va->va_start); + vb_idx = addr_to_vb_idx(va->va_start); +@@ -2082,7 +2083,6 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask) + * integrity together with list_for_each_rcu from read + * side. + */ +- vb->cpu = raw_smp_processor_id(); + vbq = per_cpu_ptr(&vmap_block_queue, vb->cpu); + spin_lock(&vbq->lock); + list_add_tail_rcu(&vb->free_list, &vbq->free); +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 83fa8e924f8ae..81533bed0b462 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2261,25 +2261,6 @@ static __always_inline void update_lru_sizes(struct lruvec *lruvec, + + } + +-#ifdef CONFIG_CMA +-/* +- * It is waste of effort to scan and reclaim CMA pages if it is not available +- * for current allocation context. Kswapd can not be enrolled as it can not +- * distinguish this scenario by using sc->gfp_mask = GFP_KERNEL +- */ +-static bool skip_cma(struct folio *folio, struct scan_control *sc) +-{ +- return !current_is_kswapd() && +- gfp_migratetype(sc->gfp_mask) != MIGRATE_MOVABLE && +- get_pageblock_migratetype(&folio->page) == MIGRATE_CMA; +-} +-#else +-static bool skip_cma(struct folio *folio, struct scan_control *sc) +-{ +- return false; +-} +-#endif +- + /* + * Isolating page from the lruvec to fill in @dst list by nr_to_scan times. + * +@@ -2326,8 +2307,7 @@ static unsigned long isolate_lru_folios(unsigned long nr_to_scan, + nr_pages = folio_nr_pages(folio); + total_scan += nr_pages; + +- if (folio_zonenum(folio) > sc->reclaim_idx || +- skip_cma(folio, sc)) { ++ if (folio_zonenum(folio) > sc->reclaim_idx) { + nr_skipped[folio_zonenum(folio)] += nr_pages; + move_to = &folios_skipped; + goto move; +@@ -4971,7 +4951,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c + } + + /* ineligible */ +- if (zone > sc->reclaim_idx || skip_cma(folio, sc)) { ++ if (zone > sc->reclaim_idx) { + gen = folio_inc_gen(lruvec, folio, false); + list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); + return true; +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index dc1c07c7d4ff9..d8a01eb016ad0 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -68,7 +68,7 @@ static const struct sco_param esco_param_msbc[] = { + }; + + /* This function requires the caller holds hdev->lock */ +-static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status) ++void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status) + { + struct hci_conn_params *params; + struct hci_dev *hdev = conn->hdev; +@@ -178,64 +178,6 @@ static void hci_conn_cleanup(struct hci_conn *conn) + hci_dev_put(hdev); + } + +-static void hci_acl_create_connection(struct hci_conn *conn) +-{ +- struct hci_dev *hdev = conn->hdev; +- struct inquiry_entry *ie; +- struct hci_cp_create_conn cp; +- +- BT_DBG("hcon %p", conn); +- +- /* Many controllers disallow HCI Create Connection while it is doing +- * HCI Inquiry. So we cancel the Inquiry first before issuing HCI Create +- * Connection. This may cause the MGMT discovering state to become false +- * without user space's request but it is okay since the MGMT Discovery +- * APIs do not promise that discovery should be done forever. Instead, +- * the user space monitors the status of MGMT discovering and it may +- * request for discovery again when this flag becomes false. +- */ +- if (test_bit(HCI_INQUIRY, &hdev->flags)) { +- /* Put this connection to "pending" state so that it will be +- * executed after the inquiry cancel command complete event. +- */ +- conn->state = BT_CONNECT2; +- hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); +- return; +- } +- +- conn->state = BT_CONNECT; +- conn->out = true; +- conn->role = HCI_ROLE_MASTER; +- +- conn->attempt++; +- +- conn->link_policy = hdev->link_policy; +- +- memset(&cp, 0, sizeof(cp)); +- bacpy(&cp.bdaddr, &conn->dst); +- cp.pscan_rep_mode = 0x02; +- +- ie = hci_inquiry_cache_lookup(hdev, &conn->dst); +- if (ie) { +- if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) { +- cp.pscan_rep_mode = ie->data.pscan_rep_mode; +- cp.pscan_mode = ie->data.pscan_mode; +- cp.clock_offset = ie->data.clock_offset | +- cpu_to_le16(0x8000); +- } +- +- memcpy(conn->dev_class, ie->data.dev_class, 3); +- } +- +- cp.pkt_type = cpu_to_le16(conn->pkt_type); +- if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) +- cp.role_switch = 0x01; +- else +- cp.role_switch = 0x00; +- +- hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp); +-} +- + int hci_disconnect(struct hci_conn *conn, __u8 reason) + { + BT_DBG("hcon %p", conn); +@@ -1201,6 +1143,9 @@ void hci_conn_del(struct hci_conn *conn) + * rest of hci_conn_del. + */ + hci_conn_cleanup(conn); ++ ++ /* Dequeue callbacks using connection pointer as data */ ++ hci_cmd_sync_dequeue(hdev, NULL, conn, NULL); + } + + struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type) +@@ -1334,53 +1279,6 @@ u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle) + return 0; + } + +-static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err) +-{ +- struct hci_conn *conn; +- u16 handle = PTR_UINT(data); +- +- conn = hci_conn_hash_lookup_handle(hdev, handle); +- if (!conn) +- return; +- +- bt_dev_dbg(hdev, "err %d", err); +- +- hci_dev_lock(hdev); +- +- if (!err) { +- hci_connect_le_scan_cleanup(conn, 0x00); +- goto done; +- } +- +- /* Check if connection is still pending */ +- if (conn != hci_lookup_le_connect(hdev)) +- goto done; +- +- /* Flush to make sure we send create conn cancel command if needed */ +- flush_delayed_work(&conn->le_conn_timeout); +- hci_conn_failed(conn, bt_status(err)); +- +-done: +- hci_dev_unlock(hdev); +-} +- +-static int hci_connect_le_sync(struct hci_dev *hdev, void *data) +-{ +- struct hci_conn *conn; +- u16 handle = PTR_UINT(data); +- +- conn = hci_conn_hash_lookup_handle(hdev, handle); +- if (!conn) +- return 0; +- +- bt_dev_dbg(hdev, "conn %p", conn); +- +- clear_bit(HCI_CONN_SCANNING, &conn->flags); +- conn->state = BT_CONNECT; +- +- return hci_le_create_conn_sync(hdev, conn); +-} +- + struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, + u8 dst_type, bool dst_resolved, u8 sec_level, + u16 conn_timeout, u8 role) +@@ -1447,9 +1345,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, + conn->sec_level = BT_SECURITY_LOW; + conn->conn_timeout = conn_timeout; + +- err = hci_cmd_sync_queue(hdev, hci_connect_le_sync, +- UINT_PTR(conn->handle), +- create_le_conn_complete); ++ err = hci_connect_le_sync(hdev, conn); + if (err) { + hci_conn_del(conn); + return ERR_PTR(err); +@@ -1702,10 +1598,17 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, + + acl->conn_reason = conn_reason; + if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { ++ int err; ++ + acl->sec_level = BT_SECURITY_LOW; + acl->pending_sec_level = sec_level; + acl->auth_type = auth_type; +- hci_acl_create_connection(acl); ++ ++ err = hci_connect_acl_sync(hdev, acl); ++ if (err) { ++ hci_conn_del(acl); ++ return ERR_PTR(err); ++ } + } + + return acl; +@@ -2616,22 +2519,6 @@ void hci_conn_hash_flush(struct hci_dev *hdev) + } + } + +-/* Check pending connect attempts */ +-void hci_conn_check_pending(struct hci_dev *hdev) +-{ +- struct hci_conn *conn; +- +- BT_DBG("hdev %s", hdev->name); +- +- hci_dev_lock(hdev); +- +- conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); +- if (conn) +- hci_acl_create_connection(conn); +- +- hci_dev_unlock(hdev); +-} +- + static u32 get_link_mode(struct hci_conn *conn) + { + u32 link_mode = 0; +@@ -2947,12 +2834,10 @@ u32 hci_conn_get_phy(struct hci_conn *conn) + + static int abort_conn_sync(struct hci_dev *hdev, void *data) + { +- struct hci_conn *conn; +- u16 handle = PTR_UINT(data); ++ struct hci_conn *conn = data; + +- conn = hci_conn_hash_lookup_handle(hdev, handle); +- if (!conn) +- return 0; ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; + + return hci_abort_conn_sync(hdev, conn, conn->abort_reason); + } +@@ -2980,14 +2865,21 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) + */ + if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) { + switch (hci_skb_event(hdev->sent_cmd)) { ++ case HCI_EV_CONN_COMPLETE: + case HCI_EV_LE_CONN_COMPLETE: + case HCI_EV_LE_ENHANCED_CONN_COMPLETE: + case HCI_EVT_LE_CIS_ESTABLISHED: + hci_cmd_sync_cancel(hdev, ECANCELED); + break; + } ++ /* Cancel connect attempt if still queued/pending */ ++ } else if (!hci_cancel_connect_sync(hdev, conn)) { ++ return 0; + } + +- return hci_cmd_sync_queue(hdev, abort_conn_sync, UINT_PTR(conn->handle), +- NULL); ++ /* Run immediately if on cmd_sync_work since this may be called ++ * as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does ++ * already queue its callback on cmd_sync_work. ++ */ ++ return hci_cmd_sync_run_once(hdev, abort_conn_sync, conn, NULL); + } +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 727f040b65297..d81c7fccdd404 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -93,11 +93,11 @@ static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data, + /* It is possible that we receive Inquiry Complete event right + * before we receive Inquiry Cancel Command Complete event, in + * which case the latter event should have status of Command +- * Disallowed (0x0c). This should not be treated as error, since ++ * Disallowed. This should not be treated as error, since + * we actually achieve what Inquiry Cancel wants to achieve, + * which is to end the last Inquiry session. + */ +- if (rp->status == 0x0c && !test_bit(HCI_INQUIRY, &hdev->flags)) { ++ if (rp->status == HCI_ERROR_COMMAND_DISALLOWED && !test_bit(HCI_INQUIRY, &hdev->flags)) { + bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command"); + rp->status = 0x00; + } +@@ -118,8 +118,6 @@ static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data, + hci_discovery_set_state(hdev, DISCOVERY_STOPPED); + hci_dev_unlock(hdev); + +- hci_conn_check_pending(hdev); +- + return rp->status; + } + +@@ -150,8 +148,6 @@ static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data, + + hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); + +- hci_conn_check_pending(hdev); +- + return rp->status; + } + +@@ -2257,10 +2253,8 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) + { + bt_dev_dbg(hdev, "status 0x%2.2x", status); + +- if (status) { +- hci_conn_check_pending(hdev); ++ if (status) + return; +- } + + if (hci_sent_cmd_data(hdev, HCI_OP_INQUIRY)) + set_bit(HCI_INQUIRY, &hdev->flags); +@@ -2285,12 +2279,9 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) + + if (status) { + if (conn && conn->state == BT_CONNECT) { +- if (status != 0x0c || conn->attempt > 2) { +- conn->state = BT_CLOSED; +- hci_connect_cfm(conn, status); +- hci_conn_del(conn); +- } else +- conn->state = BT_CONNECT2; ++ conn->state = BT_CLOSED; ++ hci_connect_cfm(conn, status); ++ hci_conn_del(conn); + } + } else { + if (!conn) { +@@ -2980,8 +2971,6 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data, + + bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); + +- hci_conn_check_pending(hdev); +- + if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) + return; + +@@ -3228,8 +3217,6 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, + + unlock: + hci_dev_unlock(hdev); +- +- hci_conn_check_pending(hdev); + } + + static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) +@@ -6430,7 +6417,7 @@ static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data, + * transition into connected state and mark it as + * successful. + */ +- if (!conn->out && ev->status == 0x1a && ++ if (!conn->out && ev->status == HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE && + (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) + status = 0x00; + else +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index 38fee34887d8a..af7817a7c585b 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -114,7 +114,7 @@ static void hci_cmd_sync_add(struct hci_request *req, u16 opcode, u32 plen, + skb_queue_tail(&req->cmd_q, skb); + } + +-static int hci_cmd_sync_run(struct hci_request *req) ++static int hci_req_sync_run(struct hci_request *req) + { + struct hci_dev *hdev = req->hdev; + struct sk_buff *skb; +@@ -164,7 +164,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, + + hdev->req_status = HCI_REQ_PEND; + +- err = hci_cmd_sync_run(&req); ++ err = hci_req_sync_run(&req); + if (err < 0) + return ERR_PTR(err); + +@@ -651,6 +651,17 @@ void hci_cmd_sync_init(struct hci_dev *hdev) + INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire); + } + ++static void _hci_cmd_sync_cancel_entry(struct hci_dev *hdev, ++ struct hci_cmd_sync_work_entry *entry, ++ int err) ++{ ++ if (entry->destroy) ++ entry->destroy(hdev, entry->data, err); ++ ++ list_del(&entry->list); ++ kfree(entry); ++} ++ + void hci_cmd_sync_clear(struct hci_dev *hdev) + { + struct hci_cmd_sync_work_entry *entry, *tmp; +@@ -659,13 +670,8 @@ void hci_cmd_sync_clear(struct hci_dev *hdev) + cancel_work_sync(&hdev->reenable_adv_work); + + mutex_lock(&hdev->cmd_sync_work_lock); +- list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) { +- if (entry->destroy) +- entry->destroy(hdev, entry->data, -ECANCELED); +- +- list_del(&entry->list); +- kfree(entry); +- } ++ list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) ++ _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED); + mutex_unlock(&hdev->cmd_sync_work_lock); + } + +@@ -757,6 +763,153 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, + } + EXPORT_SYMBOL(hci_cmd_sync_queue); + ++static struct hci_cmd_sync_work_entry * ++_hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ struct hci_cmd_sync_work_entry *entry, *tmp; ++ ++ list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) { ++ if (func && entry->func != func) ++ continue; ++ ++ if (data && entry->data != data) ++ continue; ++ ++ if (destroy && entry->destroy != destroy) ++ continue; ++ ++ return entry; ++ } ++ ++ return NULL; ++} ++ ++/* Queue HCI command entry once: ++ * ++ * - Lookup if an entry already exist and only if it doesn't creates a new entry ++ * and queue it. ++ */ ++int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy)) ++ return 0; ++ ++ return hci_cmd_sync_queue(hdev, func, data, destroy); ++} ++EXPORT_SYMBOL(hci_cmd_sync_queue_once); ++ ++/* Run HCI command: ++ * ++ * - hdev must be running ++ * - if on cmd_sync_work then run immediately otherwise queue ++ */ ++int hci_cmd_sync_run(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ /* Only queue command if hdev is running which means it had been opened ++ * and is either on init phase or is already up. ++ */ ++ if (!test_bit(HCI_RUNNING, &hdev->flags)) ++ return -ENETDOWN; ++ ++ /* If on cmd_sync_work then run immediately otherwise queue */ ++ if (current_work() == &hdev->cmd_sync_work) ++ return func(hdev, data); ++ ++ return hci_cmd_sync_submit(hdev, func, data, destroy); ++} ++EXPORT_SYMBOL(hci_cmd_sync_run); ++ ++/* Run HCI command entry once: ++ * ++ * - Lookup if an entry already exist and only if it doesn't creates a new entry ++ * and run it. ++ * - if on cmd_sync_work then run immediately otherwise queue ++ */ ++int hci_cmd_sync_run_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy)) ++ return 0; ++ ++ return hci_cmd_sync_run(hdev, func, data, destroy); ++} ++EXPORT_SYMBOL(hci_cmd_sync_run_once); ++ ++/* Lookup HCI command entry: ++ * ++ * - Return first entry that matches by function callback or data or ++ * destroy callback. ++ */ ++struct hci_cmd_sync_work_entry * ++hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ struct hci_cmd_sync_work_entry *entry; ++ ++ mutex_lock(&hdev->cmd_sync_work_lock); ++ entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy); ++ mutex_unlock(&hdev->cmd_sync_work_lock); ++ ++ return entry; ++} ++EXPORT_SYMBOL(hci_cmd_sync_lookup_entry); ++ ++/* Cancel HCI command entry */ ++void hci_cmd_sync_cancel_entry(struct hci_dev *hdev, ++ struct hci_cmd_sync_work_entry *entry) ++{ ++ mutex_lock(&hdev->cmd_sync_work_lock); ++ _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED); ++ mutex_unlock(&hdev->cmd_sync_work_lock); ++} ++EXPORT_SYMBOL(hci_cmd_sync_cancel_entry); ++ ++/* Dequeue one HCI command entry: ++ * ++ * - Lookup and cancel first entry that matches. ++ */ ++bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev, ++ hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ struct hci_cmd_sync_work_entry *entry; ++ ++ entry = hci_cmd_sync_lookup_entry(hdev, func, data, destroy); ++ if (!entry) ++ return false; ++ ++ hci_cmd_sync_cancel_entry(hdev, entry); ++ ++ return true; ++} ++EXPORT_SYMBOL(hci_cmd_sync_dequeue_once); ++ ++/* Dequeue HCI command entry: ++ * ++ * - Lookup and cancel any entry that matches by function callback or data or ++ * destroy callback. ++ */ ++bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, ++ void *data, hci_cmd_sync_work_destroy_t destroy) ++{ ++ struct hci_cmd_sync_work_entry *entry; ++ bool ret = false; ++ ++ mutex_lock(&hdev->cmd_sync_work_lock); ++ while ((entry = _hci_cmd_sync_lookup_entry(hdev, func, data, ++ destroy))) { ++ _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED); ++ ret = true; ++ } ++ mutex_unlock(&hdev->cmd_sync_work_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(hci_cmd_sync_dequeue); ++ + int hci_update_eir_sync(struct hci_dev *hdev) + { + struct hci_cp_write_eir cp; +@@ -3048,7 +3201,8 @@ int hci_update_passive_scan(struct hci_dev *hdev) + hci_dev_test_flag(hdev, HCI_UNREGISTER)) + return 0; + +- return hci_cmd_sync_queue(hdev, update_passive_scan_sync, NULL, NULL); ++ return hci_cmd_sync_queue_once(hdev, update_passive_scan_sync, NULL, ++ NULL); + } + + int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val) +@@ -6254,12 +6408,21 @@ static int hci_le_ext_create_conn_sync(struct hci_dev *hdev, + conn->conn_timeout, NULL); + } + +-int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn) ++static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data) + { + struct hci_cp_le_create_conn cp; + struct hci_conn_params *params; + u8 own_addr_type; + int err; ++ struct hci_conn *conn = data; ++ ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; ++ ++ bt_dev_dbg(hdev, "conn %p", conn); ++ ++ clear_bit(HCI_CONN_SCANNING, &conn->flags); ++ conn->state = BT_CONNECT; + + /* If requested to connect as peripheral use directed advertising */ + if (conn->role == HCI_ROLE_SLAVE) { +@@ -6577,3 +6740,125 @@ int hci_update_adv_data(struct hci_dev *hdev, u8 instance) + return hci_cmd_sync_queue(hdev, _update_adv_data_sync, + UINT_PTR(instance), NULL); + } ++ ++static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data) ++{ ++ struct hci_conn *conn = data; ++ struct inquiry_entry *ie; ++ struct hci_cp_create_conn cp; ++ int err; ++ ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; ++ ++ /* Many controllers disallow HCI Create Connection while it is doing ++ * HCI Inquiry. So we cancel the Inquiry first before issuing HCI Create ++ * Connection. This may cause the MGMT discovering state to become false ++ * without user space's request but it is okay since the MGMT Discovery ++ * APIs do not promise that discovery should be done forever. Instead, ++ * the user space monitors the status of MGMT discovering and it may ++ * request for discovery again when this flag becomes false. ++ */ ++ if (test_bit(HCI_INQUIRY, &hdev->flags)) { ++ err = __hci_cmd_sync_status(hdev, HCI_OP_INQUIRY_CANCEL, 0, ++ NULL, HCI_CMD_TIMEOUT); ++ if (err) ++ bt_dev_warn(hdev, "Failed to cancel inquiry %d", err); ++ } ++ ++ conn->state = BT_CONNECT; ++ conn->out = true; ++ conn->role = HCI_ROLE_MASTER; ++ ++ conn->attempt++; ++ ++ conn->link_policy = hdev->link_policy; ++ ++ memset(&cp, 0, sizeof(cp)); ++ bacpy(&cp.bdaddr, &conn->dst); ++ cp.pscan_rep_mode = 0x02; ++ ++ ie = hci_inquiry_cache_lookup(hdev, &conn->dst); ++ if (ie) { ++ if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) { ++ cp.pscan_rep_mode = ie->data.pscan_rep_mode; ++ cp.pscan_mode = ie->data.pscan_mode; ++ cp.clock_offset = ie->data.clock_offset | ++ cpu_to_le16(0x8000); ++ } ++ ++ memcpy(conn->dev_class, ie->data.dev_class, 3); ++ } ++ ++ cp.pkt_type = cpu_to_le16(conn->pkt_type); ++ if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) ++ cp.role_switch = 0x01; ++ else ++ cp.role_switch = 0x00; ++ ++ return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN, ++ sizeof(cp), &cp, ++ HCI_EV_CONN_COMPLETE, ++ conn->conn_timeout, NULL); ++} ++ ++int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ return hci_cmd_sync_queue_once(hdev, hci_acl_create_conn_sync, conn, ++ NULL); ++} ++ ++static void create_le_conn_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; ++ ++ hci_dev_lock(hdev); ++ ++ if (!hci_conn_valid(hdev, conn)) ++ goto done; ++ ++ if (!err) { ++ hci_connect_le_scan_cleanup(conn, 0x00); ++ goto done; ++ } ++ ++ /* Check if connection is still pending */ ++ if (conn != hci_lookup_le_connect(hdev)) ++ goto done; ++ ++ /* Flush to make sure we send create conn cancel command if needed */ ++ flush_delayed_work(&conn->le_conn_timeout); ++ hci_conn_failed(conn, bt_status(err)); ++ ++done: ++ hci_dev_unlock(hdev); ++} ++ ++int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ return hci_cmd_sync_queue_once(hdev, hci_le_create_conn_sync, conn, ++ create_le_conn_complete); ++} ++ ++int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ if (conn->state != BT_OPEN) ++ return -EINVAL; ++ ++ switch (conn->type) { ++ case ACL_LINK: ++ return !hci_cmd_sync_dequeue_once(hdev, ++ hci_acl_create_conn_sync, ++ conn, NULL); ++ case LE_LINK: ++ return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync, ++ conn, create_le_conn_complete); ++ } ++ ++ return -ENOENT; ++} +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 3533ac679e42c..4ae9029b5785f 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -2824,16 +2824,6 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, + bt_dev_dbg(hdev, "debug_keys %u key_count %u", cp->debug_keys, + key_count); + +- for (i = 0; i < key_count; i++) { +- struct mgmt_link_key_info *key = &cp->keys[i]; +- +- /* Considering SMP over BREDR/LE, there is no need to check addr_type */ +- if (key->type > 0x08) +- return mgmt_cmd_status(sk, hdev->id, +- MGMT_OP_LOAD_LINK_KEYS, +- MGMT_STATUS_INVALID_PARAMS); +- } +- + hci_dev_lock(hdev); + + hci_link_keys_clear(hdev); +@@ -2858,6 +2848,19 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, + continue; + } + ++ if (key->addr.type != BDADDR_BREDR) { ++ bt_dev_warn(hdev, ++ "Invalid link address type %u for %pMR", ++ key->addr.type, &key->addr.bdaddr); ++ continue; ++ } ++ ++ if (key->type > 0x08) { ++ bt_dev_warn(hdev, "Invalid link key type %u for %pMR", ++ key->type, &key->addr.bdaddr); ++ continue; ++ } ++ + /* Always ignore debug keys and require a new pairing if + * the user wants to use them. + */ +@@ -2915,7 +2918,12 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data) + if (!conn) + return 0; + +- return hci_abort_conn_sync(hdev, conn, HCI_ERROR_REMOTE_USER_TERM); ++ /* Disregard any possible error since the likes of hci_abort_conn_sync ++ * will clean up the connection no matter the error. ++ */ ++ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM); ++ ++ return 0; + } + + static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, +@@ -3047,13 +3055,44 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, + return err; + } + ++static void disconnect_complete(struct hci_dev *hdev, void *data, int err) ++{ ++ struct mgmt_pending_cmd *cmd = data; ++ ++ cmd->cmd_complete(cmd, mgmt_status(err)); ++ mgmt_pending_free(cmd); ++} ++ ++static int disconnect_sync(struct hci_dev *hdev, void *data) ++{ ++ struct mgmt_pending_cmd *cmd = data; ++ struct mgmt_cp_disconnect *cp = cmd->param; ++ struct hci_conn *conn; ++ ++ if (cp->addr.type == BDADDR_BREDR) ++ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, ++ &cp->addr.bdaddr); ++ else ++ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr, ++ le_addr_type(cp->addr.type)); ++ ++ if (!conn) ++ return -ENOTCONN; ++ ++ /* Disregard any possible error since the likes of hci_abort_conn_sync ++ * will clean up the connection no matter the error. ++ */ ++ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM); ++ ++ return 0; ++} ++ + static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, + u16 len) + { + struct mgmt_cp_disconnect *cp = data; + struct mgmt_rp_disconnect rp; + struct mgmt_pending_cmd *cmd; +- struct hci_conn *conn; + int err; + + bt_dev_dbg(hdev, "sock %p", sk); +@@ -3076,27 +3115,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, + goto failed; + } + +- if (pending_find(MGMT_OP_DISCONNECT, hdev)) { +- err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, +- MGMT_STATUS_BUSY, &rp, sizeof(rp)); +- goto failed; +- } +- +- if (cp->addr.type == BDADDR_BREDR) +- conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, +- &cp->addr.bdaddr); +- else +- conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr, +- le_addr_type(cp->addr.type)); +- +- if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { +- err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, +- MGMT_STATUS_NOT_CONNECTED, &rp, +- sizeof(rp)); +- goto failed; +- } +- +- cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len); ++ cmd = mgmt_pending_new(sk, MGMT_OP_DISCONNECT, hdev, data, len); + if (!cmd) { + err = -ENOMEM; + goto failed; +@@ -3104,9 +3123,10 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, + + cmd->cmd_complete = generic_cmd_complete; + +- err = hci_disconnect(conn, HCI_ERROR_REMOTE_USER_TERM); ++ err = hci_cmd_sync_queue(hdev, disconnect_sync, cmd, ++ disconnect_complete); + if (err < 0) +- mgmt_pending_remove(cmd); ++ mgmt_pending_free(cmd); + + failed: + hci_dev_unlock(hdev); +@@ -7065,7 +7085,6 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, + + for (i = 0; i < irk_count; i++) { + struct mgmt_irk_info *irk = &cp->irks[i]; +- u8 addr_type = le_addr_type(irk->addr.type); + + if (hci_is_blocked_key(hdev, + HCI_BLOCKED_KEY_TYPE_IRK, +@@ -7075,12 +7094,8 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, + continue; + } + +- /* When using SMP over BR/EDR, the addr type should be set to BREDR */ +- if (irk->addr.type == BDADDR_BREDR) +- addr_type = BDADDR_BREDR; +- + hci_add_irk(hdev, &irk->addr.bdaddr, +- addr_type, irk->val, ++ le_addr_type(irk->addr.type), irk->val, + BDADDR_ANY); + } + +@@ -7145,15 +7160,6 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + + bt_dev_dbg(hdev, "key_count %u", key_count); + +- for (i = 0; i < key_count; i++) { +- struct mgmt_ltk_info *key = &cp->keys[i]; +- +- if (!ltk_is_valid(key)) +- return mgmt_cmd_status(sk, hdev->id, +- MGMT_OP_LOAD_LONG_TERM_KEYS, +- MGMT_STATUS_INVALID_PARAMS); +- } +- + hci_dev_lock(hdev); + + hci_smp_ltks_clear(hdev); +@@ -7161,7 +7167,6 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + for (i = 0; i < key_count; i++) { + struct mgmt_ltk_info *key = &cp->keys[i]; + u8 type, authenticated; +- u8 addr_type = le_addr_type(key->addr.type); + + if (hci_is_blocked_key(hdev, + HCI_BLOCKED_KEY_TYPE_LTK, +@@ -7171,6 +7176,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + continue; + } + ++ if (!ltk_is_valid(key)) { ++ bt_dev_warn(hdev, "Invalid LTK for %pMR", ++ &key->addr.bdaddr); ++ continue; ++ } ++ + switch (key->type) { + case MGMT_LTK_UNAUTHENTICATED: + authenticated = 0x00; +@@ -7196,12 +7207,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + continue; + } + +- /* When using SMP over BR/EDR, the addr type should be set to BREDR */ +- if (key->addr.type == BDADDR_BREDR) +- addr_type = BDADDR_BREDR; +- + hci_add_ltk(hdev, &key->addr.bdaddr, +- addr_type, type, authenticated, ++ le_addr_type(key->addr.type), type, authenticated, + key->val, key->enc_size, key->ediv, key->rand); + } + +@@ -9450,7 +9457,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, + + ev.store_hint = persistent; + bacpy(&ev.key.addr.bdaddr, &key->bdaddr); +- ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); ++ ev.key.addr.type = BDADDR_BREDR; + ev.key.type = key->type; + memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); + ev.key.pin_len = key->pin_len; +@@ -9501,7 +9508,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) + ev.store_hint = persistent; + + bacpy(&ev.key.addr.bdaddr, &key->bdaddr); +- ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); ++ ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); + ev.key.type = mgmt_ltk_type(key); + ev.key.enc_size = key->enc_size; + ev.key.ediv = key->ediv; +@@ -9530,7 +9537,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent) + + bacpy(&ev.rpa, &irk->rpa); + bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr); +- ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type); ++ ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type); + memcpy(ev.irk.val, irk->val, sizeof(irk->val)); + + mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); +@@ -9559,7 +9566,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, + ev.store_hint = persistent; + + bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr); +- ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type); ++ ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type); + ev.key.type = csrk->type; + memcpy(ev.key.val, csrk->val, sizeof(csrk->val)); + +@@ -9637,18 +9644,6 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, + mgmt_event_skb(skb, NULL); + } + +-static void disconnect_rsp(struct mgmt_pending_cmd *cmd, void *data) +-{ +- struct sock **sk = data; +- +- cmd->cmd_complete(cmd, 0); +- +- *sk = cmd->sk; +- sock_hold(*sk); +- +- mgmt_pending_remove(cmd); +-} +- + static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) + { + struct hci_dev *hdev = data; +@@ -9689,8 +9684,6 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, + if (link_type != ACL_LINK && link_type != LE_LINK) + return; + +- mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); +- + bacpy(&ev.addr.bdaddr, bdaddr); + ev.addr.type = link_to_bdaddr(link_type, addr_type); + ev.reason = reason; +@@ -9703,9 +9696,6 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, + + if (sk) + sock_put(sk); +- +- mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, +- hdev); + } + + void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index fa3986cfd5266..56f7f041c9a60 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -1061,7 +1061,6 @@ static void smp_notify_keys(struct l2cap_conn *conn) + } + + if (smp->remote_irk) { +- smp->remote_irk->link_type = hcon->type; + mgmt_new_irk(hdev, smp->remote_irk, persistent); + + /* Now that user space can be considered to know the +@@ -1081,28 +1080,24 @@ static void smp_notify_keys(struct l2cap_conn *conn) + } + + if (smp->csrk) { +- smp->csrk->link_type = hcon->type; + smp->csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->csrk, persistent); + } + + if (smp->responder_csrk) { +- smp->responder_csrk->link_type = hcon->type; + smp->responder_csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->responder_csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->responder_csrk, persistent); + } + + if (smp->ltk) { +- smp->ltk->link_type = hcon->type; + smp->ltk->bdaddr_type = hcon->dst_type; + bacpy(&smp->ltk->bdaddr, &hcon->dst); + mgmt_new_ltk(hdev, smp->ltk, persistent); + } + + if (smp->responder_ltk) { +- smp->responder_ltk->link_type = hcon->type; + smp->responder_ltk->bdaddr_type = hcon->dst_type; + bacpy(&smp->responder_ltk->bdaddr, &hcon->dst); + mgmt_new_ltk(hdev, smp->responder_ltk, persistent); +@@ -1122,8 +1117,6 @@ static void smp_notify_keys(struct l2cap_conn *conn) + key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, + smp->link_key, type, 0, &persistent); + if (key) { +- key->link_type = hcon->type; +- key->bdaddr_type = hcon->dst_type; + mgmt_new_link_key(hdev, key, persistent); + + /* Don't keep debug keys around if the relevant +diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c +index e69a872bfc1d7..a6d8cd9a58078 100644 +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -1425,12 +1425,10 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, + modified = true; + } + +- if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) { ++ if (test_and_set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) { + /* Refresh entry */ + fdb->used = jiffies; +- } else if (!test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags)) { +- /* Take over SW learned entry */ +- set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags); ++ } else { + modified = true; + } + +diff --git a/net/can/bcm.c b/net/can/bcm.c +index 9168114fc87f7..00208ee13e578 100644 +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -1428,6 +1428,10 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg, + + /* remove device reference, if this is our bound device */ + if (bo->bound && bo->ifindex == dev->ifindex) { ++#if IS_ENABLED(CONFIG_PROC_FS) ++ if (sock_net(sk)->can.bcmproc_dir && bo->bcm_proc_read) ++ remove_proc_entry(bo->procname, sock_net(sk)->can.bcmproc_dir); ++#endif + bo->bound = 0; + bo->ifindex = 0; + notify_enodev = 1; +diff --git a/net/core/sock.c b/net/core/sock.c +index 55d85d50b3e49..bc2a4e38dcea8 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2019,14 +2019,6 @@ int sk_getsockopt(struct sock *sk, int level, int optname, + return 0; + } + +-int sock_getsockopt(struct socket *sock, int level, int optname, +- char __user *optval, int __user *optlen) +-{ +- return sk_getsockopt(sock->sk, level, optname, +- USER_SOCKPTR(optval), +- USER_SOCKPTR(optlen)); +-} +- + /* + * Initialize an sk_lock. + * +diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c +index b38b82ae903de..e0b8d6b17a34d 100644 +--- a/net/ipv4/fou_core.c ++++ b/net/ipv4/fou_core.c +@@ -50,7 +50,7 @@ struct fou_net { + + static inline struct fou *fou_from_sock(struct sock *sk) + { +- return sk->sk_user_data; ++ return rcu_dereference_sk_user_data(sk); + } + + static int fou_recv_pull(struct sk_buff *skb, struct fou *fou, size_t len) +@@ -233,9 +233,15 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, + struct sk_buff *skb) + { + const struct net_offload __rcu **offloads; +- u8 proto = fou_from_sock(sk)->protocol; ++ struct fou *fou = fou_from_sock(sk); + const struct net_offload *ops; + struct sk_buff *pp = NULL; ++ u8 proto; ++ ++ if (!fou) ++ goto out; ++ ++ proto = fou->protocol; + + /* We can clear the encap_mark for FOU as we are essentially doing + * one of two possible things. We are either adding an L4 tunnel +@@ -263,14 +269,24 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb, + int nhoff) + { + const struct net_offload __rcu **offloads; +- u8 proto = fou_from_sock(sk)->protocol; ++ struct fou *fou = fou_from_sock(sk); + const struct net_offload *ops; +- int err = -ENOSYS; ++ u8 proto; ++ int err; ++ ++ if (!fou) { ++ err = -ENOENT; ++ goto out; ++ } ++ ++ proto = fou->protocol; + + offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; + ops = rcu_dereference(offloads[proto]); +- if (WARN_ON(!ops || !ops->callbacks.gro_complete)) ++ if (WARN_ON(!ops || !ops->callbacks.gro_complete)) { ++ err = -ENOSYS; + goto out; ++ } + + err = ops->callbacks.gro_complete(skb, nhoff); + +@@ -320,6 +336,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, + struct gro_remcsum grc; + u8 proto; + ++ if (!fou) ++ goto out; ++ + skb_gro_remcsum_init(&grc); + + off = skb_gro_offset(skb); +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index 53b0d62fd2c2d..fe6178715ba05 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -577,7 +577,7 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + err = sk_stream_error(sk, msg->msg_flags, err); + release_sock(sk); + sk_psock_put(sk, psock); +- return copied ? copied : err; ++ return copied > 0 ? copied : err; + } + + enum { +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 24c7c955dc955..b565c8a8e7bad 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5880,6 +5880,11 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, + * RFC 5961 4.2 : Send a challenge ack + */ + if (th->syn) { ++ if (sk->sk_state == TCP_SYN_RECV && sk->sk_socket && th->ack && ++ TCP_SKB_CB(skb)->seq + 1 == TCP_SKB_CB(skb)->end_seq && ++ TCP_SKB_CB(skb)->seq + 1 == tp->rcv_nxt && ++ TCP_SKB_CB(skb)->ack_seq == tp->snd_nxt) ++ goto pass; + syn_challenge: + if (syn_inerr) + TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS); +@@ -5889,6 +5894,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, + goto discard; + } + ++pass: + bpf_skops_parse_hdr(sk, skb); + + return true; +diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h +index ad5f6f6ba3330..85b92917849bf 100644 +--- a/net/ipv6/ila/ila.h ++++ b/net/ipv6/ila/ila.h +@@ -108,6 +108,7 @@ int ila_lwt_init(void); + void ila_lwt_fini(void); + + int ila_xlat_init_net(struct net *net); ++void ila_xlat_pre_exit_net(struct net *net); + void ila_xlat_exit_net(struct net *net); + + int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info); +diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c +index 69caed07315f0..976c78efbae17 100644 +--- a/net/ipv6/ila/ila_main.c ++++ b/net/ipv6/ila/ila_main.c +@@ -71,6 +71,11 @@ static __net_init int ila_init_net(struct net *net) + return err; + } + ++static __net_exit void ila_pre_exit_net(struct net *net) ++{ ++ ila_xlat_pre_exit_net(net); ++} ++ + static __net_exit void ila_exit_net(struct net *net) + { + ila_xlat_exit_net(net); +@@ -78,6 +83,7 @@ static __net_exit void ila_exit_net(struct net *net) + + static struct pernet_operations ila_net_ops = { + .init = ila_init_net, ++ .pre_exit = ila_pre_exit_net, + .exit = ila_exit_net, + .id = &ila_net_id, + .size = sizeof(struct ila_net), +diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c +index 67e8c9440977a..534a4498e280d 100644 +--- a/net/ipv6/ila/ila_xlat.c ++++ b/net/ipv6/ila/ila_xlat.c +@@ -619,6 +619,15 @@ int ila_xlat_init_net(struct net *net) + return 0; + } + ++void ila_xlat_pre_exit_net(struct net *net) ++{ ++ struct ila_net *ilan = net_generic(net, ila_net_id); ++ ++ if (ilan->xlat.hooks_registered) ++ nf_unregister_net_hooks(net, ila_nf_hook_ops, ++ ARRAY_SIZE(ila_nf_hook_ops)); ++} ++ + void ila_xlat_exit_net(struct net *net) + { + struct ila_net *ilan = net_generic(net, ila_net_id); +@@ -626,10 +635,6 @@ void ila_xlat_exit_net(struct net *net) + rhashtable_free_and_destroy(&ilan->xlat.rhash_table, ila_free_cb, NULL); + + free_bucket_spinlocks(ilan->xlat.locks); +- +- if (ilan->xlat.hooks_registered) +- nf_unregister_net_hooks(net, ila_nf_hook_ops, +- ARRAY_SIZE(ila_nf_hook_ops)); + } + + static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila) +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 5d8ed6c90b7ef..5885810da412f 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -321,7 +321,6 @@ insert_tree(struct net *net, + struct nf_conncount_rb *rbconn; + struct nf_conncount_tuple *conn; + unsigned int count = 0, gc_count = 0; +- u8 keylen = data->keylen; + bool do_gc = true; + + spin_lock_bh(&nf_conncount_locks[hash]); +@@ -333,7 +332,7 @@ insert_tree(struct net *net, + rbconn = rb_entry(*rbnode, struct nf_conncount_rb, node); + + parent = *rbnode; +- diff = key_diff(key, rbconn->key, keylen); ++ diff = key_diff(key, rbconn->key, data->keylen); + if (diff < 0) { + rbnode = &((*rbnode)->rb_left); + } else if (diff > 0) { +@@ -378,7 +377,7 @@ insert_tree(struct net *net, + + conn->tuple = *tuple; + conn->zone = *zone; +- memcpy(rbconn->key, key, sizeof(u32) * keylen); ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); + + nf_conncount_list_init(&rbconn->list); + list_add(&conn->node, &rbconn->list.head); +@@ -403,7 +402,6 @@ count_tree(struct net *net, + struct rb_node *parent; + struct nf_conncount_rb *rbconn; + unsigned int hash; +- u8 keylen = data->keylen; + + hash = jhash2(key, data->keylen, conncount_rnd) % CONNCOUNT_SLOTS; + root = &data->root[hash]; +@@ -414,7 +412,7 @@ count_tree(struct net *net, + + rbconn = rb_entry(parent, struct nf_conncount_rb, node); + +- diff = key_diff(key, rbconn->key, keylen); ++ diff = key_diff(key, rbconn->key, data->keylen); + if (diff < 0) { + parent = rcu_dereference_raw(parent->rb_left); + } else if (diff > 0) { +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 9cff99558694d..30955dd45779e 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -786,12 +786,15 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + * queue, accept the collision, update the host tags. + */ + q->way_collisions++; +- if (q->flows[outer_hash + k].set == CAKE_SET_BULK) { +- q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; +- q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; +- } + allocate_src = cake_dsrc(flow_mode); + allocate_dst = cake_ddst(flow_mode); ++ ++ if (q->flows[outer_hash + k].set == CAKE_SET_BULK) { ++ if (allocate_src) ++ q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; ++ if (allocate_dst) ++ q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; ++ } + found: + /* reserve queue for future packets in same flow */ + reduced_hash = outer_hash + k; +diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c +index 0224a92492453..d36eeb7b05029 100644 +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -742,11 +742,10 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + + err = qdisc_enqueue(skb, q->qdisc, &to_free); + kfree_skb_list(to_free); +- if (err != NET_XMIT_SUCCESS && +- net_xmit_drop_count(err)) { +- qdisc_qstats_drop(sch); +- qdisc_tree_reduce_backlog(sch, 1, +- pkt_len); ++ if (err != NET_XMIT_SUCCESS) { ++ if (net_xmit_drop_count(err)) ++ qdisc_qstats_drop(sch); ++ qdisc_tree_reduce_backlog(sch, 1, pkt_len); + } + goto tfifo_dequeue; + } +diff --git a/net/socket.c b/net/socket.c +index 8d83c4bb163b4..9db33cd4a71b8 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -2281,33 +2281,23 @@ static bool sock_use_custom_sol_socket(const struct socket *sock) + return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags); + } + +-/* +- * Set a socket option. Because we don't know the option lengths we have +- * to pass the user mode parameter for the protocols to sort out. +- */ +-int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval, +- int optlen) ++int do_sock_setsockopt(struct socket *sock, bool compat, int level, ++ int optname, sockptr_t optval, int optlen) + { +- sockptr_t optval = USER_SOCKPTR(user_optval); + const struct proto_ops *ops; + char *kernel_optval = NULL; +- int err, fput_needed; +- struct socket *sock; ++ int err; + + if (optlen < 0) + return -EINVAL; + +- sock = sockfd_lookup_light(fd, &err, &fput_needed); +- if (!sock) +- return err; +- + err = security_socket_setsockopt(sock, level, optname); + if (err) + goto out_put; + +- if (!in_compat_syscall()) ++ if (!compat) + err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname, +- user_optval, &optlen, ++ optval, &optlen, + &kernel_optval); + if (err < 0) + goto out_put; +@@ -2328,6 +2318,27 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval, + optlen); + kfree(kernel_optval); + out_put: ++ return err; ++} ++EXPORT_SYMBOL(do_sock_setsockopt); ++ ++/* Set a socket option. Because we don't know the option lengths we have ++ * to pass the user mode parameter for the protocols to sort out. ++ */ ++int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval, ++ int optlen) ++{ ++ sockptr_t optval = USER_SOCKPTR(user_optval); ++ bool compat = in_compat_syscall(); ++ int err, fput_needed; ++ struct socket *sock; ++ ++ sock = sockfd_lookup_light(fd, &err, &fput_needed); ++ if (!sock) ++ return err; ++ ++ err = do_sock_setsockopt(sock, compat, level, optname, optval, optlen); ++ + fput_light(sock->file, fput_needed); + return err; + } +@@ -2341,6 +2352,43 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, + INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level, + int optname)); + ++int do_sock_getsockopt(struct socket *sock, bool compat, int level, ++ int optname, sockptr_t optval, sockptr_t optlen) ++{ ++ int max_optlen __maybe_unused = 0; ++ const struct proto_ops *ops; ++ int err; ++ ++ err = security_socket_getsockopt(sock, level, optname); ++ if (err) ++ return err; ++ ++ if (!compat) ++ copy_from_sockptr(&max_optlen, optlen, sizeof(int)); ++ ++ ops = READ_ONCE(sock->ops); ++ if (level == SOL_SOCKET) { ++ err = sk_getsockopt(sock->sk, level, optname, optval, optlen); ++ } else if (unlikely(!ops->getsockopt)) { ++ err = -EOPNOTSUPP; ++ } else { ++ if (WARN_ONCE(optval.is_kernel || optlen.is_kernel, ++ "Invalid argument type")) ++ return -EOPNOTSUPP; ++ ++ err = ops->getsockopt(sock, level, optname, optval.user, ++ optlen.user); ++ } ++ ++ if (!compat) ++ err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, ++ optval, optlen, max_optlen, ++ err); ++ ++ return err; ++} ++EXPORT_SYMBOL(do_sock_getsockopt); ++ + /* + * Get a socket option. Because we don't know the option lengths we have + * to pass a user mode parameter for the protocols to sort out. +@@ -2348,36 +2396,18 @@ INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level, + int __sys_getsockopt(int fd, int level, int optname, char __user *optval, + int __user *optlen) + { +- int max_optlen __maybe_unused; +- const struct proto_ops *ops; + int err, fput_needed; + struct socket *sock; ++ bool compat; + + sock = sockfd_lookup_light(fd, &err, &fput_needed); + if (!sock) + return err; + +- err = security_socket_getsockopt(sock, level, optname); +- if (err) +- goto out_put; +- +- if (!in_compat_syscall()) +- max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen); ++ compat = in_compat_syscall(); ++ err = do_sock_getsockopt(sock, compat, level, optname, ++ USER_SOCKPTR(optval), USER_SOCKPTR(optlen)); + +- ops = READ_ONCE(sock->ops); +- if (level == SOL_SOCKET) +- err = sock_getsockopt(sock, level, optname, optval, optlen); +- else if (unlikely(!ops->getsockopt)) +- err = -EOPNOTSUPP; +- else +- err = ops->getsockopt(sock, level, optname, optval, +- optlen); +- +- if (!in_compat_syscall()) +- err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, +- optval, optlen, max_optlen, +- err); +-out_put: + fput_light(sock->file, fput_needed); + return err; + } +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index b7f62442d8268..dca4429014db1 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -693,9 +693,6 @@ static void init_peercred(struct sock *sk) + + static void copy_peercred(struct sock *sk, struct sock *peersk) + { +- const struct cred *old_cred; +- struct pid *old_pid; +- + if (sk < peersk) { + spin_lock(&sk->sk_peer_lock); + spin_lock_nested(&peersk->sk_peer_lock, SINGLE_DEPTH_NESTING); +@@ -703,16 +700,12 @@ static void copy_peercred(struct sock *sk, struct sock *peersk) + spin_lock(&peersk->sk_peer_lock); + spin_lock_nested(&sk->sk_peer_lock, SINGLE_DEPTH_NESTING); + } +- old_pid = sk->sk_peer_pid; +- old_cred = sk->sk_peer_cred; ++ + sk->sk_peer_pid = get_pid(peersk->sk_peer_pid); + sk->sk_peer_cred = get_cred(peersk->sk_peer_cred); + + spin_unlock(&sk->sk_peer_lock); + spin_unlock(&peersk->sk_peer_lock); +- +- put_pid(old_pid); +- put_cred(old_cred); + } + + static int unix_listen(struct socket *sock, int backlog) +diff --git a/rust/Makefile b/rust/Makefile +index e5619f25b55ca..333b9a482473d 100644 +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -363,9 +363,7 @@ $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE + quiet_cmd_exports = EXPORTS $@ + cmd_exports = \ + $(NM) -p --defined-only $< \ +- | grep -E ' (T|R|D) ' | cut -d ' ' -f 3 \ +- | xargs -Isymbol \ +- echo 'EXPORT_SYMBOL_RUST_GPL(symbol);' > $@ ++ | awk '/ (T|R|D|B) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@ + + $(obj)/exports_core_generated.h: $(obj)/core.o FORCE + $(call if_changed,exports) +diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs +index fdb778e65d79d..e23e7827d756d 100644 +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -248,7 +248,7 @@ pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit { + } + + /// Returns a raw pointer to the opaque data. +- pub fn get(&self) -> *mut T { ++ pub const fn get(&self) -> *mut T { + UnsafeCell::get(&self.value).cast::() + } + +diff --git a/rust/macros/module.rs b/rust/macros/module.rs +index acd0393b50957..7dee348ef0cc8 100644 +--- a/rust/macros/module.rs ++++ b/rust/macros/module.rs +@@ -203,7 +203,11 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { + // freed until the module is unloaded. + #[cfg(MODULE)] + static THIS_MODULE: kernel::ThisModule = unsafe {{ +- kernel::ThisModule::from_ptr(&kernel::bindings::__this_module as *const _ as *mut _) ++ extern \"C\" {{ ++ static __this_module: kernel::types::Opaque; ++ }} ++ ++ kernel::ThisModule::from_ptr(__this_module.get()) + }}; + #[cfg(not(MODULE))] + static THIS_MODULE: kernel::ThisModule = unsafe {{ +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 98c2bdbfcaed6..4625674f0e95b 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3769,12 +3769,18 @@ static int smack_unix_stream_connect(struct sock *sock, + } + } + +- /* +- * Cross reference the peer labels for SO_PEERSEC. +- */ + if (rc == 0) { ++ /* ++ * Cross reference the peer labels for SO_PEERSEC. ++ */ + nsp->smk_packet = ssp->smk_out; + ssp->smk_packet = osp->smk_out; ++ ++ /* ++ * new/child/established socket must inherit listening socket labels ++ */ ++ nsp->smk_out = osp->smk_out; ++ nsp->smk_in = osp->smk_in; + } + + return rc; +diff --git a/sound/core/control.c b/sound/core/control.c +index 59c8658966d4c..dd4bdb39782cd 100644 +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -1553,12 +1553,16 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, + static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { +- int change; ++ int err, change; + struct user_element *ue = kcontrol->private_data; + unsigned int size = ue->elem_data_size; + char *dst = ue->elem_data + + snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size; + ++ err = sanity_check_input_values(ue->card, ucontrol, &ue->info, false); ++ if (err < 0) ++ return err; ++ + change = memcmp(&ucontrol->value, dst, size) != 0; + if (change) + memcpy(dst, &ucontrol->value, size); +diff --git a/sound/hda/hdmi_chmap.c b/sound/hda/hdmi_chmap.c +index 5d8e1d944b0af..7b276047f85a7 100644 +--- a/sound/hda/hdmi_chmap.c ++++ b/sound/hda/hdmi_chmap.c +@@ -753,6 +753,20 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol, + return 0; + } + ++/* a simple sanity check for input values to chmap kcontrol */ ++static int chmap_value_check(struct hdac_chmap *hchmap, ++ const struct snd_ctl_elem_value *ucontrol) ++{ ++ int i; ++ ++ for (i = 0; i < hchmap->channels_max; i++) { ++ if (ucontrol->value.integer.value[i] < 0 || ++ ucontrol->value.integer.value[i] > SNDRV_CHMAP_LAST) ++ return -EINVAL; ++ } ++ return 0; ++} ++ + static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { +@@ -764,6 +778,10 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol, + unsigned char chmap[8], per_pin_chmap[8]; + int i, err, ca, prepared = 0; + ++ err = chmap_value_check(hchmap, ucontrol); ++ if (err < 0) ++ return err; ++ + /* No monitor is connected in dyn_pcm_assign. + * It's invalid to setup the chmap + */ +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 8396d1d93668c..63bd0e384bae2 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -311,6 +311,7 @@ enum { + CXT_FIXUP_HEADSET_MIC, + CXT_FIXUP_HP_MIC_NO_PRESENCE, + CXT_PINCFG_SWS_JS201D, ++ CXT_PINCFG_TOP_SPEAKER, + }; + + /* for hda_fixup_thinkpad_acpi() */ +@@ -978,6 +979,13 @@ static const struct hda_fixup cxt_fixups[] = { + .type = HDA_FIXUP_PINS, + .v.pins = cxt_pincfg_sws_js201d, + }, ++ [CXT_PINCFG_TOP_SPEAKER] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x1d, 0x82170111 }, ++ { } ++ }, ++ }, + }; + + static const struct snd_pci_quirk cxt5045_fixups[] = { +@@ -1074,6 +1082,8 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI), + SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004), + SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205), ++ SND_PCI_QUIRK(0x2782, 0x12c3, "Sirius Gen1", CXT_PINCFG_TOP_SPEAKER), ++ SND_PCI_QUIRK(0x2782, 0x12c5, "Sirius Gen2", CXT_PINCFG_TOP_SPEAKER), + {} + }; + +@@ -1093,6 +1103,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { + { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, + { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, + { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, ++ { .id = CXT_PINCFG_TOP_SPEAKER, .name = "sirius-top-speaker" }, + {} + }; + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5736516275a34..6661fed2c2bbf 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7366,6 +7366,7 @@ enum { + ALC236_FIXUP_HP_GPIO_LED, + ALC236_FIXUP_HP_MUTE_LED, + ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF, ++ ALC236_FIXUP_LENOVO_INV_DMIC, + ALC298_FIXUP_SAMSUNG_AMP, + ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, + ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, +@@ -8922,6 +8923,12 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_micmute_vref, + }, ++ [ALC236_FIXUP_LENOVO_INV_DMIC] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_inv_dmic, ++ .chained = true, ++ .chain_id = ALC283_FIXUP_INT_MIC, ++ }, + [ALC298_FIXUP_SAMSUNG_AMP] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc298_fixup_samsung_amp, +@@ -9866,6 +9873,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f6, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), + SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), ++ SND_PCI_QUIRK(0x103c, 0x87fd, "HP Laptop 14-dq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x87fe, "HP Laptop 15s-fq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8805, "HP ProBook 650 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x880d, "HP EliteBook 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), +@@ -10298,6 +10306,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x38f9, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x38fa, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), ++ SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), +@@ -10546,6 +10555,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { + {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, + {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"}, + {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"}, ++ {.id = ALC236_FIXUP_LENOVO_INV_DMIC, .name = "alc236-fixup-lenovo-inv-mic"}, + {} + }; + #define ALC225_STANDARD_PINS \ +diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c +index 41ad82a429163..3639dcd0bbb2b 100644 +--- a/sound/soc/codecs/tas2781-fmwlib.c ++++ b/sound/soc/codecs/tas2781-fmwlib.c +@@ -21,7 +21,7 @@ + #include + #include + #include +- ++#include + + #define ERROR_PRAM_CRCCHK 0x0000000 + #define ERROR_YRAM_CRCCHK 0x0000001 +@@ -125,8 +125,7 @@ static struct tasdevice_config_info *tasdevice_add_config( + /* convert data[offset], data[offset + 1], data[offset + 2] and + * data[offset + 3] into host + */ +- cfg_info->nblocks = +- be32_to_cpup((__be32 *)&config_data[config_offset]); ++ cfg_info->nblocks = get_unaligned_be32(&config_data[config_offset]); + config_offset += 4; + + /* Several kinds of dsp/algorithm firmwares can run on tas2781, +@@ -170,14 +169,14 @@ static struct tasdevice_config_info *tasdevice_add_config( + + } + bk_da[i]->yram_checksum = +- be16_to_cpup((__be16 *)&config_data[config_offset]); ++ get_unaligned_be16(&config_data[config_offset]); + config_offset += 2; + bk_da[i]->block_size = +- be32_to_cpup((__be32 *)&config_data[config_offset]); ++ get_unaligned_be32(&config_data[config_offset]); + config_offset += 4; + + bk_da[i]->n_subblks = +- be32_to_cpup((__be32 *)&config_data[config_offset]); ++ get_unaligned_be32(&config_data[config_offset]); + + config_offset += 4; + +@@ -227,7 +226,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) + } + buf = (unsigned char *)fmw->data; + +- fw_hdr->img_sz = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->img_sz = get_unaligned_be32(&buf[offset]); + offset += 4; + if (fw_hdr->img_sz != fmw->size) { + dev_err(tas_priv->dev, +@@ -238,9 +237,9 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) + goto out; + } + +- fw_hdr->checksum = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->checksum = get_unaligned_be32(&buf[offset]); + offset += 4; +- fw_hdr->binary_version_num = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]); + if (fw_hdr->binary_version_num < 0x103) { + dev_err(tas_priv->dev, "File version 0x%04x is too low", + fw_hdr->binary_version_num); +@@ -249,7 +248,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) + goto out; + } + offset += 4; +- fw_hdr->drv_fw_version = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]); + offset += 8; + fw_hdr->plat_type = buf[offset]; + offset += 1; +@@ -277,11 +276,11 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) + for (i = 0; i < TASDEVICE_DEVICE_SUM; i++, offset++) + fw_hdr->devs[i] = buf[offset]; + +- fw_hdr->nconfig = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->nconfig = get_unaligned_be32(&buf[offset]); + offset += 4; + + for (i = 0; i < TASDEVICE_CONFIG_SUM; i++) { +- fw_hdr->config_size[i] = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]); + offset += 4; + total_config_sz += fw_hdr->config_size[i]; + } +@@ -330,7 +329,7 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw, + /* convert data[offset], data[offset + 1], data[offset + 2] and + * data[offset + 3] into host + */ +- block->type = be32_to_cpup((__be32 *)&data[offset]); ++ block->type = get_unaligned_be32(&data[offset]); + offset += 4; + + block->is_pchksum_present = data[offset]; +@@ -345,10 +344,10 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw, + block->ychksum = data[offset]; + offset++; + +- block->blk_size = be32_to_cpup((__be32 *)&data[offset]); ++ block->blk_size = get_unaligned_be32(&data[offset]); + offset += 4; + +- block->nr_subblocks = be32_to_cpup((__be32 *)&data[offset]); ++ block->nr_subblocks = get_unaligned_be32(&data[offset]); + offset += 4; + + if (offset + block->blk_size > fmw->size) { +@@ -381,7 +380,7 @@ static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw, + offset = -EINVAL; + goto out; + } +- img_data->nr_blk = be32_to_cpup((__be32 *)&data[offset]); ++ img_data->nr_blk = get_unaligned_be32(&data[offset]); + offset += 4; + + img_data->dev_blks = kcalloc(img_data->nr_blk, +@@ -477,14 +476,14 @@ static int fw_parse_variable_header_kernel( + offset = -EINVAL; + goto out; + } +- fw_hdr->device_family = be16_to_cpup((__be16 *)&buf[offset]); ++ fw_hdr->device_family = get_unaligned_be16(&buf[offset]); + if (fw_hdr->device_family != 0) { + dev_err(tas_priv->dev, "%s:not TAS device\n", __func__); + offset = -EINVAL; + goto out; + } + offset += 2; +- fw_hdr->device = be16_to_cpup((__be16 *)&buf[offset]); ++ fw_hdr->device = get_unaligned_be16(&buf[offset]); + if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE || + fw_hdr->device == 6) { + dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device); +@@ -502,7 +501,7 @@ static int fw_parse_variable_header_kernel( + goto out; + } + +- tas_fmw->nr_programs = be32_to_cpup((__be32 *)&buf[offset]); ++ tas_fmw->nr_programs = get_unaligned_be32(&buf[offset]); + offset += 4; + + if (tas_fmw->nr_programs == 0 || tas_fmw->nr_programs > +@@ -521,14 +520,14 @@ static int fw_parse_variable_header_kernel( + + for (i = 0; i < tas_fmw->nr_programs; i++) { + program = &(tas_fmw->programs[i]); +- program->prog_size = be32_to_cpup((__be32 *)&buf[offset]); ++ program->prog_size = get_unaligned_be32(&buf[offset]); + offset += 4; + } + + /* Skip the unused prog_size */ + offset += 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs); + +- tas_fmw->nr_configurations = be32_to_cpup((__be32 *)&buf[offset]); ++ tas_fmw->nr_configurations = get_unaligned_be32(&buf[offset]); + offset += 4; + + /* The max number of config in firmware greater than 4 pieces of +@@ -560,7 +559,7 @@ static int fw_parse_variable_header_kernel( + + for (i = 0; i < tas_fmw->nr_programs; i++) { + config = &(tas_fmw->configs[i]); +- config->cfg_size = be32_to_cpup((__be32 *)&buf[offset]); ++ config->cfg_size = get_unaligned_be32(&buf[offset]); + offset += 4; + } + +@@ -598,7 +597,7 @@ static int tasdevice_process_block(void *context, unsigned char *data, + switch (subblk_typ) { + case TASDEVICE_CMD_SING_W: { + int i; +- unsigned short len = be16_to_cpup((__be16 *)&data[2]); ++ unsigned short len = get_unaligned_be16(&data[2]); + + subblk_offset += 2; + if (subblk_offset + 4 * len > sublocksize) { +@@ -624,7 +623,7 @@ static int tasdevice_process_block(void *context, unsigned char *data, + } + break; + case TASDEVICE_CMD_BURST: { +- unsigned short len = be16_to_cpup((__be16 *)&data[2]); ++ unsigned short len = get_unaligned_be16(&data[2]); + + subblk_offset += 2; + if (subblk_offset + 4 + len > sublocksize) { +@@ -665,7 +664,7 @@ static int tasdevice_process_block(void *context, unsigned char *data, + is_err = true; + break; + } +- sleep_time = be16_to_cpup((__be16 *)&data[2]) * 1000; ++ sleep_time = get_unaligned_be16(&data[2]) * 1000; + usleep_range(sleep_time, sleep_time + 50); + subblk_offset += 2; + } +@@ -940,7 +939,7 @@ static int fw_parse_variable_hdr(struct tasdevice_priv + + offset += len; + +- fw_hdr->device_family = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->device_family = get_unaligned_be32(&buf[offset]); + if (fw_hdr->device_family != 0) { + dev_err(tas_priv->dev, "%s: not TAS device\n", __func__); + offset = -EINVAL; +@@ -948,7 +947,7 @@ static int fw_parse_variable_hdr(struct tasdevice_priv + } + offset += 4; + +- fw_hdr->device = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_hdr->device = get_unaligned_be32(&buf[offset]); + if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE || + fw_hdr->device == 6) { + dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device); +@@ -993,7 +992,7 @@ static int fw_parse_block_data(struct tasdevice_fw *tas_fmw, + offset = -EINVAL; + goto out; + } +- block->type = be32_to_cpup((__be32 *)&data[offset]); ++ block->type = get_unaligned_be32(&data[offset]); + offset += 4; + + if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) { +@@ -1018,7 +1017,7 @@ static int fw_parse_block_data(struct tasdevice_fw *tas_fmw, + block->is_ychksum_present = 0; + } + +- block->nr_cmds = be32_to_cpup((__be32 *)&data[offset]); ++ block->nr_cmds = get_unaligned_be32(&data[offset]); + offset += 4; + + n = block->nr_cmds * 4; +@@ -1069,7 +1068,7 @@ static int fw_parse_data(struct tasdevice_fw *tas_fmw, + goto out; + } + offset += n; +- img_data->nr_blk = be16_to_cpup((__be16 *)&data[offset]); ++ img_data->nr_blk = get_unaligned_be16(&data[offset]); + offset += 2; + + img_data->dev_blks = kcalloc(img_data->nr_blk, +@@ -1106,7 +1105,7 @@ static int fw_parse_program_data(struct tasdevice_priv *tas_priv, + offset = -EINVAL; + goto out; + } +- tas_fmw->nr_programs = be16_to_cpup((__be16 *)&buf[offset]); ++ tas_fmw->nr_programs = get_unaligned_be16(&buf[offset]); + offset += 2; + + if (tas_fmw->nr_programs == 0) { +@@ -1173,7 +1172,7 @@ static int fw_parse_configuration_data( + offset = -EINVAL; + goto out; + } +- tas_fmw->nr_configurations = be16_to_cpup((__be16 *)&data[offset]); ++ tas_fmw->nr_configurations = get_unaligned_be16(&data[offset]); + offset += 2; + + if (tas_fmw->nr_configurations == 0) { +@@ -1805,7 +1804,7 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv, + /* Convert data[offset], data[offset + 1], data[offset + 2] and + * data[offset + 3] into host + */ +- fw_fixed_hdr->fwsize = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_fixed_hdr->fwsize = get_unaligned_be32(&buf[offset]); + offset += 4; + if (fw_fixed_hdr->fwsize != fmw->size) { + dev_err(tas_priv->dev, "File size not match, %lu %u", +@@ -1814,9 +1813,9 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv, + goto out; + } + offset += 4; +- fw_fixed_hdr->ppcver = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_fixed_hdr->ppcver = get_unaligned_be32(&buf[offset]); + offset += 8; +- fw_fixed_hdr->drv_ver = be32_to_cpup((__be32 *)&buf[offset]); ++ fw_fixed_hdr->drv_ver = get_unaligned_be32(&buf[offset]); + offset += 72; + + out: +@@ -1858,7 +1857,7 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv, + offset = -EINVAL; + goto out; + } +- tas_fmw->nr_calibrations = be16_to_cpup((__be16 *)&data[offset]); ++ tas_fmw->nr_calibrations = get_unaligned_be16(&data[offset]); + offset += 2; + + if (tas_fmw->nr_calibrations != 1) { +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 85e3bbf7e5f0e..7729f8f4d5e61 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -4018,6 +4018,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, + + case SND_SOC_DAPM_POST_PMD: + kfree(substream->runtime); ++ substream->runtime = NULL; + break; + + default: +diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c +index 7e8fca0b06628..a643ef654b9d7 100644 +--- a/sound/soc/soc-topology.c ++++ b/sound/soc/soc-topology.c +@@ -851,6 +851,8 @@ static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum * + se->dobj.control.dvalues[i] = le32_to_cpu(ec->values[i]); + } + ++ se->items = le32_to_cpu(ec->items); ++ se->values = (const unsigned int *)se->dobj.control.dvalues; + return 0; + } + +diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c +index 7133ec13322b3..cf1e63daad86b 100644 +--- a/sound/soc/sof/topology.c ++++ b/sound/soc/sof/topology.c +@@ -2040,6 +2040,8 @@ static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj + if (!slink) + return 0; + ++ slink->link->platforms->name = NULL; ++ + kfree(slink->tuples); + list_del(&slink->list); + kfree(slink->hw_configs); +diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c +index 5124b6c9ceb4b..d1cb49d54f008 100644 +--- a/sound/soc/sunxi/sun4i-i2s.c ++++ b/sound/soc/sunxi/sun4i-i2s.c +@@ -100,8 +100,8 @@ + #define SUN8I_I2S_CTRL_MODE_PCM (0 << 4) + + #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19) +-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19) +-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19) ++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH (1 << 19) ++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW (0 << 19) + #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) + #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) + #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7) +@@ -727,65 +727,37 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + unsigned int fmt) + { +- u32 mode, val; ++ u32 mode, lrclk_pol, bclk_pol, val; + u8 offset; + +- /* +- * DAI clock polarity +- * +- * The setup for LRCK contradicts the datasheet, but under a +- * scope it's clear that the LRCK polarity is reversed +- * compared to the expected polarity on the bus. +- */ +- switch (fmt & SND_SOC_DAIFMT_INV_MASK) { +- case SND_SOC_DAIFMT_IB_IF: +- /* Invert both clocks */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_IB_NF: +- /* Invert bit clock */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED | +- SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_NB_IF: +- /* Invert frame clock */ +- val = 0; +- break; +- case SND_SOC_DAIFMT_NB_NF: +- val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- default: +- return -EINVAL; +- } +- +- regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, +- SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | +- SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, +- val); +- + /* DAI Mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 1; + break; + + case SND_SOC_DAIFMT_DSP_B: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 0; + break; + + case SND_SOC_DAIFMT_I2S: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 1; + break; + + case SND_SOC_DAIFMT_LEFT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 0; + break; + + case SND_SOC_DAIFMT_RIGHT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_RIGHT; + offset = 0; + break; +@@ -803,6 +775,35 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + SUN8I_I2S_TX_CHAN_OFFSET_MASK, + SUN8I_I2S_TX_CHAN_OFFSET(offset)); + ++ /* DAI clock polarity */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL; ++ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Invert both clocks */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* Invert bit clock */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* Invert frame clock */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ /* No inversion */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, ++ SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | ++ SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, ++ lrclk_pol | bclk_pol); ++ + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: +@@ -834,65 +835,37 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + unsigned int fmt) + { +- u32 mode, val; ++ u32 mode, lrclk_pol, bclk_pol, val; + u8 offset; + +- /* +- * DAI clock polarity +- * +- * The setup for LRCK contradicts the datasheet, but under a +- * scope it's clear that the LRCK polarity is reversed +- * compared to the expected polarity on the bus. +- */ +- switch (fmt & SND_SOC_DAIFMT_INV_MASK) { +- case SND_SOC_DAIFMT_IB_IF: +- /* Invert both clocks */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_IB_NF: +- /* Invert bit clock */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED | +- SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_NB_IF: +- /* Invert frame clock */ +- val = 0; +- break; +- case SND_SOC_DAIFMT_NB_NF: +- val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- default: +- return -EINVAL; +- } +- +- regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, +- SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | +- SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, +- val); +- + /* DAI Mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 1; + break; + + case SND_SOC_DAIFMT_DSP_B: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 0; + break; + + case SND_SOC_DAIFMT_I2S: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 1; + break; + + case SND_SOC_DAIFMT_LEFT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 0; + break; + + case SND_SOC_DAIFMT_RIGHT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_RIGHT; + offset = 0; + break; +@@ -910,6 +883,36 @@ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK, + SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)); + ++ /* DAI clock polarity */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL; ++ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Invert both clocks */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* Invert bit clock */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* Invert frame clock */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ /* No inversion */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, ++ SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | ++ SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, ++ lrclk_pol | bclk_pol); ++ ++ + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: +diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c +index 3f114a2adfced..ab3c6b2544d20 100644 +--- a/sound/soc/tegra/tegra210_ahub.c ++++ b/sound/soc/tegra/tegra210_ahub.c +@@ -2,7 +2,7 @@ + // + // tegra210_ahub.c - Tegra210 AHUB driver + // +-// Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. ++// Copyright (c) 2020-2024, NVIDIA CORPORATION. All rights reserved. + + #include + #include +@@ -1391,11 +1391,13 @@ static int tegra_ahub_probe(struct platform_device *pdev) + return err; + } + ++ pm_runtime_enable(&pdev->dev); ++ + err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); +- if (err) ++ if (err) { ++ pm_runtime_disable(&pdev->dev); + return err; +- +- pm_runtime_enable(&pdev->dev); ++ } + + return 0; + } +diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c +index de35b9a21dad7..ceed16a10285a 100644 +--- a/tools/lib/bpf/libbpf.c ++++ b/tools/lib/bpf/libbpf.c +@@ -9753,7 +9753,7 @@ __bpf_map__iter(const struct bpf_map *m, const struct bpf_object *obj, int i) + struct bpf_map * + bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev) + { +- if (prev == NULL) ++ if (prev == NULL && obj != NULL) + return obj->maps; + + return __bpf_map__iter(prev, obj, 1); +@@ -9762,7 +9762,7 @@ bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev) + struct bpf_map * + bpf_object__prev_map(const struct bpf_object *obj, const struct bpf_map *next) + { +- if (next == NULL) { ++ if (next == NULL && obj != NULL) { + if (!obj->nr_maps) + return NULL; + return obj->maps + obj->nr_maps - 1; +diff --git a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c +index 890a8236a8ba7..2809f9a25c433 100644 +--- a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c ++++ b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c +@@ -28,9 +28,11 @@ static int check_vgem(int fd) + version.name = name; + + ret = ioctl(fd, DRM_IOCTL_VERSION, &version); +- if (ret) ++ if (ret || version.name_len != 4) + return 0; + ++ name[4] = '\0'; ++ + return !strcmp(name, "vgem"); + } + +diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile +index d417de1051233..91a48efb140be 100644 +--- a/tools/testing/selftests/net/Makefile ++++ b/tools/testing/selftests/net/Makefile +@@ -85,7 +85,8 @@ TEST_GEN_FILES += csum + TEST_GEN_FILES += nat6to4.o + TEST_GEN_FILES += xdp_dummy.o + TEST_GEN_FILES += ip_local_port_range +-TEST_GEN_FILES += bind_wildcard ++TEST_GEN_PROGS += bind_wildcard ++TEST_GEN_PROGS += bind_timewait + TEST_PROGS += test_vxlan_mdb.sh + TEST_PROGS += test_bridge_neigh_suppress.sh + TEST_PROGS += test_vxlan_nolocalbypass.sh