summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2023-01-12 07:18:29 -0500
committerMike Pagano <mpagano@gentoo.org>2023-01-12 07:18:29 -0500
commitdbcd91a9d04b6c9a4783ec1824f403c2b2bda310 (patch)
tree1ab80adbb93d66278991cc9aa693067675fcde80
parentLinux patch 5.15.86 (diff)
downloadlinux-patches-dbcd91a9d04b6c9a4783ec1824f403c2b2bda310.tar.gz
linux-patches-dbcd91a9d04b6c9a4783ec1824f403c2b2bda310.tar.bz2
linux-patches-dbcd91a9d04b6c9a4783ec1824f403c2b2bda310.zip
Linux patch 5.15.875.15-91
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1086_linux-5.15.87.patch12684
2 files changed, 12688 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 2eeb88bf..554b9da3 100644
--- a/0000_README
+++ b/0000_README
@@ -387,6 +387,10 @@ Patch: 1085_linux-5.15.86.patch
From: http://www.kernel.org
Desc: Linux 5.15.86
+Patch: 1086_linux-5.15.87.patch
+From: http://www.kernel.org
+Desc: Linux 5.15.87
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1086_linux-5.15.87.patch b/1086_linux-5.15.87.patch
new file mode 100644
index 00000000..a6f7dffe
--- /dev/null
+++ b/1086_linux-5.15.87.patch
@@ -0,0 +1,12684 @@
+diff --git a/Makefile b/Makefile
+index 9f5d2e87150ed..6a9589c7b1bc0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 15
+-SUBLEVEL = 86
++SUBLEVEL = 87
+ EXTRAVERSION =
+ NAME = Trick or Treat
+
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index 9a18da3e10cc3..b682189a2b5df 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -129,15 +129,16 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
+ #define TIF_NEED_RESCHED 1 /* rescheduling necessary */
+ #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
+ #define TIF_UPROBE 3 /* breakpointed or singlestepping */
+-#define TIF_SYSCALL_TRACE 4 /* syscall trace active */
+-#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+-#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
+-#define TIF_SECCOMP 7 /* seccomp syscall filtering active */
+-#define TIF_NOTIFY_SIGNAL 8 /* signal notifications exist */
++#define TIF_NOTIFY_SIGNAL 4 /* signal notifications exist */
+
+ #define TIF_USING_IWMMXT 17
+ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
+-#define TIF_RESTORE_SIGMASK 20
++#define TIF_RESTORE_SIGMASK 19
++#define TIF_SYSCALL_TRACE 20 /* syscall trace active */
++#define TIF_SYSCALL_AUDIT 21 /* syscall auditing active */
++#define TIF_SYSCALL_TRACEPOINT 22 /* syscall tracepoint instrumentation */
++#define TIF_SECCOMP 23 /* seccomp syscall filtering active */
++
+
+ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
+index 303400fa2cdf7..2aec85ab1e8b9 100644
+--- a/arch/arm/nwfpe/Makefile
++++ b/arch/arm/nwfpe/Makefile
+@@ -11,3 +11,9 @@ nwfpe-y += fpa11.o fpa11_cpdo.o fpa11_cpdt.o \
+ entry.o
+
+ nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o
++
++# Try really hard to avoid generating calls to __aeabi_uldivmod() from
++# float64_rem() due to loop elision.
++ifdef CONFIG_CC_IS_CLANG
++CFLAGS_softfloat.o += -mllvm -replexitval=never
++endif
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index 2d5533dd4ec2d..146d3cd3f1b31 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -1045,7 +1045,10 @@
+
+ /* PINCTRL - additions to nodes defined in sdm845.dtsi */
+ &qup_spi2_default {
+- drive-strength = <16>;
++ pinconf {
++ pins = "gpio27", "gpio28", "gpio29", "gpio30";
++ drive-strength = <16>;
++ };
+ };
+
+ &qup_uart3_default{
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+index 617a634ac9051..834fb463f99ec 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+@@ -475,8 +475,10 @@
+ };
+
+ &qup_i2c12_default {
+- drive-strength = <2>;
+- bias-disable;
++ pinmux {
++ drive-strength = <2>;
++ bias-disable;
++ };
+ };
+
+ &qup_uart6_default {
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 7834ce3aa7f1b..2dae702e7a5a7 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -788,6 +788,7 @@ void __noreturn rtas_halt(void)
+
+ /* Must be in the RMO region, so we place it here */
+ static char rtas_os_term_buf[2048];
++static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE;
+
+ void rtas_os_term(char *str)
+ {
+@@ -799,16 +800,20 @@ void rtas_os_term(char *str)
+ * this property may terminate the partition which we want to avoid
+ * since it interferes with panic_timeout.
+ */
+- if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") ||
+- RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term"))
++ if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE)
+ return;
+
+ snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
+
++ /*
++ * Keep calling as long as RTAS returns a "try again" status,
++ * but don't use rtas_busy_delay(), which potentially
++ * schedules.
++ */
+ do {
+- status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
++ status = rtas_call(ibm_os_term_token, 1, 1, NULL,
+ __pa(rtas_os_term_buf));
+- } while (rtas_busy_delay(status));
++ } while (rtas_busy_delay_time(status));
+
+ if (status != 0)
+ printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
+@@ -1167,6 +1172,13 @@ void __init rtas_initialize(void)
+ no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry);
+ rtas.entry = no_entry ? rtas.base : entry;
+
++ /*
++ * Discover these now to avoid device tree lookups in the
++ * panic path.
++ */
++ if (of_property_read_bool(rtas.dev, "ibm,extended-os-term"))
++ ibm_os_term_token = rtas_token("ibm,os-term");
++
+ /* If RTAS was found, allocate the RMO buffer for it and look for
+ * the stop-self token if any
+ */
+diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
+index 0099dc1161683..5ff1f19fd45c2 100644
+--- a/arch/riscv/include/asm/mmu.h
++++ b/arch/riscv/include/asm/mmu.h
+@@ -19,6 +19,8 @@ typedef struct {
+ #ifdef CONFIG_SMP
+ /* A local icache flush is needed before user execution can resume. */
+ cpumask_t icache_stale_mask;
++ /* A local tlb flush is needed before user execution can resume. */
++ cpumask_t tlb_stale_mask;
+ #endif
+ } mm_context_t;
+
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 39b550310ec64..799c16e065253 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -386,7 +386,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
+ * Relying on flush_tlb_fix_spurious_fault would suffice, but
+ * the extra traps reduce performance. So, eagerly SFENCE.VMA.
+ */
+- local_flush_tlb_page(address);
++ flush_tlb_page(vma, address);
+ }
+
+ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
+diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
+index 801019381dea3..907b9efd39a87 100644
+--- a/arch/riscv/include/asm/tlbflush.h
++++ b/arch/riscv/include/asm/tlbflush.h
+@@ -22,6 +22,24 @@ static inline void local_flush_tlb_page(unsigned long addr)
+ {
+ ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+ }
++
++static inline void local_flush_tlb_all_asid(unsigned long asid)
++{
++ __asm__ __volatile__ ("sfence.vma x0, %0"
++ :
++ : "r" (asid)
++ : "memory");
++}
++
++static inline void local_flush_tlb_page_asid(unsigned long addr,
++ unsigned long asid)
++{
++ __asm__ __volatile__ ("sfence.vma %0, %1"
++ :
++ : "r" (addr), "r" (asid)
++ : "memory");
++}
++
+ #else /* CONFIG_MMU */
+ #define local_flush_tlb_all() do { } while (0)
+ #define local_flush_tlb_page(addr) do { } while (0)
+diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
+index f314ff44c48d1..d4d628af21a45 100644
+--- a/arch/riscv/include/asm/uaccess.h
++++ b/arch/riscv/include/asm/uaccess.h
+@@ -216,7 +216,7 @@ do { \
+ might_fault(); \
+ access_ok(__p, sizeof(*__p)) ? \
+ __get_user((x), __p) : \
+- ((x) = 0, -EFAULT); \
++ ((x) = (__force __typeof__(x))0, -EFAULT); \
+ })
+
+ #define __put_user_asm(insn, x, ptr, err) \
+diff --git a/arch/riscv/kernel/probes/simulate-insn.h b/arch/riscv/kernel/probes/simulate-insn.h
+index cb6ff7dccb92e..de8474146a9b6 100644
+--- a/arch/riscv/kernel/probes/simulate-insn.h
++++ b/arch/riscv/kernel/probes/simulate-insn.h
+@@ -31,9 +31,9 @@ __RISCV_INSN_FUNCS(fence, 0x7f, 0x0f);
+ } while (0)
+
+ __RISCV_INSN_FUNCS(c_j, 0xe003, 0xa001);
+-__RISCV_INSN_FUNCS(c_jr, 0xf007, 0x8002);
++__RISCV_INSN_FUNCS(c_jr, 0xf07f, 0x8002);
+ __RISCV_INSN_FUNCS(c_jal, 0xe003, 0x2001);
+-__RISCV_INSN_FUNCS(c_jalr, 0xf007, 0x9002);
++__RISCV_INSN_FUNCS(c_jalr, 0xf07f, 0x9002);
+ __RISCV_INSN_FUNCS(c_beqz, 0xe003, 0xc001);
+ __RISCV_INSN_FUNCS(c_bnez, 0xe003, 0xe001);
+ __RISCV_INSN_FUNCS(c_ebreak, 0xffff, 0x9002);
+diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
+index c2601150b91c8..811e837a8c4ee 100644
+--- a/arch/riscv/kernel/stacktrace.c
++++ b/arch/riscv/kernel/stacktrace.c
+@@ -60,7 +60,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
+ } else {
+ fp = frame->fp;
+ pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
+- (unsigned long *)(fp - 8));
++ &frame->ra);
+ }
+
+ }
+diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
+index ee3459cb6750b..cc4a47bda82a0 100644
+--- a/arch/riscv/mm/context.c
++++ b/arch/riscv/mm/context.c
+@@ -196,6 +196,16 @@ switch_mm_fast:
+
+ if (need_flush_tlb)
+ local_flush_tlb_all();
++#ifdef CONFIG_SMP
++ else {
++ cpumask_t *mask = &mm->context.tlb_stale_mask;
++
++ if (cpumask_test_cpu(cpu, mask)) {
++ cpumask_clear_cpu(cpu, mask);
++ local_flush_tlb_all_asid(cntx & asid_mask);
++ }
++ }
++#endif
+ }
+
+ static void set_mm_noasid(struct mm_struct *mm)
+diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
+index 64f8201237c24..efefc3986c48c 100644
+--- a/arch/riscv/mm/tlbflush.c
++++ b/arch/riscv/mm/tlbflush.c
+@@ -5,23 +5,7 @@
+ #include <linux/sched.h>
+ #include <asm/sbi.h>
+ #include <asm/mmu_context.h>
+-
+-static inline void local_flush_tlb_all_asid(unsigned long asid)
+-{
+- __asm__ __volatile__ ("sfence.vma x0, %0"
+- :
+- : "r" (asid)
+- : "memory");
+-}
+-
+-static inline void local_flush_tlb_page_asid(unsigned long addr,
+- unsigned long asid)
+-{
+- __asm__ __volatile__ ("sfence.vma %0, %1"
+- :
+- : "r" (addr), "r" (asid)
+- : "memory");
+-}
++#include <asm/tlbflush.h>
+
+ void flush_tlb_all(void)
+ {
+@@ -31,6 +15,7 @@ void flush_tlb_all(void)
+ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
+ unsigned long size, unsigned long stride)
+ {
++ struct cpumask *pmask = &mm->context.tlb_stale_mask;
+ struct cpumask *cmask = mm_cpumask(mm);
+ struct cpumask hmask;
+ unsigned int cpuid;
+@@ -45,6 +30,15 @@ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
+ if (static_branch_unlikely(&use_asid_allocator)) {
+ unsigned long asid = atomic_long_read(&mm->context.id);
+
++ /*
++ * TLB will be immediately flushed on harts concurrently
++ * executing this MM context. TLB flush on other harts
++ * is deferred until this MM context migrates there.
++ */
++ cpumask_setall(pmask);
++ cpumask_clear_cpu(cpuid, pmask);
++ cpumask_andnot(pmask, pmask, cmask);
++
+ if (broadcast) {
+ riscv_cpuid_to_hartid_mask(cmask, &hmask);
+ sbi_remote_sfence_vma_asid(cpumask_bits(&hmask),
+diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
+index b9687980aab6d..d6f7c6c1a930a 100644
+--- a/arch/x86/events/intel/uncore.h
++++ b/arch/x86/events/intel/uncore.h
+@@ -2,6 +2,7 @@
+ #include <linux/slab.h>
+ #include <linux/pci.h>
+ #include <asm/apicdef.h>
++#include <asm/intel-family.h>
+ #include <linux/io-64-nonatomic-lo-hi.h>
+
+ #include <linux/perf_event.h>
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index fcd95e93f479a..8f371f3cbbd24 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -3804,6 +3804,21 @@ static const struct attribute_group *skx_iio_attr_update[] = {
+ NULL,
+ };
+
++static void pmu_clear_mapping_attr(const struct attribute_group **groups,
++ struct attribute_group *ag)
++{
++ int i;
++
++ for (i = 0; groups[i]; i++) {
++ if (groups[i] == ag) {
++ for (i++; groups[i]; i++)
++ groups[i - 1] = groups[i];
++ groups[i - 1] = NULL;
++ break;
++ }
++ }
++}
++
+ static int
+ pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
+ {
+@@ -3852,7 +3867,7 @@ clear_attrs:
+ clear_topology:
+ kfree(type->topology);
+ clear_attr_update:
+- type->attr_update = NULL;
++ pmu_clear_mapping_attr(type->attr_update, ag);
+ return ret;
+ }
+
+@@ -5144,6 +5159,11 @@ static int icx_iio_get_topology(struct intel_uncore_type *type)
+
+ static int icx_iio_set_mapping(struct intel_uncore_type *type)
+ {
++ /* Detect ICX-D system. This case is not supported */
++ if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
++ pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
++ return -EPERM;
++ }
+ return pmu_iio_set_mapping(type, &icx_iio_mapping_group);
+ }
+
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 8961f10311809..544e6c61e17d0 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -1951,6 +1951,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
+ if (ctrl == PR_SPEC_FORCE_DISABLE)
+ task_set_spec_ib_force_disable(task);
+ task_update_spec_tif(task);
++ if (task == current)
++ indirect_branch_prediction_barrier();
+ break;
+ default:
+ return -ERANGE;
+diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
+index a873577e49dcc..6469d3135d268 100644
+--- a/arch/x86/kernel/cpu/mce/amd.c
++++ b/arch/x86/kernel/cpu/mce/amd.c
+@@ -526,7 +526,7 @@ static u32 get_block_address(u32 current_addr, u32 low, u32 high,
+ /* Fall back to method we used for older processors: */
+ switch (block) {
+ case 0:
+- addr = msr_ops.misc(bank);
++ addr = mca_msr_reg(bank, MCA_MISC);
+ break;
+ case 1:
+ offset = ((low & MASK_BLKPTR_LO) >> 21);
+@@ -965,6 +965,24 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ return status & MCI_STATUS_DEFERRED;
+ }
+
++static bool _log_error_deferred(unsigned int bank, u32 misc)
++{
++ if (!_log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
++ mca_msr_reg(bank, MCA_ADDR), misc))
++ return false;
++
++ /*
++ * Non-SMCA systems don't have MCA_DESTAT/MCA_DEADDR registers.
++ * Return true here to avoid accessing these registers.
++ */
++ if (!mce_flags.smca)
++ return true;
++
++ /* Clear MCA_DESTAT if the deferred error was logged from MCA_STATUS. */
++ wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++ return true;
++}
++
+ /*
+ * We have three scenarios for checking for Deferred errors:
+ *
+@@ -976,19 +994,8 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ */
+ static void log_error_deferred(unsigned int bank)
+ {
+- bool defrd;
+-
+- defrd = _log_error_bank(bank, msr_ops.status(bank),
+- msr_ops.addr(bank), 0);
+-
+- if (!mce_flags.smca)
+- return;
+-
+- /* Clear MCA_DESTAT if we logged the deferred error from MCA_STATUS. */
+- if (defrd) {
+- wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++ if (_log_error_deferred(bank, 0))
+ return;
+- }
+
+ /*
+ * Only deferred errors are logged in MCA_DE{STAT,ADDR} so just check
+@@ -1009,7 +1016,7 @@ static void amd_deferred_error_interrupt(void)
+
+ static void log_error_thresholding(unsigned int bank, u64 misc)
+ {
+- _log_error_bank(bank, msr_ops.status(bank), msr_ops.addr(bank), misc);
++ _log_error_deferred(bank, misc);
+ }
+
+ static void log_and_reset_block(struct threshold_block *block)
+@@ -1397,7 +1404,7 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
+ }
+ }
+
+- err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
++ err = allocate_threshold_blocks(cpu, b, bank, 0, mca_msr_reg(bank, MCA_MISC));
+ if (err)
+ goto out_kobj;
+
+diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
+index 773037e5fd761..5ee82fd386ddb 100644
+--- a/arch/x86/kernel/cpu/mce/core.c
++++ b/arch/x86/kernel/cpu/mce/core.c
+@@ -176,53 +176,27 @@ void mce_unregister_decode_chain(struct notifier_block *nb)
+ }
+ EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
+
+-static inline u32 ctl_reg(int bank)
++u32 mca_msr_reg(int bank, enum mca_msr reg)
+ {
+- return MSR_IA32_MCx_CTL(bank);
+-}
+-
+-static inline u32 status_reg(int bank)
+-{
+- return MSR_IA32_MCx_STATUS(bank);
+-}
+-
+-static inline u32 addr_reg(int bank)
+-{
+- return MSR_IA32_MCx_ADDR(bank);
+-}
+-
+-static inline u32 misc_reg(int bank)
+-{
+- return MSR_IA32_MCx_MISC(bank);
+-}
+-
+-static inline u32 smca_ctl_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_CTL(bank);
+-}
+-
+-static inline u32 smca_status_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_STATUS(bank);
+-}
++ if (mce_flags.smca) {
++ switch (reg) {
++ case MCA_CTL: return MSR_AMD64_SMCA_MCx_CTL(bank);
++ case MCA_ADDR: return MSR_AMD64_SMCA_MCx_ADDR(bank);
++ case MCA_MISC: return MSR_AMD64_SMCA_MCx_MISC(bank);
++ case MCA_STATUS: return MSR_AMD64_SMCA_MCx_STATUS(bank);
++ }
++ }
+
+-static inline u32 smca_addr_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_ADDR(bank);
+-}
++ switch (reg) {
++ case MCA_CTL: return MSR_IA32_MCx_CTL(bank);
++ case MCA_ADDR: return MSR_IA32_MCx_ADDR(bank);
++ case MCA_MISC: return MSR_IA32_MCx_MISC(bank);
++ case MCA_STATUS: return MSR_IA32_MCx_STATUS(bank);
++ }
+
+-static inline u32 smca_misc_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_MISC(bank);
++ return 0;
+ }
+
+-struct mca_msr_regs msr_ops = {
+- .ctl = ctl_reg,
+- .status = status_reg,
+- .addr = addr_reg,
+- .misc = misc_reg
+-};
+-
+ static void __print_mce(struct mce *m)
+ {
+ pr_emerg(HW_ERR "CPU %d: Machine Check%s: %Lx Bank %d: %016Lx\n",
+@@ -371,11 +345,11 @@ static int msr_to_offset(u32 msr)
+
+ if (msr == mca_cfg.rip_msr)
+ return offsetof(struct mce, ip);
+- if (msr == msr_ops.status(bank))
++ if (msr == mca_msr_reg(bank, MCA_STATUS))
+ return offsetof(struct mce, status);
+- if (msr == msr_ops.addr(bank))
++ if (msr == mca_msr_reg(bank, MCA_ADDR))
+ return offsetof(struct mce, addr);
+- if (msr == msr_ops.misc(bank))
++ if (msr == mca_msr_reg(bank, MCA_MISC))
+ return offsetof(struct mce, misc);
+ if (msr == MSR_IA32_MCG_STATUS)
+ return offsetof(struct mce, mcgstatus);
+@@ -676,10 +650,10 @@ static struct notifier_block mce_default_nb = {
+ static noinstr void mce_read_aux(struct mce *m, int i)
+ {
+ if (m->status & MCI_STATUS_MISCV)
+- m->misc = mce_rdmsrl(msr_ops.misc(i));
++ m->misc = mce_rdmsrl(mca_msr_reg(i, MCA_MISC));
+
+ if (m->status & MCI_STATUS_ADDRV) {
+- m->addr = mce_rdmsrl(msr_ops.addr(i));
++ m->addr = mce_rdmsrl(mca_msr_reg(i, MCA_ADDR));
+
+ /*
+ * Mask the reported address by the reported granularity.
+@@ -749,7 +723,7 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
+ m.bank = i;
+
+ barrier();
+- m.status = mce_rdmsrl(msr_ops.status(i));
++ m.status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
+
+ /* If this entry is not valid, ignore it */
+ if (!(m.status & MCI_STATUS_VAL))
+@@ -817,7 +791,7 @@ clear_it:
+ /*
+ * Clear state for this bank.
+ */
+- mce_wrmsrl(msr_ops.status(i), 0);
++ mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
+ }
+
+ /*
+@@ -842,7 +816,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
+ int i;
+
+ for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
+- m->status = mce_rdmsrl(msr_ops.status(i));
++ m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
+ if (!(m->status & MCI_STATUS_VAL))
+ continue;
+
+@@ -1143,7 +1117,7 @@ static void mce_clear_state(unsigned long *toclear)
+
+ for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
+ if (test_bit(i, toclear))
+- mce_wrmsrl(msr_ops.status(i), 0);
++ mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
+ }
+ }
+
+@@ -1202,7 +1176,7 @@ static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *fin
+ m->addr = 0;
+ m->bank = i;
+
+- m->status = mce_rdmsrl(msr_ops.status(i));
++ m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
+ if (!(m->status & MCI_STATUS_VAL))
+ continue;
+
+@@ -1699,8 +1673,8 @@ static void __mcheck_cpu_init_clear_banks(void)
+
+ if (!b->init)
+ continue;
+- wrmsrl(msr_ops.ctl(i), b->ctl);
+- wrmsrl(msr_ops.status(i), 0);
++ wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl);
++ wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
+ }
+ }
+
+@@ -1726,7 +1700,7 @@ static void __mcheck_cpu_check_banks(void)
+ if (!b->init)
+ continue;
+
+- rdmsrl(msr_ops.ctl(i), msrval);
++ rdmsrl(mca_msr_reg(i, MCA_CTL), msrval);
+ b->init = !!msrval;
+ }
+ }
+@@ -1883,13 +1857,6 @@ static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c)
+ mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR);
+ mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA);
+ mce_flags.amd_threshold = 1;
+-
+- if (mce_flags.smca) {
+- msr_ops.ctl = smca_ctl_reg;
+- msr_ops.status = smca_status_reg;
+- msr_ops.addr = smca_addr_reg;
+- msr_ops.misc = smca_misc_reg;
+- }
+ }
+ }
+
+@@ -2265,7 +2232,7 @@ static void mce_disable_error_reporting(void)
+ struct mce_bank *b = &mce_banks[i];
+
+ if (b->init)
+- wrmsrl(msr_ops.ctl(i), 0);
++ wrmsrl(mca_msr_reg(i, MCA_CTL), 0);
+ }
+ return;
+ }
+@@ -2617,7 +2584,7 @@ static void mce_reenable_cpu(void)
+ struct mce_bank *b = &mce_banks[i];
+
+ if (b->init)
+- wrmsrl(msr_ops.ctl(i), b->ctl);
++ wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl);
+ }
+ }
+
+diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h
+index 80dc94313bcfc..760b57814760a 100644
+--- a/arch/x86/kernel/cpu/mce/internal.h
++++ b/arch/x86/kernel/cpu/mce/internal.h
+@@ -168,14 +168,14 @@ struct mce_vendor_flags {
+
+ extern struct mce_vendor_flags mce_flags;
+
+-struct mca_msr_regs {
+- u32 (*ctl) (int bank);
+- u32 (*status) (int bank);
+- u32 (*addr) (int bank);
+- u32 (*misc) (int bank);
++enum mca_msr {
++ MCA_CTL,
++ MCA_STATUS,
++ MCA_ADDR,
++ MCA_MISC,
+ };
+
+-extern struct mca_msr_regs msr_ops;
++u32 mca_msr_reg(int bank, enum mca_msr reg);
+
+ /* Decide whether to add MCE record to MCE event pool or filter it out. */
+ extern bool filter_mce(struct mce *m);
+diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
+index 7e8e07bddd5fe..1ba590e6ef7bb 100644
+--- a/arch/x86/kernel/cpu/microcode/intel.c
++++ b/arch/x86/kernel/cpu/microcode/intel.c
+@@ -659,7 +659,6 @@ void load_ucode_intel_ap(void)
+ else
+ iup = &intel_ucode_patch;
+
+-reget:
+ if (!*iup) {
+ patch = __load_ucode_intel(&uci);
+ if (!patch)
+@@ -670,12 +669,7 @@ reget:
+
+ uci.mc = *iup;
+
+- if (apply_microcode_early(&uci, true)) {
+- /* Mixed-silicon system? Try to refetch the proper patch: */
+- *iup = NULL;
+-
+- goto reget;
+- }
++ apply_microcode_early(&uci, true);
+ }
+
+ static struct microcode_intel *find_patch(struct ucode_cpu_info *uci)
+diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
+index e8326a8d1c5dc..03a454d427c3d 100644
+--- a/arch/x86/kernel/crash.c
++++ b/arch/x86/kernel/crash.c
+@@ -401,10 +401,8 @@ int crash_load_segments(struct kimage *image)
+ kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
+ kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+ ret = kexec_add_buffer(&kbuf);
+- if (ret) {
+- vfree((void *)image->elf_headers);
++ if (ret)
+ return ret;
+- }
+ image->elf_load_addr = kbuf.mem;
+ pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ image->elf_load_addr, kbuf.bufsz, kbuf.bufsz);
+diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
+index b3c9ef01d6c09..4017da3a4c701 100644
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -219,7 +219,9 @@ void ftrace_replace_code(int enable)
+
+ ret = ftrace_verify_code(rec->ip, old);
+ if (ret) {
++ ftrace_expected = old;
+ ftrace_bug(ret, rec);
++ ftrace_expected = NULL;
+ return;
+ }
+ }
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index 6872f3834668d..c4b618d0b16a0 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -37,6 +37,7 @@
+ #include <linux/extable.h>
+ #include <linux/kdebug.h>
+ #include <linux/kallsyms.h>
++#include <linux/kgdb.h>
+ #include <linux/ftrace.h>
+ #include <linux/kasan.h>
+ #include <linux/moduleloader.h>
+@@ -289,12 +290,15 @@ static int can_probe(unsigned long paddr)
+ if (ret < 0)
+ return 0;
+
++#ifdef CONFIG_KGDB
+ /*
+- * Another debugging subsystem might insert this breakpoint.
+- * In that case, we can't recover it.
++ * If there is a dynamically installed kgdb sw breakpoint,
++ * this function should not be probed.
+ */
+- if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
++ if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
++ kgdb_has_hit_break(addr))
+ return 0;
++#endif
+ addr += insn.length;
+ }
+
+diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
+index 71425ebba98a1..a9121073d9518 100644
+--- a/arch/x86/kernel/kprobes/opt.c
++++ b/arch/x86/kernel/kprobes/opt.c
+@@ -15,6 +15,7 @@
+ #include <linux/extable.h>
+ #include <linux/kdebug.h>
+ #include <linux/kallsyms.h>
++#include <linux/kgdb.h>
+ #include <linux/ftrace.h>
+ #include <linux/objtool.h>
+ #include <linux/pgtable.h>
+@@ -272,19 +273,6 @@ static int insn_is_indirect_jump(struct insn *insn)
+ return ret;
+ }
+
+-static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
+-{
+- unsigned char ops;
+-
+- for (; addr < eaddr; addr++) {
+- if (get_kernel_nofault(ops, (void *)addr) < 0 ||
+- ops != INT3_INSN_OPCODE)
+- return false;
+- }
+-
+- return true;
+-}
+-
+ /* Decode whole function to ensure any instructions don't jump into target */
+ static int can_optimize(unsigned long paddr)
+ {
+@@ -327,15 +315,15 @@ static int can_optimize(unsigned long paddr)
+ ret = insn_decode_kernel(&insn, (void *)recovered_insn);
+ if (ret < 0)
+ return 0;
+-
++#ifdef CONFIG_KGDB
+ /*
+- * In the case of detecting unknown breakpoint, this could be
+- * a padding INT3 between functions. Let's check that all the
+- * rest of the bytes are also INT3.
++ * If there is a dynamically installed kgdb sw breakpoint,
++ * this function should not be probed.
+ */
+- if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
+- return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
+-
++ if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
++ kgdb_has_hit_break(addr))
++ return 0;
++#endif
+ /* Recover address */
+ insn.kaddr = (void *)addr;
+ insn.next_byte = (void *)(addr + insn.length);
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 817632d5a1189..cdebeceedbd06 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -4970,24 +4970,35 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ | FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
+
+ /*
+- * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks
+- * that have higher priority than VM-Exit (see Intel SDM's pseudocode
+- * for VMXON), as KVM must load valid CR0/CR4 values into hardware while
+- * running the guest, i.e. KVM needs to check the _guest_ values.
++ * Manually check CR4.VMXE checks, KVM must force CR4.VMXE=1 to enter
++ * the guest and so cannot rely on hardware to perform the check,
++ * which has higher priority than VM-Exit (see Intel SDM's pseudocode
++ * for VMXON).
+ *
+- * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and
+- * !COMPATIBILITY modes. KVM may run the guest in VM86 to emulate Real
+- * Mode, but KVM will never take the guest out of those modes.
++ * Rely on hardware for the other pre-VM-Exit checks, CR0.PE=1, !VM86
++ * and !COMPATIBILITY modes. For an unrestricted guest, KVM doesn't
++ * force any of the relevant guest state. For a restricted guest, KVM
++ * does force CR0.PE=1, but only to also force VM86 in order to emulate
++ * Real Mode, and so there's no need to check CR0.PE manually.
+ */
+- if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
+- !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
++ if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return 1;
+ }
+
+ /*
+- * CPL=0 and all other checks that are lower priority than VM-Exit must
+- * be checked manually.
++ * The CPL is checked for "not in VMX operation" and for "in VMX root",
++ * and has higher priority than the VM-Fail due to being post-VMXON,
++ * i.e. VMXON #GPs outside of VMX non-root if CPL!=0. In VMX non-root,
++ * VMXON causes VM-Exit and KVM unconditionally forwards VMXON VM-Exits
++ * from L2 to L1, i.e. there's no need to check for the vCPU being in
++ * VMX non-root.
++ *
++ * Forwarding the VM-Exit unconditionally, i.e. without performing the
++ * #UD checks (see above), is functionally ok because KVM doesn't allow
++ * L1 to run L2 without CR4.VMXE=0, and because KVM never modifies L2's
++ * CR0 or CR4, i.e. it's L2's responsibility to emulate #UDs that are
++ * missed by hardware due to shadowing CR0 and/or CR4.
+ */
+ if (vmx_get_cpl(vcpu)) {
+ kvm_inject_gp(vcpu, 0);
+@@ -4997,6 +5008,17 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ if (vmx->nested.vmxon)
+ return nested_vmx_fail(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
+
++ /*
++ * Invalid CR0/CR4 generates #GP. These checks are performed if and
++ * only if the vCPU isn't already in VMX operation, i.e. effectively
++ * have lower priority than the VM-Fail above.
++ */
++ if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
++ !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
++ kvm_inject_gp(vcpu, 0);
++ return 1;
++ }
++
+ if ((vmx->msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
+ != VMXON_NEEDED_FEATURES) {
+ kvm_inject_gp(vcpu, 0);
+@@ -6644,7 +6666,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
+ SECONDARY_EXEC_ENABLE_INVPCID |
+ SECONDARY_EXEC_RDSEED_EXITING |
+ SECONDARY_EXEC_XSAVES |
+- SECONDARY_EXEC_TSC_SCALING;
++ SECONDARY_EXEC_TSC_SCALING |
++ SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
+
+ /*
+ * We can emulate "VMCS shadowing," even if the hardware
+diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c
+index 6693ebdc07701..b8cf9a59c145e 100644
+--- a/arch/x86/kvm/vmx/sgx.c
++++ b/arch/x86/kvm/vmx/sgx.c
+@@ -188,8 +188,10 @@ static int __handle_encls_ecreate(struct kvm_vcpu *vcpu,
+ /* Enforce CPUID restriction on max enclave size. */
+ max_size_log2 = (attributes & SGX_ATTR_MODE64BIT) ? sgx_12_0->edx >> 8 :
+ sgx_12_0->edx;
+- if (size >= BIT_ULL(max_size_log2))
++ if (size >= BIT_ULL(max_size_log2)) {
+ kvm_inject_gp(vcpu, 0);
++ return 1;
++ }
+
+ /*
+ * sgx_virt_ecreate() returns:
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index b8b6e9eae94b7..85120d7b5cf02 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -5251,8 +5251,8 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfqd->lock, flags);
+- bfq_exit_bfqq(bfqd, bfqq);
+ bic_set_bfqq(bic, NULL, is_sync);
++ bfq_exit_bfqq(bfqd, bfqq);
+ spin_unlock_irqrestore(&bfqd->lock, flags);
+ }
+ }
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index bbe66a9010bf1..bb26db93ad1de 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -279,6 +279,16 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
+ *segs = nsegs;
+ return NULL;
+ split:
++ /*
++ * We can't sanely support splitting for a REQ_NOWAIT bio. End it
++ * with EAGAIN if splitting is required and return an error pointer.
++ */
++ if (bio->bi_opf & REQ_NOWAIT) {
++ bio->bi_status = BLK_STS_AGAIN;
++ bio_endio(bio);
++ return ERR_PTR(-EAGAIN);
++ }
++
+ *segs = nsegs;
+
+ /*
+diff --git a/block/mq-deadline.c b/block/mq-deadline.c
+index cd2342d297048..950c46332a76f 100644
+--- a/block/mq-deadline.c
++++ b/block/mq-deadline.c
+@@ -153,6 +153,20 @@ static u8 dd_rq_ioclass(struct request *rq)
+ return IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
+ }
+
++/*
++ * get the request before `rq' in sector-sorted order
++ */
++static inline struct request *
++deadline_earlier_request(struct request *rq)
++{
++ struct rb_node *node = rb_prev(&rq->rb_node);
++
++ if (node)
++ return rb_entry_rq(node);
++
++ return NULL;
++}
++
+ /*
+ * get the request after `rq' in sector-sorted order
+ */
+@@ -288,6 +302,39 @@ static inline int deadline_check_fifo(struct dd_per_prio *per_prio,
+ return 0;
+ }
+
++/*
++ * Check if rq has a sequential request preceding it.
++ */
++static bool deadline_is_seq_writes(struct deadline_data *dd, struct request *rq)
++{
++ struct request *prev = deadline_earlier_request(rq);
++
++ if (!prev)
++ return false;
++
++ return blk_rq_pos(prev) + blk_rq_sectors(prev) == blk_rq_pos(rq);
++}
++
++/*
++ * Skip all write requests that are sequential from @rq, even if we cross
++ * a zone boundary.
++ */
++static struct request *deadline_skip_seq_writes(struct deadline_data *dd,
++ struct request *rq)
++{
++ sector_t pos = blk_rq_pos(rq);
++ sector_t skipped_sectors = 0;
++
++ while (rq) {
++ if (blk_rq_pos(rq) != pos + skipped_sectors)
++ break;
++ skipped_sectors += blk_rq_sectors(rq);
++ rq = deadline_latter_request(rq);
++ }
++
++ return rq;
++}
++
+ /*
+ * For the specified data direction, return the next request to
+ * dispatch using arrival ordered lists.
+@@ -308,11 +355,16 @@ deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
+
+ /*
+ * Look for a write request that can be dispatched, that is one with
+- * an unlocked target zone.
++ * an unlocked target zone. For some HDDs, breaking a sequential
++ * write stream can lead to lower throughput, so make sure to preserve
++ * sequential write streams, even if that stream crosses into the next
++ * zones and these zones are unlocked.
+ */
+ spin_lock_irqsave(&dd->zone_lock, flags);
+ list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) {
+- if (blk_req_can_dispatch_to_zone(rq))
++ if (blk_req_can_dispatch_to_zone(rq) &&
++ (blk_queue_nonrot(rq->q) ||
++ !deadline_is_seq_writes(dd, rq)))
+ goto out;
+ }
+ rq = NULL;
+@@ -342,13 +394,19 @@ deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
+
+ /*
+ * Look for a write request that can be dispatched, that is one with
+- * an unlocked target zone.
++ * an unlocked target zone. For some HDDs, breaking a sequential
++ * write stream can lead to lower throughput, so make sure to preserve
++ * sequential write streams, even if that stream crosses into the next
++ * zones and these zones are unlocked.
+ */
+ spin_lock_irqsave(&dd->zone_lock, flags);
+ while (rq) {
+ if (blk_req_can_dispatch_to_zone(rq))
+ break;
+- rq = deadline_latter_request(rq);
++ if (blk_queue_nonrot(rq->q))
++ rq = deadline_latter_request(rq);
++ else
++ rq = deadline_skip_seq_writes(dd, rq);
+ }
+ spin_unlock_irqrestore(&dd->zone_lock, flags);
+
+@@ -733,6 +791,18 @@ static void dd_prepare_request(struct request *rq)
+ rq->elv.priv[0] = NULL;
+ }
+
++static bool dd_has_write_work(struct blk_mq_hw_ctx *hctx)
++{
++ struct deadline_data *dd = hctx->queue->elevator->elevator_data;
++ enum dd_prio p;
++
++ for (p = 0; p <= DD_PRIO_MAX; p++)
++ if (!list_empty_careful(&dd->per_prio[p].fifo_list[DD_WRITE]))
++ return true;
++
++ return false;
++}
++
+ /*
+ * Callback from inside blk_mq_free_request().
+ *
+@@ -755,7 +825,6 @@ static void dd_finish_request(struct request *rq)
+ struct deadline_data *dd = q->elevator->elevator_data;
+ const u8 ioprio_class = dd_rq_ioclass(rq);
+ const enum dd_prio prio = ioprio_class_to_prio[ioprio_class];
+- struct dd_per_prio *per_prio = &dd->per_prio[prio];
+
+ /*
+ * The block layer core may call dd_finish_request() without having
+@@ -771,9 +840,10 @@ static void dd_finish_request(struct request *rq)
+
+ spin_lock_irqsave(&dd->zone_lock, flags);
+ blk_req_zone_write_unlock(rq);
+- if (!list_empty(&per_prio->fifo_list[DD_WRITE]))
+- blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
+ spin_unlock_irqrestore(&dd->zone_lock, flags);
++
++ if (dd_has_write_work(rq->mq_hctx))
++ blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
+ }
+ }
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 19358a641610d..33921949bd8fd 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -399,16 +399,68 @@ static const struct dmi_system_id medion_laptop[] = {
+ { }
+ };
+
++static const struct dmi_system_id asus_laptop[] = {
++ {
++ .ident = "Asus Vivobook K3402ZA",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"),
++ },
++ },
++ {
++ .ident = "Asus Vivobook K3502ZA",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"),
++ },
++ },
++ { }
++};
++
++static const struct dmi_system_id lenovo_laptop[] = {
++ {
++ .ident = "LENOVO IdeaPad Flex 5 14ALC7",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "82R9"),
++ },
++ },
++ {
++ .ident = "LENOVO IdeaPad Flex 5 16ALC7",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "82RA"),
++ },
++ },
++ { }
++};
++
++static const struct dmi_system_id schenker_gm_rg[] = {
++ {
++ .ident = "XMG CORE 15 (M22)",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
++ DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
++ },
++ },
++ { }
++};
++
+ struct irq_override_cmp {
+ const struct dmi_system_id *system;
+ unsigned char irq;
+ unsigned char triggering;
+ unsigned char polarity;
+ unsigned char shareable;
++ bool override;
+ };
+
+-static const struct irq_override_cmp skip_override_table[] = {
+- { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
++static const struct irq_override_cmp override_table[] = {
++ { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
++ { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
++ { lenovo_laptop, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
++ { lenovo_laptop, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
++ { schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
+ };
+
+ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+@@ -416,6 +468,17 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+ {
+ int i;
+
++ for (i = 0; i < ARRAY_SIZE(override_table); i++) {
++ const struct irq_override_cmp *entry = &override_table[i];
++
++ if (dmi_check_system(entry->system) &&
++ entry->irq == gsi &&
++ entry->triggering == triggering &&
++ entry->polarity == polarity &&
++ entry->shareable == shareable)
++ return entry->override;
++ }
++
+ #ifdef CONFIG_X86
+ /*
+ * IRQ override isn't needed on modern AMD Zen systems and
+@@ -426,17 +489,6 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+ return false;
+ #endif
+
+- for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) {
+- const struct irq_override_cmp *entry = &skip_override_table[i];
+-
+- if (dmi_check_system(entry->system) &&
+- entry->irq == gsi &&
+- entry->triggering == triggering &&
+- entry->polarity == polarity &&
+- entry->shareable == shareable)
+- return false;
+- }
+-
+ return true;
+ }
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index e0185e841b2a3..2af1ae1721021 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -378,16 +378,13 @@ static int lps0_device_attach(struct acpi_device *adev,
+ * AMDI0006:
+ * - should use rev_id 0x0
+ * - function mask = 0x3: Should use Microsoft method
+- * AMDI0007:
+- * - Should use rev_id 0x2
+- * - Should only use AMD method
+ */
+ const char *hid = acpi_device_hid(adev);
+- rev_id = strcmp(hid, "AMDI0007") ? 0 : 2;
++ rev_id = 0;
+ lps0_dsm_func_mask = validate_dsm(adev->handle,
+ ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
+ lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
+- ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
++ ACPI_LPS0_DSM_UUID_MICROSOFT, rev_id,
+ &lps0_dsm_guid_microsoft);
+ if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") ||
+ !strcmp(hid, "AMD0005") ||
+@@ -395,9 +392,6 @@ static int lps0_device_attach(struct acpi_device *adev,
+ lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
+ acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
+ ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
+- } else if (lps0_dsm_func_mask_microsoft > 0 && !strcmp(hid, "AMDI0007")) {
+- lps0_dsm_func_mask_microsoft = -EINVAL;
+- acpi_handle_debug(adev->handle, "_DSM Using AMD method\n");
+ }
+ } else {
+ rev_id = 1;
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index c1bf7117a9fff..149ee16fd0225 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -83,6 +83,7 @@ enum board_ids {
+ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+ static void ahci_remove_one(struct pci_dev *dev);
+ static void ahci_shutdown_one(struct pci_dev *dev);
++static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
+ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+@@ -668,6 +669,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ ahci_save_initial_config(&pdev->dev, hpriv);
+ }
+
++static int ahci_pci_reset_controller(struct ata_host *host)
++{
++ struct pci_dev *pdev = to_pci_dev(host->dev);
++ struct ahci_host_priv *hpriv = host->private_data;
++ int rc;
++
++ rc = ahci_reset_controller(host);
++ if (rc)
++ return rc;
++
++ /*
++ * If platform firmware failed to enable ports, try to enable
++ * them here.
++ */
++ ahci_intel_pcs_quirk(pdev, hpriv);
++
++ return 0;
++}
++
+ static void ahci_pci_init_controller(struct ata_host *host)
+ {
+ struct ahci_host_priv *hpriv = host->private_data;
+@@ -869,7 +889,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
+ struct ata_host *host = pci_get_drvdata(pdev);
+ int rc;
+
+- rc = ahci_reset_controller(host);
++ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+ ahci_pci_init_controller(host);
+@@ -904,7 +924,7 @@ static int ahci_pci_device_resume(struct device *dev)
+ ahci_mcp89_apple_enable(pdev);
+
+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+- rc = ahci_reset_controller(host);
++ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+
+@@ -1789,12 +1809,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ /* save initial config */
+ ahci_pci_save_initial_config(pdev, hpriv);
+
+- /*
+- * If platform firmware failed to enable ports, try to enable
+- * them here.
+- */
+- ahci_intel_pcs_quirk(pdev, hpriv);
+-
+ /* prepare host */
+ if (hpriv->cap & HOST_CAP_NCQ) {
+ pi.flags |= ATA_FLAG_NCQ;
+@@ -1904,7 +1918,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ if (rc)
+ return rc;
+
+- rc = ahci_reset_controller(host);
++ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index 63cc011188109..060348125635b 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -1127,7 +1127,11 @@ static int __driver_attach(struct device *dev, void *data)
+ return 0;
+ } else if (ret < 0) {
+ dev_dbg(dev, "Bus failed to match device: %d\n", ret);
+- return ret;
++ /*
++ * Driver could not match with device, but may match with
++ * another device on the bus.
++ */
++ return 0;
+ } /* ret > 0 means positive match */
+
+ if (driver_allows_async_probing(drv)) {
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 8dbc349a2edd7..15c211c5d6f4e 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -1273,6 +1273,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
+ unsigned long flags;
+ struct cmd_rcvr *rcvr;
+ struct cmd_rcvr *rcvrs = NULL;
++ struct module *owner;
+
+ if (!acquire_ipmi_user(user, &i)) {
+ /*
+@@ -1334,8 +1335,9 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
+ kfree(rcvr);
+ }
+
++ owner = intf->owner;
+ kref_put(&intf->refcount, intf_free);
+- module_put(intf->owner);
++ module_put(owner);
+ }
+
+ int ipmi_destroy_user(struct ipmi_user *user)
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index 6f3272b58ced3..17255e705cb06 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -2152,6 +2152,20 @@ skip_fallback_noirq:
+ }
+ module_init(init_ipmi_si);
+
++static void wait_msg_processed(struct smi_info *smi_info)
++{
++ unsigned long jiffies_now;
++ long time_diff;
++
++ while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
++ jiffies_now = jiffies;
++ time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
++ * SI_USEC_PER_JIFFY);
++ smi_event_handler(smi_info, time_diff);
++ schedule_timeout_uninterruptible(1);
++ }
++}
++
+ static void shutdown_smi(void *send_info)
+ {
+ struct smi_info *smi_info = send_info;
+@@ -2186,16 +2200,13 @@ static void shutdown_smi(void *send_info)
+ * in the BMC. Note that timers and CPU interrupts are off,
+ * so no need for locks.
+ */
+- while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+- poll(smi_info);
+- schedule_timeout_uninterruptible(1);
+- }
++ wait_msg_processed(smi_info);
++
+ if (smi_info->handlers)
+ disable_si_irq(smi_info);
+- while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+- poll(smi_info);
+- schedule_timeout_uninterruptible(1);
+- }
++
++ wait_msg_processed(smi_info);
++
+ if (smi_info->handlers)
+ smi_info->handlers->cleanup(smi_info->si_sm);
+
+diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
+index 1b18ce5ebab1e..0913d3eb8d518 100644
+--- a/drivers/char/tpm/eventlog/acpi.c
++++ b/drivers/char/tpm/eventlog/acpi.c
+@@ -90,16 +90,21 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ return -ENODEV;
+
+ if (tbl->header.length <
+- sizeof(*tbl) + sizeof(struct acpi_tpm2_phy))
++ sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) {
++ acpi_put_table((struct acpi_table_header *)tbl);
+ return -ENODEV;
++ }
+
+ tpm2_phy = (void *)tbl + sizeof(*tbl);
+ len = tpm2_phy->log_area_minimum_length;
+
+ start = tpm2_phy->log_area_start_address;
+- if (!start || !len)
++ if (!start || !len) {
++ acpi_put_table((struct acpi_table_header *)tbl);
+ return -ENODEV;
++ }
+
++ acpi_put_table((struct acpi_table_header *)tbl);
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
+ } else {
+ /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
+@@ -120,8 +125,10 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ break;
+ }
+
++ acpi_put_table((struct acpi_table_header *)buff);
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+ }
++
+ if (!len) {
+ dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
+ return -EIO;
+@@ -156,5 +163,4 @@ err:
+ kfree(log->bios_event_log);
+ log->bios_event_log = NULL;
+ return ret;
+-
+ }
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 65f8f179a27f0..16fc481d60950 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -676,12 +676,16 @@ static int crb_acpi_add(struct acpi_device *device)
+
+ /* Should the FIFO driver handle this? */
+ sm = buf->start_method;
+- if (sm == ACPI_TPM2_MEMORY_MAPPED)
+- return -ENODEV;
++ if (sm == ACPI_TPM2_MEMORY_MAPPED) {
++ rc = -ENODEV;
++ goto out;
++ }
+
+ priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
++ if (!priv) {
++ rc = -ENOMEM;
++ goto out;
++ }
+
+ if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
+ if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) {
+@@ -689,7 +693,8 @@ static int crb_acpi_add(struct acpi_device *device)
+ FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
+ buf->header.length,
+ ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
+- return -EINVAL;
++ rc = -EINVAL;
++ goto out;
+ }
+ crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf));
+ priv->smc_func_id = crb_smc->smc_func_id;
+@@ -700,17 +705,23 @@ static int crb_acpi_add(struct acpi_device *device)
+
+ rc = crb_map_io(device, priv, buf);
+ if (rc)
+- return rc;
++ goto out;
+
+ chip = tpmm_chip_alloc(dev, &tpm_crb);
+- if (IS_ERR(chip))
+- return PTR_ERR(chip);
++ if (IS_ERR(chip)) {
++ rc = PTR_ERR(chip);
++ goto out;
++ }
+
+ dev_set_drvdata(&chip->dev, priv);
+ chip->acpi_dev_handle = device->handle;
+ chip->flags = TPM_CHIP_FLAG_TPM2;
+
+- return tpm_chip_register(chip);
++ rc = tpm_chip_register(chip);
++
++out:
++ acpi_put_table((struct acpi_table_header *)buf);
++ return rc;
+ }
+
+ static int crb_acpi_remove(struct acpi_device *device)
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index d3f2e5364c275..e53164c828085 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -125,6 +125,7 @@ static int check_acpi_tpm2(struct device *dev)
+ const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev);
+ struct acpi_table_tpm2 *tbl;
+ acpi_status st;
++ int ret = 0;
+
+ if (!aid || aid->driver_data != DEVICE_IS_TPM2)
+ return 0;
+@@ -132,8 +133,7 @@ static int check_acpi_tpm2(struct device *dev)
+ /* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2
+ * table is mandatory
+ */
+- st =
+- acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
++ st = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
+ if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
+ dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n");
+ return -EINVAL;
+@@ -141,9 +141,10 @@ static int check_acpi_tpm2(struct device *dev)
+
+ /* The tpm2_crb driver handles this device */
+ if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
+- return -ENODEV;
++ ret = -ENODEV;
+
+- return 0;
++ acpi_put_table((struct acpi_table_header *)tbl);
++ return ret;
+ }
+ #else
+ static int check_acpi_tpm2(struct device *dev)
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 799431d287ee8..b998b50839534 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1212,6 +1212,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
+ if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
+ goto err_free_rcpumask;
+
++ init_completion(&policy->kobj_unregister);
+ ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+ cpufreq_global_kobject, "policy%u", cpu);
+ if (ret) {
+@@ -1250,7 +1251,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
+ init_rwsem(&policy->rwsem);
+ spin_lock_init(&policy->transition_lock);
+ init_waitqueue_head(&policy->transition_wait);
+- init_completion(&policy->kobj_unregister);
+ INIT_WORK(&policy->update, handle_update);
+
+ policy->cpu = cpu;
+diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
+index 88c672ad27e44..9470a9a19f29d 100644
+--- a/drivers/crypto/ccp/sp-pci.c
++++ b/drivers/crypto/ccp/sp-pci.c
+@@ -320,6 +320,15 @@ static const struct psp_vdata pspv3 = {
+ .inten_reg = 0x10690,
+ .intsts_reg = 0x10694,
+ };
++
++static const struct psp_vdata pspv4 = {
++ .sev = &sevv2,
++ .tee = &teev1,
++ .feature_reg = 0x109fc,
++ .inten_reg = 0x10690,
++ .intsts_reg = 0x10694,
++};
++
+ #endif
+
+ static const struct sp_dev_vdata dev_vdata[] = {
+@@ -365,7 +374,7 @@ static const struct sp_dev_vdata dev_vdata[] = {
+ { /* 5 */
+ .bar = 2,
+ #ifdef CONFIG_CRYPTO_DEV_SP_PSP
+- .psp_vdata = &pspv2,
++ .psp_vdata = &pspv4,
+ #endif
+ },
+ };
+diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c
+index 3b0bf6fea491a..b4db560105a9e 100644
+--- a/drivers/crypto/n2_core.c
++++ b/drivers/crypto/n2_core.c
+@@ -1229,6 +1229,7 @@ struct n2_hash_tmpl {
+ const u8 *hash_init;
+ u8 hw_op_hashsz;
+ u8 digest_size;
++ u8 statesize;
+ u8 block_size;
+ u8 auth_type;
+ u8 hmac_type;
+@@ -1260,6 +1261,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_HMAC_MD5,
+ .hw_op_hashsz = MD5_DIGEST_SIZE,
+ .digest_size = MD5_DIGEST_SIZE,
++ .statesize = sizeof(struct md5_state),
+ .block_size = MD5_HMAC_BLOCK_SIZE },
+ { .name = "sha1",
+ .hash_zero = sha1_zero_message_hash,
+@@ -1268,6 +1270,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_HMAC_SHA1,
+ .hw_op_hashsz = SHA1_DIGEST_SIZE,
+ .digest_size = SHA1_DIGEST_SIZE,
++ .statesize = sizeof(struct sha1_state),
+ .block_size = SHA1_BLOCK_SIZE },
+ { .name = "sha256",
+ .hash_zero = sha256_zero_message_hash,
+@@ -1276,6 +1279,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_HMAC_SHA256,
+ .hw_op_hashsz = SHA256_DIGEST_SIZE,
+ .digest_size = SHA256_DIGEST_SIZE,
++ .statesize = sizeof(struct sha256_state),
+ .block_size = SHA256_BLOCK_SIZE },
+ { .name = "sha224",
+ .hash_zero = sha224_zero_message_hash,
+@@ -1284,6 +1288,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_RESERVED,
+ .hw_op_hashsz = SHA256_DIGEST_SIZE,
+ .digest_size = SHA224_DIGEST_SIZE,
++ .statesize = sizeof(struct sha256_state),
+ .block_size = SHA224_BLOCK_SIZE },
+ };
+ #define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls)
+@@ -1424,6 +1429,7 @@ static int __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl)
+
+ halg = &ahash->halg;
+ halg->digestsize = tmpl->digest_size;
++ halg->statesize = tmpl->statesize;
+
+ base = &halg->base;
+ snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
+diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
+index 85faa7a5c7d12..a473b640c40ae 100644
+--- a/drivers/devfreq/devfreq.c
++++ b/drivers/devfreq/devfreq.c
+@@ -775,8 +775,7 @@ static void remove_sysfs_files(struct devfreq *devfreq,
+ * @dev: the device to add devfreq feature.
+ * @profile: device-specific profile to run devfreq.
+ * @governor_name: name of the policy to choose frequency.
+- * @data: private data for the governor. The devfreq framework does not
+- * touch this value.
++ * @data: devfreq driver pass to governors, governor should not change it.
+ */
+ struct devfreq *devfreq_add_device(struct device *dev,
+ struct devfreq_dev_profile *profile,
+@@ -1003,8 +1002,7 @@ static void devm_devfreq_dev_release(struct device *dev, void *res)
+ * @dev: the device to add devfreq feature.
+ * @profile: device-specific profile to run devfreq.
+ * @governor_name: name of the policy to choose frequency.
+- * @data: private data for the governor. The devfreq framework does not
+- * touch this value.
++ * @data: devfreq driver pass to governors, governor should not change it.
+ *
+ * This function manages automatically the memory of devfreq device using device
+ * resource management and simplify the free operation for memory of devfreq
+diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
+index ab9db7adb3ade..d69672ccacc49 100644
+--- a/drivers/devfreq/governor_userspace.c
++++ b/drivers/devfreq/governor_userspace.c
+@@ -21,7 +21,7 @@ struct userspace_data {
+
+ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
+ {
+- struct userspace_data *data = df->data;
++ struct userspace_data *data = df->governor_data;
+
+ if (data->valid)
+ *freq = data->user_frequency;
+@@ -40,7 +40,7 @@ static ssize_t set_freq_store(struct device *dev, struct device_attribute *attr,
+ int err = 0;
+
+ mutex_lock(&devfreq->lock);
+- data = devfreq->data;
++ data = devfreq->governor_data;
+
+ sscanf(buf, "%lu", &wanted);
+ data->user_frequency = wanted;
+@@ -60,7 +60,7 @@ static ssize_t set_freq_show(struct device *dev,
+ int err = 0;
+
+ mutex_lock(&devfreq->lock);
+- data = devfreq->data;
++ data = devfreq->governor_data;
+
+ if (data->valid)
+ err = sprintf(buf, "%lu\n", data->user_frequency);
+@@ -91,7 +91,7 @@ static int userspace_init(struct devfreq *devfreq)
+ goto out;
+ }
+ data->valid = false;
+- devfreq->data = data;
++ devfreq->governor_data = data;
+
+ err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group);
+ out:
+@@ -107,8 +107,8 @@ static void userspace_exit(struct devfreq *devfreq)
+ if (devfreq->dev.kobj.sd)
+ sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
+
+- kfree(devfreq->data);
+- devfreq->data = NULL;
++ kfree(devfreq->governor_data);
++ devfreq->governor_data = NULL;
+ }
+
+ static int devfreq_userspace_handler(struct devfreq *devfreq,
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index 70be9c87fb673..ba03f5a4b30ce 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -590,7 +590,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+
+ seed = early_memremap(efi_rng_seed, sizeof(*seed));
+ if (seed != NULL) {
+- size = min(seed->size, EFI_RANDOM_SEED_SIZE);
++ size = min_t(u32, seed->size, SZ_1K); // sanity check
+ early_memunmap(seed, sizeof(*seed));
+ } else {
+ pr_err("Could not map UEFI random seed!\n");
+@@ -599,8 +599,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+ seed = early_memremap(efi_rng_seed,
+ sizeof(*seed) + size);
+ if (seed != NULL) {
+- pr_notice("seeding entropy pool\n");
+ add_bootloader_randomness(seed->bits, size);
++ memzero_explicit(seed->bits, size);
+ early_memunmap(seed, sizeof(*seed) + size);
+ } else {
+ pr_err("Could not map UEFI random seed!\n");
+diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
+index cde0a2ef507d9..fbffdd7290a31 100644
+--- a/drivers/firmware/efi/libstub/efistub.h
++++ b/drivers/firmware/efi/libstub/efistub.h
+@@ -766,6 +766,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
+ efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
+ unsigned long *addr, unsigned long random_seed);
+
++efi_status_t efi_random_get_seed(void);
++
+ efi_status_t check_platform_features(void);
+
+ void *get_efi_config_table(efi_guid_t guid);
+diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
+index 33ab567695951..f85d2c0668777 100644
+--- a/drivers/firmware/efi/libstub/random.c
++++ b/drivers/firmware/efi/libstub/random.c
+@@ -67,27 +67,43 @@ efi_status_t efi_random_get_seed(void)
+ efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+ efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
+ efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
++ struct linux_efi_random_seed *prev_seed, *seed = NULL;
++ int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE;
+ efi_rng_protocol_t *rng = NULL;
+- struct linux_efi_random_seed *seed = NULL;
+ efi_status_t status;
+
+ status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
+ if (status != EFI_SUCCESS)
+ return status;
+
++ /*
++ * Check whether a seed was provided by a prior boot stage. In that
++ * case, instead of overwriting it, let's create a new buffer that can
++ * hold both, and concatenate the existing and the new seeds.
++ * Note that we should read the seed size with caution, in case the
++ * table got corrupted in memory somehow.
++ */
++ prev_seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID);
++ if (prev_seed && prev_seed->size <= 512U) {
++ prev_seed_size = prev_seed->size;
++ seed_size += prev_seed_size;
++ }
++
+ /*
+ * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
+ * allocation will survive a kexec reboot (although we refresh the seed
+ * beforehand)
+ */
+ status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+- sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
++ struct_size(seed, bits, seed_size),
+ (void **)&seed);
+- if (status != EFI_SUCCESS)
+- return status;
++ if (status != EFI_SUCCESS) {
++ efi_warn("Failed to allocate memory for RNG seed.\n");
++ goto err_warn;
++ }
+
+ status = efi_call_proto(rng, get_rng, &rng_algo_raw,
+- EFI_RANDOM_SEED_SIZE, seed->bits);
++ EFI_RANDOM_SEED_SIZE, seed->bits);
+
+ if (status == EFI_UNSUPPORTED)
+ /*
+@@ -100,14 +116,28 @@ efi_status_t efi_random_get_seed(void)
+ if (status != EFI_SUCCESS)
+ goto err_freepool;
+
+- seed->size = EFI_RANDOM_SEED_SIZE;
++ seed->size = seed_size;
++ if (prev_seed_size)
++ memcpy(seed->bits + EFI_RANDOM_SEED_SIZE, prev_seed->bits,
++ prev_seed_size);
++
+ status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
+ if (status != EFI_SUCCESS)
+ goto err_freepool;
+
++ if (prev_seed_size) {
++ /* wipe and free the old seed if we managed to install the new one */
++ memzero_explicit(prev_seed->bits, prev_seed_size);
++ efi_bs_call(free_pool, prev_seed);
++ }
+ return EFI_SUCCESS;
+
+ err_freepool:
++ memzero_explicit(seed, struct_size(seed, bits, seed_size));
+ efi_bs_call(free_pool, seed);
++ efi_warn("Failed to obtain seed from EFI_RNG_PROTOCOL\n");
++err_warn:
++ if (prev_seed)
++ efi_warn("Retaining bootloader-supplied seed only");
+ return status;
+ }
+diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
+index 7d82388b4ab7c..f50236e68e888 100644
+--- a/drivers/gpio/gpio-sifive.c
++++ b/drivers/gpio/gpio-sifive.c
+@@ -209,6 +209,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+ parent = irq_find_host(irq_parent);
++ of_node_put(irq_parent);
+ if (!parent) {
+ dev_err(dev, "no IRQ parent domain\n");
+ return -ENODEV;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 28dea2eb61c7f..cabbf02eb0544 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2008,6 +2008,15 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
+ "See modparam exp_hw_support\n");
+ return -ENODEV;
+ }
++ /* differentiate between P10 and P11 asics with the same DID */
++ if (pdev->device == 0x67FF &&
++ (pdev->revision == 0xE3 ||
++ pdev->revision == 0xE7 ||
++ pdev->revision == 0xF3 ||
++ pdev->revision == 0xF7)) {
++ flags &= ~AMD_ASIC_MASK;
++ flags |= CHIP_POLARIS10;
++ }
+
+ /* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU mapping,
+ * however, SME requires an indirect IOMMU mapping because the encryption
+@@ -2081,12 +2090,12 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
+
+ pci_set_drvdata(pdev, ddev);
+
+- ret = amdgpu_driver_load_kms(adev, ent->driver_data);
++ ret = amdgpu_driver_load_kms(adev, flags);
+ if (ret)
+ goto err_pci;
+
+ retry_init:
+- ret = drm_dev_register(ddev, ent->driver_data);
++ ret = drm_dev_register(ddev, flags);
+ if (ret == -EAGAIN && ++retry <= 3) {
+ DRM_INFO("retry init %d\n", retry);
+ /* Don't request EX mode too frequently which is attacking */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index a0b1bf17cb74b..b1d0cad00b2e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1510,7 +1510,8 @@ u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo)
+ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev,
+ uint32_t domain)
+ {
+- if (domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) {
++ if ((domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) &&
++ ((adev->asic_type == CHIP_CARRIZO) || (adev->asic_type == CHIP_STONEY))) {
+ domain = AMDGPU_GEM_DOMAIN_VRAM;
+ if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD)
+ domain = AMDGPU_GEM_DOMAIN_GTT;
+diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
+index e9b7926d9b663..cfe163103cfd7 100644
+--- a/drivers/gpu/drm/drm_connector.c
++++ b/drivers/gpu/drm/drm_connector.c
+@@ -487,6 +487,9 @@ void drm_connector_cleanup(struct drm_connector *connector)
+ mutex_destroy(&connector->mutex);
+
+ memset(connector, 0, sizeof(*connector));
++
++ if (dev->registered)
++ drm_sysfs_hotplug_event(dev);
+ }
+ EXPORT_SYMBOL(drm_connector_cleanup);
+
+diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+index 0a88088a11e8c..55dd02a01f1ac 100644
+--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
++++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+@@ -133,9 +133,9 @@ static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi,
+ return ffs(intel_dsi->ports) - 1;
+
+ if (seq_port) {
+- if (intel_dsi->ports & PORT_B)
++ if (intel_dsi->ports & BIT(PORT_B))
+ return PORT_B;
+- else if (intel_dsi->ports & PORT_C)
++ else if (intel_dsi->ports & BIT(PORT_C))
+ return PORT_C;
+ }
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i915/gt/intel_migrate.c
+index 1dac21aa7e5c3..5b59a6effc207 100644
+--- a/drivers/gpu/drm/i915/gt/intel_migrate.c
++++ b/drivers/gpu/drm/i915/gt/intel_migrate.c
+@@ -13,7 +13,6 @@
+
+ struct insert_pte_data {
+ u64 offset;
+- bool is_lmem;
+ };
+
+ #define CHUNK_SZ SZ_8M /* ~1ms at 8GiB/s preemption delay */
+@@ -40,7 +39,7 @@ static void insert_pte(struct i915_address_space *vm,
+ struct insert_pte_data *d = data;
+
+ vm->insert_page(vm, px_dma(pt), d->offset, I915_CACHE_NONE,
+- d->is_lmem ? PTE_LM : 0);
++ i915_gem_object_is_lmem(pt->base) ? PTE_LM : 0);
+ d->offset += PAGE_SIZE;
+ }
+
+@@ -134,8 +133,7 @@ static struct i915_address_space *migrate_vm(struct intel_gt *gt)
+ goto err_vm;
+
+ /* Now allow the GPU to rewrite the PTE via its own ppGTT */
+- d.is_lmem = i915_gem_object_is_lmem(vm->vm.scratch[0]);
+- vm->vm.foreach(&vm->vm, base, base + sz, insert_pte, &d);
++ vm->vm.foreach(&vm->vm, base, d.offset - base, insert_pte, &d);
+ }
+
+ return &vm->vm;
+@@ -281,10 +279,10 @@ static int emit_pte(struct i915_request *rq,
+ GEM_BUG_ON(GRAPHICS_VER(rq->engine->i915) < 8);
+
+ /* Compute the page directory offset for the target address range */
+- offset += (u64)rq->engine->instance << 32;
+ offset >>= 12;
+ offset *= sizeof(u64);
+ offset += 2 * CHUNK_SZ;
++ offset += (u64)rq->engine->instance << 32;
+
+ cs = intel_ring_begin(rq, 6);
+ if (IS_ERR(cs))
+diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c
+index 9f1c209d92511..e08ed0e9f1653 100644
+--- a/drivers/gpu/drm/i915/gvt/debugfs.c
++++ b/drivers/gpu/drm/i915/gvt/debugfs.c
+@@ -175,8 +175,13 @@ void intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
+ */
+ void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu)
+ {
+- debugfs_remove_recursive(vgpu->debugfs);
+- vgpu->debugfs = NULL;
++ struct intel_gvt *gvt = vgpu->gvt;
++ struct drm_minor *minor = gvt->gt->i915->drm.primary;
++
++ if (minor->debugfs_root && gvt->debugfs_root) {
++ debugfs_remove_recursive(vgpu->debugfs);
++ vgpu->debugfs = NULL;
++ }
+ }
+
+ /**
+@@ -199,6 +204,10 @@ void intel_gvt_debugfs_init(struct intel_gvt *gvt)
+ */
+ void intel_gvt_debugfs_clean(struct intel_gvt *gvt)
+ {
+- debugfs_remove_recursive(gvt->debugfs_root);
+- gvt->debugfs_root = NULL;
++ struct drm_minor *minor = gvt->gt->i915->drm.primary;
++
++ if (minor->debugfs_root) {
++ debugfs_remove_recursive(gvt->debugfs_root);
++ gvt->debugfs_root = NULL;
++ }
+ }
+diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
+index 1bb1be5c48c84..0291d42cfba8d 100644
+--- a/drivers/gpu/drm/i915/gvt/scheduler.c
++++ b/drivers/gpu/drm/i915/gvt/scheduler.c
+@@ -694,6 +694,7 @@ intel_vgpu_shadow_mm_pin(struct intel_vgpu_workload *workload)
+
+ if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT ||
+ !workload->shadow_mm->ppgtt_mm.shadowed) {
++ intel_vgpu_unpin_mm(workload->shadow_mm);
+ gvt_vgpu_err("workload shadow ppgtt isn't ready\n");
+ return -EINVAL;
+ }
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index 846c1aae69c82..924a66f539511 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -619,6 +619,11 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ break;
+ }
+
++ if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_BG)
++ width = ipu_src_rect_width(new_state);
++ else
++ width = drm_rect_width(&new_state->src) >> 16;
++
+ eba = drm_plane_state_to_eba(new_state, 0);
+
+ /*
+@@ -627,8 +632,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ */
+ if (ipu_state->use_pre) {
+ axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
+- ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
+- ipu_src_rect_width(new_state),
++ ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, width,
+ drm_rect_height(&new_state->src) >> 16,
+ fb->pitches[0], fb->format->format,
+ fb->modifier, &eba);
+@@ -683,9 +687,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ break;
+ }
+
+- ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), 8));
++ ipu_dmfc_config_wait4eot(ipu_plane->dmfc, width);
+
+- width = ipu_src_rect_width(new_state);
+ height = drm_rect_height(&new_state->src) >> 16;
+ info = drm_format_info(fb->format->format);
+ ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
+@@ -749,8 +752,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16);
+
+ ipu_cpmem_zero(ipu_plane->alpha_ch);
+- ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
+- ipu_src_rect_width(new_state),
++ ipu_cpmem_set_resolution(ipu_plane->alpha_ch, width,
+ drm_rect_height(&new_state->src) >> 16);
+ ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
+ ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
+diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+index a5df1c8d34cde..d9231b89d73e8 100644
+--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
++++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+@@ -1326,7 +1326,11 @@ static int ingenic_drm_init(void)
+ return err;
+ }
+
+- return platform_driver_register(&ingenic_drm_driver);
++ err = platform_driver_register(&ingenic_drm_driver);
++ if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && err)
++ platform_driver_unregister(ingenic_ipu_driver_ptr);
++
++ return err;
+ }
+ module_init(ingenic_drm_init);
+
+diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
+index d4b907889a21d..cd399b0b71814 100644
+--- a/drivers/gpu/drm/meson/meson_viu.c
++++ b/drivers/gpu/drm/meson/meson_viu.c
+@@ -436,15 +436,14 @@ void meson_viu_init(struct meson_drm *priv)
+
+ /* Initialize OSD1 fifo control register */
+ reg = VIU_OSD_DDR_PRIORITY_URGENT |
+- VIU_OSD_HOLD_FIFO_LINES(31) |
+ VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
+ VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
+ VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */
+
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
+- reg |= VIU_OSD_BURST_LENGTH_32;
++ reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31));
+ else
+- reg |= VIU_OSD_BURST_LENGTH_64;
++ reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4));
+
+ writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
+ writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
+diff --git a/drivers/gpu/drm/mgag200/mgag200_pll.c b/drivers/gpu/drm/mgag200/mgag200_pll.c
+index 52be08b744ade..87f9846b9b4ff 100644
+--- a/drivers/gpu/drm/mgag200/mgag200_pll.c
++++ b/drivers/gpu/drm/mgag200/mgag200_pll.c
+@@ -268,7 +268,8 @@ static void mgag200_pixpll_update_g200se_04(struct mgag200_pll *pixpll,
+ pixpllcp = pixpllc->p - 1;
+ pixpllcs = pixpllc->s;
+
+- xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1);
++ // For G200SE A, BIT(7) should be set unconditionally.
++ xpixpllcm = BIT(7) | pixpllcm;
+ xpixpllcn = pixpllcn;
+ xpixpllcp = (pixpllcs << 3) | pixpllcp;
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
+index e48e357ea4f18..4c271244092b4 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
+@@ -82,6 +82,7 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
+ struct panfrost_gem_object *bo;
+ struct drm_panfrost_create_bo *args = data;
+ struct panfrost_gem_mapping *mapping;
++ int ret;
+
+ if (!args->size || args->pad ||
+ (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP)))
+@@ -92,21 +93,29 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
+ !(args->flags & PANFROST_BO_NOEXEC))
+ return -EINVAL;
+
+- bo = panfrost_gem_create_with_handle(file, dev, args->size, args->flags,
+- &args->handle);
++ bo = panfrost_gem_create(dev, args->size, args->flags);
+ if (IS_ERR(bo))
+ return PTR_ERR(bo);
+
++ ret = drm_gem_handle_create(file, &bo->base.base, &args->handle);
++ if (ret)
++ goto out;
++
+ mapping = panfrost_gem_mapping_get(bo, priv);
+- if (!mapping) {
+- drm_gem_object_put(&bo->base.base);
+- return -EINVAL;
++ if (mapping) {
++ args->offset = mapping->mmnode.start << PAGE_SHIFT;
++ panfrost_gem_mapping_put(mapping);
++ } else {
++ /* This can only happen if the handle from
++ * drm_gem_handle_create() has already been guessed and freed
++ * by user space
++ */
++ ret = -EINVAL;
+ }
+
+- args->offset = mapping->mmnode.start << PAGE_SHIFT;
+- panfrost_gem_mapping_put(mapping);
+-
+- return 0;
++out:
++ drm_gem_object_put(&bo->base.base);
++ return ret;
+ }
+
+ /**
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
+index 6d9bdb9180cb7..55e3a68ed28a4 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
+@@ -234,12 +234,8 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
+ }
+
+ struct panfrost_gem_object *
+-panfrost_gem_create_with_handle(struct drm_file *file_priv,
+- struct drm_device *dev, size_t size,
+- u32 flags,
+- uint32_t *handle)
++panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
+ {
+- int ret;
+ struct drm_gem_shmem_object *shmem;
+ struct panfrost_gem_object *bo;
+
+@@ -255,16 +251,6 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv,
+ bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
+ bo->is_heap = !!(flags & PANFROST_BO_HEAP);
+
+- /*
+- * Allocate an id of idr table where the obj is registered
+- * and handle has the id what user can see.
+- */
+- ret = drm_gem_handle_create(file_priv, &shmem->base, handle);
+- /* drop reference from allocate - handle holds it now. */
+- drm_gem_object_put(&shmem->base);
+- if (ret)
+- return ERR_PTR(ret);
+-
+ return bo;
+ }
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
+index 8088d5fd8480e..ad2877eeeccdf 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
+@@ -69,10 +69,7 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev,
+ struct sg_table *sgt);
+
+ struct panfrost_gem_object *
+-panfrost_gem_create_with_handle(struct drm_file *file_priv,
+- struct drm_device *dev, size_t size,
+- u32 flags,
+- uint32_t *handle);
++panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags);
+
+ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv);
+ void panfrost_gem_close(struct drm_gem_object *obj,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 171e90c4b9f3f..01d5a01af2594 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -186,7 +186,8 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
+ if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
+ box->x != 0 || box->y != 0 || box->z != 0 ||
+ box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
+- box->d != 1 || box_count != 1) {
++ box->d != 1 || box_count != 1 ||
++ box->w > 64 || box->h > 64) {
+ /* TODO handle none page aligned offsets */
+ /* TODO handle more dst & src != 0 */
+ /* TODO handle more then one copy */
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 78b55f845d2d4..8698d49edaa38 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -966,7 +966,10 @@
+ #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003
+
+ #define USB_VENDOR_ID_PLANTRONICS 0x047f
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055
+ #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
+
+ #define USB_VENDOR_ID_PANASONIC 0x04da
+ #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 08462ac72b897..6b86d368d5e74 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1965,6 +1965,10 @@ static const struct hid_device_id mt_devices[] = {
+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+ USB_VENDOR_ID_ELAN, 0x313a) },
+
++ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
++ USB_VENDOR_ID_ELAN, 0x3148) },
++
+ /* Elitegroup panel */
+ { .driver_data = MT_CLS_SERIAL,
+ MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
+diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
+index e81b7cec2d124..3d414ae194acb 100644
+--- a/drivers/hid/hid-plantronics.c
++++ b/drivers/hid/hid-plantronics.c
+@@ -198,9 +198,18 @@ err:
+ }
+
+ static const struct hid_device_id plantronics_devices[] = {
++ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
++ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
+ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
++ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
++ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
++ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
++ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
+ { }
+ };
+diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c
+index 224ba36f2946c..1a0ecf439c099 100644
+--- a/drivers/infiniband/hw/mlx5/counters.c
++++ b/drivers/infiniband/hw/mlx5/counters.c
+@@ -249,7 +249,6 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
+ const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);
+ struct mlx5_core_dev *mdev;
+ int ret, num_counters;
+- u32 mdev_port_num;
+
+ if (!stats)
+ return -EINVAL;
+@@ -270,8 +269,9 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
+ }
+
+ if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
+- mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
+- &mdev_port_num);
++ if (!port_num)
++ port_num = 1;
++ mdev = mlx5_ib_get_native_port_mdev(dev, port_num, NULL);
+ if (!mdev) {
+ /* If port is not affiliated yet, its in down state
+ * which doesn't have any counters yet, so it would be
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index e5abbcfc1d574..55b05a3e31b8e 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4499,6 +4499,40 @@ static bool mlx5_ib_modify_qp_allowed(struct mlx5_ib_dev *dev,
+ return false;
+ }
+
++static int validate_rd_atomic(struct mlx5_ib_dev *dev, struct ib_qp_attr *attr,
++ int attr_mask, enum ib_qp_type qp_type)
++{
++ int log_max_ra_res;
++ int log_max_ra_req;
++
++ if (qp_type == MLX5_IB_QPT_DCI) {
++ log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_res_dc);
++ log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_req_dc);
++ } else {
++ log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_res_qp);
++ log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_req_qp);
++ }
++
++ if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
++ attr->max_rd_atomic > log_max_ra_res) {
++ mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
++ attr->max_rd_atomic);
++ return false;
++ }
++
++ if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
++ attr->max_dest_rd_atomic > log_max_ra_req) {
++ mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
++ attr->max_dest_rd_atomic);
++ return false;
++ }
++ return true;
++}
++
+ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+ {
+@@ -4586,21 +4620,8 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ goto out;
+ }
+
+- if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
+- attr->max_rd_atomic >
+- (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_res_qp))) {
+- mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
+- attr->max_rd_atomic);
+- goto out;
+- }
+-
+- if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
+- attr->max_dest_rd_atomic >
+- (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_req_qp))) {
+- mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
+- attr->max_dest_rd_atomic);
++ if (!validate_rd_atomic(dev, attr, attr_mask, qp_type))
+ goto out;
+- }
+
+ if (cur_state == new_state && cur_state == IB_QPS_RESET) {
+ err = 0;
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 9a7742732d73f..ce91a6d8532f3 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -3226,6 +3226,13 @@ static int __init parse_ivrs_acpihid(char *str)
+ return 1;
+ }
+
++ /*
++ * Ignore leading zeroes after ':', so e.g., AMDI0095:00
++ * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match
++ */
++ while (*uid == '0' && *(uid + 1))
++ uid++;
++
+ i = early_acpihid_map_size++;
+ memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
+ memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
+diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
+index 89a73204dbf47..0f6f74e3030f7 100644
+--- a/drivers/md/dm-cache-metadata.c
++++ b/drivers/md/dm-cache-metadata.c
+@@ -551,11 +551,13 @@ static int __create_persistent_data_objects(struct dm_cache_metadata *cmd,
+ return r;
+ }
+
+-static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd)
++static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd,
++ bool destroy_bm)
+ {
+ dm_sm_destroy(cmd->metadata_sm);
+ dm_tm_destroy(cmd->tm);
+- dm_block_manager_destroy(cmd->bm);
++ if (destroy_bm)
++ dm_block_manager_destroy(cmd->bm);
+ }
+
+ typedef unsigned long (*flags_mutator)(unsigned long);
+@@ -826,7 +828,7 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
+ cmd2 = lookup(bdev);
+ if (cmd2) {
+ mutex_unlock(&table_lock);
+- __destroy_persistent_data_objects(cmd);
++ __destroy_persistent_data_objects(cmd, true);
+ kfree(cmd);
+ return cmd2;
+ }
+@@ -874,7 +876,7 @@ void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
+ mutex_unlock(&table_lock);
+
+ if (!cmd->fail_io)
+- __destroy_persistent_data_objects(cmd);
++ __destroy_persistent_data_objects(cmd, true);
+ kfree(cmd);
+ }
+ }
+@@ -1808,14 +1810,52 @@ int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
+
+ int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
+ {
+- int r;
++ int r = -EINVAL;
++ struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
++
++ /* fail_io is double-checked with cmd->root_lock held below */
++ if (unlikely(cmd->fail_io))
++ return r;
++
++ /*
++ * Replacement block manager (new_bm) is created and old_bm destroyed outside of
++ * cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
++ * shrinker associated with the block manager's bufio client vs cmd root_lock).
++ * - must take shrinker_rwsem without holding cmd->root_lock
++ */
++ new_bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
++ CACHE_MAX_CONCURRENT_LOCKS);
+
+ WRITE_LOCK(cmd);
+- __destroy_persistent_data_objects(cmd);
+- r = __create_persistent_data_objects(cmd, false);
++ if (cmd->fail_io) {
++ WRITE_UNLOCK(cmd);
++ goto out;
++ }
++
++ __destroy_persistent_data_objects(cmd, false);
++ old_bm = cmd->bm;
++ if (IS_ERR(new_bm)) {
++ DMERR("could not create block manager during abort");
++ cmd->bm = NULL;
++ r = PTR_ERR(new_bm);
++ goto out_unlock;
++ }
++
++ cmd->bm = new_bm;
++ r = __open_or_format_metadata(cmd, false);
++ if (r) {
++ cmd->bm = NULL;
++ goto out_unlock;
++ }
++ new_bm = NULL;
++out_unlock:
+ if (r)
+ cmd->fail_io = true;
+ WRITE_UNLOCK(cmd);
++ dm_block_manager_destroy(old_bm);
++out:
++ if (new_bm && !IS_ERR(new_bm))
++ dm_block_manager_destroy(new_bm);
+
+ return r;
+ }
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index bdd500447dea2..abfe7e37b76f4 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -915,16 +915,16 @@ static void abort_transaction(struct cache *cache)
+ if (get_cache_mode(cache) >= CM_READ_ONLY)
+ return;
+
+- if (dm_cache_metadata_set_needs_check(cache->cmd)) {
+- DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
+- set_cache_mode(cache, CM_FAIL);
+- }
+-
+ DMERR_LIMIT("%s: aborting current metadata transaction", dev_name);
+ if (dm_cache_metadata_abort(cache->cmd)) {
+ DMERR("%s: failed to abort metadata transaction", dev_name);
+ set_cache_mode(cache, CM_FAIL);
+ }
++
++ if (dm_cache_metadata_set_needs_check(cache->cmd)) {
++ DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
++ set_cache_mode(cache, CM_FAIL);
++ }
+ }
+
+ static void metadata_operation_failed(struct cache *cache, const char *op, int r)
+@@ -1895,6 +1895,7 @@ static void destroy(struct cache *cache)
+ if (cache->prison)
+ dm_bio_prison_destroy_v2(cache->prison);
+
++ cancel_delayed_work_sync(&cache->waker);
+ if (cache->wq)
+ destroy_workqueue(cache->wq);
+
+diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
+index edd22e4d65dff..ec4f2487ef10d 100644
+--- a/drivers/md/dm-clone-target.c
++++ b/drivers/md/dm-clone-target.c
+@@ -1959,6 +1959,7 @@ static void clone_dtr(struct dm_target *ti)
+
+ mempool_exit(&clone->hydration_pool);
+ dm_kcopyd_client_destroy(clone->kcopyd_client);
++ cancel_delayed_work_sync(&clone->waker);
+ destroy_workqueue(clone->wq);
+ hash_table_exit(clone);
+ dm_clone_metadata_close(clone->cmd);
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index 9705f3c358dd4..508e81bfef2c4 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -4539,6 +4539,8 @@ static void dm_integrity_dtr(struct dm_target *ti)
+ BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
+ BUG_ON(!list_empty(&ic->wait_list));
+
++ if (ic->mode == 'B')
++ cancel_delayed_work_sync(&ic->bitmap_flush_work);
+ if (ic->metadata_wq)
+ destroy_workqueue(ic->metadata_wq);
+ if (ic->wait_wq)
+diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
+index 0ada99572b689..3ce7017bf9d56 100644
+--- a/drivers/md/dm-thin-metadata.c
++++ b/drivers/md/dm-thin-metadata.c
+@@ -724,6 +724,15 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
+ goto bad_cleanup_data_sm;
+ }
+
++ /*
++ * For pool metadata opening process, root setting is redundant
++ * because it will be set again in __begin_transaction(). But dm
++ * pool aborting process really needs to get last transaction's
++ * root to avoid accessing broken btree.
++ */
++ pmd->root = le64_to_cpu(disk_super->data_mapping_root);
++ pmd->details_root = le64_to_cpu(disk_super->device_details_root);
++
+ __setup_btree_details(pmd);
+ dm_bm_unlock(sblock);
+
+@@ -776,13 +785,15 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f
+ return r;
+ }
+
+-static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd)
++static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd,
++ bool destroy_bm)
+ {
+ dm_sm_destroy(pmd->data_sm);
+ dm_sm_destroy(pmd->metadata_sm);
+ dm_tm_destroy(pmd->nb_tm);
+ dm_tm_destroy(pmd->tm);
+- dm_block_manager_destroy(pmd->bm);
++ if (destroy_bm)
++ dm_block_manager_destroy(pmd->bm);
+ }
+
+ static int __begin_transaction(struct dm_pool_metadata *pmd)
+@@ -989,7 +1000,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
+ }
+ pmd_write_unlock(pmd);
+ if (!pmd->fail_io)
+- __destroy_persistent_data_objects(pmd);
++ __destroy_persistent_data_objects(pmd, true);
+
+ kfree(pmd);
+ return 0;
+@@ -1888,19 +1899,52 @@ static void __set_abort_with_changes_flags(struct dm_pool_metadata *pmd)
+ int dm_pool_abort_metadata(struct dm_pool_metadata *pmd)
+ {
+ int r = -EINVAL;
++ struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
++
++ /* fail_io is double-checked with pmd->root_lock held below */
++ if (unlikely(pmd->fail_io))
++ return r;
++
++ /*
++ * Replacement block manager (new_bm) is created and old_bm destroyed outside of
++ * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
++ * shrinker associated with the block manager's bufio client vs pmd root_lock).
++ * - must take shrinker_rwsem without holding pmd->root_lock
++ */
++ new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
++ THIN_MAX_CONCURRENT_LOCKS);
+
+ pmd_write_lock(pmd);
+- if (pmd->fail_io)
++ if (pmd->fail_io) {
++ pmd_write_unlock(pmd);
+ goto out;
++ }
+
+ __set_abort_with_changes_flags(pmd);
+- __destroy_persistent_data_objects(pmd);
+- r = __create_persistent_data_objects(pmd, false);
++ __destroy_persistent_data_objects(pmd, false);
++ old_bm = pmd->bm;
++ if (IS_ERR(new_bm)) {
++ DMERR("could not create block manager during abort");
++ pmd->bm = NULL;
++ r = PTR_ERR(new_bm);
++ goto out_unlock;
++ }
++
++ pmd->bm = new_bm;
++ r = __open_or_format_metadata(pmd, false);
++ if (r) {
++ pmd->bm = NULL;
++ goto out_unlock;
++ }
++ new_bm = NULL;
++out_unlock:
+ if (r)
+ pmd->fail_io = true;
+-
+-out:
+ pmd_write_unlock(pmd);
++ dm_block_manager_destroy(old_bm);
++out:
++ if (new_bm && !IS_ERR(new_bm))
++ dm_block_manager_destroy(new_bm);
+
+ return r;
+ }
+diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
+index 0a85e4cd607c6..cce26f46ded52 100644
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -2907,6 +2907,8 @@ static void __pool_destroy(struct pool *pool)
+ dm_bio_prison_destroy(pool->prison);
+ dm_kcopyd_client_destroy(pool->copier);
+
++ cancel_delayed_work_sync(&pool->waker);
++ cancel_delayed_work_sync(&pool->no_space_timeout);
+ if (pool->wq)
+ destroy_workqueue(pool->wq);
+
+@@ -3566,20 +3568,28 @@ static int pool_preresume(struct dm_target *ti)
+ */
+ r = bind_control_target(pool, ti);
+ if (r)
+- return r;
++ goto out;
+
+ r = maybe_resize_data_dev(ti, &need_commit1);
+ if (r)
+- return r;
++ goto out;
+
+ r = maybe_resize_metadata_dev(ti, &need_commit2);
+ if (r)
+- return r;
++ goto out;
+
+ if (need_commit1 || need_commit2)
+ (void) commit(pool);
++out:
++ /*
++ * When a thin-pool is PM_FAIL, it cannot be rebuilt if
++ * bio is in deferred list. Therefore need to return 0
++ * to allow pool_resume() to flush IO.
++ */
++ if (r && get_pool_mode(pool) == PM_FAIL)
++ r = 0;
+
+- return 0;
++ return r;
+ }
+
+ static void pool_suspend_active_thins(struct pool *pool)
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 650bfccd066fe..062142559caa3 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -486,7 +486,7 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
+ sb = kmap_atomic(bitmap->storage.sb_page);
+ pr_debug("%s: bitmap file superblock:\n", bmname(bitmap));
+ pr_debug(" magic: %08x\n", le32_to_cpu(sb->magic));
+- pr_debug(" version: %d\n", le32_to_cpu(sb->version));
++ pr_debug(" version: %u\n", le32_to_cpu(sb->version));
+ pr_debug(" uuid: %08x.%08x.%08x.%08x\n",
+ le32_to_cpu(*(__le32 *)(sb->uuid+0)),
+ le32_to_cpu(*(__le32 *)(sb->uuid+4)),
+@@ -497,11 +497,11 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
+ pr_debug("events cleared: %llu\n",
+ (unsigned long long) le64_to_cpu(sb->events_cleared));
+ pr_debug(" state: %08x\n", le32_to_cpu(sb->state));
+- pr_debug(" chunksize: %d B\n", le32_to_cpu(sb->chunksize));
+- pr_debug(" daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
++ pr_debug(" chunksize: %u B\n", le32_to_cpu(sb->chunksize));
++ pr_debug(" daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep));
+ pr_debug(" sync size: %llu KB\n",
+ (unsigned long long)le64_to_cpu(sb->sync_size)/2);
+- pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind));
++ pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind));
+ kunmap_atomic(sb);
+ }
+
+@@ -2106,7 +2106,8 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ bytes = DIV_ROUND_UP(chunks, 8);
+ if (!bitmap->mddev->bitmap_info.external)
+ bytes += sizeof(bitmap_super_t);
+- } while (bytes > (space << 9));
++ } while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) <
++ (BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1));
+ } else
+ chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
+
+@@ -2151,7 +2152,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ bitmap->counts.missing_pages = pages;
+ bitmap->counts.chunkshift = chunkshift;
+ bitmap->counts.chunks = chunks;
+- bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
++ bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift +
+ BITMAP_BLOCK_SHIFT);
+
+ blocks = min(old_counts.chunks << old_counts.chunkshift,
+@@ -2177,8 +2178,8 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ bitmap->counts.missing_pages = old_counts.pages;
+ bitmap->counts.chunkshift = old_counts.chunkshift;
+ bitmap->counts.chunks = old_counts.chunks;
+- bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift +
+- BITMAP_BLOCK_SHIFT);
++ bitmap->mddev->bitmap_info.chunksize =
++ 1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT);
+ blocks = old_counts.chunks << old_counts.chunkshift;
+ pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n");
+ break;
+@@ -2519,6 +2520,9 @@ chunksize_store(struct mddev *mddev, const char *buf, size_t len)
+ if (csize < 512 ||
+ !is_power_of_2(csize))
+ return -EINVAL;
++ if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE *
++ sizeof(((bitmap_super_t *)0)->chunksize))))
++ return -EOVERFLOW;
+ mddev->bitmap_info.chunksize = csize;
+ return len;
+ }
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 04e1e294b4b1e..59ab99844df8e 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -526,13 +526,14 @@ static void md_end_flush(struct bio *bio)
+ struct md_rdev *rdev = bio->bi_private;
+ struct mddev *mddev = rdev->mddev;
+
++ bio_put(bio);
++
+ rdev_dec_pending(rdev, mddev);
+
+ if (atomic_dec_and_test(&mddev->flush_pending)) {
+ /* The pre-request flush has finished */
+ queue_work(md_wq, &mddev->flush_work);
+ }
+- bio_put(bio);
+ }
+
+ static void md_submit_flush_data(struct work_struct *ws);
+@@ -935,10 +936,12 @@ static void super_written(struct bio *bio)
+ } else
+ clear_bit(LastDev, &rdev->flags);
+
++ bio_put(bio);
++
++ rdev_dec_pending(rdev, mddev);
++
+ if (atomic_dec_and_test(&mddev->pending_writes))
+ wake_up(&mddev->sb_wait);
+- rdev_dec_pending(rdev, mddev);
+- bio_put(bio);
+ }
+
+ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
+diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
+index 01f288fa37e0e..8abf7f44d96bc 100644
+--- a/drivers/media/dvb-core/dmxdev.c
++++ b/drivers/media/dvb-core/dmxdev.c
+@@ -800,6 +800,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
+ if (mutex_lock_interruptible(&dmxdev->mutex))
+ return -ERESTARTSYS;
+
++ if (dmxdev->exit) {
++ mutex_unlock(&dmxdev->mutex);
++ return -ENODEV;
++ }
++
+ for (i = 0; i < dmxdev->filternum; i++)
+ if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
+ break;
+@@ -1458,7 +1463,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
+
+ void dvb_dmxdev_release(struct dmxdev *dmxdev)
+ {
++ mutex_lock(&dmxdev->mutex);
+ dmxdev->exit = 1;
++ mutex_unlock(&dmxdev->mutex);
++
+ if (dmxdev->dvbdev->users > 1) {
+ wait_event(dmxdev->dvbdev->wait_queue,
+ dmxdev->dvbdev->users == 1);
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 828a0069a2968..6e2b7e97da176 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -345,6 +345,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
+ GFP_KERNEL);
+ if (!dvbdev->pads) {
+ kfree(dvbdev->entity);
++ dvbdev->entity = NULL;
+ return -ENOMEM;
+ }
+ }
+diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
+index 3d54a0ec86afd..3ae1f3a2f1420 100644
+--- a/drivers/media/dvb-frontends/stv0288.c
++++ b/drivers/media/dvb-frontends/stv0288.c
+@@ -440,9 +440,8 @@ static int stv0288_set_frontend(struct dvb_frontend *fe)
+ struct stv0288_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+- char tm;
+- unsigned char tda[3];
+- u8 reg, time_out = 0;
++ u8 tda[3], reg, time_out = 0;
++ s8 tm;
+
+ dprintk("%s : FE_SET_FRONTEND\n", __func__);
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+index da138c314963a..58822ec5370e2 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+@@ -468,8 +468,10 @@ void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+ /* Wait until instance is returned or timeout occurred */
+ if (s5p_mfc_wait_for_done_ctx(ctx,
+- S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
++ S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){
++ clear_work_bit_irqsave(ctx);
+ mfc_err("Err returning instance\n");
++ }
+
+ /* Free resources */
+ s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+index 1fad99edb0913..3da1775a65f19 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+@@ -1218,6 +1218,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ unsigned long mb_y_addr, mb_c_addr;
+ int slice_type;
+ unsigned int strm_size;
++ bool src_ready;
+
+ slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
+ strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
+@@ -1257,7 +1258,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ }
+ }
+ }
+- if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
++ if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING ||
++ ctx->state == MFCINST_FINISHING)) {
+ mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
+ list);
+ if (mb_entry->flags & MFC_BUF_FLAG_USED) {
+@@ -1288,7 +1290,13 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);
+ vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+- if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
++
++ src_ready = true;
++ if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0)
++ src_ready = false;
++ if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0)
++ src_ready = false;
++ if (!src_ready || ctx->dst_queue_cnt == 0)
+ clear_work_bit(ctx);
+
+ return 0;
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+index a1453053e31ab..ef8169f6c428c 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+@@ -1060,7 +1060,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ }
+
+ /* aspect ratio VUI */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 5);
+ reg |= ((p_h264->vui_sar & 0x1) << 5);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1083,7 +1083,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+
+ /* intra picture period for H.264 open GOP */
+ /* control */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 4);
+ reg |= ((p_h264->open_gop & 0x1) << 4);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1097,23 +1097,23 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ }
+
+ /* 'WEIGHTED_BI_PREDICTION' for B is disable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x3 << 9);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 14);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* ASO */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 6);
+ reg |= ((p_h264->aso & 0x1) << 6);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* hier qp enable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 8);
+ reg |= ((p_h264->open_gop & 0x1) << 8);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1134,7 +1134,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ writel(reg, mfc_regs->e_h264_num_t_layer);
+
+ /* frame packing SEI generation */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 25);
+ reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
+ writel(reg, mfc_regs->e_h264_options);
+diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c
+index 6eaa6775b8885..d3b32eb798377 100644
+--- a/drivers/mfd/mt6360-core.c
++++ b/drivers/mfd/mt6360-core.c
+@@ -402,7 +402,7 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
+ struct mt6360_ddata *ddata = context;
+ u8 bank = *(u8 *)reg;
+ u8 reg_addr = *(u8 *)(reg + 1);
+- struct i2c_client *i2c = ddata->i2c[bank];
++ struct i2c_client *i2c;
+ bool crc_needed = false;
+ u8 *buf;
+ int buf_len = MT6360_ALLOC_READ_SIZE(val_size);
+@@ -410,6 +410,11 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
+ u8 crc;
+ int ret;
+
++ if (bank >= MT6360_SLAVE_MAX)
++ return -EINVAL;
++
++ i2c = ddata->i2c[bank];
++
+ if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
+ crc_needed = true;
+ ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size);
+@@ -453,13 +458,18 @@ static int mt6360_regmap_write(void *context, const void *val, size_t val_size)
+ struct mt6360_ddata *ddata = context;
+ u8 bank = *(u8 *)val;
+ u8 reg_addr = *(u8 *)(val + 1);
+- struct i2c_client *i2c = ddata->i2c[bank];
++ struct i2c_client *i2c;
+ bool crc_needed = false;
+ u8 *buf;
+ int buf_len = MT6360_ALLOC_WRITE_SIZE(val_size);
+ int write_size = val_size - MT6360_REGMAP_REG_BYTE_SIZE;
+ int ret;
+
++ if (bank >= MT6360_SLAVE_MAX)
++ return -EINVAL;
++
++ i2c = ddata->i2c[bank];
++
+ if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
+ crc_needed = true;
+ ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size - MT6360_REGMAP_REG_BYTE_SIZE);
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index e85c95f3a8682..256260339f692 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -224,13 +224,15 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
+ div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
+ sdhci_enable_clk(host, div);
+
+- /* enable auto gate sdhc_enable_auto_gate */
+- val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
+- mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
+- SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
+- if (mask != (val & mask)) {
+- val |= mask;
+- sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
++ /* Enable CLK_AUTO when the clock is greater than 400K. */
++ if (clk > 400000) {
++ val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
++ mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
++ SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
++ if (mask != (val & mask)) {
++ val |= mask;
++ sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
++ }
+ }
+ }
+
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index ab36ec4797478..72f65f32abbc7 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -2049,6 +2049,7 @@ static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ return;
+ kref_get(&vub300->kref);
+ if (enable) {
++ set_current_state(TASK_RUNNING);
+ mutex_lock(&vub300->irq_mutex);
+ if (vub300->irqs_queued) {
+ vub300->irqs_queued -= 1;
+@@ -2064,6 +2065,7 @@ static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ vub300_queue_poll_work(vub300, 0);
+ }
+ mutex_unlock(&vub300->irq_mutex);
++ set_current_state(TASK_INTERRUPTIBLE);
+ } else {
+ vub300->irq_enabled = 0;
+ }
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index aad7076ae0202..d5dcc74a625ed 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1409,6 +1409,8 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
+ continue;
+
+ erase = &map->erase_type[i];
++ if (!erase->size)
++ continue;
+
+ /* Alignment is not mandatory for overlaid regions */
+ if (region->offset & SNOR_OVERLAID_REGION &&
+diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
+index 8ad095c19f271..ff6d4e74a186a 100644
+--- a/drivers/net/bonding/bond_3ad.c
++++ b/drivers/net/bonding/bond_3ad.c
+@@ -1539,6 +1539,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)
+ slave_err(bond->dev, port->slave->dev,
+ "Port %d did not find a suitable aggregator\n",
+ port->actor_port_number);
++ return;
+ }
+ }
+ /* if all aggregator's ports are READY_N == TRUE, set ready=TRUE
+diff --git a/drivers/net/dsa/mv88e6xxx/Kconfig b/drivers/net/dsa/mv88e6xxx/Kconfig
+index 7a2445a34eb77..e3181d5471dfe 100644
+--- a/drivers/net/dsa/mv88e6xxx/Kconfig
++++ b/drivers/net/dsa/mv88e6xxx/Kconfig
+@@ -2,7 +2,6 @@
+ config NET_DSA_MV88E6XXX
+ tristate "Marvell 88E6xxx Ethernet switch fabric support"
+ depends on NET_DSA
+- depends on PTP_1588_CLOCK_OPTIONAL
+ select IRQ_DOMAIN
+ select NET_DSA_TAG_EDSA
+ select NET_DSA_TAG_DSA
+@@ -13,7 +12,8 @@ config NET_DSA_MV88E6XXX
+ config NET_DSA_MV88E6XXX_PTP
+ bool "PTP support for Marvell 88E6xxx"
+ default n
+- depends on NET_DSA_MV88E6XXX && PTP_1588_CLOCK
++ depends on (NET_DSA_MV88E6XXX = y && PTP_1588_CLOCK = y) || \
++ (NET_DSA_MV88E6XXX = m && PTP_1588_CLOCK)
+ help
+ Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
+ chips that support it.
+diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
+index ab413fc1f68e3..f0faad149a3bd 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2392,29 +2392,18 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
+ return -EOPNOTSUPP;
+ }
+
+- switch (func) {
+- case ENA_ADMIN_TOEPLITZ:
+- if (key) {
+- if (key_len != sizeof(hash_key->key)) {
+- netdev_err(ena_dev->net_device,
+- "key len (%u) doesn't equal the supported size (%zu)\n",
+- key_len, sizeof(hash_key->key));
+- return -EINVAL;
+- }
+- memcpy(hash_key->key, key, key_len);
+- rss->hash_init_val = init_val;
+- hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
++ if ((func == ENA_ADMIN_TOEPLITZ) && key) {
++ if (key_len != sizeof(hash_key->key)) {
++ netdev_err(ena_dev->net_device,
++ "key len (%u) doesn't equal the supported size (%zu)\n",
++ key_len, sizeof(hash_key->key));
++ return -EINVAL;
+ }
+- break;
+- case ENA_ADMIN_CRC32:
+- rss->hash_init_val = init_val;
+- break;
+- default:
+- netdev_err(ena_dev->net_device, "Invalid hash function (%d)\n",
+- func);
+- return -EINVAL;
++ memcpy(hash_key->key, key, key_len);
++ hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
+ }
+
++ rss->hash_init_val = init_val;
+ old_func = rss->hash_func;
+ rss->hash_func = func;
+ rc = ena_com_set_hash_function(ena_dev);
+diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+index 13e745cf3781b..413082f10dc1c 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -880,11 +880,7 @@ static int ena_set_tunable(struct net_device *netdev,
+ switch (tuna->id) {
+ case ETHTOOL_RX_COPYBREAK:
+ len = *(u32 *)data;
+- if (len > adapter->netdev->mtu) {
+- ret = -EINVAL;
+- break;
+- }
+- adapter->rx_copybreak = len;
++ ret = ena_set_rx_copybreak(adapter, len);
+ break;
+ default:
+ ret = -EINVAL;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index f032e58a4c3c5..23c9750850e98 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -378,9 +378,9 @@ static int ena_xdp_xmit(struct net_device *dev, int n,
+
+ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ {
++ u32 verdict = ENA_XDP_PASS;
+ struct bpf_prog *xdp_prog;
+ struct ena_ring *xdp_ring;
+- u32 verdict = XDP_PASS;
+ struct xdp_frame *xdpf;
+ u64 *xdp_stat;
+
+@@ -397,7 +397,7 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ if (unlikely(!xdpf)) {
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+- verdict = XDP_ABORTED;
++ verdict = ENA_XDP_DROP;
+ break;
+ }
+
+@@ -413,29 +413,35 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+
+ spin_unlock(&xdp_ring->xdp_tx_lock);
+ xdp_stat = &rx_ring->rx_stats.xdp_tx;
++ verdict = ENA_XDP_TX;
+ break;
+ case XDP_REDIRECT:
+ if (likely(!xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog))) {
+ xdp_stat = &rx_ring->rx_stats.xdp_redirect;
++ verdict = ENA_XDP_REDIRECT;
+ break;
+ }
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+- verdict = XDP_ABORTED;
++ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_ABORTED:
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
++ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_DROP:
+ xdp_stat = &rx_ring->rx_stats.xdp_drop;
++ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_PASS:
+ xdp_stat = &rx_ring->rx_stats.xdp_pass;
++ verdict = ENA_XDP_PASS;
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_invalid;
++ verdict = ENA_XDP_DROP;
+ }
+
+ ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
+@@ -516,16 +522,18 @@ static void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
+ struct bpf_prog *prog,
+ int first, int count)
+ {
++ struct bpf_prog *old_bpf_prog;
+ struct ena_ring *rx_ring;
+ int i = 0;
+
+ for (i = first; i < count; i++) {
+ rx_ring = &adapter->rx_ring[i];
+- xchg(&rx_ring->xdp_bpf_prog, prog);
+- if (prog) {
++ old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
++
++ if (!old_bpf_prog && prog) {
+ ena_xdp_register_rxq_info(rx_ring);
+ rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
+- } else {
++ } else if (old_bpf_prog && !prog) {
+ ena_xdp_unregister_rxq_info(rx_ring);
+ rx_ring->rx_headroom = NET_SKB_PAD;
+ }
+@@ -676,6 +684,7 @@ static void ena_init_io_rings_common(struct ena_adapter *adapter,
+ ring->ena_dev = adapter->ena_dev;
+ ring->per_napi_packets = 0;
+ ring->cpu = 0;
++ ring->numa_node = 0;
+ ring->no_interrupt_event_cnt = 0;
+ u64_stats_init(&ring->syncp);
+ }
+@@ -779,6 +788,7 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+ tx_ring->cpu = ena_irq->cpu;
++ tx_ring->numa_node = node;
+ return 0;
+
+ err_push_buf_intermediate_buf:
+@@ -911,6 +921,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+ rx_ring->cpu = ena_irq->cpu;
++ rx_ring->numa_node = node;
+
+ return 0;
+ }
+@@ -1629,12 +1640,12 @@ static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ * we expect, then we simply drop it
+ */
+ if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU))
+- return XDP_DROP;
++ return ENA_XDP_DROP;
+
+ ret = ena_xdp_execute(rx_ring, xdp);
+
+ /* The xdp program might expand the headers */
+- if (ret == XDP_PASS) {
++ if (ret == ENA_XDP_PASS) {
+ rx_info->page_offset = xdp->data - xdp->data_hard_start;
+ rx_ring->ena_bufs[0].len = xdp->data_end - xdp->data;
+ }
+@@ -1673,7 +1684,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ xdp_init_buff(&xdp, ENA_PAGE_SIZE, &rx_ring->xdp_rxq);
+
+ do {
+- xdp_verdict = XDP_PASS;
++ xdp_verdict = ENA_XDP_PASS;
+ skb = NULL;
+ ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
+ ena_rx_ctx.max_bufs = rx_ring->sgl_size;
+@@ -1701,7 +1712,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp);
+
+ /* allocate skb and fill it */
+- if (xdp_verdict == XDP_PASS)
++ if (xdp_verdict == ENA_XDP_PASS)
+ skb = ena_rx_skb(rx_ring,
+ rx_ring->ena_bufs,
+ ena_rx_ctx.descs,
+@@ -1719,14 +1730,15 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ /* Packets was passed for transmission, unmap it
+ * from RX side.
+ */
+- if (xdp_verdict == XDP_TX || xdp_verdict == XDP_REDIRECT) {
++ if (xdp_verdict & ENA_XDP_FORWARDED) {
+ ena_unmap_rx_buff(rx_ring,
+ &rx_ring->rx_buffer_info[req_id]);
+ rx_ring->rx_buffer_info[req_id].page = NULL;
+ }
+ }
+- if (xdp_verdict != XDP_PASS) {
++ if (xdp_verdict != ENA_XDP_PASS) {
+ xdp_flags |= xdp_verdict;
++ total_len += ena_rx_ctx.ena_bufs[0].len;
+ res_budget--;
+ continue;
+ }
+@@ -1770,7 +1782,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ ena_refill_rx_bufs(rx_ring, refill_required);
+ }
+
+- if (xdp_flags & XDP_REDIRECT)
++ if (xdp_flags & ENA_XDP_REDIRECT)
+ xdp_do_flush_map();
+
+ return work_done;
+@@ -1827,8 +1839,9 @@ static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
+ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring)
+ {
++ u32 rx_interval = tx_ring->smoothed_interval;
+ struct ena_eth_io_intr_reg intr_reg;
+- u32 rx_interval = 0;
++
+ /* Rx ring can be NULL when for XDP tx queues which don't have an
+ * accompanying rx_ring pair.
+ */
+@@ -1866,20 +1879,27 @@ static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+ if (likely(tx_ring->cpu == cpu))
+ goto out;
+
++ tx_ring->cpu = cpu;
++ if (rx_ring)
++ rx_ring->cpu = cpu;
++
+ numa_node = cpu_to_node(cpu);
++
++ if (likely(tx_ring->numa_node == numa_node))
++ goto out;
++
+ put_cpu();
+
+ if (numa_node != NUMA_NO_NODE) {
+ ena_com_update_numa_node(tx_ring->ena_com_io_cq, numa_node);
+- if (rx_ring)
++ tx_ring->numa_node = numa_node;
++ if (rx_ring) {
++ rx_ring->numa_node = numa_node;
+ ena_com_update_numa_node(rx_ring->ena_com_io_cq,
+ numa_node);
++ }
+ }
+
+- tx_ring->cpu = cpu;
+- if (rx_ring)
+- rx_ring->cpu = cpu;
+-
+ return;
+ out:
+ put_cpu();
+@@ -2000,11 +2020,10 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
+ if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
+ ena_adjust_adaptive_rx_intr_moderation(ena_napi);
+
++ ena_update_ring_numa_node(tx_ring, rx_ring);
+ ena_unmask_interrupt(tx_ring, rx_ring);
+ }
+
+- ena_update_ring_numa_node(tx_ring, rx_ring);
+-
+ ret = rx_work_done;
+ } else {
+ ret = budget;
+@@ -2391,7 +2410,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
+ ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
+ ctx.msix_vector = msix_vector;
+ ctx.queue_size = tx_ring->ring_size;
+- ctx.numa_node = cpu_to_node(tx_ring->cpu);
++ ctx.numa_node = tx_ring->numa_node;
+
+ rc = ena_com_create_io_queue(ena_dev, &ctx);
+ if (rc) {
+@@ -2459,7 +2478,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
+ ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ ctx.msix_vector = msix_vector;
+ ctx.queue_size = rx_ring->ring_size;
+- ctx.numa_node = cpu_to_node(rx_ring->cpu);
++ ctx.numa_node = rx_ring->numa_node;
+
+ rc = ena_com_create_io_queue(ena_dev, &ctx);
+ if (rc) {
+@@ -2820,6 +2839,24 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
+ return dev_was_up ? ena_up(adapter) : 0;
+ }
+
++int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak)
++{
++ struct ena_ring *rx_ring;
++ int i;
++
++ if (rx_copybreak > min_t(u16, adapter->netdev->mtu, ENA_PAGE_SIZE))
++ return -EINVAL;
++
++ adapter->rx_copybreak = rx_copybreak;
++
++ for (i = 0; i < adapter->num_io_queues; i++) {
++ rx_ring = &adapter->rx_ring[i];
++ rx_ring->rx_copybreak = rx_copybreak;
++ }
++
++ return 0;
++}
++
+ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count)
+ {
+ struct ena_com_dev *ena_dev = adapter->ena_dev;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+index 0c39fc2fa345c..bf2a39c91c00d 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -273,9 +273,11 @@ struct ena_ring {
+ bool disable_meta_caching;
+ u16 no_interrupt_event_cnt;
+
+- /* cpu for TPH */
++ /* cpu and NUMA for TPH */
+ int cpu;
+- /* number of tx/rx_buffer_info's entries */
++ int numa_node;
++
++ /* number of tx/rx_buffer_info's entries */
+ int ring_size;
+
+ enum ena_admin_placement_policy_type tx_mem_queue_type;
+@@ -404,6 +406,8 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
+
+ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count);
+
++int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak);
++
+ int ena_get_sset_count(struct net_device *netdev, int sset);
+
+ enum ena_xdp_errors_t {
+@@ -412,6 +416,15 @@ enum ena_xdp_errors_t {
+ ENA_XDP_NO_ENOUGH_QUEUES,
+ };
+
++enum ENA_XDP_ACTIONS {
++ ENA_XDP_PASS = 0,
++ ENA_XDP_TX = BIT(0),
++ ENA_XDP_REDIRECT = BIT(1),
++ ENA_XDP_DROP = BIT(2)
++};
++
++#define ENA_XDP_FORWARDED (ENA_XDP_TX | ENA_XDP_REDIRECT)
++
+ static inline bool ena_xdp_present(struct ena_adapter *adapter)
+ {
+ return !!adapter->xdp_bpf_prog;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+index e6883d52d230c..555db1871ec9f 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+@@ -1064,6 +1064,9 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
+
+ devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
+
++ tasklet_kill(&pdata->tasklet_dev);
++ tasklet_kill(&pdata->tasklet_ecc);
++
+ if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
+ devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+index 22d4fc547a0a3..a9ccc4258ee50 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+@@ -447,8 +447,10 @@ static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
+ xgbe_i2c_disable(pdata);
+ xgbe_i2c_clear_all_interrupts(pdata);
+
+- if (pdata->dev_irq != pdata->i2c_irq)
++ if (pdata->dev_irq != pdata->i2c_irq) {
+ devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
++ tasklet_kill(&pdata->tasklet_i2c);
++ }
+ }
+
+ static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 4e97b48695220..0c5c1b1556830 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -1390,8 +1390,10 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
+ /* Disable auto-negotiation */
+ xgbe_an_disable_all(pdata);
+
+- if (pdata->dev_irq != pdata->an_irq)
++ if (pdata->dev_irq != pdata->an_irq) {
+ devm_free_irq(pdata->dev, pdata->an_irq, pdata);
++ tasklet_kill(&pdata->tasklet_an);
++ }
+
+ pdata->phy_if.phy_impl.stop(pdata);
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 818a028703c65..dc835f316d471 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -1005,9 +1005,7 @@ static bool hns3_can_use_tx_bounce(struct hns3_enet_ring *ring,
+ return false;
+
+ if (ALIGN(len, dma_get_cache_alignment()) > space) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_spare_full++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_spare_full);
+ return false;
+ }
+
+@@ -1024,9 +1022,7 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring,
+ return false;
+
+ if (space < HNS3_MAX_SGL_SIZE) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_spare_full++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_spare_full);
+ return false;
+ }
+
+@@ -1554,9 +1550,7 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
+
+ ret = hns3_handle_vtags(ring, skb);
+ if (unlikely(ret < 0)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_vlan_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_vlan_err);
+ return ret;
+ } else if (ret == HNS3_INNER_VLAN_TAG) {
+ inner_vtag = skb_vlan_tag_get(skb);
+@@ -1591,9 +1585,7 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
+
+ ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto);
+ if (unlikely(ret < 0)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_l4_proto_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_l4_proto_err);
+ return ret;
+ }
+
+@@ -1601,18 +1593,14 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
+ &type_cs_vlan_tso,
+ &ol_type_vlan_len_msec);
+ if (unlikely(ret < 0)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_l2l3l4_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_l2l3l4_err);
+ return ret;
+ }
+
+ ret = hns3_set_tso(skb, &paylen_ol4cs, &mss_hw_csum,
+ &type_cs_vlan_tso, &desc_cb->send_bytes);
+ if (unlikely(ret < 0)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_tso_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_tso_err);
+ return ret;
+ }
+ }
+@@ -1705,9 +1693,7 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
+ }
+
+ if (unlikely(dma_mapping_error(dev, dma))) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.sw_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, sw_err_cnt);
+ return -ENOMEM;
+ }
+
+@@ -1853,9 +1839,7 @@ static int hns3_skb_linearize(struct hns3_enet_ring *ring,
+ * recursion level of over HNS3_MAX_RECURSION_LEVEL.
+ */
+ if (bd_num == UINT_MAX) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.over_max_recursion++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, over_max_recursion);
+ return -ENOMEM;
+ }
+
+@@ -1864,16 +1848,12 @@ static int hns3_skb_linearize(struct hns3_enet_ring *ring,
+ */
+ if (skb->len > HNS3_MAX_TSO_SIZE ||
+ (!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.hw_limitation++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, hw_limitation);
+ return -ENOMEM;
+ }
+
+ if (__skb_linearize(skb)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.sw_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, sw_err_cnt);
+ return -ENOMEM;
+ }
+
+@@ -1903,9 +1883,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
+
+ bd_num = hns3_tx_bd_count(skb->len);
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_copy++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_copy);
+ }
+
+ out:
+@@ -1925,9 +1903,7 @@ out:
+ return bd_num;
+ }
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_busy++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_busy);
+
+ return -EBUSY;
+ }
+@@ -2012,9 +1988,7 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,
+ ring->pending_buf += num;
+
+ if (!doorbell) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_more++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_more);
+ return;
+ }
+
+@@ -2064,9 +2038,7 @@ static int hns3_handle_tx_bounce(struct hns3_enet_ring *ring,
+ ret = skb_copy_bits(skb, 0, buf, size);
+ if (unlikely(ret < 0)) {
+ hns3_tx_spare_rollback(ring, cb_len);
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.copy_bits_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, copy_bits_err);
+ return ret;
+ }
+
+@@ -2089,9 +2061,8 @@ static int hns3_handle_tx_bounce(struct hns3_enet_ring *ring,
+ dma_sync_single_for_device(ring_to_dev(ring), dma, size,
+ DMA_TO_DEVICE);
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_bounce++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_bounce);
++
+ return bd_num;
+ }
+
+@@ -2121,9 +2092,7 @@ static int hns3_handle_tx_sgl(struct hns3_enet_ring *ring,
+ nents = skb_to_sgvec(skb, sgt->sgl, 0, skb->len);
+ if (unlikely(nents < 0)) {
+ hns3_tx_spare_rollback(ring, cb_len);
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.skb2sgl_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, skb2sgl_err);
+ return -ENOMEM;
+ }
+
+@@ -2132,9 +2101,7 @@ static int hns3_handle_tx_sgl(struct hns3_enet_ring *ring,
+ DMA_TO_DEVICE);
+ if (unlikely(!sgt->nents)) {
+ hns3_tx_spare_rollback(ring, cb_len);
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.map_sg_err++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, map_sg_err);
+ return -ENOMEM;
+ }
+
+@@ -2146,10 +2113,7 @@ static int hns3_handle_tx_sgl(struct hns3_enet_ring *ring,
+ for (i = 0; i < sgt->nents; i++)
+ bd_num += hns3_fill_desc(ring, sg_dma_address(sgt->sgl + i),
+ sg_dma_len(sgt->sgl + i));
+-
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.tx_sgl++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, tx_sgl);
+
+ return bd_num;
+ }
+@@ -2188,9 +2152,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+ if (skb_put_padto(skb, HNS3_MIN_TX_LEN)) {
+ hns3_tx_doorbell(ring, 0, !netdev_xmit_more());
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.sw_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, sw_err_cnt);
+
+ return NETDEV_TX_OK;
+ }
+@@ -3522,17 +3484,13 @@ static bool hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
+ for (i = 0; i < cleand_count; i++) {
+ desc_cb = &ring->desc_cb[ring->next_to_use];
+ if (desc_cb->reuse_flag) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.reuse_pg_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, reuse_pg_cnt);
+
+ hns3_reuse_buffer(ring, ring->next_to_use);
+ } else {
+ ret = hns3_alloc_and_map_buffer(ring, &res_cbs);
+ if (ret) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.sw_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, sw_err_cnt);
+
+ hns3_rl_err(ring_to_netdev(ring),
+ "alloc rx buffer failed: %d\n",
+@@ -3544,9 +3502,7 @@ static bool hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
+ }
+ hns3_replace_buffer(ring, ring->next_to_use, &res_cbs);
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.non_reuse_pg++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, non_reuse_pg);
+ }
+
+ ring_ptr_move_fw(ring, next_to_use);
+@@ -3561,6 +3517,34 @@ static bool hns3_can_reuse_page(struct hns3_desc_cb *cb)
+ return page_count(cb->priv) == cb->pagecnt_bias;
+ }
+
++static int hns3_handle_rx_copybreak(struct sk_buff *skb, int i,
++ struct hns3_enet_ring *ring,
++ int pull_len,
++ struct hns3_desc_cb *desc_cb)
++{
++ struct hns3_desc *desc = &ring->desc[ring->next_to_clean];
++ u32 frag_offset = desc_cb->page_offset + pull_len;
++ int size = le16_to_cpu(desc->rx.size);
++ u32 frag_size = size - pull_len;
++ void *frag = napi_alloc_frag(frag_size);
++
++ if (unlikely(!frag)) {
++ hns3_ring_stats_update(ring, frag_alloc_err);
++
++ hns3_rl_err(ring_to_netdev(ring),
++ "failed to allocate rx frag\n");
++ return -ENOMEM;
++ }
++
++ desc_cb->reuse_flag = 1;
++ memcpy(frag, desc_cb->buf + frag_offset, frag_size);
++ skb_add_rx_frag(skb, i, virt_to_page(frag),
++ offset_in_page(frag), frag_size, frag_size);
++
++ hns3_ring_stats_update(ring, frag_alloc);
++ return 0;
++}
++
+ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
+ struct hns3_enet_ring *ring, int pull_len,
+ struct hns3_desc_cb *desc_cb)
+@@ -3570,6 +3554,7 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
+ int size = le16_to_cpu(desc->rx.size);
+ u32 truesize = hns3_buf_size(ring);
+ u32 frag_size = size - pull_len;
++ int ret = 0;
+ bool reused;
+
+ if (ring->page_pool) {
+@@ -3604,27 +3589,9 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
+ desc_cb->page_offset = 0;
+ desc_cb->reuse_flag = 1;
+ } else if (frag_size <= ring->rx_copybreak) {
+- void *frag = napi_alloc_frag(frag_size);
+-
+- if (unlikely(!frag)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.frag_alloc_err++;
+- u64_stats_update_end(&ring->syncp);
+-
+- hns3_rl_err(ring_to_netdev(ring),
+- "failed to allocate rx frag\n");
+- goto out;
+- }
+-
+- desc_cb->reuse_flag = 1;
+- memcpy(frag, desc_cb->buf + frag_offset, frag_size);
+- skb_add_rx_frag(skb, i, virt_to_page(frag),
+- offset_in_page(frag), frag_size, frag_size);
+-
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.frag_alloc++;
+- u64_stats_update_end(&ring->syncp);
+- return;
++ ret = hns3_handle_rx_copybreak(skb, i, ring, pull_len, desc_cb);
++ if (!ret)
++ return;
+ }
+
+ out:
+@@ -3700,20 +3667,16 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 l234info)
+ return 0;
+ }
+
+-static bool hns3_checksum_complete(struct hns3_enet_ring *ring,
++static void hns3_checksum_complete(struct hns3_enet_ring *ring,
+ struct sk_buff *skb, u32 ptype, u16 csum)
+ {
+ if (ptype == HNS3_INVALID_PTYPE ||
+ hns3_rx_ptype_tbl[ptype].ip_summed != CHECKSUM_COMPLETE)
+- return false;
++ return;
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.csum_complete++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, csum_complete);
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ skb->csum = csum_unfold((__force __sum16)csum);
+-
+- return true;
+ }
+
+ static void hns3_rx_handle_csum(struct sk_buff *skb, u32 l234info,
+@@ -3773,8 +3736,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
+ ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
+ HNS3_RXD_PTYPE_S);
+
+- if (hns3_checksum_complete(ring, skb, ptype, csum))
+- return;
++ hns3_checksum_complete(ring, skb, ptype, csum);
+
+ /* check if hardware has done checksum */
+ if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
+@@ -3783,9 +3745,8 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
+ if (unlikely(l234info & (BIT(HNS3_RXD_L3E_B) | BIT(HNS3_RXD_L4E_B) |
+ BIT(HNS3_RXD_OL3E_B) |
+ BIT(HNS3_RXD_OL4E_B)))) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.l3l4_csum_err++;
+- u64_stats_update_end(&ring->syncp);
++ skb->ip_summed = CHECKSUM_NONE;
++ hns3_ring_stats_update(ring, l3l4_csum_err);
+
+ return;
+ }
+@@ -3876,10 +3837,7 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length,
+ skb = ring->skb;
+ if (unlikely(!skb)) {
+ hns3_rl_err(netdev, "alloc rx skb fail\n");
+-
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.sw_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, sw_err_cnt);
+
+ return -ENOMEM;
+ }
+@@ -3910,9 +3868,7 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length,
+ if (ring->page_pool)
+ skb_mark_for_recycle(skb);
+
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.seg_pkt_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, seg_pkt_cnt);
+
+ ring->pull_len = eth_get_headlen(netdev, va, HNS3_RX_HEAD_SIZE);
+ __skb_put(skb, ring->pull_len);
+@@ -4104,9 +4060,7 @@ static int hns3_handle_bdinfo(struct hns3_enet_ring *ring, struct sk_buff *skb)
+ ret = hns3_set_gro_and_checksum(ring, skb, l234info,
+ bd_base_info, ol_info, csum);
+ if (unlikely(ret)) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.rx_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, rx_err_cnt);
+ return ret;
+ }
+
+@@ -5318,9 +5272,7 @@ static int hns3_clear_rx_ring(struct hns3_enet_ring *ring)
+ if (!ring->desc_cb[ring->next_to_use].reuse_flag) {
+ ret = hns3_alloc_and_map_buffer(ring, &res_cbs);
+ if (ret) {
+- u64_stats_update_begin(&ring->syncp);
+- ring->stats.sw_err_cnt++;
+- u64_stats_update_end(&ring->syncp);
++ hns3_ring_stats_update(ring, sw_err_cnt);
+ /* if alloc new buffer fail, exit directly
+ * and reclear in up flow.
+ */
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+index f09a61d9c6264..91b656adaacb0 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+@@ -654,6 +654,13 @@ static inline bool hns3_nic_resetting(struct net_device *netdev)
+
+ #define hns3_buf_size(_ring) ((_ring)->buf_size)
+
++#define hns3_ring_stats_update(ring, cnt) do { \
++ typeof(ring) (tmp) = (ring); \
++ u64_stats_update_begin(&(tmp)->syncp); \
++ ((tmp)->stats.cnt)++; \
++ u64_stats_update_end(&(tmp)->syncp); \
++} while (0) \
++
+ static inline unsigned int hns3_page_order(struct hns3_enet_ring *ring)
+ {
+ #if (PAGE_SIZE < 8192)
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 2102b38b9c350..f4d58fcdba272 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -12825,60 +12825,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
+ return ret;
+ }
+
+-static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
++static int hclge_sync_vport_promisc_mode(struct hclge_vport *vport)
+ {
+- struct hclge_vport *vport = &hdev->vport[0];
+ struct hnae3_handle *handle = &vport->nic;
++ struct hclge_dev *hdev = vport->back;
++ bool uc_en = false;
++ bool mc_en = false;
+ u8 tmp_flags;
++ bool bc_en;
+ int ret;
+- u16 i;
+
+ if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
+ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
+ vport->last_promisc_flags = vport->overflow_promisc_flags;
+ }
+
+- if (test_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state)) {
++ if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
++ &vport->state))
++ return 0;
++
++ /* for PF */
++ if (!vport->vport_id) {
+ tmp_flags = handle->netdev_flags | vport->last_promisc_flags;
+ ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
+ tmp_flags & HNAE3_MPE);
+- if (!ret) {
+- clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+- &vport->state);
++ if (!ret)
+ set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
+ &vport->state);
+- }
++ else
++ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
++ &vport->state);
++ return ret;
+ }
+
+- for (i = 1; i < hdev->num_alloc_vport; i++) {
+- bool uc_en = false;
+- bool mc_en = false;
+- bool bc_en;
++ /* for VF */
++ if (vport->vf_info.trusted) {
++ uc_en = vport->vf_info.request_uc_en > 0 ||
++ vport->overflow_promisc_flags & HNAE3_OVERFLOW_UPE;
++ mc_en = vport->vf_info.request_mc_en > 0 ||
++ vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE;
++ }
++ bc_en = vport->vf_info.request_bc_en > 0;
+
+- vport = &hdev->vport[i];
++ ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
++ mc_en, bc_en);
++ if (ret) {
++ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
++ return ret;
++ }
++ hclge_set_vport_vlan_fltr_change(vport);
+
+- if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+- &vport->state))
+- continue;
++ return 0;
++}
+
+- if (vport->vf_info.trusted) {
+- uc_en = vport->vf_info.request_uc_en > 0 ||
+- vport->overflow_promisc_flags &
+- HNAE3_OVERFLOW_UPE;
+- mc_en = vport->vf_info.request_mc_en > 0 ||
+- vport->overflow_promisc_flags &
+- HNAE3_OVERFLOW_MPE;
+- }
+- bc_en = vport->vf_info.request_bc_en > 0;
++static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
++{
++ struct hclge_vport *vport;
++ int ret;
++ u16 i;
+
+- ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
+- mc_en, bc_en);
+- if (ret) {
+- set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+- &vport->state);
++ for (i = 0; i < hdev->num_alloc_vport; i++) {
++ vport = &hdev->vport[i];
++
++ ret = hclge_sync_vport_promisc_mode(vport);
++ if (ret)
+ return;
+- }
+- hclge_set_vport_vlan_fltr_change(vport);
+ }
+ }
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 21678c12afa26..3c1ff33132213 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -3258,7 +3258,8 @@ static int hclgevf_pci_reset(struct hclgevf_dev *hdev)
+ struct pci_dev *pdev = hdev->pdev;
+ int ret = 0;
+
+- if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
++ if ((hdev->reset_type == HNAE3_VF_FULL_RESET ||
++ hdev->reset_type == HNAE3_FLR_RESET) &&
+ test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
+ hclgevf_misc_irq_uninit(hdev);
+ hclgevf_uninit_msi(hdev);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index e14624caddc67..f6306eedd59b9 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -962,6 +962,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ rbpool = cq->rbpool;
+ free_ptrs = cq->pool_ptrs;
+
++ get_cpu();
+ while (cq->pool_ptrs) {
+ if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) {
+ /* Schedule a WQ if we fails to free atleast half of the
+@@ -981,6 +982,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
+ cq->pool_ptrs--;
+ }
++ put_cpu();
+ cq->refill_task_sched = false;
+ }
+
+@@ -1314,6 +1316,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ if (err)
+ goto fail;
+
++ get_cpu();
+ /* Allocate pointers and free them to aura/pool */
+ for (qidx = 0; qidx < hw->tx_queues; qidx++) {
+ pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx);
+@@ -1322,18 +1325,24 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ sq = &qset->sq[qidx];
+ sq->sqb_count = 0;
+ sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL);
+- if (!sq->sqb_ptrs)
+- return -ENOMEM;
++ if (!sq->sqb_ptrs) {
++ err = -ENOMEM;
++ goto err_mem;
++ }
+
+ for (ptr = 0; ptr < num_sqbs; ptr++) {
+- if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
+- return -ENOMEM;
++ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
++ if (err)
++ goto err_mem;
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
+ sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
+ }
+ }
+
+- return 0;
++err_mem:
++ put_cpu();
++ return err ? -ENOMEM : 0;
++
+ fail:
+ otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ otx2_aura_pool_free(pfvf);
+@@ -1372,18 +1381,21 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf)
+ if (err)
+ goto fail;
+
++ get_cpu();
+ /* Allocate pointers and free them to aura/pool */
+ for (pool_id = 0; pool_id < hw->rqpool_cnt; pool_id++) {
+ pool = &pfvf->qset.pool[pool_id];
+ for (ptr = 0; ptr < num_ptrs; ptr++) {
+- if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
+- return -ENOMEM;
++ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
++ if (err)
++ goto err_mem;
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id,
+ bufptr + OTX2_HEAD_ROOM);
+ }
+ }
+-
+- return 0;
++err_mem:
++ put_cpu();
++ return err ? -ENOMEM : 0;
+ fail:
+ otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ otx2_aura_pool_free(pfvf);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+index 700c463ea3679..a8d7f07ee2ca0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+@@ -188,12 +188,19 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ int err;
+
+ list_for_each_entry(flow, flow_list, tmp_list) {
+- if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
++ if (!mlx5e_is_offloaded_flow(flow))
+ continue;
+ attr = flow->attr;
+ esw_attr = attr->esw_attr;
+ spec = &attr->parse_attr->spec;
+
++ /* Clear pkt_reformat before checking slow path flag. Because
++ * in next iteration, the same flow is already set slow path
++ * flag, but still need to clear the pkt_reformat.
++ */
++ if (flow_flag_test(flow, SLOW))
++ continue;
++
+ /* update from encap rule to slow path rule */
+ rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+ /* mark the flow's encap dest as non-valid */
+@@ -1342,7 +1349,7 @@ static void mlx5e_reoffload_encap(struct mlx5e_priv *priv,
+ continue;
+ }
+
+- err = mlx5e_tc_add_flow_mod_hdr(priv, parse_attr, flow);
++ err = mlx5e_tc_add_flow_mod_hdr(priv, flow, attr);
+ if (err) {
+ mlx5_core_warn(priv->mdev, "Failed to update flow mod_hdr err=%d",
+ err);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index c1c4f380803a1..be19f5cf9d150 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -977,7 +977,7 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
+ sq->channel = c;
+ sq->uar_map = mdev->mlx5e_res.hw_objs.bfreg.map;
+ sq->min_inline_mode = params->tx_min_inline_mode;
+- sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
++ sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
+ sq->xsk_pool = xsk_pool;
+
+ sq->stats = sq->xsk_pool ?
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index 843c8435387f3..8f2f99689abac 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1342,10 +1342,10 @@ int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *ro
+ }
+
+ int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv,
+- struct mlx5e_tc_flow_parse_attr *parse_attr,
+- struct mlx5e_tc_flow *flow)
++ struct mlx5e_tc_flow *flow,
++ struct mlx5_flow_attr *attr)
+ {
+- struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts = &parse_attr->mod_hdr_acts;
++ struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts = &attr->parse_attr->mod_hdr_acts;
+ struct mlx5_modify_hdr *mod_hdr;
+
+ mod_hdr = mlx5_modify_header_alloc(priv->mdev,
+@@ -1355,8 +1355,8 @@ int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv,
+ if (IS_ERR(mod_hdr))
+ return PTR_ERR(mod_hdr);
+
+- WARN_ON(flow->attr->modify_hdr);
+- flow->attr->modify_hdr = mod_hdr;
++ WARN_ON(attr->modify_hdr);
++ attr->modify_hdr = mod_hdr;
+
+ return 0;
+ }
+@@ -1457,7 +1457,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
+ !(attr->ct_attr.ct_action & TCA_CT_ACT_CLEAR)) {
+ if (vf_tun) {
+- err = mlx5e_tc_add_flow_mod_hdr(priv, parse_attr, flow);
++ err = mlx5e_tc_add_flow_mod_hdr(priv, flow, attr);
+ if (err)
+ goto err_out;
+ } else {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+index 1a4cd882f0fba..f48af82781f88 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+@@ -241,8 +241,8 @@ int mlx5e_tc_match_to_reg_set_and_get_id(struct mlx5_core_dev *mdev,
+ u32 data);
+
+ int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv,
+- struct mlx5e_tc_flow_parse_attr *parse_attr,
+- struct mlx5e_tc_flow *flow);
++ struct mlx5e_tc_flow *flow,
++ struct mlx5_flow_attr *attr);
+
+ int alloc_mod_hdr_actions(struct mlx5_core_dev *mdev,
+ int namespace,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+index 60a73990017c2..6b4c9ffad95b2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+@@ -67,6 +67,7 @@ static void esw_acl_egress_lgcy_groups_destroy(struct mlx5_vport *vport)
+ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport)
+ {
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ struct mlx5_flow_destination drop_ctr_dst = {};
+ struct mlx5_flow_destination *dst = NULL;
+ struct mlx5_fc *drop_counter = NULL;
+@@ -77,6 +78,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ */
+ int table_size = 2;
+ int dest_num = 0;
++ int actions_flag;
+ int err = 0;
+
+ if (vport->egress.legacy.drop_counter) {
+@@ -119,8 +121,11 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ vport->vport, vport->info.vlan, vport->info.qos);
+
+ /* Allowed vlan rule */
++ actions_flag = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
++ if (vst_mode_steering)
++ actions_flag |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
+ err = esw_egress_acl_vlan_create(esw, vport, NULL, vport->info.vlan,
+- MLX5_FLOW_CONTEXT_ACTION_ALLOW);
++ actions_flag);
+ if (err)
+ goto out;
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+index b1a5199260f69..093ed86a0acd8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+@@ -139,11 +139,14 @@ static void esw_acl_ingress_lgcy_groups_destroy(struct mlx5_vport *vport)
+ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport)
+ {
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ struct mlx5_flow_destination drop_ctr_dst = {};
+ struct mlx5_flow_destination *dst = NULL;
+ struct mlx5_flow_act flow_act = {};
+ struct mlx5_flow_spec *spec = NULL;
+ struct mlx5_fc *counter = NULL;
++ bool vst_check_cvlan = false;
++ bool vst_push_cvlan = false;
+ /* The ingress acl table contains 4 groups
+ * (2 active rules at the same time -
+ * 1 allow rule from one of the first 3 groups.
+@@ -203,7 +206,26 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ goto out;
+ }
+
+- if (vport->info.vlan || vport->info.qos)
++ if ((vport->info.vlan || vport->info.qos)) {
++ if (vst_mode_steering)
++ vst_push_cvlan = true;
++ else if (!MLX5_CAP_ESW(esw->dev, vport_cvlan_insert_always))
++ vst_check_cvlan = true;
++ }
++
++ if (vst_check_cvlan || vport->info.spoofchk)
++ spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
++
++ /* Create ingress allow rule */
++ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
++ if (vst_push_cvlan) {
++ flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
++ flow_act.vlan[0].prio = vport->info.qos;
++ flow_act.vlan[0].vid = vport->info.vlan;
++ flow_act.vlan[0].ethtype = ETH_P_8021Q;
++ }
++
++ if (vst_check_cvlan)
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.cvlan_tag);
+
+@@ -218,9 +240,6 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ ether_addr_copy(smac_v, vport->info.mac);
+ }
+
+- /* Create ingress allow rule */
+- spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
+ vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec,
+ &flow_act, NULL, 0);
+ if (IS_ERR(vport->ingress.allow_rule)) {
+@@ -232,6 +251,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ goto out;
+ }
+
++ if (!vst_check_cvlan && !vport->info.spoofchk)
++ goto out;
++
+ memset(&flow_act, 0, sizeof(flow_act));
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
+ /* Attach drop flow counter */
+@@ -257,7 +279,8 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ return 0;
+
+ out:
+- esw_acl_ingress_lgcy_cleanup(esw, vport);
++ if (err)
++ esw_acl_ingress_lgcy_cleanup(esw, vport);
+ kvfree(spec);
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 51a8cecc4a7ce..2b9278002354c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -160,10 +160,17 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u16 vport,
+ esw_vport_context.vport_cvlan_strip, 1);
+
+ if (set_flags & SET_VLAN_INSERT) {
+- /* insert only if no vlan in packet */
+- MLX5_SET(modify_esw_vport_context_in, in,
+- esw_vport_context.vport_cvlan_insert, 1);
+-
++ if (MLX5_CAP_ESW(dev, vport_cvlan_insert_always)) {
++ /* insert either if vlan exist in packet or not */
++ MLX5_SET(modify_esw_vport_context_in, in,
++ esw_vport_context.vport_cvlan_insert,
++ MLX5_VPORT_CVLAN_INSERT_ALWAYS);
++ } else {
++ /* insert only if no vlan in packet */
++ MLX5_SET(modify_esw_vport_context_in, in,
++ esw_vport_context.vport_cvlan_insert,
++ MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN);
++ }
+ MLX5_SET(modify_esw_vport_context_in, in,
+ esw_vport_context.cvlan_pcp, qos);
+ MLX5_SET(modify_esw_vport_context_in, in,
+@@ -773,6 +780,7 @@ static void esw_vport_cleanup_acl(struct mlx5_eswitch *esw,
+
+ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+ {
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ u16 vport_num = vport->vport;
+ int flags;
+ int err;
+@@ -802,8 +810,9 @@ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+
+ flags = (vport->info.vlan || vport->info.qos) ?
+ SET_VLAN_STRIP | SET_VLAN_INSERT : 0;
+- modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
+- vport->info.qos, flags);
++ if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering)
++ modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
++ vport->info.qos, flags);
+
+ return 0;
+ }
+@@ -1846,6 +1855,7 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ u16 vport, u16 vlan, u8 qos, u8 set_flags)
+ {
+ struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ int err = 0;
+
+ if (IS_ERR(evport))
+@@ -1853,9 +1863,11 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ if (vlan > 4095 || qos > 7)
+ return -EINVAL;
+
+- err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
+- if (err)
+- return err;
++ if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering) {
++ err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
++ if (err)
++ return err;
++ }
+
+ evport->info.vlan = vlan;
+ evport->info.qos = qos;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+index 2c7444101bb93..0e2c9e6fccb67 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+@@ -505,6 +505,12 @@ static inline bool mlx5_esw_qos_enabled(struct mlx5_eswitch *esw)
+ return esw->qos.enabled;
+ }
+
++static inline bool esw_vst_mode_is_steering(struct mlx5_eswitch *esw)
++{
++ return (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, pop_vlan) &&
++ MLX5_CAP_ESW_INGRESS_ACL(esw->dev, push_vlan));
++}
++
+ static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
+ u8 vlan_depth)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+index 037e18dd4be0e..3dceab45986d2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -614,6 +614,12 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
+ priv = container_of(health, struct mlx5_priv, health);
+ dev = container_of(priv, struct mlx5_core_dev, priv);
+
++ mutex_lock(&dev->intf_state_mutex);
++ if (test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) {
++ mlx5_core_err(dev, "health works are not permitted at this stage\n");
++ return;
++ }
++ mutex_unlock(&dev->intf_state_mutex);
+ enter_error_state(dev, false);
+ if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) {
+ if (mlx5_health_try_recover(dev))
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+index cfde0a45b8b8a..10940b8dc83e2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+@@ -70,6 +70,10 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
+ params->packet_merge.type = MLX5E_PACKET_MERGE_NONE;
+ params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
+ params->tunneled_offload_en = false;
++
++ /* CQE compression is not supported for IPoIB */
++ params->rx_cqe_compress_def = false;
++ MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
+ }
+
+ /* Called directly after IPoIB netdevice was created to initialize SW structs */
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 19c11d33f4b68..145e56f5eeee1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -928,6 +928,8 @@ err_rl_cleanup:
+ err_tables_cleanup:
+ mlx5_geneve_destroy(dev->geneve);
+ mlx5_vxlan_destroy(dev->vxlan);
++ mlx5_cleanup_clock(dev);
++ mlx5_cleanup_reserved_gids(dev);
+ mlx5_cq_debugfs_cleanup(dev);
+ mlx5_fw_reset_cleanup(dev);
+ err_events_cleanup:
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index 0463f20da17b3..174d89ee63749 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -779,7 +779,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
+ if (err)
+ goto cleanup_config;
+
+- if (!of_get_mac_address(np, sparx5->base_mac)) {
++ if (of_get_mac_address(np, sparx5->base_mac)) {
+ dev_info(sparx5->dev, "MAC addr was not set, use random MAC\n");
+ eth_random_addr(sparx5->base_mac);
+ sparx5->base_mac[5] = 0;
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+index 27dffa299ca6f..7c3cf9ad4563c 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+@@ -2505,7 +2505,13 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
+ goto disable_mbx_intr;
+
+ qlcnic_83xx_clear_function_resources(adapter);
+- qlcnic_dcb_enable(adapter->dcb);
++
++ err = qlcnic_dcb_enable(adapter->dcb);
++ if (err) {
++ qlcnic_dcb_free(adapter->dcb);
++ goto disable_mbx_intr;
++ }
++
+ qlcnic_83xx_initialize_nic(adapter, 1);
+ qlcnic_dcb_get_info(adapter->dcb);
+
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+index 7519773eaca6e..22afa2be85fdb 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+@@ -41,11 +41,6 @@ struct qlcnic_dcb {
+ unsigned long state;
+ };
+
+-static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
+-{
+- kfree(dcb);
+-}
+-
+ static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
+ {
+ if (dcb && dcb->ops->get_hw_capability)
+@@ -112,9 +107,8 @@ static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
+ dcb->ops->init_dcbnl_ops(dcb);
+ }
+
+-static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
++static inline int qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
+ {
+- if (dcb && qlcnic_dcb_attach(dcb))
+- qlcnic_clear_dcb_ops(dcb);
++ return dcb ? qlcnic_dcb_attach(dcb) : 0;
+ }
+ #endif
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+index 75960a29f80ea..cec07d5bbe67a 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+@@ -2616,7 +2616,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ "Device does not support MSI interrupts\n");
+
+ if (qlcnic_82xx_check(adapter)) {
+- qlcnic_dcb_enable(adapter->dcb);
++ err = qlcnic_dcb_enable(adapter->dcb);
++ if (err) {
++ qlcnic_dcb_free(adapter->dcb);
++ dev_err(&pdev->dev, "Failed to enable DCB\n");
++ goto err_out_free_hw;
++ }
++
+ qlcnic_dcb_get_info(adapter->dcb);
+ err = qlcnic_setup_intr(adapter);
+
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 77a19336abec8..c89bcdd15f164 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -2378,11 +2378,11 @@ static int ravb_remove(struct platform_device *pdev)
+ priv->desc_bat_dma);
+ /* Set reset mode */
+ ravb_write(ndev, CCC_OPC_RESET, CCC);
+- pm_runtime_put_sync(&pdev->dev);
+ unregister_netdev(ndev);
+ netif_napi_del(&priv->napi[RAVB_NC]);
+ netif_napi_del(&priv->napi[RAVB_BE]);
+ ravb_mdio_release(priv);
++ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ reset_control_assert(priv->rstc);
+ free_netdev(ndev);
+diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
+index 8dcb49ed1f3d9..7fd9fe6a602bc 100644
+--- a/drivers/net/phy/xilinx_gmii2rgmii.c
++++ b/drivers/net/phy/xilinx_gmii2rgmii.c
+@@ -105,6 +105,7 @@ static int xgmiitorgmii_probe(struct mdio_device *mdiodev)
+
+ if (!priv->phy_dev->drv) {
+ dev_info(dev, "Attached phy not ready\n");
++ put_device(&priv->phy_dev->mdio.dev);
+ return -EPROBE_DEFER;
+ }
+
+diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
+index bedd36ab5cf01..e5f6614da5acc 100644
+--- a/drivers/net/usb/rndis_host.c
++++ b/drivers/net/usb/rndis_host.c
+@@ -255,7 +255,8 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
+
+ off = le32_to_cpu(u.get_c->offset);
+ len = le32_to_cpu(u.get_c->len);
+- if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
++ if (unlikely((off > CONTROL_BUFFER_SIZE - 8) ||
++ (len > CONTROL_BUFFER_SIZE - 8 - off)))
+ goto response_error;
+
+ if (*reply_len != -1 && len != *reply_len)
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 64fa8e9c0a22b..41cb9179e8b79 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -916,6 +916,9 @@ static int veth_poll(struct napi_struct *napi, int budget)
+ xdp_set_return_frame_no_direct();
+ done = veth_xdp_rcv(rq, budget, &bq, &stats);
+
++ if (stats.xdp_redirect > 0)
++ xdp_do_flush();
++
+ if (done < budget && napi_complete_done(napi, done)) {
+ /* Write rx_notify_masked before reading ptr_ring */
+ smp_store_mb(rq->rx_notify_masked, false);
+@@ -929,8 +932,6 @@ static int veth_poll(struct napi_struct *napi, int budget)
+
+ if (stats.xdp_tx > 0)
+ veth_xdp_flush(rq, &bq);
+- if (stats.xdp_redirect > 0)
+- xdp_do_flush();
+ xdp_clear_return_frame_no_direct();
+
+ return done;
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index 21896e2213004..b88092a6bc851 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -1242,6 +1242,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ (le32_to_cpu(gdesc->dword[3]) &
+ VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ if ((le32_to_cpu(gdesc->dword[0]) &
++ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
++ skb->csum_level = 1;
++ }
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
+ !(le32_to_cpu(gdesc->dword[0]) &
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
+@@ -1251,6 +1255,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ } else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
+ (1 << VMXNET3_RCD_TUC_SHIFT))) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ if ((le32_to_cpu(gdesc->dword[0]) &
++ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
++ skb->csum_level = 1;
++ }
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
+ !(le32_to_cpu(gdesc->dword[0]) &
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
+diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c
+index 6c0727fc4abd9..cb4efbfd0811f 100644
+--- a/drivers/net/wireless/microchip/wilc1000/sdio.c
++++ b/drivers/net/wireless/microchip/wilc1000/sdio.c
+@@ -20,6 +20,7 @@ static const struct sdio_device_id wilc_sdio_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
+ { },
+ };
++MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);
+
+ #define WILC_SDIO_BLOCK_SIZE 512
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 2d5b5e0fb66a3..672f53d5651ad 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1113,6 +1113,18 @@ static u32 nvme_known_admin_effects(u8 opcode)
+ return 0;
+ }
+
++static u32 nvme_known_nvm_effects(u8 opcode)
++{
++ switch (opcode) {
++ case nvme_cmd_write:
++ case nvme_cmd_write_zeroes:
++ case nvme_cmd_write_uncor:
++ return NVME_CMD_EFFECTS_LBCC;
++ default:
++ return 0;
++ }
++}
++
+ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ {
+ u32 effects = 0;
+@@ -1120,16 +1132,24 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ if (ns) {
+ if (ns->head->effects)
+ effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
++ if (ns->head->ids.csi == NVME_CAP_CSS_NVM)
++ effects |= nvme_known_nvm_effects(opcode);
+ if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))
+ dev_warn_once(ctrl->device,
+- "IO command:%02x has unhandled effects:%08x\n",
++ "IO command:%02x has unusual effects:%08x\n",
+ opcode, effects);
+- return 0;
+- }
+
+- if (ctrl->effects)
+- effects = le32_to_cpu(ctrl->effects->acs[opcode]);
+- effects |= nvme_known_admin_effects(opcode);
++ /*
++ * NVME_CMD_EFFECTS_CSE_MASK causes a freeze all I/O queues,
++ * which would deadlock when done on an I/O command. Note that
++ * We already warn about an unusual effect above.
++ */
++ effects &= ~NVME_CMD_EFFECTS_CSE_MASK;
++ } else {
++ if (ctrl->effects)
++ effects = le32_to_cpu(ctrl->effects->acs[opcode]);
++ effects |= nvme_known_admin_effects(opcode);
++ }
+
+ return effects;
+ }
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 7f52b2b179b8c..39ca48babbe82 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -799,7 +799,7 @@ static inline void nvme_trace_bio_complete(struct request *req)
+ {
+ struct nvme_ns *ns = req->q->queuedata;
+
+- if (req->cmd_flags & REQ_NVME_MPATH)
++ if ((req->cmd_flags & REQ_NVME_MPATH) && req->bio)
+ trace_block_bio_complete(ns->head->disk->queue, req->bio);
+ }
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index d49df71236771..0165e65cf5480 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -33,7 +33,7 @@
+ #define SQ_SIZE(q) ((q)->q_depth << (q)->sqes)
+ #define CQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_completion))
+
+-#define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc))
++#define SGES_PER_PAGE (NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc))
+
+ /*
+ * These can be higher, but we need to ensure that any command doesn't
+@@ -142,9 +142,9 @@ struct nvme_dev {
+ mempool_t *iod_mempool;
+
+ /* shadow doorbell buffer support: */
+- u32 *dbbuf_dbs;
++ __le32 *dbbuf_dbs;
+ dma_addr_t dbbuf_dbs_dma_addr;
+- u32 *dbbuf_eis;
++ __le32 *dbbuf_eis;
+ dma_addr_t dbbuf_eis_dma_addr;
+
+ /* host memory buffer support: */
+@@ -208,10 +208,10 @@ struct nvme_queue {
+ #define NVMEQ_SQ_CMB 1
+ #define NVMEQ_DELETE_ERROR 2
+ #define NVMEQ_POLLED 3
+- u32 *dbbuf_sq_db;
+- u32 *dbbuf_cq_db;
+- u32 *dbbuf_sq_ei;
+- u32 *dbbuf_cq_ei;
++ __le32 *dbbuf_sq_db;
++ __le32 *dbbuf_cq_db;
++ __le32 *dbbuf_sq_ei;
++ __le32 *dbbuf_cq_ei;
+ struct completion delete_done;
+ };
+
+@@ -332,11 +332,11 @@ static inline int nvme_dbbuf_need_event(u16 event_idx, u16 new_idx, u16 old)
+ }
+
+ /* Update dbbuf and return true if an MMIO is required */
+-static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+- volatile u32 *dbbuf_ei)
++static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
++ volatile __le32 *dbbuf_ei)
+ {
+ if (dbbuf_db) {
+- u16 old_value;
++ u16 old_value, event_idx;
+
+ /*
+ * Ensure that the queue is written before updating
+@@ -344,8 +344,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ */
+ wmb();
+
+- old_value = *dbbuf_db;
+- *dbbuf_db = value;
++ old_value = le32_to_cpu(*dbbuf_db);
++ *dbbuf_db = cpu_to_le32(value);
+
+ /*
+ * Ensure that the doorbell is updated before reading the event
+@@ -355,7 +355,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ */
+ mb();
+
+- if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
++ event_idx = le32_to_cpu(*dbbuf_ei);
++ if (!nvme_dbbuf_need_event(event_idx, value, old_value))
+ return false;
+ }
+
+@@ -369,9 +370,9 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ */
+ static int nvme_pci_npages_prp(void)
+ {
+- unsigned nprps = DIV_ROUND_UP(NVME_MAX_KB_SZ + NVME_CTRL_PAGE_SIZE,
+- NVME_CTRL_PAGE_SIZE);
+- return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
++ unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
++ unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
++ return DIV_ROUND_UP(8 * nprps, NVME_CTRL_PAGE_SIZE - 8);
+ }
+
+ /*
+@@ -381,7 +382,7 @@ static int nvme_pci_npages_prp(void)
+ static int nvme_pci_npages_sgl(void)
+ {
+ return DIV_ROUND_UP(NVME_MAX_SEGS * sizeof(struct nvme_sgl_desc),
+- PAGE_SIZE);
++ NVME_CTRL_PAGE_SIZE);
+ }
+
+ static size_t nvme_pci_iod_alloc_size(void)
+@@ -731,7 +732,7 @@ static void nvme_pci_sgl_set_seg(struct nvme_sgl_desc *sge,
+ sge->length = cpu_to_le32(entries * sizeof(*sge));
+ sge->type = NVME_SGL_FMT_LAST_SEG_DESC << 4;
+ } else {
+- sge->length = cpu_to_le32(PAGE_SIZE);
++ sge->length = cpu_to_le32(NVME_CTRL_PAGE_SIZE);
+ sge->type = NVME_SGL_FMT_SEG_DESC << 4;
+ }
+ }
+diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
+index 52bb262d267ac..bf78c58ed41d4 100644
+--- a/drivers/nvme/target/admin-cmd.c
++++ b/drivers/nvme/target/admin-cmd.c
+@@ -164,26 +164,29 @@ out:
+
+ static void nvmet_get_cmd_effects_nvm(struct nvme_effects_log *log)
+ {
+- log->acs[nvme_admin_get_log_page] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_identify] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_abort_cmd] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_set_features] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_get_features] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_async_event] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_keep_alive] = cpu_to_le32(1 << 0);
+-
+- log->iocs[nvme_cmd_read] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_write] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_flush] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_dsm] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_write_zeroes] = cpu_to_le32(1 << 0);
++ log->acs[nvme_admin_get_log_page] =
++ log->acs[nvme_admin_identify] =
++ log->acs[nvme_admin_abort_cmd] =
++ log->acs[nvme_admin_set_features] =
++ log->acs[nvme_admin_get_features] =
++ log->acs[nvme_admin_async_event] =
++ log->acs[nvme_admin_keep_alive] =
++ cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
++
++ log->iocs[nvme_cmd_read] =
++ log->iocs[nvme_cmd_write] =
++ log->iocs[nvme_cmd_flush] =
++ log->iocs[nvme_cmd_dsm] =
++ log->iocs[nvme_cmd_write_zeroes] =
++ cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+ }
+
+ static void nvmet_get_cmd_effects_zns(struct nvme_effects_log *log)
+ {
+- log->iocs[nvme_cmd_zone_append] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_zone_mgmt_send] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_zone_mgmt_recv] = cpu_to_le32(1 << 0);
++ log->iocs[nvme_cmd_zone_append] =
++ log->iocs[nvme_cmd_zone_mgmt_send] =
++ log->iocs[nvme_cmd_zone_mgmt_recv] =
++ cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+ }
+
+ static void nvmet_execute_get_log_cmd_effects_ns(struct nvmet_req *req)
+diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
+index 6220e1dd961ad..9b5929754195b 100644
+--- a/drivers/nvme/target/passthru.c
++++ b/drivers/nvme/target/passthru.c
+@@ -271,14 +271,13 @@ static void nvmet_passthru_execute_cmd(struct nvmet_req *req)
+ }
+
+ /*
+- * If there are effects for the command we are about to execute, or
+- * an end_req function we need to use nvme_execute_passthru_rq()
+- * synchronously in a work item seeing the end_req function and
+- * nvme_passthru_end() can't be called in the request done callback
+- * which is typically in interrupt context.
++ * If a command needs post-execution fixups, or there are any
++ * non-trivial effects, make sure to execute the command synchronously
++ * in a workqueue so that nvme_passthru_end gets called.
+ */
+ effects = nvme_command_effects(ctrl, ns, req->cmd->common.opcode);
+- if (req->p.use_workqueue || effects) {
++ if (req->p.use_workqueue ||
++ (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))) {
+ INIT_WORK(&req->p.work, nvmet_passthru_execute_cmd_work);
+ req->p.rq = rq;
+ queue_work(nvmet_wq, &req->p.work);
+diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
+index 8f9dba11873cb..52bb68fb22169 100644
+--- a/drivers/of/kexec.c
++++ b/drivers/of/kexec.c
+@@ -284,7 +284,7 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ const char *cmdline, size_t extra_fdt_size)
+ {
+ void *fdt;
+- int ret, chosen_node;
++ int ret, chosen_node, len;
+ const void *prop;
+ size_t fdt_size;
+
+@@ -327,19 +327,19 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ goto out;
+
+ /* Did we boot using an initrd? */
+- prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
++ prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", &len);
+ if (prop) {
+ u64 tmp_start, tmp_end, tmp_size;
+
+- tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
++ tmp_start = of_read_number(prop, len / 4);
+
+- prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
++ prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", &len);
+ if (!prop) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+- tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
++ tmp_end = of_read_number(prop, len / 4);
+
+ /*
+ * kexec reserves exact initrd size, while firmware may
+diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
+index cf91cb024be30..4c0551f89c449 100644
+--- a/drivers/parisc/led.c
++++ b/drivers/parisc/led.c
+@@ -137,6 +137,9 @@ static int start_task(void)
+
+ /* Create the work queue and queue the LED task */
+ led_wq = create_singlethread_workqueue("led_wq");
++ if (!led_wq)
++ return -ENOMEM;
++
+ queue_delayed_work(led_wq, &led_task, 0);
+
+ return 0;
+diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
+index 7fb5cd17cc981..f2909ae93f2f8 100644
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -1179,11 +1179,9 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+
+ sysfs_bin_attr_init(res_attr);
+ if (write_combine) {
+- pdev->res_attr_wc[num] = res_attr;
+ sprintf(res_attr_name, "resource%d_wc", num);
+ res_attr->mmap = pci_mmap_resource_wc;
+ } else {
+- pdev->res_attr[num] = res_attr;
+ sprintf(res_attr_name, "resource%d", num);
+ if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
+ res_attr->read = pci_read_resource_io;
+@@ -1201,10 +1199,17 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+ res_attr->size = pci_resource_len(pdev, num);
+ res_attr->private = (void *)(unsigned long)num;
+ retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+- if (retval)
++ if (retval) {
+ kfree(res_attr);
++ return retval;
++ }
++
++ if (write_combine)
++ pdev->res_attr_wc[num] = res_attr;
++ else
++ pdev->res_attr[num] = res_attr;
+
+- return retval;
++ return 0;
+ }
+
+ /**
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 2bfff2328cf87..a0c6a9eeb7c6d 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -6383,6 +6383,8 @@ bool pci_device_is_present(struct pci_dev *pdev)
+ {
+ u32 v;
+
++ /* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */
++ pdev = pci_physfn(pdev);
+ if (pci_dev_is_disconnected(pdev))
+ return false;
+ return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
+index ed69d455ac0ea..a9687e0409600 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
+@@ -3417,8 +3417,8 @@ static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
+
+ .clk_list = qmp_v3_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l),
+- .reset_list = sc7180_usb3phy_reset_l,
+- .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++ .reset_list = msm8996_usb3phy_reset_l,
++ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v3_usb3phy_regs_layout,
+@@ -3805,8 +3805,8 @@ static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
+ .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3,
+ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
+
+- .clk_list = qmp_v4_phy_clk_l,
+- .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
++ .clk_list = qmp_v4_sm8250_usbphy_clk_l,
++ .num_clks = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index 775df165eb450..97e59f7461261 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -1955,12 +1955,18 @@ static void rproc_crash_handler_work(struct work_struct *work)
+
+ mutex_lock(&rproc->lock);
+
+- if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
++ if (rproc->state == RPROC_CRASHED) {
+ /* handle only the first crash detected */
+ mutex_unlock(&rproc->lock);
+ return;
+ }
+
++ if (rproc->state == RPROC_OFFLINE) {
++ /* Don't recover if the remote processor was stopped */
++ mutex_unlock(&rproc->lock);
++ goto out;
++ }
++
+ rproc->state = RPROC_CRASHED;
+ dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
+ rproc->name);
+@@ -1970,6 +1976,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
+ if (!rproc->recovery_disabled)
+ rproc_trigger_recovery(rproc);
+
++out:
+ pm_relax(rproc->dev.parent);
+ }
+
+diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
+index 157bf5209ac40..a40c1a52df659 100644
+--- a/drivers/rtc/rtc-ds1347.c
++++ b/drivers/rtc/rtc-ds1347.c
+@@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
+ return err;
+
+ century = (dt->tm_year / 100) + 19;
+- err = regmap_write(map, DS1347_CENTURY_REG, century);
++ err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century));
+ if (err)
+ return err;
+
+diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
+index 499718e131d72..6a97e8af93908 100644
+--- a/drivers/soc/qcom/Kconfig
++++ b/drivers/soc/qcom/Kconfig
+@@ -63,6 +63,7 @@ config QCOM_GSBI
+ config QCOM_LLCC
+ tristate "Qualcomm Technologies, Inc. LLCC driver"
+ depends on ARCH_QCOM || COMPILE_TEST
++ select REGMAP_MMIO
+ help
+ Qualcomm Technologies, Inc. platform specific
+ Last Level Cache Controller(LLCC) driver for platforms such as,
+diff --git a/drivers/soc/ux500/ux500-soc-id.c b/drivers/soc/ux500/ux500-soc-id.c
+index a9472e0e5d61c..27d6e25a01153 100644
+--- a/drivers/soc/ux500/ux500-soc-id.c
++++ b/drivers/soc/ux500/ux500-soc-id.c
+@@ -167,20 +167,18 @@ ATTRIBUTE_GROUPS(ux500_soc);
+ static const char *db8500_read_soc_id(struct device_node *backupram)
+ {
+ void __iomem *base;
+- void __iomem *uid;
+ const char *retstr;
++ u32 uid[5];
+
+ base = of_iomap(backupram, 0);
+ if (!base)
+ return NULL;
+- uid = base + 0x1fc0;
++ memcpy_fromio(uid, base + 0x1fc0, sizeof(uid));
+
+ /* Throw these device-specific numbers into the entropy pool */
+- add_device_randomness(uid, 0x14);
++ add_device_randomness(uid, sizeof(uid));
+ retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
+- readl((u32 *)uid+0),
+- readl((u32 *)uid+1), readl((u32 *)uid+2),
+- readl((u32 *)uid+3), readl((u32 *)uid+4));
++ uid[0], uid[1], uid[2], uid[3], uid[4]);
+ iounmap(base);
+ return retstr;
+ }
+diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
+index 747983743a14b..2bf534632f644 100644
+--- a/drivers/soundwire/dmi-quirks.c
++++ b/drivers/soundwire/dmi-quirks.c
+@@ -71,6 +71,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ },
+ .driver_data = (void *)intel_tgl_bios,
+ },
++ {
++ /* quirk used for NUC15 LAPBC710 skew */
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
++ },
++ .driver_data = (void *)intel_tgl_bios,
++ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
+index bbb57b9f6e01e..90e0bf8ca37d9 100644
+--- a/drivers/soundwire/intel.c
++++ b/drivers/soundwire/intel.c
+@@ -1065,8 +1065,8 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
+ .prepare = intel_prepare,
+ .hw_free = intel_hw_free,
+ .shutdown = intel_shutdown,
+- .set_sdw_stream = intel_pcm_set_sdw_stream,
+- .get_sdw_stream = intel_get_sdw_stream,
++ .set_stream = intel_pcm_set_sdw_stream,
++ .get_stream = intel_get_sdw_stream,
+ };
+
+ static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
+@@ -1075,8 +1075,8 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
+ .prepare = intel_prepare,
+ .hw_free = intel_hw_free,
+ .shutdown = intel_shutdown,
+- .set_sdw_stream = intel_pdm_set_sdw_stream,
+- .get_sdw_stream = intel_get_sdw_stream,
++ .set_stream = intel_pdm_set_sdw_stream,
++ .get_stream = intel_get_sdw_stream,
+ };
+
+ static const struct snd_soc_component_driver dai_component = {
+diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
+index f88c5d451f098..500035a1fd460 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -1032,8 +1032,8 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
+ ctrl->sruntime[dai->id] = sruntime;
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+- ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime,
+- substream->stream);
++ ret = snd_soc_dai_set_stream(codec_dai, sruntime,
++ substream->stream);
+ if (ret < 0 && ret != -ENOTSUPP) {
+ dev_err(dai->dev, "Failed to set sdw stream on %s\n",
+ codec_dai->name);
+@@ -1059,8 +1059,8 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = {
+ .hw_free = qcom_swrm_hw_free,
+ .startup = qcom_swrm_startup,
+ .shutdown = qcom_swrm_shutdown,
+- .set_sdw_stream = qcom_swrm_set_sdw_stream,
+- .get_sdw_stream = qcom_swrm_get_sdw_stream,
++ .set_stream = qcom_swrm_set_sdw_stream,
++ .get_stream = qcom_swrm_get_sdw_stream,
+ };
+
+ static const struct snd_soc_component_driver qcom_swrm_dai_component = {
+diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
+index ebbe138a56266..2a900aa302a3b 100644
+--- a/drivers/soundwire/stream.c
++++ b/drivers/soundwire/stream.c
+@@ -1880,7 +1880,7 @@ static int set_stream(struct snd_pcm_substream *substream,
+
+ /* Set stream pointer on all DAIs */
+ for_each_rtd_dais(rtd, i, dai) {
+- ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
++ ret = snd_soc_dai_set_stream(dai, sdw_stream, substream->stream);
+ if (ret < 0) {
+ dev_err(rtd->dev, "failed to set stream pointer on dai %s\n", dai->name);
+ break;
+@@ -1951,7 +1951,7 @@ void sdw_shutdown_stream(void *sdw_substream)
+ /* Find stream from first CPU DAI */
+ dai = asoc_rtd_to_cpu(rtd, 0);
+
+- sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
++ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index f0e61c1b6ffdc..ed091418f7e73 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -188,6 +188,28 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd,
+ return 0;
+ }
+
++static struct v4l2_rect *
++imgu_subdev_get_crop(struct imgu_v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state, unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_crop(&sd->subdev, sd_state, pad);
++ else
++ return &sd->rect.eff;
++}
++
++static struct v4l2_rect *
++imgu_subdev_get_compose(struct imgu_v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state, unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_compose(&sd->subdev, sd_state, pad);
++ else
++ return &sd->rect.bds;
++}
++
+ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+@@ -200,18 +222,12 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
+- sel->pad);
+- else
+- sel->r = imgu_sd->rect.eff;
++ sel->r = *imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ return 0;
+ case V4L2_SEL_TGT_COMPOSE:
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
+- sel->pad);
+- else
+- sel->r = imgu_sd->rect.bds;
++ sel->r = *imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ return 0;
+ default:
+ return -EINVAL;
+@@ -223,10 +239,9 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_selection *sel)
+ {
+ struct imgu_device *imgu = v4l2_get_subdevdata(sd);
+- struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
+- struct imgu_v4l2_subdev,
+- subdev);
+- struct v4l2_rect *rect, *try_sel;
++ struct imgu_v4l2_subdev *imgu_sd =
++ container_of(sd, struct imgu_v4l2_subdev, subdev);
++ struct v4l2_rect *rect;
+
+ dev_dbg(&imgu->pci_dev->dev,
+ "set subdev %u sel which %u target 0x%4x rect [%ux%u]",
+@@ -238,22 +253,18 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
+- rect = &imgu_sd->rect.eff;
++ rect = imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ break;
+ case V4L2_SEL_TGT_COMPOSE:
+- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
+- rect = &imgu_sd->rect.bds;
++ rect = imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- *try_sel = sel->r;
+- else
+- *rect = sel->r;
+-
++ *rect = sel->r;
+ return 0;
+ }
+
+diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c
+index b26e44adb2be7..426e653bd55d5 100644
+--- a/drivers/staging/media/tegra-video/csi.c
++++ b/drivers/staging/media/tegra-video/csi.c
+@@ -433,7 +433,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
+ for (i = 0; i < chan->numgangports; i++)
+ chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;
+
+- chan->of_node = node;
++ chan->of_node = of_node_get(node);
+ chan->numpads = num_pads;
+ if (num_pads & 0x2) {
+ chan->pads[0].flags = MEDIA_PAD_FL_SINK;
+@@ -448,6 +448,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
+ chan->mipi = tegra_mipi_request(csi->dev, node);
+ if (IS_ERR(chan->mipi)) {
+ ret = PTR_ERR(chan->mipi);
++ chan->mipi = NULL;
+ dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
+ }
+
+@@ -640,6 +641,7 @@ static void tegra_csi_channels_cleanup(struct tegra_csi *csi)
+ media_entity_cleanup(&subdev->entity);
+ }
+
++ of_node_put(chan->of_node);
+ list_del(&chan->list);
+ kfree(chan);
+ }
+diff --git a/drivers/staging/media/tegra-video/csi.h b/drivers/staging/media/tegra-video/csi.h
+index 4ee05a1785cfa..6960ea2e3d360 100644
+--- a/drivers/staging/media/tegra-video/csi.h
++++ b/drivers/staging/media/tegra-video/csi.h
+@@ -56,7 +56,7 @@ struct tegra_csi;
+ * @framerate: active framerate for TPG
+ * @h_blank: horizontal blanking for TPG active format
+ * @v_blank: vertical blanking for TPG active format
+- * @mipi: mipi device for corresponding csi channel pads
++ * @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error)
+ * @pixel_rate: active pixel rate from the sensor on this channel
+ */
+ struct tegra_csi_channel {
+diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+index 8c42e76620333..92ed1213fe379 100644
+--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+@@ -172,6 +172,7 @@ static const struct attribute_group fivr_attribute_group = {
+ RFIM_SHOW(rfi_restriction_run_busy, 1)
+ RFIM_SHOW(rfi_restriction_err_code, 1)
+ RFIM_SHOW(rfi_restriction_data_rate, 1)
++RFIM_SHOW(rfi_restriction_data_rate_base, 1)
+ RFIM_SHOW(ddr_data_rate_point_0, 1)
+ RFIM_SHOW(ddr_data_rate_point_1, 1)
+ RFIM_SHOW(ddr_data_rate_point_2, 1)
+@@ -181,11 +182,13 @@ RFIM_SHOW(rfi_disable, 1)
+ RFIM_STORE(rfi_restriction_run_busy, 1)
+ RFIM_STORE(rfi_restriction_err_code, 1)
+ RFIM_STORE(rfi_restriction_data_rate, 1)
++RFIM_STORE(rfi_restriction_data_rate_base, 1)
+ RFIM_STORE(rfi_disable, 1)
+
+ static DEVICE_ATTR_RW(rfi_restriction_run_busy);
+ static DEVICE_ATTR_RW(rfi_restriction_err_code);
+ static DEVICE_ATTR_RW(rfi_restriction_data_rate);
++static DEVICE_ATTR_RW(rfi_restriction_data_rate_base);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_0);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_1);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_2);
+@@ -248,6 +251,7 @@ static struct attribute *dvfs_attrs[] = {
+ &dev_attr_rfi_restriction_run_busy.attr,
+ &dev_attr_rfi_restriction_err_code.attr,
+ &dev_attr_rfi_restriction_data_rate.attr,
++ &dev_attr_rfi_restriction_data_rate_base.attr,
+ &dev_attr_ddr_data_rate_point_0.attr,
+ &dev_attr_ddr_data_rate_point_1.attr,
+ &dev_attr_ddr_data_rate_point_2.attr,
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index d0352daab0128..ec1de6f6c2903 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -258,7 +258,8 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
+ if (IS_ERR(qcom->icc_path_apps)) {
+ dev_err(dev, "failed to get apps-usb path: %ld\n",
+ PTR_ERR(qcom->icc_path_apps));
+- return PTR_ERR(qcom->icc_path_apps);
++ ret = PTR_ERR(qcom->icc_path_apps);
++ goto put_path_ddr;
+ }
+
+ if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
+@@ -271,17 +272,23 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
+
+ if (ret) {
+ dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
+- return ret;
++ goto put_path_apps;
+ }
+
+ ret = icc_set_bw(qcom->icc_path_apps,
+ APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
+ if (ret) {
+ dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
+- return ret;
++ goto put_path_apps;
+ }
+
+ return 0;
++
++put_path_apps:
++ icc_put(qcom->icc_path_apps);
++put_path_ddr:
++ icc_put(qcom->icc_path_ddr);
++ return ret;
+ }
+
+ /**
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
+index 2faf3bd1c3ba5..4d9e3fdae5f6c 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
+@@ -66,8 +66,7 @@ static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
+ {
+ struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
+
+- vringh_init_iotlb(&vq->vring, vdpasim->dev_attr.supported_features,
+- VDPASIM_QUEUE_MAX, false,
++ vringh_init_iotlb(&vq->vring, vdpasim->features, vq->num, false,
+ (struct vring_desc *)(uintptr_t)vq->desc_addr,
+ (struct vring_avail *)
+ (uintptr_t)vq->driver_addr,
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+index a790903f243e8..22b812c32bee8 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+@@ -308,8 +308,10 @@ static int __init vdpasim_blk_init(void)
+ int ret;
+
+ ret = device_register(&vdpasim_blk_mgmtdev);
+- if (ret)
++ if (ret) {
++ put_device(&vdpasim_blk_mgmtdev);
+ return ret;
++ }
+
+ ret = vdpa_mgmtdev_register(&mgmt_dev);
+ if (ret)
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+index a1ab6163f7d13..f1c420c5e26eb 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+@@ -194,8 +194,10 @@ static int __init vdpasim_net_init(void)
+ }
+
+ ret = device_register(&vdpasim_net_mgmtdev);
+- if (ret)
++ if (ret) {
++ put_device(&vdpasim_net_mgmtdev);
+ return ret;
++ }
+
+ ret = vdpa_mgmtdev_register(&mgmt_dev);
+ if (ret)
+diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
+index 6942472cffb0f..0a9746bc9228d 100644
+--- a/drivers/vhost/vhost.c
++++ b/drivers/vhost/vhost.c
+@@ -2048,7 +2048,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
+ struct vhost_dev *dev = vq->dev;
+ struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem;
+ struct iovec *_iov;
+- u64 s = 0;
++ u64 s = 0, last = addr + len - 1;
+ int ret = 0;
+
+ while ((u64)len > s) {
+@@ -2058,7 +2058,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
+ break;
+ }
+
+- map = vhost_iotlb_itree_first(umem, addr, addr + len - 1);
++ map = vhost_iotlb_itree_first(umem, addr, last);
+ if (map == NULL || map->start > addr) {
+ if (umem != dev->iotlb) {
+ ret = -EFAULT;
+diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
+index eab55accf381f..786876af0a73a 100644
+--- a/drivers/vhost/vringh.c
++++ b/drivers/vhost/vringh.c
+@@ -1101,7 +1101,7 @@ static int iotlb_translate(const struct vringh *vrh,
+ struct vhost_iotlb_map *map;
+ struct vhost_iotlb *iotlb = vrh->iotlb;
+ int ret = 0;
+- u64 s = 0;
++ u64 s = 0, last = addr + len - 1;
+
+ spin_lock(vrh->iotlb_lock);
+
+@@ -1113,8 +1113,7 @@ static int iotlb_translate(const struct vringh *vrh,
+ break;
+ }
+
+- map = vhost_iotlb_itree_first(iotlb, addr,
+- addr + len - 1);
++ map = vhost_iotlb_itree_first(iotlb, addr, last);
+ if (!map || map->start > addr) {
+ ret = -EINVAL;
+ break;
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
+index 97bfe499222b6..74ac0c28fe43a 100644
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -968,7 +968,14 @@ static int __init vhost_vsock_init(void)
+ VSOCK_TRANSPORT_F_H2G);
+ if (ret < 0)
+ return ret;
+- return misc_register(&vhost_vsock_misc);
++
++ ret = misc_register(&vhost_vsock_misc);
++ if (ret) {
++ vsock_core_unregister(&vhost_transport.transport);
++ return ret;
++ }
++
++ return 0;
+ };
+
+ static void __exit vhost_vsock_exit(void)
+diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
+index 236521b19daf7..e7348d657e183 100644
+--- a/drivers/video/fbdev/matrox/matroxfb_base.c
++++ b/drivers/video/fbdev/matrox/matroxfb_base.c
+@@ -1377,8 +1377,8 @@ static struct video_board vbG200 = {
+ .lowlevel = &matrox_G100
+ };
+ static struct video_board vbG200eW = {
+- .maxvram = 0x100000,
+- .maxdisplayable = 0x800000,
++ .maxvram = 0x1000000,
++ .maxdisplayable = 0x0800000,
+ .accelID = FB_ACCEL_MATROX_MGAG200,
+ .lowlevel = &matrox_G100
+ };
+diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
+index 830a6a876ffea..c316931fc99c5 100644
+--- a/fs/binfmt_elf_fdpic.c
++++ b/fs/binfmt_elf_fdpic.c
+@@ -434,8 +434,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
+ current->mm->start_stack = current->mm->start_brk + stack_size;
+ #endif
+
+- if (create_elf_fdpic_tables(bprm, current->mm,
+- &exec_params, &interp_params) < 0)
++ retval = create_elf_fdpic_tables(bprm, current->mm, &exec_params,
++ &interp_params);
++ if (retval < 0)
+ goto error;
+
+ kdebug("- start_code %lx", current->mm->start_code);
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index 1ff527bbe54c5..cd9202867d98a 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -433,6 +433,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+ u64 wanted_disk_byte = ref->wanted_disk_byte;
+ u64 count = 0;
+ u64 data_offset;
++ u8 type;
+
+ if (level != 0) {
+ eb = path->nodes[level];
+@@ -487,6 +488,9 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+ continue;
+ }
+ fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
++ type = btrfs_file_extent_type(eb, fi);
++ if (type == BTRFS_FILE_EXTENT_INLINE)
++ goto next;
+ disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+ data_offset = btrfs_file_extent_offset(eb, fi);
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 2fd46093e5bba..2c80fc902f592 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -202,11 +202,9 @@ static bool btrfs_supported_super_csum(u16 csum_type)
+ * Return 0 if the superblock checksum type matches the checksum value of that
+ * algorithm. Pass the raw disk superblock data.
+ */
+-static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
+- char *raw_disk_sb)
++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
++ const struct btrfs_super_block *disk_sb)
+ {
+- struct btrfs_super_block *disk_sb =
+- (struct btrfs_super_block *)raw_disk_sb;
+ char result[BTRFS_CSUM_SIZE];
+ SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
+
+@@ -217,7 +215,7 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
+ * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is
+ * filled with zeros and is included in the checksum.
+ */
+- crypto_shash_digest(shash, raw_disk_sb + BTRFS_CSUM_SIZE,
++ crypto_shash_digest(shash, (const u8 *)disk_sb + BTRFS_CSUM_SIZE,
+ BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE, result);
+
+ if (memcmp(disk_sb->csum, result, fs_info->csum_size))
+@@ -2491,8 +2489,8 @@ out:
+ * 1, 2 2nd and 3rd backup copy
+ * -1 skip bytenr check
+ */
+-static int validate_super(struct btrfs_fs_info *fs_info,
+- struct btrfs_super_block *sb, int mirror_num)
++int btrfs_validate_super(struct btrfs_fs_info *fs_info,
++ struct btrfs_super_block *sb, int mirror_num)
+ {
+ u64 nodesize = btrfs_super_nodesize(sb);
+ u64 sectorsize = btrfs_super_sectorsize(sb);
+@@ -2675,7 +2673,7 @@ static int validate_super(struct btrfs_fs_info *fs_info,
+ */
+ static int btrfs_validate_mount_super(struct btrfs_fs_info *fs_info)
+ {
+- return validate_super(fs_info, fs_info->super_copy, 0);
++ return btrfs_validate_super(fs_info, fs_info->super_copy, 0);
+ }
+
+ /*
+@@ -2689,7 +2687,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
+ {
+ int ret;
+
+- ret = validate_super(fs_info, sb, -1);
++ ret = btrfs_validate_super(fs_info, sb, -1);
+ if (ret < 0)
+ goto out;
+ if (!btrfs_supported_super_csum(btrfs_super_csum_type(sb))) {
+@@ -3210,7 +3208,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
+ * We want to check superblock checksum, the type is stored inside.
+ * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
+ */
+- if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) {
++ if (btrfs_check_super_csum(fs_info, disk_super)) {
+ btrfs_err(fs_info, "superblock checksum mismatch");
+ err = -EINVAL;
+ btrfs_release_disk_super(disk_super);
+@@ -3703,7 +3701,7 @@ static void btrfs_end_super_write(struct bio *bio)
+ }
+
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+- int copy_num)
++ int copy_num, bool drop_cache)
+ {
+ struct btrfs_super_block *super;
+ struct page *page;
+@@ -3721,6 +3719,19 @@ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+ if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
+ return ERR_PTR(-EINVAL);
+
++ if (drop_cache) {
++ /* This should only be called with the primary sb. */
++ ASSERT(copy_num == 0);
++
++ /*
++ * Drop the page of the primary superblock, so later read will
++ * always read from the device.
++ */
++ invalidate_inode_pages2_range(mapping,
++ bytenr >> PAGE_SHIFT,
++ (bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
++ }
++
+ page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
+ if (IS_ERR(page))
+ return ERR_CAST(page);
+@@ -3752,7 +3763,7 @@ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev)
+ * later supers, using BTRFS_SUPER_MIRROR_MAX instead
+ */
+ for (i = 0; i < 1; i++) {
+- super = btrfs_read_dev_one_super(bdev, i);
++ super = btrfs_read_dev_one_super(bdev, i, false);
+ if (IS_ERR(super))
+ continue;
+
+diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
+index 1b8fd3deafc92..718787dfdb8ea 100644
+--- a/fs/btrfs/disk-io.h
++++ b/fs/btrfs/disk-io.h
+@@ -52,14 +52,18 @@ struct extent_buffer *btrfs_find_create_tree_block(
+ void btrfs_clean_tree_block(struct extent_buffer *buf);
+ void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info);
+ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info);
++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
++ const struct btrfs_super_block *disk_sb);
+ int __cold open_ctree(struct super_block *sb,
+ struct btrfs_fs_devices *fs_devices,
+ char *options);
+ void __cold close_ctree(struct btrfs_fs_info *fs_info);
++int btrfs_validate_super(struct btrfs_fs_info *fs_info,
++ struct btrfs_super_block *sb, int mirror_num);
+ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
+ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev);
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+- int copy_num);
++ int copy_num, bool drop_cache);
+ int btrfs_commit_super(struct btrfs_fs_info *fs_info);
+ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
+ struct btrfs_key *key);
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 391a4af9c5e51..ed9c715d25796 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3415,13 +3415,10 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
+ di_args->bytes_used = btrfs_device_get_bytes_used(dev);
+ di_args->total_bytes = btrfs_device_get_total_bytes(dev);
+ memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
+- if (dev->name) {
+- strncpy(di_args->path, rcu_str_deref(dev->name),
+- sizeof(di_args->path) - 1);
+- di_args->path[sizeof(di_args->path) - 1] = 0;
+- } else {
++ if (dev->name)
++ strscpy(di_args->path, rcu_str_deref(dev->name), sizeof(di_args->path));
++ else
+ di_args->path[0] = '\0';
+- }
+
+ out:
+ rcu_read_unlock();
+diff --git a/fs/btrfs/rcu-string.h b/fs/btrfs/rcu-string.h
+index 5c1a617eb25de..5c2b66d155ef7 100644
+--- a/fs/btrfs/rcu-string.h
++++ b/fs/btrfs/rcu-string.h
+@@ -18,7 +18,11 @@ static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask)
+ (len * sizeof(char)), mask);
+ if (!ret)
+ return ret;
+- strncpy(ret->str, src, len);
++ /* Warn if the source got unexpectedly truncated. */
++ if (WARN_ON(strscpy(ret->str, src, len) < 0)) {
++ kfree(ret);
++ return NULL;
++ }
+ return ret;
+ }
+
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index 61b84391be58c..4ff55457f9021 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2497,11 +2497,87 @@ static int btrfs_freeze(struct super_block *sb)
+ return btrfs_commit_transaction(trans);
+ }
+
++static int check_dev_super(struct btrfs_device *dev)
++{
++ struct btrfs_fs_info *fs_info = dev->fs_info;
++ struct btrfs_super_block *sb;
++ u16 csum_type;
++ int ret = 0;
++
++ /* This should be called with fs still frozen. */
++ ASSERT(test_bit(BTRFS_FS_FROZEN, &fs_info->flags));
++
++ /* Missing dev, no need to check. */
++ if (!dev->bdev)
++ return 0;
++
++ /* Only need to check the primary super block. */
++ sb = btrfs_read_dev_one_super(dev->bdev, 0, true);
++ if (IS_ERR(sb))
++ return PTR_ERR(sb);
++
++ /* Verify the checksum. */
++ csum_type = btrfs_super_csum_type(sb);
++ if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) {
++ btrfs_err(fs_info, "csum type changed, has %u expect %u",
++ csum_type, btrfs_super_csum_type(fs_info->super_copy));
++ ret = -EUCLEAN;
++ goto out;
++ }
++
++ if (btrfs_check_super_csum(fs_info, sb)) {
++ btrfs_err(fs_info, "csum for on-disk super block no longer matches");
++ ret = -EUCLEAN;
++ goto out;
++ }
++
++ /* Btrfs_validate_super() includes fsid check against super->fsid. */
++ ret = btrfs_validate_super(fs_info, sb, 0);
++ if (ret < 0)
++ goto out;
++
++ if (btrfs_super_generation(sb) != fs_info->last_trans_committed) {
++ btrfs_err(fs_info, "transid mismatch, has %llu expect %llu",
++ btrfs_super_generation(sb),
++ fs_info->last_trans_committed);
++ ret = -EUCLEAN;
++ goto out;
++ }
++out:
++ btrfs_release_disk_super(sb);
++ return ret;
++}
++
+ static int btrfs_unfreeze(struct super_block *sb)
+ {
+ struct btrfs_fs_info *fs_info = btrfs_sb(sb);
++ struct btrfs_device *device;
++ int ret = 0;
+
++ /*
++ * Make sure the fs is not changed by accident (like hibernation then
++ * modified by other OS).
++ * If we found anything wrong, we mark the fs error immediately.
++ *
++ * And since the fs is frozen, no one can modify the fs yet, thus
++ * we don't need to hold device_list_mutex.
++ */
++ list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) {
++ ret = check_dev_super(device);
++ if (ret < 0) {
++ btrfs_handle_fs_error(fs_info, ret,
++ "super block on devid %llu got modified unexpectedly",
++ device->devid);
++ break;
++ }
++ }
+ clear_bit(BTRFS_FS_FROZEN, &fs_info->flags);
++
++ /*
++ * We still return 0, to allow VFS layer to unfreeze the fs even the
++ * above checks failed. Since the fs is either fine or read-only, we're
++ * safe to continue, without causing further damage.
++ */
+ return 0;
+ }
+
+diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
+index 7c45d960b53c6..259a3b5f93032 100644
+--- a/fs/btrfs/tree-defrag.c
++++ b/fs/btrfs/tree-defrag.c
+@@ -39,8 +39,10 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
+ goto out;
+
+ path = btrfs_alloc_path();
+- if (!path)
+- return -ENOMEM;
++ if (!path) {
++ ret = -ENOMEM;
++ goto out;
++ }
+
+ level = btrfs_header_level(root->node);
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index c886ec81c5d00..f01549b8c7c54 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -2074,7 +2074,7 @@ void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info,
+ struct page *page;
+ int ret;
+
+- disk_super = btrfs_read_dev_one_super(bdev, copy_num);
++ disk_super = btrfs_read_dev_one_super(bdev, copy_num, false);
+ if (IS_ERR(disk_super))
+ continue;
+
+@@ -7043,6 +7043,27 @@ static void warn_32bit_meta_chunk(struct btrfs_fs_info *fs_info,
+ }
+ #endif
+
++static struct btrfs_device *handle_missing_device(struct btrfs_fs_info *fs_info,
++ u64 devid, u8 *uuid)
++{
++ struct btrfs_device *dev;
++
++ if (!btrfs_test_opt(fs_info, DEGRADED)) {
++ btrfs_report_missing_device(fs_info, devid, uuid, true);
++ return ERR_PTR(-ENOENT);
++ }
++
++ dev = add_missing_dev(fs_info->fs_devices, devid, uuid);
++ if (IS_ERR(dev)) {
++ btrfs_err(fs_info, "failed to init missing device %llu: %ld",
++ devid, PTR_ERR(dev));
++ return dev;
++ }
++ btrfs_report_missing_device(fs_info, devid, uuid, false);
++
++ return dev;
++}
++
+ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ struct btrfs_chunk *chunk)
+ {
+@@ -7130,28 +7151,18 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ BTRFS_UUID_SIZE);
+ args.uuid = uuid;
+ map->stripes[i].dev = btrfs_find_device(fs_info->fs_devices, &args);
+- if (!map->stripes[i].dev &&
+- !btrfs_test_opt(fs_info, DEGRADED)) {
+- free_extent_map(em);
+- btrfs_report_missing_device(fs_info, devid, uuid, true);
+- return -ENOENT;
+- }
+ if (!map->stripes[i].dev) {
+- map->stripes[i].dev =
+- add_missing_dev(fs_info->fs_devices, devid,
+- uuid);
++ map->stripes[i].dev = handle_missing_device(fs_info,
++ devid, uuid);
+ if (IS_ERR(map->stripes[i].dev)) {
++ ret = PTR_ERR(map->stripes[i].dev);
+ free_extent_map(em);
+- btrfs_err(fs_info,
+- "failed to init missing dev %llu: %ld",
+- devid, PTR_ERR(map->stripes[i].dev));
+- return PTR_ERR(map->stripes[i].dev);
++ return ret;
+ }
+- btrfs_report_missing_device(fs_info, devid, uuid, false);
+ }
++
+ set_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
+ &(map->stripes[i].dev->dev_state));
+-
+ }
+
+ write_lock(&map_tree->lock);
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index be96fe615bec3..67b782b0a90aa 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2872,7 +2872,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
+
+ while (true) {
+ flags &= CEPH_FILE_MODE_MASK;
+- if (atomic_read(&fi->num_locks))
++ if (vfs_inode_has_locks(inode))
+ flags |= CHECK_FILELOCK;
+ _got = 0;
+ ret = try_get_cap_refs(inode, need, want, endoff,
+diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
+index bdeb271f47d95..3e3b8be76b21e 100644
+--- a/fs/ceph/locks.c
++++ b/fs/ceph/locks.c
+@@ -32,18 +32,14 @@ void __init ceph_flock_init(void)
+
+ static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
+ {
+- struct ceph_file_info *fi = dst->fl_file->private_data;
+ struct inode *inode = file_inode(dst->fl_file);
+ atomic_inc(&ceph_inode(inode)->i_filelock_ref);
+- atomic_inc(&fi->num_locks);
+ }
+
+ static void ceph_fl_release_lock(struct file_lock *fl)
+ {
+- struct ceph_file_info *fi = fl->fl_file->private_data;
+ struct inode *inode = file_inode(fl->fl_file);
+ struct ceph_inode_info *ci = ceph_inode(inode);
+- atomic_dec(&fi->num_locks);
+ if (atomic_dec_and_test(&ci->i_filelock_ref)) {
+ /* clear error when all locks are released */
+ spin_lock(&ci->i_ceph_lock);
+diff --git a/fs/ceph/super.h b/fs/ceph/super.h
+index 14f951cd5b61b..8c9021d0f8374 100644
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -773,7 +773,6 @@ struct ceph_file_info {
+ struct list_head rw_contexts;
+
+ u32 filp_gen;
+- atomic_t num_locks;
+ };
+
+ struct ceph_dir_file_info {
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 668dd6a86295f..fc736ced6f4a3 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -656,9 +656,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
+ seq_printf(s, ",echo_interval=%lu",
+ tcon->ses->server->echo_interval / HZ);
+
+- /* Only display max_credits if it was overridden on mount */
++ /* Only display the following if overridden on mount */
+ if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
+ seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
++ if (tcon->ses->server->tcp_nodelay)
++ seq_puts(s, ",tcpnodelay");
++ if (tcon->ses->server->noautotune)
++ seq_puts(s, ",noautotune");
++ if (tcon->ses->server->noblocksnd)
++ seq_puts(s, ",noblocksend");
+
+ if (tcon->snapshot_time)
+ seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 1ab72c3d0bff9..0f1b9c48838cc 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -13,6 +13,8 @@
+ #include <linux/in6.h>
+ #include <linux/inet.h>
+ #include <linux/slab.h>
++#include <linux/scatterlist.h>
++#include <linux/mm.h>
+ #include <linux/mempool.h>
+ #include <linux/workqueue.h>
+ #include "cifs_fs_sb.h"
+@@ -21,6 +23,7 @@
+ #include <linux/scatterlist.h>
+ #include <uapi/linux/cifs/cifs_mount.h>
+ #include "smb2pdu.h"
++#include "smb2glob.h"
+
+ #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
+
+@@ -1972,4 +1975,70 @@ static inline bool cifs_is_referral_server(struct cifs_tcon *tcon,
+ return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER));
+ }
+
++static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
++ int num_rqst,
++ const u8 *sig)
++{
++ unsigned int len, skip;
++ unsigned int nents = 0;
++ unsigned long addr;
++ int i, j;
++
++ /* Assumes the first rqst has a transform header as the first iov.
++ * I.e.
++ * rqst[0].rq_iov[0] is transform header
++ * rqst[0].rq_iov[1+] data to be encrypted/decrypted
++ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
++ */
++ for (i = 0; i < num_rqst; i++) {
++ /*
++ * The first rqst has a transform header where the
++ * first 20 bytes are not part of the encrypted blob.
++ */
++ for (j = 0; j < rqst[i].rq_nvec; j++) {
++ struct kvec *iov = &rqst[i].rq_iov[j];
++
++ skip = (i == 0) && (j == 0) ? 20 : 0;
++ addr = (unsigned long)iov->iov_base + skip;
++ if (unlikely(is_vmalloc_addr((void *)addr))) {
++ len = iov->iov_len - skip;
++ nents += DIV_ROUND_UP(offset_in_page(addr) + len,
++ PAGE_SIZE);
++ } else {
++ nents++;
++ }
++ }
++ nents += rqst[i].rq_npages;
++ }
++ nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
++ return nents;
++}
++
++/* We can not use the normal sg_set_buf() as we will sometimes pass a
++ * stack object as buf.
++ */
++static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
++ const void *buf,
++ unsigned int buflen)
++{
++ unsigned long addr = (unsigned long)buf;
++ unsigned int off = offset_in_page(addr);
++
++ addr &= PAGE_MASK;
++ if (unlikely(is_vmalloc_addr((void *)addr))) {
++ do {
++ unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
++
++ sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);
++
++ off = 0;
++ addr += PAGE_SIZE;
++ buflen -= len;
++ } while (buflen);
++ } else {
++ sg_set_page(sg++, virt_to_page(addr), buflen, off);
++ }
++ return sg;
++}
++
+ #endif /* _CIFS_GLOB_H */
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index b2697356b5e7d..50844d51da5d9 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -590,8 +590,8 @@ int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
+ struct sdesc **sdesc);
+ void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
+
+-extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
+- unsigned int *len, unsigned int *offset);
++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
++ unsigned int *len, unsigned int *offset);
+ struct cifs_chan *
+ cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
+ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index a4284c4d7e031..555bd386a24df 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1948,7 +1948,7 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)),
+ struct cifs_ses *
+ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ {
+- int rc = -ENOMEM;
++ int rc = 0;
+ unsigned int xid;
+ struct cifs_ses *ses;
+ struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
+@@ -1990,6 +1990,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ return ses;
+ }
+
++ rc = -ENOMEM;
++
+ cifs_dbg(FYI, "Existing smb sess not found\n");
+ ses = sesInfoAlloc();
+ if (ses == NULL)
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 94143d7f58c78..3a90ee314ed73 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -1134,8 +1134,8 @@ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
+ * @len: Where to store the length for this page:
+ * @offset: Where to store the offset for this page
+ */
+-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
+- unsigned int *len, unsigned int *offset)
++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
++ unsigned int *len, unsigned int *offset)
+ {
+ *len = rqst->rq_pagesz;
+ *offset = (page == 0) ? rqst->rq_offset : 0;
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 5e6526c201fec..817d78129bd2e 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -4416,69 +4416,82 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
+ memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
+ }
+
+-/* We can not use the normal sg_set_buf() as we will sometimes pass a
+- * stack object as buf.
+- */
+-static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
+- unsigned int buflen)
++static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst,
++ int num_rqst, const u8 *sig, u8 **iv,
++ struct aead_request **req, struct scatterlist **sgl,
++ unsigned int *num_sgs)
+ {
+- void *addr;
+- /*
+- * VMAP_STACK (at least) puts stack into the vmalloc address space
+- */
+- if (is_vmalloc_addr(buf))
+- addr = vmalloc_to_page(buf);
+- else
+- addr = virt_to_page(buf);
+- sg_set_page(sg, addr, buflen, offset_in_page(buf));
++ unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm);
++ unsigned int iv_size = crypto_aead_ivsize(tfm);
++ unsigned int len;
++ u8 *p;
++
++ *num_sgs = cifs_get_num_sgs(rqst, num_rqst, sig);
++
++ len = iv_size;
++ len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1);
++ len = ALIGN(len, crypto_tfm_ctx_alignment());
++ len += req_size;
++ len = ALIGN(len, __alignof__(struct scatterlist));
++ len += *num_sgs * sizeof(**sgl);
++
++ p = kmalloc(len, GFP_ATOMIC);
++ if (!p)
++ return NULL;
++
++ *iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1);
++ *req = (struct aead_request *)PTR_ALIGN(*iv + iv_size,
++ crypto_tfm_ctx_alignment());
++ *sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size,
++ __alignof__(struct scatterlist));
++ return p;
+ }
+
+-/* Assumes the first rqst has a transform header as the first iov.
+- * I.e.
+- * rqst[0].rq_iov[0] is transform header
+- * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+- * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+- */
+-static struct scatterlist *
+-init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign)
++static void *smb2_get_aead_req(struct crypto_aead *tfm, const struct smb_rqst *rqst,
++ int num_rqst, const u8 *sig, u8 **iv,
++ struct aead_request **req, struct scatterlist **sgl)
+ {
+- unsigned int sg_len;
++ unsigned int off, len, skip;
+ struct scatterlist *sg;
+- unsigned int i;
+- unsigned int j;
+- unsigned int idx = 0;
+- int skip;
+-
+- sg_len = 1;
+- for (i = 0; i < num_rqst; i++)
+- sg_len += rqst[i].rq_nvec + rqst[i].rq_npages;
++ unsigned int num_sgs;
++ unsigned long addr;
++ int i, j;
++ void *p;
+
+- sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL);
+- if (!sg)
++ p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, sgl, &num_sgs);
++ if (!p)
+ return NULL;
+
+- sg_init_table(sg, sg_len);
++ sg_init_table(*sgl, num_sgs);
++ sg = *sgl;
++
++ /* Assumes the first rqst has a transform header as the first iov.
++ * I.e.
++ * rqst[0].rq_iov[0] is transform header
++ * rqst[0].rq_iov[1+] data to be encrypted/decrypted
++ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
++ */
+ for (i = 0; i < num_rqst; i++) {
++ /*
++ * The first rqst has a transform header where the
++ * first 20 bytes are not part of the encrypted blob.
++ */
+ for (j = 0; j < rqst[i].rq_nvec; j++) {
+- /*
+- * The first rqst has a transform header where the
+- * first 20 bytes are not part of the encrypted blob
+- */
+- skip = (i == 0) && (j == 0) ? 20 : 0;
+- smb2_sg_set_buf(&sg[idx++],
+- rqst[i].rq_iov[j].iov_base + skip,
+- rqst[i].rq_iov[j].iov_len - skip);
+- }
++ struct kvec *iov = &rqst[i].rq_iov[j];
+
++ skip = (i == 0) && (j == 0) ? 20 : 0;
++ addr = (unsigned long)iov->iov_base + skip;
++ len = iov->iov_len - skip;
++ sg = cifs_sg_set_buf(sg, (void *)addr, len);
++ }
+ for (j = 0; j < rqst[i].rq_npages; j++) {
+- unsigned int len, offset;
+-
+- rqst_page_get_length(&rqst[i], j, &len, &offset);
+- sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset);
++ rqst_page_get_length(&rqst[i], j, &len, &off);
++ sg_set_page(sg++, rqst[i].rq_pages[j], len, off);
+ }
+ }
+- smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE);
+- return sg;
++ cifs_sg_set_buf(sg, sig, SMB2_SIGNATURE_SIZE);
++
++ return p;
+ }
+
+ static int
+@@ -4522,11 +4535,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ u8 sign[SMB2_SIGNATURE_SIZE] = {};
+ u8 key[SMB3_ENC_DEC_KEY_SIZE];
+ struct aead_request *req;
+- char *iv;
+- unsigned int iv_len;
++ u8 *iv;
+ DECLARE_CRYPTO_WAIT(wait);
+ struct crypto_aead *tfm;
+ unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
++ void *creq;
+
+ rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
+ if (rc) {
+@@ -4561,32 +4574,15 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ return rc;
+ }
+
+- req = aead_request_alloc(tfm, GFP_KERNEL);
+- if (!req) {
+- cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
++ creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg);
++ if (unlikely(!creq))
+ return -ENOMEM;
+- }
+
+ if (!enc) {
+ memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
+ crypt_len += SMB2_SIGNATURE_SIZE;
+ }
+
+- sg = init_sg(num_rqst, rqst, sign);
+- if (!sg) {
+- cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__);
+- rc = -ENOMEM;
+- goto free_req;
+- }
+-
+- iv_len = crypto_aead_ivsize(tfm);
+- iv = kzalloc(iv_len, GFP_KERNEL);
+- if (!iv) {
+- cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
+- rc = -ENOMEM;
+- goto free_sg;
+- }
+-
+ if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+ (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
+ memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
+@@ -4595,6 +4591,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
+ }
+
++ aead_request_set_tfm(req, tfm);
+ aead_request_set_crypt(req, sg, sg, crypt_len, iv);
+ aead_request_set_ad(req, assoc_data_len);
+
+@@ -4607,11 +4604,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ if (!rc && enc)
+ memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
+
+- kfree(iv);
+-free_sg:
+- kfree(sg);
+-free_req:
+- kfree(req);
++ kfree_sensitive(creq);
+ return rc;
+ }
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 9d7078a1dc8b0..d56a8f88a3852 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1520,7 +1520,11 @@ static void process_recv_sockets(struct work_struct *work)
+
+ static void process_listen_recv_socket(struct work_struct *work)
+ {
+- accept_from_sock(&listen_con);
++ int ret;
++
++ do {
++ ret = accept_from_sock(&listen_con);
++ } while (!ret);
+ }
+
+ static void dlm_connect(struct connection *con)
+@@ -1797,7 +1801,7 @@ static int dlm_listen_for_all(void)
+ result = sock->ops->listen(sock, 5);
+ if (result < 0) {
+ dlm_close_sock(&listen_con.sock);
+- goto out;
++ return result;
+ }
+
+ return 0;
+@@ -2000,7 +2004,6 @@ fail_listen:
+ dlm_proto_ops = NULL;
+ fail_proto_ops:
+ dlm_allow_conn = 0;
+- dlm_close_sock(&listen_con.sock);
+ work_stop();
+ fail_local:
+ deinit_local();
+diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
+index a0fb0c4bdc7cd..f9a79053f03ad 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -665,7 +665,7 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
+ * it's possible we've just missed a transaction commit here,
+ * so ignore the returned status
+ */
+- jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
++ ext4_debug("%s: retrying operation after ENOSPC\n", sb->s_id);
+ (void) jbd2_journal_force_commit_nested(sbi->s_journal);
+ return 1;
+ }
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 2d84030d7b7fc..bc209f3033273 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -559,7 +559,7 @@ enum {
+ *
+ * It's not paranoia if the Murphy's Law really *is* out to get you. :-)
+ */
+-#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1 << EXT4_INODE_##FLAG))
++#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1U << EXT4_INODE_##FLAG))
+ #define CHECK_FLAG_VALUE(FLAG) BUILD_BUG_ON(!TEST_FLAG_VALUE(FLAG))
+
+ static inline void ext4_check_flag_values(void)
+@@ -2996,7 +2996,8 @@ int do_journal_get_write_access(handle_t *handle, struct inode *inode,
+ typedef enum {
+ EXT4_IGET_NORMAL = 0,
+ EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */
+- EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */
++ EXT4_IGET_HANDLE = 0x0002, /* Inode # is from a handle */
++ EXT4_IGET_BAD = 0x0004 /* Allow to iget a bad inode */
+ } ext4_iget_flags;
+
+ extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+@@ -3646,8 +3647,8 @@ extern void ext4_initialize_dirent_tail(struct buffer_head *bh,
+ unsigned int blocksize);
+ extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh);
+-extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
+- struct inode *inode);
++extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
++ struct inode *inode, struct dentry *dentry);
+ extern int __ext4_link(struct inode *dir, struct inode *inode,
+ struct dentry *dentry);
+
+diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
+index 3477a16d08aee..8e1fb18f465ea 100644
+--- a/fs/ext4/ext4_jbd2.c
++++ b/fs/ext4/ext4_jbd2.c
+@@ -267,8 +267,7 @@ int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
+ trace_ext4_forget(inode, is_metadata, blocknr);
+ BUFFER_TRACE(bh, "enter");
+
+- jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
+- "data mode %x\n",
++ ext4_debug("forgetting bh %p: is_metadata=%d, mode %o, data mode %x\n",
+ bh, is_metadata, inode->i_mode,
+ test_opt(inode->i_sb, DATA_FLAGS));
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 9e09caaf9b0b3..d3fae909fcbf8 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5810,6 +5810,14 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
+ struct ext4_extent *extent;
+ ext4_lblk_t first_lblk, first_lclu, last_lclu;
+
++ /*
++ * if data can be stored inline, the logical cluster isn't
++ * mapped - no physical clusters have been allocated, and the
++ * file has no extents
++ */
++ if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
++ return 0;
++
+ /* search for the extent closest to the first block in the cluster */
+ path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
+ if (IS_ERR(path)) {
+diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
+index 9a3a8996aacf7..aa99a3659edfc 100644
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -1372,7 +1372,7 @@ retry:
+ if (count_reserved)
+ count_rsvd(inode, lblk, orig_es.es_len - len1 - len2,
+ &orig_es, &rc);
+- goto out;
++ goto out_get_reserved;
+ }
+
+ if (len1 > 0) {
+@@ -1414,6 +1414,7 @@ retry:
+ }
+ }
+
++out_get_reserved:
+ if (count_reserved)
+ *reserved = get_rsvd(inode, end, es, &rc);
+ out:
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index be3f8ce98962f..a8d0a8081a1da 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -399,25 +399,34 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
+ struct __track_dentry_update_args *dentry_update =
+ (struct __track_dentry_update_args *)arg;
+ struct dentry *dentry = dentry_update->dentry;
+- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++ struct inode *dir = dentry->d_parent->d_inode;
++ struct super_block *sb = inode->i_sb;
++ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ mutex_unlock(&ei->i_fc_lock);
++
++ if (IS_ENCRYPTED(dir)) {
++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME,
++ NULL);
++ mutex_lock(&ei->i_fc_lock);
++ return -EOPNOTSUPP;
++ }
++
+ node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
+ if (!node) {
+- ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL);
++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+ mutex_lock(&ei->i_fc_lock);
+ return -ENOMEM;
+ }
+
+ node->fcd_op = dentry_update->op;
+- node->fcd_parent = dentry->d_parent->d_inode->i_ino;
++ node->fcd_parent = dir->i_ino;
+ node->fcd_ino = inode->i_ino;
+ if (dentry->d_name.len > DNAME_INLINE_LEN) {
+ node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS);
+ if (!node->fcd_name.name) {
+ kmem_cache_free(ext4_fc_dentry_cachep, node);
+- ext4_fc_mark_ineligible(inode->i_sb,
+- EXT4_FC_REASON_NOMEM, NULL);
++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+ mutex_lock(&ei->i_fc_lock);
+ return -ENOMEM;
+ }
+@@ -595,6 +604,15 @@ static void ext4_fc_submit_bh(struct super_block *sb, bool is_tail)
+
+ /* Ext4 commit path routines */
+
++/* memcpy to fc reserved space and update CRC */
++static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src,
++ int len, u32 *crc)
++{
++ if (crc)
++ *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len);
++ return memcpy(dst, src, len);
++}
++
+ /* memzero and update CRC */
+ static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len,
+ u32 *crc)
+@@ -620,62 +638,59 @@ static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len,
+ */
+ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ {
+- struct ext4_fc_tl *tl;
++ struct ext4_fc_tl tl;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct buffer_head *bh;
+ int bsize = sbi->s_journal->j_blocksize;
+ int ret, off = sbi->s_fc_bytes % bsize;
+- int pad_len;
++ int remaining;
++ u8 *dst;
+
+ /*
+- * After allocating len, we should have space at least for a 0 byte
+- * padding.
++ * If 'len' is too long to fit in any block alongside a PAD tlv, then we
++ * cannot fulfill the request.
+ */
+- if (len + sizeof(struct ext4_fc_tl) > bsize)
++ if (len > bsize - EXT4_FC_TAG_BASE_LEN)
+ return NULL;
+
+- if (bsize - off - 1 > len + sizeof(struct ext4_fc_tl)) {
+- /*
+- * Only allocate from current buffer if we have enough space for
+- * this request AND we have space to add a zero byte padding.
+- */
+- if (!sbi->s_fc_bh) {
+- ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
+- if (ret)
+- return NULL;
+- sbi->s_fc_bh = bh;
+- }
++ if (!sbi->s_fc_bh) {
++ ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
++ if (ret)
++ return NULL;
++ sbi->s_fc_bh = bh;
++ }
++ dst = sbi->s_fc_bh->b_data + off;
++
++ /*
++ * Allocate the bytes in the current block if we can do so while still
++ * leaving enough space for a PAD tlv.
++ */
++ remaining = bsize - EXT4_FC_TAG_BASE_LEN - off;
++ if (len <= remaining) {
+ sbi->s_fc_bytes += len;
+- return sbi->s_fc_bh->b_data + off;
++ return dst;
+ }
+- /* Need to add PAD tag */
+- tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off);
+- tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
+- pad_len = bsize - off - 1 - sizeof(struct ext4_fc_tl);
+- tl->fc_len = cpu_to_le16(pad_len);
+- if (crc)
+- *crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl));
+- if (pad_len > 0)
+- ext4_fc_memzero(sb, tl + 1, pad_len, crc);
++
++ /*
++ * Else, terminate the current block with a PAD tlv, then allocate a new
++ * block and allocate the bytes at the start of that new block.
++ */
++
++ tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
++ tl.fc_len = cpu_to_le16(remaining);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++ ext4_fc_memzero(sb, dst + EXT4_FC_TAG_BASE_LEN, remaining, crc);
++
+ ext4_fc_submit_bh(sb, false);
+
+ ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
+ if (ret)
+ return NULL;
+ sbi->s_fc_bh = bh;
+- sbi->s_fc_bytes = (sbi->s_fc_bytes / bsize + 1) * bsize + len;
++ sbi->s_fc_bytes += bsize - off + len;
+ return sbi->s_fc_bh->b_data;
+ }
+
+-/* memcpy to fc reserved space and update CRC */
+-static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src,
+- int len, u32 *crc)
+-{
+- if (crc)
+- *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len);
+- return memcpy(dst, src, len);
+-}
+-
+ /*
+ * Complete a fast commit by writing tail tag.
+ *
+@@ -696,23 +711,25 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ * ext4_fc_reserve_space takes care of allocating an extra block if
+ * there's no enough space on this block for accommodating this tail.
+ */
+- dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(tail), &crc);
++ dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + sizeof(tail), &crc);
+ if (!dst)
+ return -ENOSPC;
+
+ off = sbi->s_fc_bytes % bsize;
+
+ tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_TAIL);
+- tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail));
++ tl.fc_len = cpu_to_le16(bsize - off + sizeof(struct ext4_fc_tail));
+ sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize);
+
+- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), &crc);
+- dst += sizeof(tl);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc);
++ dst += EXT4_FC_TAG_BASE_LEN;
+ tail.fc_tid = cpu_to_le32(sbi->s_journal->j_running_transaction->t_tid);
+ ext4_fc_memcpy(sb, dst, &tail.fc_tid, sizeof(tail.fc_tid), &crc);
+ dst += sizeof(tail.fc_tid);
+ tail.fc_crc = cpu_to_le32(crc);
+ ext4_fc_memcpy(sb, dst, &tail.fc_crc, sizeof(tail.fc_crc), NULL);
++ dst += sizeof(tail.fc_crc);
++ memset(dst, 0, bsize - off); /* Don't leak uninitialized memory. */
+
+ ext4_fc_submit_bh(sb, true);
+
+@@ -729,15 +746,15 @@ static bool ext4_fc_add_tlv(struct super_block *sb, u16 tag, u16 len, u8 *val,
+ struct ext4_fc_tl tl;
+ u8 *dst;
+
+- dst = ext4_fc_reserve_space(sb, sizeof(tl) + len, crc);
++ dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + len, crc);
+ if (!dst)
+ return false;
+
+ tl.fc_tag = cpu_to_le16(tag);
+ tl.fc_len = cpu_to_le16(len);
+
+- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc);
+- ext4_fc_memcpy(sb, dst + sizeof(tl), val, len, crc);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++ ext4_fc_memcpy(sb, dst + EXT4_FC_TAG_BASE_LEN, val, len, crc);
+
+ return true;
+ }
+@@ -749,8 +766,8 @@ static bool ext4_fc_add_dentry_tlv(struct super_block *sb, u32 *crc,
+ struct ext4_fc_dentry_info fcd;
+ struct ext4_fc_tl tl;
+ int dlen = fc_dentry->fcd_name.len;
+- u8 *dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(fcd) + dlen,
+- crc);
++ u8 *dst = ext4_fc_reserve_space(sb,
++ EXT4_FC_TAG_BASE_LEN + sizeof(fcd) + dlen, crc);
+
+ if (!dst)
+ return false;
+@@ -759,8 +776,8 @@ static bool ext4_fc_add_dentry_tlv(struct super_block *sb, u32 *crc,
+ fcd.fc_ino = cpu_to_le32(fc_dentry->fcd_ino);
+ tl.fc_tag = cpu_to_le16(fc_dentry->fcd_op);
+ tl.fc_len = cpu_to_le16(sizeof(fcd) + dlen);
+- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc);
+- dst += sizeof(tl);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++ dst += EXT4_FC_TAG_BASE_LEN;
+ ext4_fc_memcpy(sb, dst, &fcd, sizeof(fcd), crc);
+ dst += sizeof(fcd);
+ ext4_fc_memcpy(sb, dst, fc_dentry->fcd_name.name, dlen, crc);
+@@ -796,13 +813,13 @@ static int ext4_fc_write_inode(struct inode *inode, u32 *crc)
+
+ ret = -ECANCELED;
+ dst = ext4_fc_reserve_space(inode->i_sb,
+- sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc);
++ EXT4_FC_TAG_BASE_LEN + inode_len + sizeof(fc_inode.fc_ino), crc);
+ if (!dst)
+ goto err;
+
+- if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc))
++ if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc))
+ goto err;
+- dst += sizeof(tl);
++ dst += EXT4_FC_TAG_BASE_LEN;
+ if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc))
+ goto err;
+ dst += sizeof(fc_inode);
+@@ -840,8 +857,8 @@ static int ext4_fc_write_inode_data(struct inode *inode, u32 *crc)
+ mutex_unlock(&ei->i_fc_lock);
+
+ cur_lblk_off = old_blk_size;
+- jbd_debug(1, "%s: will try writing %d to %d for inode %ld\n",
+- __func__, cur_lblk_off, new_blk_size, inode->i_ino);
++ ext4_debug("will try writing %d to %d for inode %ld\n",
++ cur_lblk_off, new_blk_size, inode->i_ino);
+
+ while (cur_lblk_off <= new_blk_size) {
+ map.m_lblk = cur_lblk_off;
+@@ -1096,7 +1113,7 @@ static void ext4_fc_update_stats(struct super_block *sb, int status,
+ {
+ struct ext4_fc_stats *stats = &EXT4_SB(sb)->s_fc_stats;
+
+- jbd_debug(1, "Fast commit ended with status = %d", status);
++ ext4_debug("Fast commit ended with status = %d", status);
+ if (status == EXT4_FC_STATUS_OK) {
+ stats->fc_num_commits++;
+ stats->fc_numblks += nblks;
+@@ -1266,7 +1283,7 @@ struct dentry_info_args {
+ };
+
+ static inline void tl_to_darg(struct dentry_info_args *darg,
+- struct ext4_fc_tl *tl, u8 *val)
++ struct ext4_fc_tl *tl, u8 *val)
+ {
+ struct ext4_fc_dentry_info fcd;
+
+@@ -1275,8 +1292,14 @@ static inline void tl_to_darg(struct dentry_info_args *darg,
+ darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino);
+ darg->ino = le32_to_cpu(fcd.fc_ino);
+ darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname);
+- darg->dname_len = le16_to_cpu(tl->fc_len) -
+- sizeof(struct ext4_fc_dentry_info);
++ darg->dname_len = tl->fc_len - sizeof(struct ext4_fc_dentry_info);
++}
++
++static inline void ext4_fc_get_tl(struct ext4_fc_tl *tl, u8 *val)
++{
++ memcpy(tl, val, EXT4_FC_TAG_BASE_LEN);
++ tl->fc_len = le16_to_cpu(tl->fc_len);
++ tl->fc_tag = le16_to_cpu(tl->fc_tag);
+ }
+
+ /* Unlink replay function */
+@@ -1298,19 +1321,19 @@ static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
+ inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL);
+
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "Inode %d not found", darg.ino);
++ ext4_debug("Inode %d not found", darg.ino);
+ return 0;
+ }
+
+ old_parent = ext4_iget(sb, darg.parent_ino,
+ EXT4_IGET_NORMAL);
+ if (IS_ERR(old_parent)) {
+- jbd_debug(1, "Dir with inode %d not found", darg.parent_ino);
++ ext4_debug("Dir with inode %d not found", darg.parent_ino);
+ iput(inode);
+ return 0;
+ }
+
+- ret = __ext4_unlink(NULL, old_parent, &entry, inode);
++ ret = __ext4_unlink(old_parent, &entry, inode, NULL);
+ /* -ENOENT ok coz it might not exist anymore. */
+ if (ret == -ENOENT)
+ ret = 0;
+@@ -1330,21 +1353,21 @@ static int ext4_fc_replay_link_internal(struct super_block *sb,
+
+ dir = ext4_iget(sb, darg->parent_ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(dir)) {
+- jbd_debug(1, "Dir with inode %d not found.", darg->parent_ino);
++ ext4_debug("Dir with inode %d not found.", darg->parent_ino);
+ dir = NULL;
+ goto out;
+ }
+
+ dentry_dir = d_obtain_alias(dir);
+ if (IS_ERR(dentry_dir)) {
+- jbd_debug(1, "Failed to obtain dentry");
++ ext4_debug("Failed to obtain dentry");
+ dentry_dir = NULL;
+ goto out;
+ }
+
+ dentry_inode = d_alloc(dentry_dir, &qstr_dname);
+ if (!dentry_inode) {
+- jbd_debug(1, "Inode dentry not created.");
++ ext4_debug("Inode dentry not created.");
+ ret = -ENOMEM;
+ goto out;
+ }
+@@ -1357,7 +1380,7 @@ static int ext4_fc_replay_link_internal(struct super_block *sb,
+ * could complete.
+ */
+ if (ret && ret != -EEXIST) {
+- jbd_debug(1, "Failed to link\n");
++ ext4_debug("Failed to link\n");
+ goto out;
+ }
+
+@@ -1391,7 +1414,7 @@ static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl,
+
+ inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "Inode not found.");
++ ext4_debug("Inode not found.");
+ return 0;
+ }
+
+@@ -1441,7 +1464,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ struct ext4_inode *raw_fc_inode;
+ struct inode *inode = NULL;
+ struct ext4_iloc iloc;
+- int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag);
++ int inode_len, ino, ret, tag = tl->fc_tag;
+ struct ext4_extent_header *eh;
+
+ memcpy(&fc_inode, val, sizeof(fc_inode));
+@@ -1466,7 +1489,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ if (ret)
+ goto out;
+
+- inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode);
++ inode_len = tl->fc_len - sizeof(struct ext4_fc_inode);
+ raw_inode = ext4_raw_inode(&iloc);
+
+ memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block));
+@@ -1501,7 +1524,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ /* Given that we just wrote the inode on disk, this SHOULD succeed. */
+ inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "Inode not found.");
++ ext4_debug("Inode not found.");
+ return -EFSCORRUPTED;
+ }
+
+@@ -1554,7 +1577,7 @@ static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl,
+
+ inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "inode %d not found.", darg.ino);
++ ext4_debug("inode %d not found.", darg.ino);
+ inode = NULL;
+ ret = -EINVAL;
+ goto out;
+@@ -1567,7 +1590,7 @@ static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl,
+ */
+ dir = ext4_iget(sb, darg.parent_ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(dir)) {
+- jbd_debug(1, "Dir %d not found.", darg.ino);
++ ext4_debug("Dir %d not found.", darg.ino);
+ goto out;
+ }
+ ret = ext4_init_new_dir(NULL, dir, inode);
+@@ -1655,7 +1678,7 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
+
+ inode = ext4_iget(sb, le32_to_cpu(fc_add_ex.fc_ino), EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "Inode not found.");
++ ext4_debug("Inode not found.");
+ return 0;
+ }
+
+@@ -1669,7 +1692,7 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
+
+ cur = start;
+ remaining = len;
+- jbd_debug(1, "ADD_RANGE, lblk %d, pblk %lld, len %d, unwritten %d, inode %ld\n",
++ ext4_debug("ADD_RANGE, lblk %d, pblk %lld, len %d, unwritten %d, inode %ld\n",
+ start, start_pblk, len, ext4_ext_is_unwritten(ex),
+ inode->i_ino);
+
+@@ -1730,7 +1753,7 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
+ }
+
+ /* Range is mapped and needs a state change */
+- jbd_debug(1, "Converting from %ld to %d %lld",
++ ext4_debug("Converting from %ld to %d %lld",
+ map.m_flags & EXT4_MAP_UNWRITTEN,
+ ext4_ext_is_unwritten(ex), map.m_pblk);
+ ret = ext4_ext_replay_update_ex(inode, cur, map.m_len,
+@@ -1773,7 +1796,7 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
+
+ inode = ext4_iget(sb, le32_to_cpu(lrange.fc_ino), EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange.fc_ino));
++ ext4_debug("Inode %d not found", le32_to_cpu(lrange.fc_ino));
+ return 0;
+ }
+
+@@ -1781,7 +1804,7 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
+ if (ret)
+ goto out;
+
+- jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n",
++ ext4_debug("DEL_RANGE, inode %ld, lblk %d, len %d\n",
+ inode->i_ino, le32_to_cpu(lrange.fc_lblk),
+ le32_to_cpu(lrange.fc_len));
+ while (remaining > 0) {
+@@ -1830,7 +1853,7 @@ static void ext4_fc_set_bitmaps_and_counters(struct super_block *sb)
+ inode = ext4_iget(sb, state->fc_modified_inodes[i],
+ EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+- jbd_debug(1, "Inode %d not found.",
++ ext4_debug("Inode %d not found.",
+ state->fc_modified_inodes[i]);
+ continue;
+ }
+@@ -1896,6 +1919,33 @@ void ext4_fc_replay_cleanup(struct super_block *sb)
+ kfree(sbi->s_fc_replay_state.fc_modified_inodes);
+ }
+
++static bool ext4_fc_value_len_isvalid(struct ext4_sb_info *sbi,
++ int tag, int len)
++{
++ switch (tag) {
++ case EXT4_FC_TAG_ADD_RANGE:
++ return len == sizeof(struct ext4_fc_add_range);
++ case EXT4_FC_TAG_DEL_RANGE:
++ return len == sizeof(struct ext4_fc_del_range);
++ case EXT4_FC_TAG_CREAT:
++ case EXT4_FC_TAG_LINK:
++ case EXT4_FC_TAG_UNLINK:
++ len -= sizeof(struct ext4_fc_dentry_info);
++ return len >= 1 && len <= EXT4_NAME_LEN;
++ case EXT4_FC_TAG_INODE:
++ len -= sizeof(struct ext4_fc_inode);
++ return len >= EXT4_GOOD_OLD_INODE_SIZE &&
++ len <= sbi->s_inode_size;
++ case EXT4_FC_TAG_PAD:
++ return true; /* padding can have any length */
++ case EXT4_FC_TAG_TAIL:
++ return len >= sizeof(struct ext4_fc_tail);
++ case EXT4_FC_TAG_HEAD:
++ return len == sizeof(struct ext4_fc_head);
++ }
++ return false;
++}
++
+ /*
+ * Recovery Scan phase handler
+ *
+@@ -1931,7 +1981,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ state = &sbi->s_fc_replay_state;
+
+ start = (u8 *)bh->b_data;
+- end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
++ end = start + journal->j_blocksize;
+
+ if (state->fc_replay_expected_off == 0) {
+ state->fc_cur_tag = 0;
+@@ -1952,12 +2002,19 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ }
+
+ state->fc_replay_expected_off++;
+- for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
+- memcpy(&tl, cur, sizeof(tl));
+- val = cur + sizeof(tl);
+- jbd_debug(3, "Scan phase, tag:%s, blk %lld\n",
+- tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
+- switch (le16_to_cpu(tl.fc_tag)) {
++ for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN;
++ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
++ ext4_fc_get_tl(&tl, cur);
++ val = cur + EXT4_FC_TAG_BASE_LEN;
++ if (tl.fc_len > end - val ||
++ !ext4_fc_value_len_isvalid(sbi, tl.fc_tag, tl.fc_len)) {
++ ret = state->fc_replay_num_tags ?
++ JBD2_FC_REPLAY_STOP : -ECANCELED;
++ goto out_err;
++ }
++ ext4_debug("Scan phase, tag:%s, blk %lld\n",
++ tag2str(tl.fc_tag), bh->b_blocknr);
++ switch (tl.fc_tag) {
+ case EXT4_FC_TAG_ADD_RANGE:
+ memcpy(&ext, val, sizeof(ext));
+ ex = (struct ext4_extent *)&ext.fc_ex;
+@@ -1977,13 +2034,13 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ case EXT4_FC_TAG_PAD:
+ state->fc_cur_tag++;
+ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+- sizeof(tl) + le16_to_cpu(tl.fc_len));
++ EXT4_FC_TAG_BASE_LEN + tl.fc_len);
+ break;
+ case EXT4_FC_TAG_TAIL:
+ state->fc_cur_tag++;
+ memcpy(&tail, val, sizeof(tail));
+ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+- sizeof(tl) +
++ EXT4_FC_TAG_BASE_LEN +
+ offsetof(struct ext4_fc_tail,
+ fc_crc));
+ if (le32_to_cpu(tail.fc_tid) == expected_tid &&
+@@ -2010,7 +2067,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ }
+ state->fc_cur_tag++;
+ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+- sizeof(tl) + le16_to_cpu(tl.fc_len));
++ EXT4_FC_TAG_BASE_LEN + tl.fc_len);
+ break;
+ default:
+ ret = state->fc_replay_num_tags ?
+@@ -2050,7 +2107,7 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ sbi->s_mount_state |= EXT4_FC_REPLAY;
+ }
+ if (!sbi->s_fc_replay_state.fc_replay_num_tags) {
+- jbd_debug(1, "Replay stops\n");
++ ext4_debug("Replay stops\n");
+ ext4_fc_set_bitmaps_and_counters(sb);
+ return 0;
+ }
+@@ -2063,21 +2120,22 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ #endif
+
+ start = (u8 *)bh->b_data;
+- end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
++ end = start + journal->j_blocksize;
+
+- for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
+- memcpy(&tl, cur, sizeof(tl));
+- val = cur + sizeof(tl);
++ for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN;
++ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
++ ext4_fc_get_tl(&tl, cur);
++ val = cur + EXT4_FC_TAG_BASE_LEN;
+
+ if (state->fc_replay_num_tags == 0) {
+ ret = JBD2_FC_REPLAY_STOP;
+ ext4_fc_set_bitmaps_and_counters(sb);
+ break;
+ }
+- jbd_debug(3, "Replay phase, tag:%s\n",
+- tag2str(le16_to_cpu(tl.fc_tag)));
++
++ ext4_debug("Replay phase, tag:%s\n", tag2str(tl.fc_tag));
+ state->fc_replay_num_tags--;
+- switch (le16_to_cpu(tl.fc_tag)) {
++ switch (tl.fc_tag) {
+ case EXT4_FC_TAG_LINK:
+ ret = ext4_fc_replay_link(sb, &tl, val);
+ break;
+@@ -2098,19 +2156,18 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ break;
+ case EXT4_FC_TAG_PAD:
+ trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0,
+- le16_to_cpu(tl.fc_len), 0);
++ tl.fc_len, 0);
+ break;
+ case EXT4_FC_TAG_TAIL:
+- trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0,
+- le16_to_cpu(tl.fc_len), 0);
++ trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL,
++ 0, tl.fc_len, 0);
+ memcpy(&tail, val, sizeof(tail));
+ WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid);
+ break;
+ case EXT4_FC_TAG_HEAD:
+ break;
+ default:
+- trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0,
+- le16_to_cpu(tl.fc_len), 0);
++ trace_ext4_fc_replay(sb, tl.fc_tag, 0, tl.fc_len, 0);
+ ret = -ECANCELED;
+ break;
+ }
+@@ -2134,17 +2191,17 @@ void ext4_fc_init(struct super_block *sb, journal_t *journal)
+ journal->j_fc_cleanup_callback = ext4_fc_cleanup;
+ }
+
+-static const char *fc_ineligible_reasons[] = {
+- "Extended attributes changed",
+- "Cross rename",
+- "Journal flag changed",
+- "Insufficient memory",
+- "Swap boot",
+- "Resize",
+- "Dir renamed",
+- "Falloc range op",
+- "Data journalling",
+- "FC Commit Failed"
++static const char * const fc_ineligible_reasons[] = {
++ [EXT4_FC_REASON_XATTR] = "Extended attributes changed",
++ [EXT4_FC_REASON_CROSS_RENAME] = "Cross rename",
++ [EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed",
++ [EXT4_FC_REASON_NOMEM] = "Insufficient memory",
++ [EXT4_FC_REASON_SWAP_BOOT] = "Swap boot",
++ [EXT4_FC_REASON_RESIZE] = "Resize",
++ [EXT4_FC_REASON_RENAME_DIR] = "Dir renamed",
++ [EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op",
++ [EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
++ [EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
+ };
+
+ int ext4_fc_info_show(struct seq_file *seq, void *v)
+diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
+index 083ad1cb705a7..2cbd317eda26b 100644
+--- a/fs/ext4/fast_commit.h
++++ b/fs/ext4/fast_commit.h
+@@ -58,7 +58,7 @@ struct ext4_fc_dentry_info {
+ __u8 fc_dname[0];
+ };
+
+-/* Value structure for EXT4_FC_TAG_INODE and EXT4_FC_TAG_INODE_PARTIAL. */
++/* Value structure for EXT4_FC_TAG_INODE. */
+ struct ext4_fc_inode {
+ __le32 fc_ino;
+ __u8 fc_raw_inode[0];
+@@ -70,6 +70,9 @@ struct ext4_fc_tail {
+ __le32 fc_crc;
+ };
+
++/* Tag base length */
++#define EXT4_FC_TAG_BASE_LEN (sizeof(struct ext4_fc_tl))
++
+ /*
+ * Fast commit status codes
+ */
+@@ -93,7 +96,7 @@ enum {
+ EXT4_FC_REASON_RENAME_DIR,
+ EXT4_FC_REASON_FALLOC_RANGE,
+ EXT4_FC_REASON_INODE_JOURNAL_DATA,
+- EXT4_FC_COMMIT_FAILED,
++ EXT4_FC_REASON_ENCRYPTED_FILENAME,
+ EXT4_FC_REASON_MAX
+ };
+
+diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
+index 89efa78ed4b21..9813cc4b7b2a9 100644
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -148,6 +148,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ struct super_block *sb = inode->i_sb;
+ Indirect *p = chain;
+ struct buffer_head *bh;
++ unsigned int key;
+ int ret = -EIO;
+
+ *err = 0;
+@@ -156,7 +157,13 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ if (!p->key)
+ goto no_block;
+ while (--depth) {
+- bh = sb_getblk(sb, le32_to_cpu(p->key));
++ key = le32_to_cpu(p->key);
++ if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) {
++ /* the block was out of range */
++ ret = -EFSCORRUPTED;
++ goto failure;
++ }
++ bh = sb_getblk(sb, key);
+ if (unlikely(!bh)) {
+ ret = -ENOMEM;
+ goto failure;
+@@ -460,7 +467,7 @@ static int ext4_splice_branch(handle_t *handle,
+ * the new i_size. But that is not done here - it is done in
+ * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode.
+ */
+- jbd_debug(5, "splicing indirect only\n");
++ ext4_debug("splicing indirect only\n");
+ BUFFER_TRACE(where->bh, "call ext4_handle_dirty_metadata");
+ err = ext4_handle_dirty_metadata(handle, ar->inode, where->bh);
+ if (err)
+@@ -472,7 +479,7 @@ static int ext4_splice_branch(handle_t *handle,
+ err = ext4_mark_inode_dirty(handle, ar->inode);
+ if (unlikely(err))
+ goto err_out;
+- jbd_debug(5, "splicing direct\n");
++ ext4_debug("splicing direct\n");
+ }
+ return err;
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index bdadbe57ea804..0a63863bc58c1 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -225,13 +225,13 @@ void ext4_evict_inode(struct inode *inode)
+
+ /*
+ * For inodes with journalled data, transaction commit could have
+- * dirtied the inode. Flush worker is ignoring it because of I_FREEING
+- * flag but we still need to remove the inode from the writeback lists.
++ * dirtied the inode. And for inodes with dioread_nolock, unwritten
++ * extents converting worker could merge extents and also have dirtied
++ * the inode. Flush worker is ignoring it because of I_FREEING flag but
++ * we still need to remove the inode from the writeback lists.
+ */
+- if (!list_empty_careful(&inode->i_io_list)) {
+- WARN_ON_ONCE(!ext4_should_journal_data(inode));
++ if (!list_empty_careful(&inode->i_io_list))
+ inode_io_list_del(inode);
+- }
+
+ /*
+ * Protect us against freezing - iput() caller didn't have to have any
+@@ -338,6 +338,12 @@ stop_handle:
+ ext4_xattr_inode_array_free(ea_inode_array);
+ return;
+ no_delete:
++ /*
++ * Check out some where else accidentally dirty the evicting inode,
++ * which may probably cause inode use-after-free issues later.
++ */
++ WARN_ON_ONCE(!list_empty_careful(&inode->i_io_list));
++
+ if (!list_empty(&EXT4_I(inode)->i_fc_list))
+ ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL);
+ ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
+@@ -1298,7 +1304,8 @@ static int ext4_write_end(struct file *file,
+
+ trace_ext4_write_end(inode, pos, len, copied);
+
+- if (ext4_has_inline_data(inode))
++ if (ext4_has_inline_data(inode) &&
++ ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+ return ext4_write_inline_data_end(inode, pos, len, copied, page);
+
+ copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+@@ -4198,7 +4205,8 @@ int ext4_truncate(struct inode *inode)
+
+ /* If we zero-out tail of the page, we have to create jinode for jbd2 */
+ if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
+- if (ext4_inode_attach_jinode(inode) < 0)
++ err = ext4_inode_attach_jinode(inode);
++ if (err)
+ goto out_trace;
+ }
+
+@@ -4299,9 +4307,17 @@ static int __ext4_get_inode_loc(struct super_block *sb, unsigned long ino,
+ inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
+ inode_offset = ((ino - 1) %
+ EXT4_INODES_PER_GROUP(sb));
+- block = ext4_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
+ iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
+
++ block = ext4_inode_table(sb, gdp);
++ if ((block <= le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) ||
++ (block >= ext4_blocks_count(EXT4_SB(sb)->s_es))) {
++ ext4_error(sb, "Invalid inode table block %llu in "
++ "block_group %u", block, iloc->block_group);
++ return -EFSCORRUPTED;
++ }
++ block += (inode_offset / inodes_per_block);
++
+ bh = sb_getblk(sb, block);
+ if (unlikely(!bh))
+ return -ENOMEM;
+@@ -4876,8 +4892,14 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+ if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb))
+ ext4_error_inode(inode, function, line, 0,
+ "casefold flag without casefold feature");
+- brelse(iloc.bh);
++ if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD)) {
++ ext4_error_inode(inode, function, line, 0,
++ "bad inode without EXT4_IGET_BAD flag");
++ ret = -EUCLEAN;
++ goto bad_inode;
++ }
+
++ brelse(iloc.bh);
+ unlock_new_inode(inode);
+ return inode;
+
+@@ -5198,7 +5220,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
+
+ if (EXT4_SB(inode->i_sb)->s_journal) {
+ if (ext4_journal_current_handle()) {
+- jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
++ ext4_debug("called recursively, non-PF_MEMALLOC!\n");
+ dump_stack();
+ return -EIO;
+ }
+@@ -5791,6 +5813,14 @@ static int __ext4_expand_extra_isize(struct inode *inode,
+ return 0;
+ }
+
++ /*
++ * We may need to allocate external xattr block so we need quotas
++ * initialized. Here we can be called with various locks held so we
++ * cannot affort to initialize quotas ourselves. So just bail.
++ */
++ if (dquot_initialize_needed(inode))
++ return -EAGAIN;
++
+ /* try to expand with EAs present */
+ error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
+ raw_inode, handle);
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index f61b59045c6d3..2e6d03e5790e5 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -124,7 +124,8 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ blkcnt_t blocks;
+ unsigned short bytes;
+
+- inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
++ inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO,
++ EXT4_IGET_SPECIAL | EXT4_IGET_BAD);
+ if (IS_ERR(inode_bl))
+ return PTR_ERR(inode_bl);
+ ei_bl = EXT4_I(inode_bl);
+@@ -174,7 +175,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ /* Protect extent tree against block allocations via delalloc */
+ ext4_double_down_write_data_sem(inode, inode_bl);
+
+- if (inode_bl->i_nlink == 0) {
++ if (is_bad_inode(inode_bl) || !S_ISREG(inode_bl->i_mode)) {
+ /* this inode has never been used as a BOOT_LOADER */
+ set_nlink(inode_bl, 1);
+ i_uid_write(inode_bl, 0);
+@@ -491,6 +492,10 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ if (ext4_is_quota_file(inode))
+ return err;
+
++ err = dquot_initialize(inode);
++ if (err)
++ return err;
++
+ err = ext4_get_inode_loc(inode, &iloc);
+ if (err)
+ return err;
+@@ -506,10 +511,6 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ brelse(iloc.bh);
+ }
+
+- err = dquot_initialize(inode);
+- if (err)
+- return err;
+-
+ handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+ EXT4_QUOTA_INIT_BLOCKS(sb) +
+ EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index b8cf3e986b000..1e6cc6c21d606 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -3204,14 +3204,20 @@ end_rmdir:
+ return retval;
+ }
+
+-int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
+- struct inode *inode)
++int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
++ struct inode *inode,
++ struct dentry *dentry /* NULL during fast_commit recovery */)
+ {
+ int retval = -ENOENT;
+ struct buffer_head *bh;
+ struct ext4_dir_entry_2 *de;
++ handle_t *handle;
+ int skip_remove_dentry = 0;
+
++ /*
++ * Keep this outside the transaction; it may have to set up the
++ * directory's encryption key, which isn't GFP_NOFS-safe.
++ */
+ bh = ext4_find_entry(dir, d_name, &de, NULL);
+ if (IS_ERR(bh))
+ return PTR_ERR(bh);
+@@ -3228,7 +3234,14 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
+ skip_remove_dentry = 1;
+ else
+- goto out;
++ goto out_bh;
++ }
++
++ handle = ext4_journal_start(dir, EXT4_HT_DIR,
++ EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
++ if (IS_ERR(handle)) {
++ retval = PTR_ERR(handle);
++ goto out_bh;
+ }
+
+ if (IS_DIRSYNC(dir))
+@@ -3237,12 +3250,12 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ if (!skip_remove_dentry) {
+ retval = ext4_delete_entry(handle, dir, de, bh);
+ if (retval)
+- goto out;
++ goto out_handle;
+ dir->i_ctime = dir->i_mtime = current_time(dir);
+ ext4_update_dx_flag(dir);
+ retval = ext4_mark_inode_dirty(handle, dir);
+ if (retval)
+- goto out;
++ goto out_handle;
+ } else {
+ retval = 0;
+ }
+@@ -3255,15 +3268,17 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ ext4_orphan_add(handle, inode);
+ inode->i_ctime = current_time(inode);
+ retval = ext4_mark_inode_dirty(handle, inode);
+-
+-out:
++ if (dentry && !retval)
++ ext4_fc_track_unlink(handle, dentry);
++out_handle:
++ ext4_journal_stop(handle);
++out_bh:
+ brelse(bh);
+ return retval;
+ }
+
+ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ {
+- handle_t *handle;
+ int retval;
+
+ if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb))))
+@@ -3281,16 +3296,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ if (retval)
+ goto out_trace;
+
+- handle = ext4_journal_start(dir, EXT4_HT_DIR,
+- EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
+- if (IS_ERR(handle)) {
+- retval = PTR_ERR(handle);
+- goto out_trace;
+- }
+-
+- retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry));
+- if (!retval)
+- ext4_fc_track_unlink(handle, dentry);
++ retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry);
+ #ifdef CONFIG_UNICODE
+ /* VFS negative dentries are incompatible with Encoding and
+ * Case-insensitiveness. Eventually we'll want avoid
+@@ -3301,8 +3307,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ if (IS_CASEFOLDED(dir))
+ d_invalidate(dentry);
+ #endif
+- if (handle)
+- ext4_journal_stop(handle);
+
+ out_trace:
+ trace_ext4_unlink_exit(dentry, retval);
+@@ -3806,6 +3810,9 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+ return -EXDEV;
+
+ retval = dquot_initialize(old.dir);
++ if (retval)
++ return retval;
++ retval = dquot_initialize(old.inode);
+ if (retval)
+ return retval;
+ retval = dquot_initialize(new.dir);
+diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
+index 53adc8f570a3f..c26c404ac58bf 100644
+--- a/fs/ext4/orphan.c
++++ b/fs/ext4/orphan.c
+@@ -181,8 +181,8 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
+ } else
+ brelse(iloc.bh);
+
+- jbd_debug(4, "superblock will point to %lu\n", inode->i_ino);
+- jbd_debug(4, "orphan inode %lu will point to %d\n",
++ ext4_debug("superblock will point to %lu\n", inode->i_ino);
++ ext4_debug("orphan inode %lu will point to %d\n",
+ inode->i_ino, NEXT_ORPHAN(inode));
+ out:
+ ext4_std_error(sb, err);
+@@ -251,7 +251,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
+ }
+
+ mutex_lock(&sbi->s_orphan_lock);
+- jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
++ ext4_debug("remove inode %lu from orphan list\n", inode->i_ino);
+
+ prev = ei->i_orphan.prev;
+ list_del_init(&ei->i_orphan);
+@@ -267,7 +267,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
+
+ ino_next = NEXT_ORPHAN(inode);
+ if (prev == &sbi->s_orphan) {
+- jbd_debug(4, "superblock will point to %u\n", ino_next);
++ ext4_debug("superblock will point to %u\n", ino_next);
+ BUFFER_TRACE(sbi->s_sbh, "get_write_access");
+ err = ext4_journal_get_write_access(handle, inode->i_sb,
+ sbi->s_sbh, EXT4_JTR_NONE);
+@@ -286,7 +286,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
+ struct inode *i_prev =
+ &list_entry(prev, struct ext4_inode_info, i_orphan)->vfs_inode;
+
+- jbd_debug(4, "orphan inode %lu will point to %u\n",
++ ext4_debug("orphan inode %lu will point to %u\n",
+ i_prev->i_ino, ino_next);
+ err = ext4_reserve_inode_write(handle, i_prev, &iloc2);
+ if (err) {
+@@ -332,8 +332,8 @@ static void ext4_process_orphan(struct inode *inode,
+ ext4_msg(sb, KERN_DEBUG,
+ "%s: truncating inode %lu to %lld bytes",
+ __func__, inode->i_ino, inode->i_size);
+- jbd_debug(2, "truncating inode %lu to %lld bytes\n",
+- inode->i_ino, inode->i_size);
++ ext4_debug("truncating inode %lu to %lld bytes\n",
++ inode->i_ino, inode->i_size);
+ inode_lock(inode);
+ truncate_inode_pages(inode->i_mapping, inode->i_size);
+ ret = ext4_truncate(inode);
+@@ -353,8 +353,8 @@ static void ext4_process_orphan(struct inode *inode,
+ ext4_msg(sb, KERN_DEBUG,
+ "%s: deleting unreferenced inode %lu",
+ __func__, inode->i_ino);
+- jbd_debug(2, "deleting unreferenced inode %lu\n",
+- inode->i_ino);
++ ext4_debug("deleting unreferenced inode %lu\n",
++ inode->i_ino);
+ (*nr_orphans)++;
+ }
+ iput(inode); /* The delete magic happens here! */
+@@ -391,7 +391,7 @@ void ext4_orphan_cleanup(struct super_block *sb, struct ext4_super_block *es)
+ int inodes_per_ob = ext4_inodes_per_orphan_block(sb);
+
+ if (!es->s_last_orphan && !oi->of_blocks) {
+- jbd_debug(4, "no orphan inodes to clean up\n");
++ ext4_debug("no orphan inodes to clean up\n");
+ return;
+ }
+
+@@ -412,10 +412,10 @@ void ext4_orphan_cleanup(struct super_block *sb, struct ext4_super_block *es)
+ /* don't clear list on RO mount w/ errors */
+ if (es->s_last_orphan && !(s_flags & SB_RDONLY)) {
+ ext4_msg(sb, KERN_INFO, "Errors on filesystem, "
+- "clearing orphan list.\n");
++ "clearing orphan list.");
+ es->s_last_orphan = 0;
+ }
+- jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
++ ext4_debug("Skipping orphan recovery on fs with errors.\n");
+ return;
+ }
+
+@@ -459,7 +459,7 @@ void ext4_orphan_cleanup(struct super_block *sb, struct ext4_super_block *es)
+ * so, skip the rest.
+ */
+ if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
+- jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
++ ext4_debug("Skipping orphan recovery on fs with errors.\n");
+ es->s_last_orphan = 0;
+ break;
+ }
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 62bbfe8960f3b..405c68085055f 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1557,8 +1557,8 @@ exit_journal:
+ int meta_bg = ext4_has_feature_meta_bg(sb);
+ sector_t old_gdb = 0;
+
+- update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
+- sizeof(struct ext4_super_block), 0);
++ update_backups(sb, ext4_group_first_block_no(sb, 0),
++ (char *)es, sizeof(struct ext4_super_block), 0);
+ for (; gdb_num <= gdb_num_end; gdb_num++) {
+ struct buffer_head *gdb_bh;
+
+@@ -1769,7 +1769,7 @@ errout:
+ if (test_opt(sb, DEBUG))
+ printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
+ "blocks\n", ext4_blocks_count(es));
+- update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr,
++ update_backups(sb, ext4_group_first_block_no(sb, 0),
+ (char *)es, sizeof(struct ext4_super_block), 0);
+ }
+ return err;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 985d79fb61287..802ca160d31ed 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1288,6 +1288,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+ return NULL;
+
+ inode_set_iversion(&ei->vfs_inode, 1);
++ ei->i_flags = 0;
+ spin_lock_init(&ei->i_raw_lock);
+ INIT_LIST_HEAD(&ei->i_prealloc_list);
+ atomic_set(&ei->i_prealloc_active, 0);
+@@ -4663,30 +4664,31 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ ext4_has_feature_journal_needs_recovery(sb)) {
+ ext4_msg(sb, KERN_ERR, "required journal recovery "
+ "suppressed and not mounted read-only");
+- goto failed_mount_wq;
++ goto failed_mount3a;
+ } else {
+ /* Nojournal mode, all journal mount options are illegal */
+- if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
+- ext4_msg(sb, KERN_ERR, "can't mount with "
+- "journal_checksum, fs mounted w/o journal");
+- goto failed_mount_wq;
+- }
+ if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "journal_async_commit, fs mounted w/o journal");
+- goto failed_mount_wq;
++ goto failed_mount3a;
++ }
++
++ if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
++ ext4_msg(sb, KERN_ERR, "can't mount with "
++ "journal_checksum, fs mounted w/o journal");
++ goto failed_mount3a;
+ }
+ if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "commit=%lu, fs mounted w/o journal",
+ sbi->s_commit_interval / HZ);
+- goto failed_mount_wq;
++ goto failed_mount3a;
+ }
+ if (EXT4_MOUNT_DATA_FLAGS &
+ (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "data=, fs mounted w/o journal");
+- goto failed_mount_wq;
++ goto failed_mount3a;
+ }
+ sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM;
+ clear_opt(sb, JOURNAL_CHECKSUM);
+@@ -5153,9 +5155,9 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb,
+ return NULL;
+ }
+
+- jbd_debug(2, "Journal inode found at %p: %lld bytes\n",
++ ext4_debug("Journal inode found at %p: %lld bytes\n",
+ journal_inode, journal_inode->i_size);
+- if (!S_ISREG(journal_inode->i_mode)) {
++ if (!S_ISREG(journal_inode->i_mode) || IS_ENCRYPTED(journal_inode)) {
+ ext4_msg(sb, KERN_ERR, "invalid journal inode");
+ iput(journal_inode);
+ return NULL;
+@@ -6309,6 +6311,20 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
+ return err;
+ }
+
++static inline bool ext4_check_quota_inum(int type, unsigned long qf_inum)
++{
++ switch (type) {
++ case USRQUOTA:
++ return qf_inum == EXT4_USR_QUOTA_INO;
++ case GRPQUOTA:
++ return qf_inum == EXT4_GRP_QUOTA_INO;
++ case PRJQUOTA:
++ return qf_inum >= EXT4_GOOD_OLD_FIRST_INO;
++ default:
++ BUG();
++ }
++}
++
+ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
+ unsigned int flags)
+ {
+@@ -6325,9 +6341,16 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
+ if (!qf_inums[type])
+ return -EPERM;
+
++ if (!ext4_check_quota_inum(type, qf_inums[type])) {
++ ext4_error(sb, "Bad quota inum: %lu, type: %d",
++ qf_inums[type], type);
++ return -EUCLEAN;
++ }
++
+ qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL);
+ if (IS_ERR(qf_inode)) {
+- ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]);
++ ext4_error(sb, "Bad quota inode: %lu, type: %d",
++ qf_inums[type], type);
+ return PTR_ERR(qf_inode);
+ }
+
+@@ -6366,8 +6389,9 @@ int ext4_enable_quotas(struct super_block *sb)
+ if (err) {
+ ext4_warning(sb,
+ "Failed to enable quota tracking "
+- "(type=%d, err=%d). Please run "
+- "e2fsck to fix.", type, err);
++ "(type=%d, err=%d, ino=%lu). "
++ "Please run e2fsck to fix.", type,
++ err, qf_inums[type]);
+ for (type--; type >= 0; type--) {
+ struct inode *inode;
+
+diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
+index 840639e7a7caa..5ece4d3c62109 100644
+--- a/fs/ext4/verity.c
++++ b/fs/ext4/verity.c
+@@ -76,7 +76,7 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count,
+ size_t n = min_t(size_t, count,
+ PAGE_SIZE - offset_in_page(pos));
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ int res;
+
+ res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0,
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 533216e80fa2b..b92da41e96409 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1281,7 +1281,7 @@ retry_ref:
+ ce = mb_cache_entry_get(ea_block_cache, hash,
+ bh->b_blocknr);
+ if (ce) {
+- ce->e_reusable = 1;
++ set_bit(MBE_REUSABLE_B, &ce->e_flags);
+ mb_cache_entry_put(ea_block_cache, ce);
+ }
+ }
+@@ -1441,6 +1441,9 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle,
+ if (!err)
+ err = ext4_inode_attach_jinode(ea_inode);
+ if (err) {
++ if (ext4_xattr_inode_dec_ref(handle, ea_inode))
++ ext4_warning_inode(ea_inode,
++ "cleanup dec ref error %d", err);
+ iput(ea_inode);
+ return ERR_PTR(err);
+ }
+@@ -2042,7 +2045,7 @@ inserted:
+ }
+ BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
+ if (ref == EXT4_XATTR_REFCOUNT_MAX)
+- ce->e_reusable = 0;
++ clear_bit(MBE_REUSABLE_B, &ce->e_flags);
+ ea_bdebug(new_bh, "reusing; refcount now=%d",
+ ref);
+ ext4_xattr_block_csum_set(inode, new_bh);
+@@ -2070,19 +2073,11 @@ inserted:
+
+ goal = ext4_group_first_block_no(sb,
+ EXT4_I(inode)->i_block_group);
+-
+- /* non-extent files can't have physical blocks past 2^32 */
+- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+- goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+-
+ block = ext4_new_meta_blocks(handle, inode, goal, 0,
+ NULL, &error);
+ if (error)
+ goto cleanup;
+
+- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+- BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
+-
+ ea_idebug(inode, "creating block %llu",
+ (unsigned long long)block);
+
+@@ -2554,7 +2549,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
+
+ is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
+ bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
+- buffer = kmalloc(value_size, GFP_NOFS);
++ buffer = kvmalloc(value_size, GFP_NOFS);
+ b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
+ if (!is || !bs || !buffer || !b_entry_name) {
+ error = -ENOMEM;
+@@ -2606,7 +2601,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
+ error = 0;
+ out:
+ kfree(b_entry_name);
+- kfree(buffer);
++ kvfree(buffer);
+ if (is)
+ brelse(is->iloc.bh);
+ if (bs)
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 7863f8fd3b95e..280a93855eafe 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1033,6 +1033,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ if (ofs_in_node >= max_addrs) {
+ f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
+ ofs_in_node, dni->ino, dni->nid, max_addrs);
++ f2fs_put_page(node_page, 1);
+ return false;
+ }
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 0e6e73bc42d4c..f810c6bbeff02 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1357,8 +1357,7 @@ static int read_node_page(struct page *page, int op_flags)
+ return err;
+
+ /* NEW_ADDR can be seen, after cp_error drops some dirty node pages */
+- if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR) ||
+- is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) {
++ if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR)) {
+ ClearPageUptodate(page);
+ return -ENOENT;
+ }
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+index a58a5b733224c..7c9c6d0b38fd6 100644
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -456,16 +456,16 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ /* panic? */
+ return -EIO;
+
++ res = -EIO;
+ if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
+- return -EIO;
++ goto out;
+ fd.search_key->cat = HFS_I(main_inode)->cat_key;
+ if (hfs_brec_find(&fd))
+- /* panic? */
+ goto out;
+
+ if (S_ISDIR(main_inode->i_mode)) {
+ if (fd.entrylength < sizeof(struct hfs_cat_dir))
+- /* panic? */;
++ goto out;
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_dir));
+ if (rec.type != HFS_CDR_DIR ||
+@@ -478,6 +478,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_dir));
+ } else if (HFS_IS_RSRC(inode)) {
++ if (fd.entrylength < sizeof(struct hfs_cat_file))
++ goto out;
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ hfs_inode_write_fork(inode, rec.file.RExtRec,
+@@ -486,7 +488,7 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ sizeof(struct hfs_cat_file));
+ } else {
+ if (fd.entrylength < sizeof(struct hfs_cat_file))
+- /* panic? */;
++ goto out;
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ if (rec.type != HFS_CDR_FIL ||
+@@ -503,9 +505,10 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ }
++ res = 0;
+ out:
+ hfs_find_exit(&fd);
+- return 0;
++ return res;
+ }
+
+ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
+diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
+index 1798949f269bb..ebc0d5c678d0c 100644
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -198,6 +198,8 @@ struct hfsplus_sb_info {
+ #define HFSPLUS_SB_HFSX 3
+ #define HFSPLUS_SB_CASEFOLD 4
+ #define HFSPLUS_SB_NOBARRIER 5
++#define HFSPLUS_SB_UID 6
++#define HFSPLUS_SB_GID 7
+
+ static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
+ {
+diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
+index 6fef67c2a9f09..bf6f75f569e4d 100644
+--- a/fs/hfsplus/inode.c
++++ b/fs/hfsplus/inode.c
+@@ -190,11 +190,11 @@ static void hfsplus_get_perms(struct inode *inode,
+ mode = be16_to_cpu(perms->mode);
+
+ i_uid_write(inode, be32_to_cpu(perms->owner));
+- if (!i_uid_read(inode) && !mode)
++ if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode))
+ inode->i_uid = sbi->uid;
+
+ i_gid_write(inode, be32_to_cpu(perms->group));
+- if (!i_gid_read(inode) && !mode)
++ if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode))
+ inode->i_gid = sbi->gid;
+
+ if (dir) {
+@@ -509,8 +509,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
+ if (type == HFSPLUS_FOLDER) {
+ struct hfsplus_cat_folder *folder = &entry.folder;
+
+- if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
+- /* panic? */;
++ WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
+ sizeof(struct hfsplus_cat_folder));
+ hfsplus_get_perms(inode, &folder->permissions, 1);
+@@ -530,8 +529,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
+ } else if (type == HFSPLUS_FILE) {
+ struct hfsplus_cat_file *file = &entry.file;
+
+- if (fd->entrylength < sizeof(struct hfsplus_cat_file))
+- /* panic? */;
++ WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
+ sizeof(struct hfsplus_cat_file));
+
+@@ -588,8 +586,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
+ if (S_ISDIR(main_inode->i_mode)) {
+ struct hfsplus_cat_folder *folder = &entry.folder;
+
+- if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
+- /* panic? */;
++ WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
+ sizeof(struct hfsplus_cat_folder));
+ /* simple node checks? */
+@@ -614,8 +611,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
+ } else {
+ struct hfsplus_cat_file *file = &entry.file;
+
+- if (fd.entrylength < sizeof(struct hfsplus_cat_file))
+- /* panic? */;
++ WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
+ sizeof(struct hfsplus_cat_file));
+ hfsplus_inode_write_fork(inode, &file->data_fork);
+diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
+index 047e05c575601..c94a58762ad6d 100644
+--- a/fs/hfsplus/options.c
++++ b/fs/hfsplus/options.c
+@@ -140,6 +140,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
+ if (!uid_valid(sbi->uid)) {
+ pr_err("invalid uid specified\n");
+ return 0;
++ } else {
++ set_bit(HFSPLUS_SB_UID, &sbi->flags);
+ }
+ break;
+ case opt_gid:
+@@ -151,6 +153,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
+ if (!gid_valid(sbi->gid)) {
+ pr_err("invalid gid specified\n");
+ return 0;
++ } else {
++ set_bit(HFSPLUS_SB_GID, &sbi->flags);
+ }
+ break;
+ case opt_part:
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index 30a92ddc18174..b962b16e5aeb7 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -319,7 +319,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+ dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
+ dn_len = le16_to_cpu(authblob->DomainName.Length);
+
+- if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
++ if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len ||
++ nt_len < CIFS_ENCPWD_SIZE)
+ return -EINVAL;
+
+ /* TODO : use domain name that imported from configuration file */
+diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c
+index 02254b09c0daf..6a1d1fbe5fb2d 100644
+--- a/fs/ksmbd/connection.c
++++ b/fs/ksmbd/connection.c
+@@ -310,9 +310,12 @@ int ksmbd_conn_handler_loop(void *p)
+
+ /* 4 for rfc1002 length field */
+ size = pdu_size + 4;
+- conn->request_buf = kvmalloc(size, GFP_KERNEL);
++ conn->request_buf = kvmalloc(size,
++ GFP_KERNEL |
++ __GFP_NOWARN |
++ __GFP_NORETRY);
+ if (!conn->request_buf)
+- continue;
++ break;
+
+ memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf));
+ if (!ksmbd_smb_request(conn))
+diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c
+index 755329c295cab..293af921f2ad4 100644
+--- a/fs/ksmbd/transport_tcp.c
++++ b/fs/ksmbd/transport_tcp.c
+@@ -295,6 +295,7 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ struct msghdr ksmbd_msg;
+ struct kvec *iov;
+ struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
++ int max_retry = 2;
+
+ iov = get_conn_iovec(t, nr_segs);
+ if (!iov)
+@@ -321,9 +322,11 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
+ total_read = -EAGAIN;
+ break;
+- } else if (length == -ERESTARTSYS || length == -EAGAIN) {
++ } else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
++ max_retry) {
+ usleep_range(1000, 2000);
+ length = 0;
++ max_retry--;
+ continue;
+ } else if (length <= 0) {
+ total_read = -EAGAIN;
+diff --git a/fs/locks.c b/fs/locks.c
+index 3d6fb4ae847b4..82a4487e95b37 100644
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -2703,6 +2703,29 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+ }
+ EXPORT_SYMBOL_GPL(vfs_cancel_lock);
+
++/**
++ * vfs_inode_has_locks - are any file locks held on @inode?
++ * @inode: inode to check for locks
++ *
++ * Return true if there are any FL_POSIX or FL_FLOCK locks currently
++ * set on @inode.
++ */
++bool vfs_inode_has_locks(struct inode *inode)
++{
++ struct file_lock_context *ctx;
++ bool ret;
++
++ ctx = smp_load_acquire(&inode->i_flctx);
++ if (!ctx)
++ return false;
++
++ spin_lock(&ctx->flc_lock);
++ ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock);
++ spin_unlock(&ctx->flc_lock);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(vfs_inode_has_locks);
++
+ #ifdef CONFIG_PROC_FS
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+diff --git a/fs/mbcache.c b/fs/mbcache.c
+index 2010bc80a3f2d..95b047256d093 100644
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -90,12 +90,19 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&entry->e_list);
+- /* One ref for hash, one ref returned */
+- atomic_set(&entry->e_refcnt, 1);
++ /*
++ * We create entry with two references. One reference is kept by the
++ * hash table, the other reference is used to protect us from
++ * mb_cache_entry_delete_or_get() until the entry is fully setup. This
++ * avoids nesting of cache->c_list_lock into hash table bit locks which
++ * is problematic for RT.
++ */
++ atomic_set(&entry->e_refcnt, 2);
+ entry->e_key = key;
+ entry->e_value = value;
+- entry->e_reusable = reusable;
+- entry->e_referenced = 0;
++ entry->e_flags = 0;
++ if (reusable)
++ set_bit(MBE_REUSABLE_B, &entry->e_flags);
+ head = mb_cache_entry_head(cache, key);
+ hlist_bl_lock(head);
+ hlist_bl_for_each_entry(dup, dup_node, head, e_hash_list) {
+@@ -107,20 +114,24 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ }
+ hlist_bl_add_head(&entry->e_hash_list, head);
+ hlist_bl_unlock(head);
+-
+ spin_lock(&cache->c_list_lock);
+ list_add_tail(&entry->e_list, &cache->c_list);
+- /* Grab ref for LRU list */
+- atomic_inc(&entry->e_refcnt);
+ cache->c_entry_count++;
+ spin_unlock(&cache->c_list_lock);
++ mb_cache_entry_put(cache, entry);
+
+ return 0;
+ }
+ EXPORT_SYMBOL(mb_cache_entry_create);
+
+-void __mb_cache_entry_free(struct mb_cache_entry *entry)
++void __mb_cache_entry_free(struct mb_cache *cache, struct mb_cache_entry *entry)
+ {
++ struct hlist_bl_head *head;
++
++ head = mb_cache_entry_head(cache, entry->e_key);
++ hlist_bl_lock(head);
++ hlist_bl_del(&entry->e_hash_list);
++ hlist_bl_unlock(head);
+ kmem_cache_free(mb_entry_cache, entry);
+ }
+ EXPORT_SYMBOL(__mb_cache_entry_free);
+@@ -134,7 +145,7 @@ EXPORT_SYMBOL(__mb_cache_entry_free);
+ */
+ void mb_cache_entry_wait_unused(struct mb_cache_entry *entry)
+ {
+- wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 3);
++ wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 2);
+ }
+ EXPORT_SYMBOL(mb_cache_entry_wait_unused);
+
+@@ -155,10 +166,10 @@ static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
+ while (node) {
+ entry = hlist_bl_entry(node, struct mb_cache_entry,
+ e_hash_list);
+- if (entry->e_key == key && entry->e_reusable) {
+- atomic_inc(&entry->e_refcnt);
++ if (entry->e_key == key &&
++ test_bit(MBE_REUSABLE_B, &entry->e_flags) &&
++ atomic_inc_not_zero(&entry->e_refcnt))
+ goto out;
+- }
+ node = node->next;
+ }
+ entry = NULL;
+@@ -218,10 +229,9 @@ struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
+ head = mb_cache_entry_head(cache, key);
+ hlist_bl_lock(head);
+ hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
+- if (entry->e_key == key && entry->e_value == value) {
+- atomic_inc(&entry->e_refcnt);
++ if (entry->e_key == key && entry->e_value == value &&
++ atomic_inc_not_zero(&entry->e_refcnt))
+ goto out;
+- }
+ }
+ entry = NULL;
+ out:
+@@ -281,37 +291,25 @@ EXPORT_SYMBOL(mb_cache_entry_delete);
+ struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
+ u32 key, u64 value)
+ {
+- struct hlist_bl_node *node;
+- struct hlist_bl_head *head;
+ struct mb_cache_entry *entry;
+
+- head = mb_cache_entry_head(cache, key);
+- hlist_bl_lock(head);
+- hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
+- if (entry->e_key == key && entry->e_value == value) {
+- if (atomic_read(&entry->e_refcnt) > 2) {
+- atomic_inc(&entry->e_refcnt);
+- hlist_bl_unlock(head);
+- return entry;
+- }
+- /* We keep hash list reference to keep entry alive */
+- hlist_bl_del_init(&entry->e_hash_list);
+- hlist_bl_unlock(head);
+- spin_lock(&cache->c_list_lock);
+- if (!list_empty(&entry->e_list)) {
+- list_del_init(&entry->e_list);
+- if (!WARN_ONCE(cache->c_entry_count == 0,
+- "mbcache: attempt to decrement c_entry_count past zero"))
+- cache->c_entry_count--;
+- atomic_dec(&entry->e_refcnt);
+- }
+- spin_unlock(&cache->c_list_lock);
+- mb_cache_entry_put(cache, entry);
+- return NULL;
+- }
+- }
+- hlist_bl_unlock(head);
++ entry = mb_cache_entry_get(cache, key, value);
++ if (!entry)
++ return NULL;
++
++ /*
++ * Drop the ref we got from mb_cache_entry_get() and the initial hash
++ * ref if we are the last user
++ */
++ if (atomic_cmpxchg(&entry->e_refcnt, 2, 0) != 2)
++ return entry;
+
++ spin_lock(&cache->c_list_lock);
++ if (!list_empty(&entry->e_list))
++ list_del_init(&entry->e_list);
++ cache->c_entry_count--;
++ spin_unlock(&cache->c_list_lock);
++ __mb_cache_entry_free(cache, entry);
+ return NULL;
+ }
+ EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
+@@ -325,7 +323,7 @@ EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
+ void mb_cache_entry_touch(struct mb_cache *cache,
+ struct mb_cache_entry *entry)
+ {
+- entry->e_referenced = 1;
++ set_bit(MBE_REFERENCED_B, &entry->e_flags);
+ }
+ EXPORT_SYMBOL(mb_cache_entry_touch);
+
+@@ -343,42 +341,24 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache,
+ unsigned long nr_to_scan)
+ {
+ struct mb_cache_entry *entry;
+- struct hlist_bl_head *head;
+ unsigned long shrunk = 0;
+
+ spin_lock(&cache->c_list_lock);
+ while (nr_to_scan-- && !list_empty(&cache->c_list)) {
+ entry = list_first_entry(&cache->c_list,
+ struct mb_cache_entry, e_list);
+- if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) {
+- entry->e_referenced = 0;
++ /* Drop initial hash reference if there is no user */
++ if (test_bit(MBE_REFERENCED_B, &entry->e_flags) ||
++ atomic_cmpxchg(&entry->e_refcnt, 1, 0) != 1) {
++ clear_bit(MBE_REFERENCED_B, &entry->e_flags);
+ list_move_tail(&entry->e_list, &cache->c_list);
+ continue;
+ }
+ list_del_init(&entry->e_list);
+ cache->c_entry_count--;
+- /*
+- * We keep LRU list reference so that entry doesn't go away
+- * from under us.
+- */
+ spin_unlock(&cache->c_list_lock);
+- head = mb_cache_entry_head(cache, entry->e_key);
+- hlist_bl_lock(head);
+- /* Now a reliable check if the entry didn't get used... */
+- if (atomic_read(&entry->e_refcnt) > 2) {
+- hlist_bl_unlock(head);
+- spin_lock(&cache->c_list_lock);
+- list_add_tail(&entry->e_list, &cache->c_list);
+- cache->c_entry_count++;
+- continue;
+- }
+- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
+- hlist_bl_del_init(&entry->e_hash_list);
+- atomic_dec(&entry->e_refcnt);
+- }
+- hlist_bl_unlock(head);
+- if (mb_cache_entry_put(cache, entry))
+- shrunk++;
++ __mb_cache_entry_free(cache, entry);
++ shrunk++;
+ cond_resched();
+ spin_lock(&cache->c_list_lock);
+ }
+@@ -470,11 +450,6 @@ void mb_cache_destroy(struct mb_cache *cache)
+ * point.
+ */
+ list_for_each_entry_safe(entry, next, &cache->c_list, e_list) {
+- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
+- hlist_bl_del_init(&entry->e_hash_list);
+- atomic_dec(&entry->e_refcnt);
+- } else
+- WARN_ON(1);
+ list_del(&entry->e_list);
+ WARN_ON(atomic_read(&entry->e_refcnt) != 1);
+ mb_cache_entry_put(cache, entry);
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index e0409f6cdfd5f..dfd3877fdd818 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -3514,6 +3514,17 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
+ case nfserr_noent:
+ xdr_truncate_encode(xdr, start_offset);
+ goto skip_entry;
++ case nfserr_jukebox:
++ /*
++ * The pseudoroot should only display dentries that lead to
++ * exports. If we get EJUKEBOX here, then we can't tell whether
++ * this entry should be included. Just fail the whole READDIR
++ * with NFS4ERR_DELAY in that case, and hope that the situation
++ * will resolve itself by the client's next attempt.
++ */
++ if (cd->rd_fhp->fh_export->ex_flags & NFSEXP_V4ROOT)
++ goto fail;
++ fallthrough;
+ default:
+ /*
+ * If the client requested the RDATTR_ERROR attribute,
+diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
+index ccb59e91011b7..373695cc62a7a 100644
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -425,8 +425,8 @@ static void nfsd_shutdown_net(struct net *net)
+ {
+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+
+- nfsd_file_cache_shutdown_net(net);
+ nfs4_state_shutdown_net(net);
++ nfsd_file_cache_shutdown_net(net);
+ if (nn->lockd_up) {
+ lockd_down(net);
+ nn->lockd_up = false;
+diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
+index e8c00dda42adb..42af83bcaf136 100644
+--- a/fs/ntfs3/attrib.c
++++ b/fs/ntfs3/attrib.c
+@@ -101,6 +101,10 @@ int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
+
+ asize = le32_to_cpu(attr->size);
+ run_off = le16_to_cpu(attr->nres.run_off);
++
++ if (run_off > asize)
++ return -EINVAL;
++
+ err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn,
+ vcn ? *vcn : svcn, Add2Ptr(attr, run_off),
+ asize - run_off);
+@@ -1142,6 +1146,11 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
+ CLST svcn, evcn;
+ u16 ro;
+
++ if (!ni) {
++ /* Is record corrupted? */
++ return -ENOENT;
++ }
++
+ attr = ni_find_attr(ni, NULL, NULL, type, name, name_len, &vcn, NULL);
+ if (!attr) {
+ /* Is record corrupted? */
+@@ -1157,6 +1166,10 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
+ }
+
+ ro = le16_to_cpu(attr->nres.run_off);
++
++ if (ro > le32_to_cpu(attr->size))
++ return -EINVAL;
++
+ err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, ro), le32_to_cpu(attr->size) - ro);
+ if (err < 0)
+@@ -1832,6 +1845,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
+ u16 le_sz;
+ u16 roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > le32_to_cpu(attr->size)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
+ evcn1 - 1, svcn, Add2Ptr(attr, roff),
+ le32_to_cpu(attr->size) - roff);
+diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c
+index bad6d8a849a24..c0c6bcbc8c05c 100644
+--- a/fs/ntfs3/attrlist.c
++++ b/fs/ntfs3/attrlist.c
+@@ -68,6 +68,11 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
+
+ run_init(&ni->attr_list.run);
+
++ if (run_off > le32_to_cpu(attr->size)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = run_unpack_ex(&ni->attr_list.run, ni->mi.sbi, ni->mi.rno,
+ 0, le64_to_cpu(attr->nres.evcn), 0,
+ Add2Ptr(attr, run_off),
+diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
+index 7f2055b7427a6..2a63793f522d4 100644
+--- a/fs/ntfs3/bitmap.c
++++ b/fs/ntfs3/bitmap.c
+@@ -666,7 +666,7 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits)
+ if (!wnd->bits_last)
+ wnd->bits_last = wbits;
+
+- wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS);
++ wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
+ if (!wnd->free_bits)
+ return -ENOMEM;
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 7a678a5b1ca5f..c526e0427f2bf 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -488,10 +488,10 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
+
+ new_valid = ntfs_up_block(sb, min_t(u64, ni->i_valid, new_size));
+
+- ni_lock(ni);
+-
+ truncate_setsize(inode, new_size);
+
++ ni_lock(ni);
++
+ down_write(&ni->file.run_lock);
+ err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size,
+ &new_valid, ni->mi.sbi->options->prealloc, NULL);
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 18842998c8fa3..cdeb0b51f0ba8 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -567,6 +567,12 @@ static int ni_repack(struct ntfs_inode *ni)
+ }
+
+ roff = le16_to_cpu(attr->nres.run_off);
++
++ if (roff > le32_to_cpu(attr->size)) {
++ err = -EINVAL;
++ break;
++ }
++
+ err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, roff),
+ le32_to_cpu(attr->size) - roff);
+@@ -1541,6 +1547,9 @@ 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)
++ return -EINVAL;
++
+ /* run==1 means unpack and deallocate. */
+ run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, roff), asize - roff);
+@@ -2242,6 +2251,11 @@ remove_wof:
+ asize = le32_to_cpu(attr->size);
+ roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > asize) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ /*run==1 Means unpack and deallocate. */
+ run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, roff), asize - roff);
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index 614513460b8e0..20abdb2682860 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -1132,7 +1132,7 @@ static int read_log_page(struct ntfs_log *log, u32 vbo,
+ return -EINVAL;
+
+ if (!*buffer) {
+- to_free = kmalloc(bytes, GFP_NOFS);
++ to_free = kmalloc(log->page_size, GFP_NOFS);
+ if (!to_free)
+ return -ENOMEM;
+ *buffer = to_free;
+@@ -1180,10 +1180,7 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ struct restart_info *info)
+ {
+ u32 skip, vbo;
+- struct RESTART_HDR *r_page = kmalloc(DefaultLogPageSize, GFP_NOFS);
+-
+- if (!r_page)
+- return -ENOMEM;
++ struct RESTART_HDR *r_page = NULL;
+
+ /* Determine which restart area we are looking for. */
+ if (first) {
+@@ -1197,7 +1194,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ /* Loop continuously until we succeed. */
+ for (; vbo < l_size; vbo = 2 * vbo + skip, skip = 0) {
+ bool usa_error;
+- u32 sys_page_size;
+ bool brst, bchk;
+ struct RESTART_AREA *ra;
+
+@@ -1251,24 +1247,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ goto check_result;
+ }
+
+- /* Read the entire restart area. */
+- sys_page_size = le32_to_cpu(r_page->sys_page_size);
+- if (DefaultLogPageSize != sys_page_size) {
+- kfree(r_page);
+- r_page = kzalloc(sys_page_size, GFP_NOFS);
+- if (!r_page)
+- return -ENOMEM;
+-
+- if (read_log_page(log, vbo,
+- (struct RECORD_PAGE_HDR **)&r_page,
+- &usa_error)) {
+- /* Ignore any errors. */
+- kfree(r_page);
+- r_page = NULL;
+- continue;
+- }
+- }
+-
+ if (is_client_area_valid(r_page, usa_error)) {
+ info->valid_page = true;
+ ra = Add2Ptr(r_page, le16_to_cpu(r_page->ra_off));
+@@ -2727,6 +2705,9 @@ static inline bool check_attr(const struct MFT_REC *rec,
+ return false;
+ }
+
++ if (run_off > asize)
++ return false;
++
+ if (run_unpack(NULL, sbi, 0, svcn, evcn, svcn,
+ Add2Ptr(attr, run_off), asize - run_off) < 0) {
+ return false;
+@@ -4769,6 +4750,12 @@ fake_attr:
+ u16 roff = le16_to_cpu(attr->nres.run_off);
+ CLST svcn = le64_to_cpu(attr->nres.svcn);
+
++ if (roff > t32) {
++ kfree(oa->attr);
++ oa->attr = NULL;
++ goto fake_attr;
++ }
++
+ err = run_unpack(&oa->run0, sbi, inode->i_ino, svcn,
+ le64_to_cpu(attr->nres.evcn), svcn,
+ Add2Ptr(attr, roff), t32 - roff);
+diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
+index 24b57c3cc625c..4a97a28cb8f29 100644
+--- a/fs/ntfs3/fsntfs.c
++++ b/fs/ntfs3/fsntfs.c
+@@ -1878,9 +1878,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
+ goto out;
+ }
+
+- root_sdh = resident_data(attr);
++ root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
+ if (root_sdh->type != ATTR_ZERO ||
+- root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH) {
++ root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH ||
++ offsetof(struct INDEX_ROOT, ihdr) + root_sdh->ihdr.used > attr->res.data_size) {
+ err = -EINVAL;
+ goto out;
+ }
+@@ -1896,9 +1897,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
+ goto out;
+ }
+
+- root_sii = resident_data(attr);
++ root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
+ if (root_sii->type != ATTR_ZERO ||
+- root_sii->rule != NTFS_COLLATION_TYPE_UINT) {
++ root_sii->rule != NTFS_COLLATION_TYPE_UINT ||
++ offsetof(struct INDEX_ROOT, ihdr) + root_sii->ihdr.used > attr->res.data_size) {
+ err = -EINVAL;
+ goto out;
+ }
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 76ebea253fa25..99f8a57e9f7a9 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -1017,6 +1017,12 @@ ok:
+ err = 0;
+ }
+
++ /* check for index header length */
++ if (offsetof(struct INDEX_BUFFER, ihdr) + ib->ihdr.used > bytes) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ in->index = ib;
+ *node = in;
+
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 64b4a3c29878c..ed640e4e3fac0 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -129,6 +129,9 @@ next_attr:
+ rsize = attr->non_res ? 0 : le32_to_cpu(attr->res.data_size);
+ asize = le32_to_cpu(attr->size);
+
++ if (le16_to_cpu(attr->name_off) + attr->name_len > asize)
++ goto out;
++
+ switch (attr->type) {
+ case ATTR_STD:
+ if (attr->non_res ||
+@@ -364,7 +367,13 @@ next_attr:
+ attr_unpack_run:
+ roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > asize) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ t64 = le64_to_cpu(attr->nres.svcn);
++
+ err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
+ t64, Add2Ptr(attr, roff), asize - roff);
+ if (err < 0)
+diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
+index 861e35791506e..fd342da398bea 100644
+--- a/fs/ntfs3/record.c
++++ b/fs/ntfs3/record.c
+@@ -220,6 +220,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ return NULL;
+ }
+
++ if (off + asize < off) {
++ /* overflow check */
++ return NULL;
++ }
++
+ attr = Add2Ptr(attr, asize);
+ off += asize;
+ }
+@@ -260,6 +265,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ if (t16 + t32 > asize)
+ return NULL;
+
++ if (attr->name_len &&
++ le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > t16) {
++ return NULL;
++ }
++
+ return attr;
+ }
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 39b09f32f4db7..33b1833ad525c 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -789,7 +789,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
+ : (u32)boot->record_size
+ << sbi->cluster_bits;
+
+- if (record_size > MAXIMUM_BYTES_PER_MFT)
++ if (record_size > MAXIMUM_BYTES_PER_MFT || record_size < SECTOR_SIZE)
+ goto out;
+
+ sbi->record_bits = blksize_bits(record_size);
+@@ -1136,7 +1136,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
+ goto put_inode_out;
+ }
+ bytes = inode->i_size;
+- sbi->def_table = t = kmalloc(bytes, GFP_NOFS);
++ sbi->def_table = t = kmalloc(bytes, GFP_NOFS | __GFP_NOWARN);
+ if (!t) {
+ err = -ENOMEM;
+ goto put_inode_out;
+@@ -1255,9 +1255,9 @@ load_root:
+ ref.low = cpu_to_le32(MFT_REC_ROOT);
+ ref.seq = cpu_to_le16(MFT_REC_ROOT);
+ inode = ntfs_iget5(sb, &ref, &NAME_ROOT);
+- if (IS_ERR(inode)) {
++ if (IS_ERR(inode) || !inode->i_op) {
+ ntfs_err(sb, "Failed to load root.");
+- err = PTR_ERR(inode);
++ err = IS_ERR(inode) ? PTR_ERR(inode) : -EINVAL;
+ goto out;
+ }
+
+@@ -1276,6 +1276,7 @@ out:
+ * Free resources here.
+ * ntfs_fs_free will be called with fc->s_fs_info = NULL
+ */
++ put_mount_options(sbi->options);
+ put_ntfs(sbi);
+ sb->s_fs_info = NULL;
+
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 3fc86c51e260c..eca984d6484d1 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -589,28 +589,42 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
+ goto out_revert_creds;
+ }
+
+- err = -ENOMEM;
+- override_cred = prepare_creds();
+- if (override_cred) {
++ if (!attr->hardlink) {
++ err = -ENOMEM;
++ override_cred = prepare_creds();
++ if (!override_cred)
++ goto out_revert_creds;
++ /*
++ * In the creation cases(create, mkdir, mknod, symlink),
++ * ovl should transfer current's fs{u,g}id to underlying
++ * fs. Because underlying fs want to initialize its new
++ * inode owner using current's fs{u,g}id. And in this
++ * case, the @inode is a new inode that is initialized
++ * in inode_init_owner() to current's fs{u,g}id. So use
++ * the inode's i_{u,g}id to override the cred's fs{u,g}id.
++ *
++ * But in the other hardlink case, ovl_link() does not
++ * create a new inode, so just use the ovl mounter's
++ * fs{u,g}id.
++ */
+ override_cred->fsuid = inode->i_uid;
+ override_cred->fsgid = inode->i_gid;
+- if (!attr->hardlink) {
+- err = security_dentry_create_files_as(dentry,
+- attr->mode, &dentry->d_name, old_cred,
+- override_cred);
+- if (err) {
+- put_cred(override_cred);
+- goto out_revert_creds;
+- }
++ err = security_dentry_create_files_as(dentry,
++ attr->mode, &dentry->d_name, old_cred,
++ override_cred);
++ if (err) {
++ put_cred(override_cred);
++ goto out_revert_creds;
+ }
+ put_cred(override_creds(override_cred));
+ put_cred(override_cred);
+-
+- if (!ovl_dentry_is_whiteout(dentry))
+- err = ovl_create_upper(dentry, inode, attr);
+- else
+- err = ovl_create_over_whiteout(dentry, inode, attr);
+ }
++
++ if (!ovl_dentry_is_whiteout(dentry))
++ err = ovl_create_upper(dentry, inode, attr);
++ else
++ err = ovl_create_over_whiteout(dentry, inode, attr);
++
+ out_revert_creds:
+ revert_creds(old_cred);
+ return err;
+diff --git a/fs/pnode.c b/fs/pnode.c
+index 1106137c747a3..468e4e65a615d 100644
+--- a/fs/pnode.c
++++ b/fs/pnode.c
+@@ -244,7 +244,7 @@ static int propagate_one(struct mount *m)
+ }
+ do {
+ struct mount *parent = last_source->mnt_parent;
+- if (last_source == first_source)
++ if (peers(last_source, first_source))
+ break;
+ done = parent->mnt_master == p;
+ if (done && peers(n, parent))
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index 74e4d93f3e08d..f3fa3625d772c 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -670,7 +670,7 @@ static int ramoops_parse_dt(struct platform_device *pdev,
+ field = value; \
+ }
+
+- parse_u32("mem-type", pdata->record_size, pdata->mem_type);
++ parse_u32("mem-type", pdata->mem_type, pdata->mem_type);
+ parse_u32("record-size", pdata->record_size, 0);
+ parse_u32("console-size", pdata->console_size, 0);
+ parse_u32("ftrace-size", pdata->ftrace_size, 0);
+diff --git a/fs/pstore/zone.c b/fs/pstore/zone.c
+index 7c8f8feac6c34..5d3f944f60185 100644
+--- a/fs/pstore/zone.c
++++ b/fs/pstore/zone.c
+@@ -761,7 +761,7 @@ static inline int notrace psz_kmsg_write_record(struct psz_context *cxt,
+ /* avoid destroying old data, allocate a new one */
+ len = zone->buffer_size + sizeof(*zone->buffer);
+ zone->oldbuf = zone->buffer;
+- zone->buffer = kzalloc(len, GFP_KERNEL);
++ zone->buffer = kzalloc(len, GFP_ATOMIC);
+ if (!zone->buffer) {
+ zone->buffer = zone->oldbuf;
+ return -ENOMEM;
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 09d1307959d08..cddd07b7d1329 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -2317,6 +2317,8 @@ static int vfs_setup_quota_inode(struct inode *inode, int type)
+ struct super_block *sb = inode->i_sb;
+ struct quota_info *dqopt = sb_dqopt(sb);
+
++ if (is_bad_inode(inode))
++ return -EUCLEAN;
+ if (!S_ISREG(inode->i_mode))
+ return -EACCES;
+ if (IS_RDONLY(inode))
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index 6a0e8ef664c11..d2488b7e54a58 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -599,7 +599,7 @@ static void udf_do_extend_final_block(struct inode *inode,
+ */
+ if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
+ return;
+- added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen;
++ added_bytes = new_elen - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ last_ext->extLength += added_bytes;
+ UDF_I(inode)->i_lenExtents += added_bytes;
+
+diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
+index 142474b4af963..d94b9ed9443e5 100644
+--- a/include/linux/devfreq.h
++++ b/include/linux/devfreq.h
+@@ -149,8 +149,8 @@ struct devfreq_stats {
+ * @work: delayed work for load monitoring.
+ * @previous_freq: previously configured frequency value.
+ * @last_status: devfreq user device info, performance statistics
+- * @data: Private data of the governor. The devfreq framework does not
+- * touch this.
++ * @data: devfreq driver pass to governors, governor should not change it.
++ * @governor_data: private data for governors, devfreq core doesn't touch it.
+ * @user_min_freq_req: PM QoS minimum frequency request from user (via sysfs)
+ * @user_max_freq_req: PM QoS maximum frequency request from user (via sysfs)
+ * @scaling_min_freq: Limit minimum frequency requested by OPP interface
+@@ -187,7 +187,8 @@ struct devfreq {
+ unsigned long previous_freq;
+ struct devfreq_dev_status last_status;
+
+- void *data; /* private data for governors */
++ void *data;
++ void *governor_data;
+
+ struct dev_pm_qos_request user_min_freq_req;
+ struct dev_pm_qos_request user_max_freq_req;
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 4cd4ed34d3cb8..5598fc348c69a 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1114,8 +1114,6 @@ void efi_check_for_embedded_firmwares(void);
+ static inline void efi_check_for_embedded_firmwares(void) { }
+ #endif
+
+-efi_status_t efi_random_get_seed(void);
+-
+ /*
+ * Arch code can implement the following three template macros, avoiding
+ * reptition for the void/non-void return cases of {__,}efi_call_virt():
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 68fcf3ec9cf6a..1e1ac116dd136 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1195,6 +1195,7 @@ extern int locks_delete_block(struct file_lock *);
+ extern int vfs_test_lock(struct file *, struct file_lock *);
+ extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
+ extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
++bool vfs_inode_has_locks(struct inode *inode);
+ extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl);
+ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
+ extern void lease_get_mtime(struct inode *, struct timespec64 *time);
+@@ -1307,6 +1308,11 @@ static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+ return 0;
+ }
+
++static inline bool vfs_inode_has_locks(struct inode *inode)
++{
++ return false;
++}
++
+ static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
+ {
+ return -ENOLCK;
+diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
+index 8eca7f25c4320..591bc4cefe1d6 100644
+--- a/include/linux/mbcache.h
++++ b/include/linux/mbcache.h
+@@ -10,16 +10,29 @@
+
+ struct mb_cache;
+
++/* Cache entry flags */
++enum {
++ MBE_REFERENCED_B = 0,
++ MBE_REUSABLE_B
++};
++
+ struct mb_cache_entry {
+ /* List of entries in cache - protected by cache->c_list_lock */
+ struct list_head e_list;
+- /* Hash table list - protected by hash chain bitlock */
++ /*
++ * Hash table list - protected by hash chain bitlock. The entry is
++ * guaranteed to be hashed while e_refcnt > 0.
++ */
+ struct hlist_bl_node e_hash_list;
++ /*
++ * Entry refcount. Once it reaches zero, entry is unhashed and freed.
++ * While refcount > 0, the entry is guaranteed to stay in the hash and
++ * e.g. mb_cache_entry_try_delete() will fail.
++ */
+ atomic_t e_refcnt;
+ /* Key in hash - stable during lifetime of the entry */
+ u32 e_key;
+- u32 e_referenced:1;
+- u32 e_reusable:1;
++ unsigned long e_flags;
+ /* User provided value - stable during lifetime of the entry */
+ u64 e_value;
+ };
+@@ -29,20 +42,20 @@ void mb_cache_destroy(struct mb_cache *cache);
+
+ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ u64 value, bool reusable);
+-void __mb_cache_entry_free(struct mb_cache_entry *entry);
++void __mb_cache_entry_free(struct mb_cache *cache,
++ struct mb_cache_entry *entry);
+ void mb_cache_entry_wait_unused(struct mb_cache_entry *entry);
+-static inline int mb_cache_entry_put(struct mb_cache *cache,
+- struct mb_cache_entry *entry)
++static inline void mb_cache_entry_put(struct mb_cache *cache,
++ struct mb_cache_entry *entry)
+ {
+ unsigned int cnt = atomic_dec_return(&entry->e_refcnt);
+
+ if (cnt > 0) {
+- if (cnt <= 3)
++ if (cnt <= 2)
+ wake_up_var(&entry->e_refcnt);
+- return 0;
++ return;
+ }
+- __mb_cache_entry_free(entry);
+- return 1;
++ __mb_cache_entry_free(cache, entry);
+ }
+
+ struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
+diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
+index 66eaf0aa7f698..3e72133545caf 100644
+--- a/include/linux/mlx5/device.h
++++ b/include/linux/mlx5/device.h
+@@ -1074,6 +1074,11 @@ enum {
+ MLX5_VPORT_ADMIN_STATE_AUTO = 0x2,
+ };
+
++enum {
++ MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN = 0x1,
++ MLX5_VPORT_CVLAN_INSERT_ALWAYS = 0x3,
++};
++
+ enum {
+ MLX5_L3_PROT_TYPE_IPV4 = 0,
+ MLX5_L3_PROT_TYPE_IPV6 = 1,
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index cd9d1c95129e3..49ea0004109e1 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -822,7 +822,8 @@ struct mlx5_ifc_e_switch_cap_bits {
+ u8 vport_svlan_insert[0x1];
+ u8 vport_cvlan_insert_if_not_exist[0x1];
+ u8 vport_cvlan_insert_overwrite[0x1];
+- u8 reserved_at_5[0x2];
++ u8 reserved_at_5[0x1];
++ u8 vport_cvlan_insert_always[0x1];
+ u8 esw_shared_ingress_acl[0x1];
+ u8 esw_uplink_ingress_acl[0x1];
+ u8 root_ft_on_other_esw[0x1];
+diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
+index ada1296c87d50..72f5ebc5c97a9 100644
+--- a/include/linux/netfilter/ipset/ip_set.h
++++ b/include/linux/netfilter/ipset/ip_set.h
+@@ -197,7 +197,7 @@ struct ip_set_region {
+ };
+
+ /* Max range where every element is added/deleted in one step */
+-#define IPSET_MAX_RANGE (1<<20)
++#define IPSET_MAX_RANGE (1<<14)
+
+ /* The max revision number supported by any set type + 1 */
+ #define IPSET_REVISION_MAX 9
+diff --git a/include/linux/nvme.h b/include/linux/nvme.h
+index 039f59ee8f435..de235916c31c2 100644
+--- a/include/linux/nvme.h
++++ b/include/linux/nvme.h
+@@ -7,6 +7,7 @@
+ #ifndef _LINUX_NVME_H
+ #define _LINUX_NVME_H
+
++#include <linux/bits.h>
+ #include <linux/types.h>
+ #include <linux/uuid.h>
+
+@@ -539,7 +540,7 @@ enum {
+ NVME_CMD_EFFECTS_NCC = 1 << 2,
+ NVME_CMD_EFFECTS_NIC = 1 << 3,
+ NVME_CMD_EFFECTS_CCC = 1 << 4,
+- NVME_CMD_EFFECTS_CSE_MASK = 3 << 16,
++ NVME_CMD_EFFECTS_CSE_MASK = GENMASK(18, 16),
+ NVME_CMD_EFFECTS_UUID_SEL = 1 << 19,
+ };
+
+diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
+index cd188a527d169..3b35b6f6533aa 100644
+--- a/include/linux/sunrpc/rpc_pipe_fs.h
++++ b/include/linux/sunrpc/rpc_pipe_fs.h
+@@ -92,6 +92,11 @@ extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
+ char __user *, size_t);
+ extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
+
++/* returns true if the msg is in-flight, i.e., already eaten by the peer */
++static inline bool rpc_msg_is_inflight(const struct rpc_pipe_msg *msg) {
++ return (msg->copied != 0 && list_empty(&msg->list));
++}
++
+ struct rpc_clnt;
+ extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
+ extern int rpc_remove_client_dir(struct rpc_clnt *);
+diff --git a/include/net/mptcp.h b/include/net/mptcp.h
+index 3214848402ec9..1120363987d05 100644
+--- a/include/net/mptcp.h
++++ b/include/net/mptcp.h
+@@ -93,8 +93,6 @@ struct mptcp_out_options {
+ };
+
+ #ifdef CONFIG_MPTCP
+-extern struct request_sock_ops mptcp_subflow_request_sock_ops;
+-
+ void mptcp_init(void);
+
+ static inline bool sk_is_mptcp(const struct sock *sk)
+@@ -182,6 +180,9 @@ void mptcp_seq_show(struct seq_file *seq);
+ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+ const struct sock *sk_listener,
+ struct sk_buff *skb);
++struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++ struct sock *sk_listener,
++ bool attach_listener);
+
+ __be32 mptcp_get_reset_option(const struct sk_buff *skb);
+
+@@ -274,6 +275,13 @@ static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
+ return 0; /* TCP fallback */
+ }
+
++static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++ struct sock *sk_listener,
++ bool attach_listener)
++{
++ return NULL;
++}
++
+ static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
+ #endif /* CONFIG_MPTCP */
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 53746494eb846..80df8ff5e6752 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -283,17 +283,29 @@ struct nft_set_iter {
+ /**
+ * struct nft_set_desc - description of set elements
+ *
++ * @ktype: key type
+ * @klen: key length
++ * @dtype: data type
+ * @dlen: data length
++ * @objtype: object type
++ * @flags: flags
+ * @size: number of set elements
++ * @policy: set policy
++ * @gc_int: garbage collector interval
+ * @field_len: length of each field in concatenation, bytes
+ * @field_count: number of concatenated fields in element
+ * @expr: set must support for expressions
+ */
+ struct nft_set_desc {
++ u32 ktype;
+ unsigned int klen;
++ u32 dtype;
+ unsigned int dlen;
++ u32 objtype;
+ unsigned int size;
++ u32 policy;
++ u32 gc_int;
++ u64 timeout;
+ u8 field_len[NFT_REG32_COUNT];
+ u8 field_count;
+ bool expr;
+@@ -550,7 +562,9 @@ void *nft_set_catchall_gc(const struct nft_set *set);
+
+ static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
+ {
+- return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
++ u32 gc_int = READ_ONCE(set->gc_int);
++
++ return gc_int ? msecs_to_jiffies(gc_int) : HZ;
+ }
+
+ /**
+@@ -1499,6 +1513,9 @@ struct nft_trans_rule {
+ struct nft_trans_set {
+ struct nft_set *set;
+ u32 set_id;
++ u32 gc_int;
++ u64 timeout;
++ bool update;
+ bool bound;
+ };
+
+@@ -1508,6 +1525,12 @@ struct nft_trans_set {
+ (((struct nft_trans_set *)trans->data)->set_id)
+ #define nft_trans_set_bound(trans) \
+ (((struct nft_trans_set *)trans->data)->bound)
++#define nft_trans_set_update(trans) \
++ (((struct nft_trans_set *)trans->data)->update)
++#define nft_trans_set_timeout(trans) \
++ (((struct nft_trans_set *)trans->data)->timeout)
++#define nft_trans_set_gc_int(trans) \
++ (((struct nft_trans_set *)trans->data)->gc_int)
+
+ struct nft_trans_chain {
+ bool update;
+diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
+index 0dcb361a98bb3..ef3bb1bcea4e0 100644
+--- a/include/sound/soc-dai.h
++++ b/include/sound/soc-dai.h
+@@ -295,9 +295,9 @@ struct snd_soc_dai_ops {
+ unsigned int *rx_num, unsigned int *rx_slot);
+ int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
+
+- int (*set_sdw_stream)(struct snd_soc_dai *dai,
+- void *stream, int direction);
+- void *(*get_sdw_stream)(struct snd_soc_dai *dai, int direction);
++ int (*set_stream)(struct snd_soc_dai *dai,
++ void *stream, int direction);
++ void *(*get_stream)(struct snd_soc_dai *dai, int direction);
+
+ /*
+ * DAI digital mute - optional.
+@@ -515,42 +515,42 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
+ }
+
+ /**
+- * snd_soc_dai_set_sdw_stream() - Configures a DAI for SDW stream operation
++ * snd_soc_dai_set_stream() - Configures a DAI for stream operation
+ * @dai: DAI
+- * @stream: STREAM
++ * @stream: STREAM (opaque structure depending on DAI type)
+ * @direction: Stream direction(Playback/Capture)
+- * SoundWire subsystem doesn't have a notion of direction and we reuse
++ * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
+ * the ASoC stream direction to configure sink/source ports.
+ * Playback maps to source ports and Capture for sink ports.
+ *
+ * This should be invoked with NULL to clear the stream set previously.
+ * Returns 0 on success, a negative error code otherwise.
+ */
+-static inline int snd_soc_dai_set_sdw_stream(struct snd_soc_dai *dai,
+- void *stream, int direction)
++static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
++ void *stream, int direction)
+ {
+- if (dai->driver->ops->set_sdw_stream)
+- return dai->driver->ops->set_sdw_stream(dai, stream, direction);
++ if (dai->driver->ops->set_stream)
++ return dai->driver->ops->set_stream(dai, stream, direction);
+ else
+ return -ENOTSUPP;
+ }
+
+ /**
+- * snd_soc_dai_get_sdw_stream() - Retrieves SDW stream from DAI
++ * snd_soc_dai_get_stream() - Retrieves stream from DAI
+ * @dai: DAI
+ * @direction: Stream direction(Playback/Capture)
+ *
+ * This routine only retrieves that was previously configured
+- * with snd_soc_dai_get_sdw_stream()
++ * with snd_soc_dai_get_stream()
+ *
+ * Returns pointer to stream or an ERR_PTR value, e.g.
+ * ERR_PTR(-ENOTSUPP) if callback is not supported;
+ */
+-static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai,
+- int direction)
++static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
++ int direction)
+ {
+- if (dai->driver->ops->get_sdw_stream)
+- return dai->driver->ops->get_sdw_stream(dai, direction);
++ if (dai->driver->ops->get_stream)
++ return dai->driver->ops->get_stream(dai, direction);
+ else
+ return ERR_PTR(-ENOTSUPP);
+ }
+diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
+index 61a64d1b2bb68..c649c7fcb9afb 100644
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -104,6 +104,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RESIZE);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RENAME_DIR);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_FALLOC_RANGE);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
++TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
+
+ #define show_fc_reason(reason) \
+@@ -116,7 +117,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
+ { EXT4_FC_REASON_RESIZE, "RESIZE"}, \
+ { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, \
+ { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, \
+- { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"})
++ { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}, \
++ { EXT4_FC_REASON_ENCRYPTED_FILENAME, "ENCRYPTED_FILENAME"})
+
+ TRACE_EVENT(ext4_other_inode_update_time,
+ TP_PROTO(struct inode *inode, ino_t orig_ino),
+@@ -2764,7 +2766,7 @@ TRACE_EVENT(ext4_fc_stats,
+ ),
+
+ TP_printk("dev %d,%d fc ineligible reasons:\n"
+- "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u "
++ "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u"
+ "num_commits:%lu, ineligible: %lu, numblks: %lu",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR),
+@@ -2776,6 +2778,7 @@ TRACE_EVENT(ext4_fc_stats,
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_RENAME_DIR),
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_FALLOC_RANGE),
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_INODE_JOURNAL_DATA),
++ FC_REASON_NAME_STAT(EXT4_FC_REASON_ENCRYPTED_FILENAME),
+ __entry->fc_commits, __entry->fc_ineligible_commits,
+ __entry->fc_numblks)
+ );
+diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
+index a4dfe005983d3..29414288ea3e0 100644
+--- a/include/trace/events/jbd2.h
++++ b/include/trace/events/jbd2.h
+@@ -40,7 +40,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( char, sync_commit )
+- __field( int, transaction )
++ __field( tid_t, transaction )
+ ),
+
+ TP_fast_assign(
+@@ -49,7 +49,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
+ __entry->transaction = commit_transaction->t_tid;
+ ),
+
+- TP_printk("dev %d,%d transaction %d sync %d",
++ TP_printk("dev %d,%d transaction %u sync %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->transaction, __entry->sync_commit)
+ );
+@@ -97,8 +97,8 @@ TRACE_EVENT(jbd2_end_commit,
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( char, sync_commit )
+- __field( int, transaction )
+- __field( int, head )
++ __field( tid_t, transaction )
++ __field( tid_t, head )
+ ),
+
+ TP_fast_assign(
+@@ -108,7 +108,7 @@ TRACE_EVENT(jbd2_end_commit,
+ __entry->head = journal->j_tail_sequence;
+ ),
+
+- TP_printk("dev %d,%d transaction %d sync %d head %d",
++ TP_printk("dev %d,%d transaction %u sync %d head %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->transaction, __entry->sync_commit, __entry->head)
+ );
+@@ -134,14 +134,14 @@ TRACE_EVENT(jbd2_submit_inode_data,
+ );
+
+ DECLARE_EVENT_CLASS(jbd2_handle_start_class,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int requested_blocks),
+
+ TP_ARGS(dev, tid, type, line_no, requested_blocks),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned int, type )
+ __field( unsigned int, line_no )
+ __field( int, requested_blocks)
+@@ -155,28 +155,28 @@ DECLARE_EVENT_CLASS(jbd2_handle_start_class,
+ __entry->requested_blocks = requested_blocks;
+ ),
+
+- TP_printk("dev %d,%d tid %lu type %u line_no %u "
++ TP_printk("dev %d,%d tid %u type %u line_no %u "
+ "requested_blocks %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ __entry->type, __entry->line_no, __entry->requested_blocks)
+ );
+
+ DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_start,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int requested_blocks),
+
+ TP_ARGS(dev, tid, type, line_no, requested_blocks)
+ );
+
+ DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_restart,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int requested_blocks),
+
+ TP_ARGS(dev, tid, type, line_no, requested_blocks)
+ );
+
+ TRACE_EVENT(jbd2_handle_extend,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int buffer_credits,
+ int requested_blocks),
+
+@@ -184,7 +184,7 @@ TRACE_EVENT(jbd2_handle_extend,
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned int, type )
+ __field( unsigned int, line_no )
+ __field( int, buffer_credits )
+@@ -200,7 +200,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ __entry->requested_blocks = requested_blocks;
+ ),
+
+- TP_printk("dev %d,%d tid %lu type %u line_no %u "
++ TP_printk("dev %d,%d tid %u type %u line_no %u "
+ "buffer_credits %d requested_blocks %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ __entry->type, __entry->line_no, __entry->buffer_credits,
+@@ -208,7 +208,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ );
+
+ TRACE_EVENT(jbd2_handle_stats,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int interval, int sync,
+ int requested_blocks, int dirtied_blocks),
+
+@@ -217,7 +217,7 @@ TRACE_EVENT(jbd2_handle_stats,
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned int, type )
+ __field( unsigned int, line_no )
+ __field( int, interval )
+@@ -237,7 +237,7 @@ TRACE_EVENT(jbd2_handle_stats,
+ __entry->dirtied_blocks = dirtied_blocks;
+ ),
+
+- TP_printk("dev %d,%d tid %lu type %u line_no %u interval %d "
++ TP_printk("dev %d,%d tid %u type %u line_no %u interval %d "
+ "sync %d requested_blocks %d dirtied_blocks %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ __entry->type, __entry->line_no, __entry->interval,
+@@ -246,14 +246,14 @@ TRACE_EVENT(jbd2_handle_stats,
+ );
+
+ TRACE_EVENT(jbd2_run_stats,
+- TP_PROTO(dev_t dev, unsigned long tid,
++ TP_PROTO(dev_t dev, tid_t tid,
+ struct transaction_run_stats_s *stats),
+
+ TP_ARGS(dev, tid, stats),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned long, wait )
+ __field( unsigned long, request_delay )
+ __field( unsigned long, running )
+@@ -279,7 +279,7 @@ TRACE_EVENT(jbd2_run_stats,
+ __entry->blocks_logged = stats->rs_blocks_logged;
+ ),
+
+- TP_printk("dev %d,%d tid %lu wait %u request_delay %u running %u "
++ TP_printk("dev %d,%d tid %u wait %u request_delay %u running %u "
+ "locked %u flushing %u logging %u handle_count %u "
+ "blocks %u blocks_logged %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+@@ -294,14 +294,14 @@ TRACE_EVENT(jbd2_run_stats,
+ );
+
+ TRACE_EVENT(jbd2_checkpoint_stats,
+- TP_PROTO(dev_t dev, unsigned long tid,
++ TP_PROTO(dev_t dev, tid_t tid,
+ struct transaction_chp_stats_s *stats),
+
+ TP_ARGS(dev, tid, stats),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned long, chp_time )
+ __field( __u32, forced_to_close )
+ __field( __u32, written )
+@@ -317,7 +317,7 @@ TRACE_EVENT(jbd2_checkpoint_stats,
+ __entry->dropped = stats->cs_dropped;
+ ),
+
+- TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u "
++ TP_printk("dev %d,%d tid %u chp_time %u forced_to_close %u "
+ "written %u dropped %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ jiffies_to_msecs(__entry->chp_time),
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index eebbe8a6da0c5..c587221a289c1 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2701,7 +2701,7 @@ static bool __io_complete_rw_common(struct io_kiocb *req, long res)
+ return false;
+ }
+
+-static inline int io_fixup_rw_res(struct io_kiocb *req, unsigned res)
++static inline int io_fixup_rw_res(struct io_kiocb *req, long res)
+ {
+ struct io_async_rw *io = req->async_data;
+
+@@ -7598,7 +7598,7 @@ static int io_run_task_work_sig(void)
+ /* when returns >0, the caller should retry */
+ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
+ struct io_wait_queue *iowq,
+- ktime_t timeout)
++ ktime_t *timeout)
+ {
+ int ret;
+
+@@ -7610,7 +7610,7 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
+ if (test_bit(0, &ctx->check_cq_overflow))
+ return 1;
+
+- if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS))
++ if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS))
+ return -ETIME;
+ return 1;
+ }
+@@ -7673,7 +7673,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+ }
+ prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq,
+ TASK_INTERRUPTIBLE);
+- ret = io_cqring_wait_schedule(ctx, &iowq, timeout);
++ ret = io_cqring_wait_schedule(ctx, &iowq, &timeout);
+ finish_wait(&ctx->cq_wait, &iowq.wq);
+ cond_resched();
+ } while (ret > 0);
+@@ -10895,8 +10895,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
+ return -ENXIO;
+
+ if (ctx->restricted) {
+- if (opcode >= IORING_REGISTER_LAST)
+- return -EINVAL;
+ opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
+ if (!test_bit(opcode, ctx->restrictions.register_op))
+ return -EACCES;
+@@ -11028,6 +11026,9 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
+ long ret = -EBADF;
+ struct fd f;
+
++ if (opcode >= IORING_REGISTER_LAST)
++ return -EINVAL;
++
+ f = fdget(fd);
+ if (!f.file)
+ return -EBADF;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index e950881444715..d8795036202ac 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -12215,12 +12215,12 @@ SYSCALL_DEFINE5(perf_event_open,
+ if (flags & ~PERF_FLAG_ALL)
+ return -EINVAL;
+
+- /* Do we allow access to perf_event_open(2) ? */
+- err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
++ err = perf_copy_attr(attr_uptr, &attr);
+ if (err)
+ return err;
+
+- err = perf_copy_attr(attr_uptr, &attr);
++ /* Do we allow access to perf_event_open(2) ? */
++ err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
+ if (err)
+ return err;
+
+diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
+index 76e67d1e02d48..526510b3791ed 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -14,10 +14,12 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
++#include <linux/minmax.h>
+ #include <linux/moduleparam.h>
+ #include <linux/percpu.h>
+ #include <linux/preempt.h>
+ #include <linux/sched.h>
++#include <linux/string.h>
+ #include <linux/uaccess.h>
+
+ #include "encoding.h"
+@@ -1060,3 +1062,51 @@ EXPORT_SYMBOL(__tsan_atomic_thread_fence);
+ void __tsan_atomic_signal_fence(int memorder);
+ void __tsan_atomic_signal_fence(int memorder) { }
+ EXPORT_SYMBOL(__tsan_atomic_signal_fence);
++
++#ifdef __HAVE_ARCH_MEMSET
++void *__tsan_memset(void *s, int c, size_t count);
++noinline void *__tsan_memset(void *s, int c, size_t count)
++{
++ /*
++ * Instead of not setting up watchpoints where accessed size is greater
++ * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE.
++ */
++ size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE);
++
++ check_access(s, check_len, KCSAN_ACCESS_WRITE);
++ return memset(s, c, count);
++}
++#else
++void *__tsan_memset(void *s, int c, size_t count) __alias(memset);
++#endif
++EXPORT_SYMBOL(__tsan_memset);
++
++#ifdef __HAVE_ARCH_MEMMOVE
++void *__tsan_memmove(void *dst, const void *src, size_t len);
++noinline void *__tsan_memmove(void *dst, const void *src, size_t len)
++{
++ size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
++
++ check_access(dst, check_len, KCSAN_ACCESS_WRITE);
++ check_access(src, check_len, 0);
++ return memmove(dst, src, len);
++}
++#else
++void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove);
++#endif
++EXPORT_SYMBOL(__tsan_memmove);
++
++#ifdef __HAVE_ARCH_MEMCPY
++void *__tsan_memcpy(void *dst, const void *src, size_t len);
++noinline void *__tsan_memcpy(void *dst, const void *src, size_t len)
++{
++ size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
++
++ check_access(dst, check_len, KCSAN_ACCESS_WRITE);
++ check_access(src, check_len, 0);
++ return memcpy(dst, src, len);
++}
++#else
++void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy);
++#endif
++EXPORT_SYMBOL(__tsan_memcpy);
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index ae8396032b5da..4bd07cc3c0eab 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -892,32 +892,24 @@ static void trc_read_check_handler(void *t_in)
+
+ // If the task is no longer running on this CPU, leave.
+ if (unlikely(texp != t)) {
+- if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
+- wake_up(&trc_wait);
+ goto reset_ipi; // Already on holdout list, so will check later.
+ }
+
+ // If the task is not in a read-side critical section, and
+ // if this is the last reader, awaken the grace-period kthread.
+ if (likely(!READ_ONCE(t->trc_reader_nesting))) {
+- if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
+- wake_up(&trc_wait);
+- // Mark as checked after decrement to avoid false
+- // positives on the above WARN_ON_ONCE().
+ WRITE_ONCE(t->trc_reader_checked, true);
+ goto reset_ipi;
+ }
+ // If we are racing with an rcu_read_unlock_trace(), try again later.
+- if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0)) {
+- if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
+- wake_up(&trc_wait);
++ if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0))
+ goto reset_ipi;
+- }
+ WRITE_ONCE(t->trc_reader_checked, true);
+
+ // Get here if the task is in a read-side critical section. Set
+ // its state so that it will awaken the grace-period kthread upon
+ // exit from that critical section.
++ atomic_inc(&trc_n_readers_need_end); // One more to wait on.
+ WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs));
+ WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
+
+@@ -1017,21 +1009,15 @@ static void trc_wait_for_one_reader(struct task_struct *t,
+ if (per_cpu(trc_ipi_to_cpu, cpu) || t->trc_ipi_to_cpu >= 0)
+ return;
+
+- atomic_inc(&trc_n_readers_need_end);
+ per_cpu(trc_ipi_to_cpu, cpu) = true;
+ t->trc_ipi_to_cpu = cpu;
+ rcu_tasks_trace.n_ipis++;
+- if (smp_call_function_single(cpu,
+- trc_read_check_handler, t, 0)) {
++ if (smp_call_function_single(cpu, trc_read_check_handler, t, 0)) {
+ // Just in case there is some other reason for
+ // failure than the target CPU being offline.
+ rcu_tasks_trace.n_ipis_fails++;
+ per_cpu(trc_ipi_to_cpu, cpu) = false;
+ t->trc_ipi_to_cpu = cpu;
+- if (atomic_dec_and_test(&trc_n_readers_need_end)) {
+- WARN_ON_ONCE(1);
+- wake_up(&trc_wait);
+- }
+ }
+ }
+ }
+diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
+index 420ff4bc67fd7..4265d125d50f3 100644
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -328,6 +328,7 @@ config SCHED_TRACER
+ config HWLAT_TRACER
+ bool "Tracer to detect hardware latencies (like SMIs)"
+ select GENERIC_TRACER
++ select TRACER_MAX_TRACE
+ help
+ This tracer, when enabled will create one or more kernel threads,
+ depending on what the cpumask file is set to, which each thread
+@@ -363,6 +364,7 @@ config HWLAT_TRACER
+ config OSNOISE_TRACER
+ bool "OS Noise tracer"
+ select GENERIC_TRACER
++ select TRACER_MAX_TRACE
+ help
+ In the context of high-performance computing (HPC), the Operating
+ System Noise (osnoise) refers to the interference experienced by an
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index b26de6ff5d0bf..114d94d1e0a90 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1409,6 +1409,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ return false;
+ }
+ EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
++#define free_snapshot(tr) do { } while (0)
+ #endif /* CONFIG_TRACER_SNAPSHOT */
+
+ void tracer_tracing_off(struct trace_array *tr)
+@@ -1679,6 +1680,8 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
+ }
+
+ unsigned long __read_mostly tracing_thresh;
++
++#ifdef CONFIG_TRACER_MAX_TRACE
+ static const struct file_operations tracing_max_lat_fops;
+
+ #ifdef LATENCY_FS_NOTIFY
+@@ -1735,18 +1738,14 @@ void latency_fsnotify(struct trace_array *tr)
+ irq_work_queue(&tr->fsnotify_irqwork);
+ }
+
+-#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+- || defined(CONFIG_OSNOISE_TRACER)
++#else /* !LATENCY_FS_NOTIFY */
+
+ #define trace_create_maxlat_file(tr, d_tracer) \
+ trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \
+ d_tracer, &tr->max_latency, &tracing_max_lat_fops)
+
+-#else
+-#define trace_create_maxlat_file(tr, d_tracer) do { } while (0)
+ #endif
+
+-#ifdef CONFIG_TRACER_MAX_TRACE
+ /*
+ * Copy the new maximum trace into the separate maximum-trace
+ * structure. (this way the maximum trace is permanently saved,
+@@ -1821,14 +1820,15 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
+ ring_buffer_record_off(tr->max_buffer.buffer);
+
+ #ifdef CONFIG_TRACER_SNAPSHOT
+- if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data))
+- goto out_unlock;
++ if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) {
++ arch_spin_unlock(&tr->max_lock);
++ return;
++ }
+ #endif
+ swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
+
+ __update_max_tr(tr, tsk, cpu);
+
+- out_unlock:
+ arch_spin_unlock(&tr->max_lock);
+ }
+
+@@ -1875,6 +1875,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
+ __update_max_tr(tr, tsk, cpu);
+ arch_spin_unlock(&tr->max_lock);
+ }
++
+ #endif /* CONFIG_TRACER_MAX_TRACE */
+
+ static int wait_on_pipe(struct trace_iterator *iter, int full)
+@@ -6536,7 +6537,7 @@ out:
+ return ret;
+ }
+
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+
+ static ssize_t
+ tracing_max_lat_read(struct file *filp, char __user *ubuf,
+@@ -6763,7 +6764,20 @@ waitagain:
+
+ ret = print_trace_line(iter);
+ if (ret == TRACE_TYPE_PARTIAL_LINE) {
+- /* don't print partial lines */
++ /*
++ * If one print_trace_line() fills entire trace_seq in one shot,
++ * trace_seq_to_user() will returns -EBUSY because save_len == 0,
++ * In this case, we need to consume it, otherwise, loop will peek
++ * this event next time, resulting in an infinite loop.
++ */
++ if (save_len == 0) {
++ iter->seq.full = 0;
++ trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
++ trace_consume(iter);
++ break;
++ }
++
++ /* In other cases, don't print partial lines */
+ iter->seq.seq.len = save_len;
+ break;
+ }
+@@ -7560,7 +7574,7 @@ static const struct file_operations tracing_thresh_fops = {
+ .llseek = generic_file_llseek,
+ };
+
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ static const struct file_operations tracing_max_lat_fops = {
+ .open = tracing_open_generic,
+ .read = tracing_max_lat_read,
+@@ -9549,7 +9563,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
+
+ create_trace_options_dir(tr);
+
++#ifdef CONFIG_TRACER_MAX_TRACE
+ trace_create_maxlat_file(tr, d_tracer);
++#endif
+
+ if (ftrace_create_function_files(tr, d_tracer))
+ MEM_FAIL(1, "Could not allocate function filter files");
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 28ea6c0be4953..9fc598165f3a2 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -309,8 +309,7 @@ struct trace_array {
+ struct array_buffer max_buffer;
+ bool allocated_snapshot;
+ #endif
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+- || defined(CONFIG_OSNOISE_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ unsigned long max_latency;
+ #ifdef CONFIG_FSNOTIFY
+ struct dentry *d_max_latency;
+@@ -688,12 +687,11 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
+ void *cond_data);
+ void update_max_tr_single(struct trace_array *tr,
+ struct task_struct *tsk, int cpu);
+-#endif /* CONFIG_TRACER_MAX_TRACE */
+
+-#if (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+- || defined(CONFIG_OSNOISE_TRACER)) && defined(CONFIG_FSNOTIFY)
++#ifdef CONFIG_FSNOTIFY
+ #define LATENCY_FS_NOTIFY
+ #endif
++#endif /* CONFIG_TRACER_MAX_TRACE */
+
+ #ifdef LATENCY_FS_NOTIFY
+ void latency_fsnotify(struct trace_array *tr);
+@@ -1941,17 +1939,30 @@ static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
+ }
+
+ /* Check the name is good for event/group/fields */
+-static inline bool is_good_name(const char *name)
++static inline bool __is_good_name(const char *name, bool hash_ok)
+ {
+- if (!isalpha(*name) && *name != '_')
++ if (!isalpha(*name) && *name != '_' && (!hash_ok || *name != '-'))
+ return false;
+ while (*++name != '\0') {
+- if (!isalpha(*name) && !isdigit(*name) && *name != '_')
++ if (!isalpha(*name) && !isdigit(*name) && *name != '_' &&
++ (!hash_ok || *name != '-'))
+ return false;
+ }
+ return true;
+ }
+
++/* Check the name is good for event/group/fields */
++static inline bool is_good_name(const char *name)
++{
++ return __is_good_name(name, false);
++}
++
++/* Check the name is good for system */
++static inline bool is_good_system_name(const char *name)
++{
++ return __is_good_name(name, true);
++}
++
+ /* Convert certain expected symbols into '_' when generating event names */
+ static inline void sanitize_event_name(char *name)
+ {
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index d19dab21848e0..9806316af1279 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -567,6 +567,9 @@ static void eprobe_trigger_func(struct event_trigger_data *data,
+ {
+ struct eprobe_data *edata = data->private_data;
+
++ if (unlikely(!rec))
++ return;
++
+ if (unlikely(!rec))
+ return;
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 6397285883fa0..cc1a078f7a164 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -452,7 +452,7 @@ struct action_data {
+ * event param, and is passed to the synthetic event
+ * invocation.
+ */
+- unsigned int var_ref_idx[TRACING_MAP_VARS_MAX];
++ unsigned int var_ref_idx[SYNTH_FIELDS_MAX];
+ struct synth_event *synth_event;
+ bool use_trace_keyword;
+ char *synth_event_name;
+@@ -1895,7 +1895,9 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
+ return ref_field;
+ }
+ }
+-
++ /* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
++ if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
++ return NULL;
+ ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
+ if (ref_field) {
+ if (init_var_ref(ref_field, var_field, system, event_name)) {
+@@ -3188,6 +3190,7 @@ static int parse_action_params(struct trace_array *tr, char *params,
+ while (params) {
+ if (data->n_params >= SYNTH_FIELDS_MAX) {
+ hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
++ ret = -EINVAL;
+ goto out;
+ }
+
+@@ -3524,6 +3527,10 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
+
+ lockdep_assert_held(&event_mutex);
+
++ /* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
++ if (data->n_params > SYNTH_FIELDS_MAX)
++ return -EINVAL;
++
+ if (data->use_trace_keyword)
+ synth_event_name = data->synth_event_name;
+ else
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index 47eb92b3edd07..2fdf3fd591e18 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -1275,12 +1275,12 @@ static int __create_synth_event(const char *name, const char *raw_fields)
+ goto err;
+ }
+
+- fields[n_fields++] = field;
+ if (n_fields == SYNTH_FIELDS_MAX) {
+ synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0);
+ ret = -EINVAL;
+ goto err;
+ }
++ fields[n_fields++] = field;
+
+ n_fields_this_loop++;
+ }
+diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
+index 2bbe4a7c6a2b6..cb8f9fe5669ad 100644
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -246,7 +246,7 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
+ return -EINVAL;
+ }
+ strlcpy(buf, event, slash - event + 1);
+- if (!is_good_name(buf)) {
++ if (!is_good_system_name(buf)) {
+ trace_probe_log_err(offset, BAD_GROUP_NAME);
+ return -EINVAL;
+ }
+diff --git a/mm/compaction.c b/mm/compaction.c
+index e8fcf0e0c1ca3..89517ad5d6a0b 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -1350,7 +1350,7 @@ move_freelist_tail(struct list_head *freelist, struct page *freepage)
+ }
+
+ static void
+-fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long nr_isolated)
++fast_isolate_around(struct compact_control *cc, unsigned long pfn)
+ {
+ unsigned long start_pfn, end_pfn;
+ struct page *page;
+@@ -1371,21 +1371,13 @@ fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long
+ if (!page)
+ return;
+
+- /* Scan before */
+- if (start_pfn != pfn) {
+- isolate_freepages_block(cc, &start_pfn, pfn, &cc->freepages, 1, false);
+- if (cc->nr_freepages >= cc->nr_migratepages)
+- return;
+- }
+-
+- /* Scan after */
+- start_pfn = pfn + nr_isolated;
+- if (start_pfn < end_pfn)
+- isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
++ isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
+
+ /* Skip this pageblock in the future as it's full or nearly full */
+ if (cc->nr_freepages < cc->nr_migratepages)
+ set_pageblock_skip(page);
++
++ return;
+ }
+
+ /* Search orders in round-robin fashion */
+@@ -1561,7 +1553,7 @@ fast_isolate_freepages(struct compact_control *cc)
+ return cc->free_pfn;
+
+ low_pfn = page_to_pfn(page);
+- fast_isolate_around(cc, low_pfn, nr_isolated);
++ fast_isolate_around(cc, low_pfn);
+ return low_pfn;
+ }
+
+diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
+index 2809cbd6b7f74..d8cb4b2a076b4 100644
+--- a/net/caif/cfctrl.c
++++ b/net/caif/cfctrl.c
+@@ -269,11 +269,15 @@ int cfctrl_linkup_request(struct cflayer *layer,
+ default:
+ pr_warn("Request setup of bad link type = %d\n",
+ param->linktype);
++ cfpkt_destroy(pkt);
+ return -EINVAL;
+ }
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+- if (!req)
++ if (!req) {
++ cfpkt_destroy(pkt);
+ return -ENOMEM;
++ }
++
+ req->client_layer = user_layer;
+ req->cmd = CFCTRL_CMD_LINK_SETUP;
+ req->param = *param;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 2da05622afbe8..b2031148dd8b4 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3182,15 +3182,18 @@ static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
+
+ static int bpf_skb_generic_pop(struct sk_buff *skb, u32 off, u32 len)
+ {
++ void *old_data;
++
+ /* skb_ensure_writable() is not needed here, as we're
+ * already working on an uncloned skb.
+ */
+ if (unlikely(!pskb_may_pull(skb, off + len)))
+ return -ENOMEM;
+
+- skb_postpull_rcsum(skb, skb->data + off, len);
+- memmove(skb->data + len, skb->data, off);
++ old_data = skb->data;
+ __skb_pull(skb, len);
++ skb_postpull_rcsum(skb, old_data + off, len);
++ memmove(skb->data, old_data, off);
+
+ return 0;
+ }
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 9408392640250..3aab914eb1039 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -290,12 +290,11 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+ struct tcp_request_sock *treq;
+ struct request_sock *req;
+
+-#ifdef CONFIG_MPTCP
+ if (sk_is_mptcp(sk))
+- ops = &mptcp_subflow_request_sock_ops;
+-#endif
++ req = mptcp_subflow_reqsk_alloc(ops, sk, false);
++ else
++ req = inet_reqsk_alloc(ops, sk, false);
+
+- req = inet_reqsk_alloc(ops, sk, false);
+ if (!req)
+ return NULL;
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 5ef9013b94c74..ba4241d7c5ef1 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -45,7 +45,6 @@ static void subflow_req_destructor(struct request_sock *req)
+ sock_put((struct sock *)subflow_req->msk);
+
+ mptcp_token_destroy_request(req);
+- tcp_request_sock_ops.destructor(req);
+ }
+
+ static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
+@@ -483,9 +482,8 @@ do_reset:
+ mptcp_subflow_reset(sk);
+ }
+
+-struct request_sock_ops mptcp_subflow_request_sock_ops;
+-EXPORT_SYMBOL_GPL(mptcp_subflow_request_sock_ops);
+-static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops;
++static struct request_sock_ops mptcp_subflow_v4_request_sock_ops __ro_after_init;
++static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
+
+ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+ {
+@@ -497,7 +495,7 @@ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+ goto drop;
+
+- return tcp_conn_request(&mptcp_subflow_request_sock_ops,
++ return tcp_conn_request(&mptcp_subflow_v4_request_sock_ops,
+ &subflow_request_sock_ipv4_ops,
+ sk, skb);
+ drop:
+@@ -505,10 +503,17 @@ drop:
+ return 0;
+ }
+
++static void subflow_v4_req_destructor(struct request_sock *req)
++{
++ subflow_req_destructor(req);
++ tcp_request_sock_ops.destructor(req);
++}
++
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
+-static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops;
+-static struct inet_connection_sock_af_ops subflow_v6_specific;
+-static struct inet_connection_sock_af_ops subflow_v6m_specific;
++static struct request_sock_ops mptcp_subflow_v6_request_sock_ops __ro_after_init;
++static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init;
++static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init;
++static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init;
+ static struct proto tcpv6_prot_override;
+
+ static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+@@ -528,15 +533,36 @@ static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+ return 0;
+ }
+
+- return tcp_conn_request(&mptcp_subflow_request_sock_ops,
++ return tcp_conn_request(&mptcp_subflow_v6_request_sock_ops,
+ &subflow_request_sock_ipv6_ops, sk, skb);
+
+ drop:
+ tcp_listendrop(sk);
+ return 0; /* don't send reset */
+ }
++
++static void subflow_v6_req_destructor(struct request_sock *req)
++{
++ subflow_req_destructor(req);
++ tcp6_request_sock_ops.destructor(req);
++}
++#endif
++
++struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++ struct sock *sk_listener,
++ bool attach_listener)
++{
++ if (ops->family == AF_INET)
++ ops = &mptcp_subflow_v4_request_sock_ops;
++#if IS_ENABLED(CONFIG_MPTCP_IPV6)
++ else if (ops->family == AF_INET6)
++ ops = &mptcp_subflow_v6_request_sock_ops;
+ #endif
+
++ return inet_reqsk_alloc(ops, sk_listener, attach_listener);
++}
++EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc);
++
+ /* validate hmac received in third ACK */
+ static bool subflow_hmac_valid(const struct request_sock *req,
+ const struct mptcp_options_received *mp_opt)
+@@ -790,7 +816,7 @@ dispose_child:
+ return child;
+ }
+
+-static struct inet_connection_sock_af_ops subflow_specific;
++static struct inet_connection_sock_af_ops subflow_specific __ro_after_init;
+ static struct proto tcp_prot_override;
+
+ enum mapping_status {
+@@ -1327,7 +1353,7 @@ static void subflow_write_space(struct sock *ssk)
+ mptcp_write_space(sk);
+ }
+
+-static struct inet_connection_sock_af_ops *
++static const struct inet_connection_sock_af_ops *
+ subflow_default_af_ops(struct sock *sk)
+ {
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
+@@ -1342,7 +1368,7 @@ void mptcpv6_handle_mapped(struct sock *sk, bool mapped)
+ {
+ struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
+ struct inet_connection_sock *icsk = inet_csk(sk);
+- struct inet_connection_sock_af_ops *target;
++ const struct inet_connection_sock_af_ops *target;
+
+ target = mapped ? &subflow_v6m_specific : subflow_default_af_ops(sk);
+
+@@ -1782,7 +1808,6 @@ static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = {
+ static int subflow_ops_init(struct request_sock_ops *subflow_ops)
+ {
+ subflow_ops->obj_size = sizeof(struct mptcp_subflow_request_sock);
+- subflow_ops->slab_name = "request_sock_subflow";
+
+ subflow_ops->slab = kmem_cache_create(subflow_ops->slab_name,
+ subflow_ops->obj_size, 0,
+@@ -1792,16 +1817,17 @@ static int subflow_ops_init(struct request_sock_ops *subflow_ops)
+ if (!subflow_ops->slab)
+ return -ENOMEM;
+
+- subflow_ops->destructor = subflow_req_destructor;
+-
+ return 0;
+ }
+
+ void __init mptcp_subflow_init(void)
+ {
+- mptcp_subflow_request_sock_ops = tcp_request_sock_ops;
+- if (subflow_ops_init(&mptcp_subflow_request_sock_ops) != 0)
+- panic("MPTCP: failed to init subflow request sock ops\n");
++ mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops;
++ mptcp_subflow_v4_request_sock_ops.slab_name = "request_sock_subflow_v4";
++ mptcp_subflow_v4_request_sock_ops.destructor = subflow_v4_req_destructor;
++
++ if (subflow_ops_init(&mptcp_subflow_v4_request_sock_ops) != 0)
++ panic("MPTCP: failed to init subflow v4 request sock ops\n");
+
+ subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
+ subflow_request_sock_ipv4_ops.route_req = subflow_v4_route_req;
+@@ -1815,6 +1841,20 @@ void __init mptcp_subflow_init(void)
+ tcp_prot_override.release_cb = tcp_release_cb_override;
+
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
++ /* In struct mptcp_subflow_request_sock, we assume the TCP request sock
++ * structures for v4 and v6 have the same size. It should not changed in
++ * the future but better to make sure to be warned if it is no longer
++ * the case.
++ */
++ BUILD_BUG_ON(sizeof(struct tcp_request_sock) != sizeof(struct tcp6_request_sock));
++
++ mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops;
++ mptcp_subflow_v6_request_sock_ops.slab_name = "request_sock_subflow_v6";
++ mptcp_subflow_v6_request_sock_ops.destructor = subflow_v6_req_destructor;
++
++ if (subflow_ops_init(&mptcp_subflow_v6_request_sock_ops) != 0)
++ panic("MPTCP: failed to init subflow v6 request sock ops\n");
++
+ subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops;
+ subflow_request_sock_ipv6_ops.route_req = subflow_v6_route_req;
+
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 16ae92054baa8..ae061b27e4465 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1698,9 +1698,10 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
+ ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried);
+ ip_set_unlock(set);
+ retried = true;
+- } while (ret == -EAGAIN &&
+- set->variant->resize &&
+- (ret = set->variant->resize(set, retried)) == 0);
++ } while (ret == -ERANGE ||
++ (ret == -EAGAIN &&
++ set->variant->resize &&
++ (ret = set->variant->resize(set, retried)) == 0));
+
+ if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
+ return 0;
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index 75d556d71652d..24adcdd7a0b16 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -98,11 +98,11 @@ static int
+ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ip4 *h = set->data;
++ struct hash_ip4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ip4_elem e = { 0 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0, hosts;
++ u32 ip = 0, ip_to = 0, hosts, i = 0;
+ int ret = 0;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -147,14 +147,14 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+
+ hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
+
+- /* 64bit division is not allowed on 32bit */
+- if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+- for (; ip <= ip_to;) {
++ for (; ip <= ip_to; i++) {
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ip4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
+index 153de3457423e..a22ec1a6f6ec8 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
+@@ -97,11 +97,11 @@ static int
+ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipmark4 *h = set->data;
++ struct hash_ipmark4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipmark4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip, ip_to = 0;
++ u32 ip, ip_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -148,13 +148,14 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ip_set_mask_from_to(ip, ip_to, cidr);
+ }
+
+- if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+- for (; ip <= ip_to; ip++) {
++ for (; ip <= ip_to; ip++, i++) {
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipmark4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
+index 7303138e46be1..10481760a9b25 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipport.c
++++ b/net/netfilter/ipset/ip_set_hash_ipport.c
+@@ -105,11 +105,11 @@ static int
+ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipport4 *h = set->data;
++ struct hash_ipport4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipport4_elem e = { .ip = 0 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip, ip_to = 0, p = 0, port, port_to;
++ u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -173,17 +173,18 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
+- if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+ p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+ : port;
+- for (; p <= port_to; p++) {
++ for (; p <= port_to; p++, i++) {
+ e.ip = htonl(ip);
+ e.port = htons(p);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipport4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
+index 334fb1ad0e86c..39a01934b1536 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
+@@ -108,11 +108,11 @@ static int
+ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipportip4 *h = set->data;
++ struct hash_ipportip4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipportip4_elem e = { .ip = 0 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip, ip_to = 0, p = 0, port, port_to;
++ u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -180,17 +180,18 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
+- if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+ p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+ : port;
+- for (; p <= port_to; p++) {
++ for (; p <= port_to; p++, i++) {
+ e.ip = htonl(ip);
+ e.port = htons(p);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipportip4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+index 7df94f437f600..5c6de605a9fb7 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+@@ -160,12 +160,12 @@ static int
+ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipportnet4 *h = set->data;
++ struct hash_ipportnet4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+- u32 ip2_from = 0, ip2_to = 0, ip2;
++ u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
+ bool with_ports = false;
+ u8 cidr;
+ int ret;
+@@ -253,9 +253,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
+- if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ ip2_to = ip2_from;
+ if (tb[IPSET_ATTR_IP2_TO]) {
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
+@@ -282,9 +279,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ for (; p <= port_to; p++) {
+ e.port = htons(p);
+ do {
++ i++;
+ e.ip2 = htonl(ip2);
+ ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr);
+ e.cidr = cidr - 1;
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipportnet4_data_next(&h->next,
++ &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
+index 1422739d9aa25..ce0a9ce5a91f1 100644
+--- a/net/netfilter/ipset/ip_set_hash_net.c
++++ b/net/netfilter/ipset/ip_set_hash_net.c
+@@ -136,11 +136,11 @@ static int
+ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_net4 *h = set->data;
++ struct hash_net4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_net4_elem e = { .cidr = HOST_MASK };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0, ipn, n = 0;
++ u32 ip = 0, ip_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -188,19 +188,16 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ if (ip + UINT_MAX == ip_to)
+ return -IPSET_ERR_HASH_RANGE;
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
+- n++;
+- } while (ipn++ < ip_to);
+-
+- if (n > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried)
+ ip = ntohl(h->next.ip);
+ do {
++ i++;
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_net4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
+index 9810f5bf63f5e..0310732862362 100644
+--- a/net/netfilter/ipset/ip_set_hash_netiface.c
++++ b/net/netfilter/ipset/ip_set_hash_netiface.c
+@@ -202,7 +202,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0, ipn, n = 0;
++ u32 ip = 0, ip_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -256,19 +256,16 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip, ip_to, e.cidr);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
+- n++;
+- } while (ipn++ < ip_to);
+-
+- if (n > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried)
+ ip = ntohl(h->next.ip);
+ do {
++ i++;
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netiface4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
+index 3d09eefe998a7..c07b70bf32db4 100644
+--- a/net/netfilter/ipset/ip_set_hash_netnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netnet.c
+@@ -163,13 +163,12 @@ static int
+ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_netnet4 *h = set->data;
++ struct hash_netnet4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netnet4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0;
+- u32 ip2 = 0, ip2_from = 0, ip2_to = 0, ipn;
+- u64 n = 0, m = 0;
++ u32 ip2 = 0, ip2_from = 0, ip2_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -245,19 +244,6 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
+- n++;
+- } while (ipn++ < ip_to);
+- ipn = ip2_from;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
+- m++;
+- } while (ipn++ < ip2_to);
+-
+- if (n*m > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip[0]);
+@@ -270,7 +256,12 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ e.ip[0] = htonl(ip);
+ ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
+ do {
++ i++;
+ e.ip[1] = htonl(ip2);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netnet4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ip2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
+index 09cf72eb37f8d..d1a0628df4ef3 100644
+--- a/net/netfilter/ipset/ip_set_hash_netport.c
++++ b/net/netfilter/ipset/ip_set_hash_netport.c
+@@ -154,12 +154,11 @@ static int
+ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_netport4 *h = set->data;
++ struct hash_netport4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 port, port_to, p = 0, ip = 0, ip_to = 0, ipn;
+- u64 n = 0;
++ u32 port, port_to, p = 0, ip = 0, ip_to = 0, i = 0;
+ bool with_ports = false;
+ u8 cidr;
+ int ret;
+@@ -236,14 +235,6 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &cidr);
+- n++;
+- } while (ipn++ < ip_to);
+-
+- if (n*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip);
+@@ -255,8 +246,12 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ e.ip = htonl(ip);
+ ip = ip_set_range_to_cidr(ip, ip_to, &cidr);
+ e.cidr = cidr - 1;
+- for (; p <= port_to; p++) {
++ for (; p <= port_to; p++, i++) {
+ e.port = htons(p);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netport4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
+index 19bcdb3141f6e..005a7ce87217e 100644
+--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
+@@ -173,17 +173,26 @@ hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
+ return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+ }
+
++static u32
++hash_netportnet4_range_to_cidr(u32 from, u32 to, u8 *cidr)
++{
++ if (from == 0 && to == UINT_MAX) {
++ *cidr = 0;
++ return to;
++ }
++ return ip_set_range_to_cidr(from, to, cidr);
++}
++
+ static int
+ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_netportnet4 *h = set->data;
++ struct hash_netportnet4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netportnet4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+- u32 ip2_from = 0, ip2_to = 0, ip2, ipn;
+- u64 n = 0, m = 0;
++ u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -285,19 +294,6 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
+- n++;
+- } while (ipn++ < ip_to);
+- ipn = ip2_from;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
+- m++;
+- } while (ipn++ < ip2_to);
+-
+- if (n*m*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip[0]);
+@@ -310,13 +306,19 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+
+ do {
+ e.ip[0] = htonl(ip);
+- ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
++ ip = hash_netportnet4_range_to_cidr(ip, ip_to, &e.cidr[0]);
+ for (; p <= port_to; p++) {
+ e.port = htons(p);
+ do {
++ i++;
+ e.ip[1] = htonl(ip2);
+- ip2 = ip_set_range_to_cidr(ip2, ip2_to,
+- &e.cidr[1]);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netportnet4_data_next(&h->next,
++ &e);
++ return -ERANGE;
++ }
++ ip2 = hash_netportnet4_range_to_cidr(ip2,
++ ip2_to, &e.cidr[1]);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 3fac57d66ddac..81bd13b3d8fd4 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -465,8 +465,9 @@ static int nft_delrule_by_chain(struct nft_ctx *ctx)
+ return 0;
+ }
+
+-static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+- struct nft_set *set)
++static int __nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
++ struct nft_set *set,
++ const struct nft_set_desc *desc)
+ {
+ struct nft_trans *trans;
+
+@@ -474,17 +475,28 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+ if (trans == NULL)
+ return -ENOMEM;
+
+- if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
++ if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] && !desc) {
+ nft_trans_set_id(trans) =
+ ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
+ nft_activate_next(ctx->net, set);
+ }
+ nft_trans_set(trans) = set;
++ if (desc) {
++ nft_trans_set_update(trans) = true;
++ nft_trans_set_gc_int(trans) = desc->gc_int;
++ nft_trans_set_timeout(trans) = desc->timeout;
++ }
+ nft_trans_commit_list_add_tail(ctx->net, trans);
+
+ return 0;
+ }
+
++static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
++ struct nft_set *set)
++{
++ return __nft_trans_set_add(ctx, msg_type, set, NULL);
++}
++
+ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
+ {
+ int err;
+@@ -3635,8 +3647,7 @@ static bool nft_set_ops_candidate(const struct nft_set_type *type, u32 flags)
+ static const struct nft_set_ops *
+ nft_select_set_ops(const struct nft_ctx *ctx,
+ const struct nlattr * const nla[],
+- const struct nft_set_desc *desc,
+- enum nft_set_policies policy)
++ const struct nft_set_desc *desc)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net);
+ const struct nft_set_ops *ops, *bops;
+@@ -3665,7 +3676,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
+ if (!ops->estimate(desc, flags, &est))
+ continue;
+
+- switch (policy) {
++ switch (desc->policy) {
+ case NFT_SET_POL_PERFORMANCE:
+ if (est.lookup < best.lookup)
+ break;
+@@ -3900,8 +3911,10 @@ static int nf_tables_fill_set_concat(struct sk_buff *skb,
+ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
+ const struct nft_set *set, u16 event, u16 flags)
+ {
+- struct nlmsghdr *nlh;
++ u64 timeout = READ_ONCE(set->timeout);
++ u32 gc_int = READ_ONCE(set->gc_int);
+ u32 portid = ctx->portid;
++ struct nlmsghdr *nlh;
+ struct nlattr *nest;
+ u32 seq = ctx->seq;
+ int i;
+@@ -3937,13 +3950,13 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
+ nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
+ goto nla_put_failure;
+
+- if (set->timeout &&
++ if (timeout &&
+ nla_put_be64(skb, NFTA_SET_TIMEOUT,
+- nf_jiffies64_to_msecs(set->timeout),
++ nf_jiffies64_to_msecs(timeout),
+ NFTA_SET_PAD))
+ goto nla_put_failure;
+- if (set->gc_int &&
+- nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
++ if (gc_int &&
++ nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(gc_int)))
+ goto nla_put_failure;
+
+ if (set->policy != NFT_SET_POL_PERFORMANCE) {
+@@ -4244,15 +4257,94 @@ static int nf_tables_set_desc_parse(struct nft_set_desc *desc,
+ return err;
+ }
+
++static int nft_set_expr_alloc(struct nft_ctx *ctx, struct nft_set *set,
++ const struct nlattr * const *nla,
++ struct nft_expr **exprs, int *num_exprs,
++ u32 flags)
++{
++ struct nft_expr *expr;
++ int err, i;
++
++ if (nla[NFTA_SET_EXPR]) {
++ expr = nft_set_elem_expr_alloc(ctx, set, nla[NFTA_SET_EXPR]);
++ if (IS_ERR(expr)) {
++ err = PTR_ERR(expr);
++ goto err_set_expr_alloc;
++ }
++ exprs[0] = expr;
++ (*num_exprs)++;
++ } else if (nla[NFTA_SET_EXPRESSIONS]) {
++ struct nlattr *tmp;
++ int left;
++
++ if (!(flags & NFT_SET_EXPR)) {
++ err = -EINVAL;
++ goto err_set_expr_alloc;
++ }
++ i = 0;
++ nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
++ if (i == NFT_SET_EXPR_MAX) {
++ err = -E2BIG;
++ goto err_set_expr_alloc;
++ }
++ if (nla_type(tmp) != NFTA_LIST_ELEM) {
++ err = -EINVAL;
++ goto err_set_expr_alloc;
++ }
++ expr = nft_set_elem_expr_alloc(ctx, set, tmp);
++ if (IS_ERR(expr)) {
++ err = PTR_ERR(expr);
++ goto err_set_expr_alloc;
++ }
++ exprs[i++] = expr;
++ (*num_exprs)++;
++ }
++ }
++
++ return 0;
++
++err_set_expr_alloc:
++ for (i = 0; i < *num_exprs; i++)
++ nft_expr_destroy(ctx, exprs[i]);
++
++ return err;
++}
++
++static bool nft_set_is_same(const struct nft_set *set,
++ const struct nft_set_desc *desc,
++ struct nft_expr *exprs[], u32 num_exprs, u32 flags)
++{
++ int i;
++
++ if (set->ktype != desc->ktype ||
++ set->dtype != desc->dtype ||
++ set->flags != flags ||
++ set->klen != desc->klen ||
++ set->dlen != desc->dlen ||
++ set->field_count != desc->field_count ||
++ set->num_exprs != num_exprs)
++ return false;
++
++ for (i = 0; i < desc->field_count; i++) {
++ if (set->field_len[i] != desc->field_len[i])
++ return false;
++ }
++
++ for (i = 0; i < num_exprs; i++) {
++ if (set->exprs[i]->ops != exprs[i]->ops)
++ return false;
++ }
++
++ return true;
++}
++
+ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ const struct nlattr * const nla[])
+ {
+- u32 ktype, dtype, flags, policy, gc_int, objtype;
+ struct netlink_ext_ack *extack = info->extack;
+ u8 genmask = nft_genmask_next(info->net);
+ u8 family = info->nfmsg->nfgen_family;
+ const struct nft_set_ops *ops;
+- struct nft_expr *expr = NULL;
+ struct net *net = info->net;
+ struct nft_set_desc desc;
+ struct nft_table *table;
+@@ -4260,10 +4352,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ struct nft_set *set;
+ struct nft_ctx ctx;
+ size_t alloc_size;
+- u64 timeout;
++ int num_exprs = 0;
+ char *name;
+ int err, i;
+ u16 udlen;
++ u32 flags;
+ u64 size;
+
+ if (nla[NFTA_SET_TABLE] == NULL ||
+@@ -4274,10 +4367,10 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+
+ memset(&desc, 0, sizeof(desc));
+
+- ktype = NFT_DATA_VALUE;
++ desc.ktype = NFT_DATA_VALUE;
+ if (nla[NFTA_SET_KEY_TYPE] != NULL) {
+- ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
+- if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
++ desc.ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
++ if ((desc.ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
+ return -EINVAL;
+ }
+
+@@ -4302,17 +4395,17 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ return -EOPNOTSUPP;
+ }
+
+- dtype = 0;
++ desc.dtype = 0;
+ if (nla[NFTA_SET_DATA_TYPE] != NULL) {
+ if (!(flags & NFT_SET_MAP))
+ return -EINVAL;
+
+- dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
+- if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
+- dtype != NFT_DATA_VERDICT)
++ desc.dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
++ if ((desc.dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
++ desc.dtype != NFT_DATA_VERDICT)
+ return -EINVAL;
+
+- if (dtype != NFT_DATA_VERDICT) {
++ if (desc.dtype != NFT_DATA_VERDICT) {
+ if (nla[NFTA_SET_DATA_LEN] == NULL)
+ return -EINVAL;
+ desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
+@@ -4327,34 +4420,34 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ if (!(flags & NFT_SET_OBJECT))
+ return -EINVAL;
+
+- objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
+- if (objtype == NFT_OBJECT_UNSPEC ||
+- objtype > NFT_OBJECT_MAX)
++ desc.objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
++ if (desc.objtype == NFT_OBJECT_UNSPEC ||
++ desc.objtype > NFT_OBJECT_MAX)
+ return -EOPNOTSUPP;
+ } else if (flags & NFT_SET_OBJECT)
+ return -EINVAL;
+ else
+- objtype = NFT_OBJECT_UNSPEC;
++ desc.objtype = NFT_OBJECT_UNSPEC;
+
+- timeout = 0;
++ desc.timeout = 0;
+ if (nla[NFTA_SET_TIMEOUT] != NULL) {
+ if (!(flags & NFT_SET_TIMEOUT))
+ return -EINVAL;
+
+- err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &timeout);
++ err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &desc.timeout);
+ if (err)
+ return err;
+ }
+- gc_int = 0;
++ desc.gc_int = 0;
+ if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
+ if (!(flags & NFT_SET_TIMEOUT))
+ return -EINVAL;
+- gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
++ desc.gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
+ }
+
+- policy = NFT_SET_POL_PERFORMANCE;
++ desc.policy = NFT_SET_POL_PERFORMANCE;
+ if (nla[NFTA_SET_POLICY] != NULL)
+- policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
++ desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
+
+ if (nla[NFTA_SET_DESC] != NULL) {
+ err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
+@@ -4386,6 +4479,8 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ return PTR_ERR(set);
+ }
+ } else {
++ struct nft_expr *exprs[NFT_SET_EXPR_MAX] = {};
++
+ if (info->nlh->nlmsg_flags & NLM_F_EXCL) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
+ return -EEXIST;
+@@ -4393,13 +4488,29 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ if (info->nlh->nlmsg_flags & NLM_F_REPLACE)
+ return -EOPNOTSUPP;
+
+- return 0;
++ err = nft_set_expr_alloc(&ctx, set, nla, exprs, &num_exprs, flags);
++ if (err < 0)
++ return err;
++
++ err = 0;
++ if (!nft_set_is_same(set, &desc, exprs, num_exprs, flags)) {
++ NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
++ err = -EEXIST;
++ }
++
++ for (i = 0; i < num_exprs; i++)
++ nft_expr_destroy(&ctx, exprs[i]);
++
++ if (err < 0)
++ return err;
++
++ return __nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set, &desc);
+ }
+
+ if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
+ return -ENOENT;
+
+- ops = nft_select_set_ops(&ctx, nla, &desc, policy);
++ ops = nft_select_set_ops(&ctx, nla, &desc);
+ if (IS_ERR(ops))
+ return PTR_ERR(ops);
+
+@@ -4439,18 +4550,18 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ set->table = table;
+ write_pnet(&set->net, net);
+ set->ops = ops;
+- set->ktype = ktype;
++ set->ktype = desc.ktype;
+ set->klen = desc.klen;
+- set->dtype = dtype;
+- set->objtype = objtype;
++ set->dtype = desc.dtype;
++ set->objtype = desc.objtype;
+ set->dlen = desc.dlen;
+ set->flags = flags;
+ set->size = desc.size;
+- set->policy = policy;
++ set->policy = desc.policy;
+ set->udlen = udlen;
+ set->udata = udata;
+- set->timeout = timeout;
+- set->gc_int = gc_int;
++ set->timeout = desc.timeout;
++ set->gc_int = desc.gc_int;
+
+ set->field_count = desc.field_count;
+ for (i = 0; i < desc.field_count; i++)
+@@ -4460,43 +4571,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ if (err < 0)
+ goto err_set_init;
+
+- if (nla[NFTA_SET_EXPR]) {
+- expr = nft_set_elem_expr_alloc(&ctx, set, nla[NFTA_SET_EXPR]);
+- if (IS_ERR(expr)) {
+- err = PTR_ERR(expr);
+- goto err_set_expr_alloc;
+- }
+- set->exprs[0] = expr;
+- set->num_exprs++;
+- } else if (nla[NFTA_SET_EXPRESSIONS]) {
+- struct nft_expr *expr;
+- struct nlattr *tmp;
+- int left;
+-
+- if (!(flags & NFT_SET_EXPR)) {
+- err = -EINVAL;
+- goto err_set_expr_alloc;
+- }
+- i = 0;
+- nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
+- if (i == NFT_SET_EXPR_MAX) {
+- err = -E2BIG;
+- goto err_set_expr_alloc;
+- }
+- if (nla_type(tmp) != NFTA_LIST_ELEM) {
+- err = -EINVAL;
+- goto err_set_expr_alloc;
+- }
+- expr = nft_set_elem_expr_alloc(&ctx, set, tmp);
+- if (IS_ERR(expr)) {
+- err = PTR_ERR(expr);
+- goto err_set_expr_alloc;
+- }
+- set->exprs[i++] = expr;
+- set->num_exprs++;
+- }
+- }
++ err = nft_set_expr_alloc(&ctx, set, nla, set->exprs, &num_exprs, flags);
++ if (err < 0)
++ goto err_set_destroy;
+
++ set->num_exprs = num_exprs;
+ set->handle = nf_tables_alloc_handle(table);
+
+ err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
+@@ -4510,7 +4589,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ err_set_expr_alloc:
+ for (i = 0; i < set->num_exprs; i++)
+ nft_expr_destroy(&ctx, set->exprs[i]);
+-
++err_set_destroy:
+ ops->destroy(set);
+ err_set_init:
+ kfree(set->name);
+@@ -5815,7 +5894,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ return err;
+ } else if (set->flags & NFT_SET_TIMEOUT &&
+ !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+- timeout = set->timeout;
++ timeout = READ_ONCE(set->timeout);
+ }
+
+ expiration = 0;
+@@ -5916,7 +5995,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ if (err < 0)
+ goto err_parse_key_end;
+
+- if (timeout != set->timeout) {
++ if (timeout != READ_ONCE(set->timeout)) {
+ err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
+ if (err < 0)
+ goto err_parse_key_end;
+@@ -8771,14 +8850,20 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+ break;
+ case NFT_MSG_NEWSET:
+- nft_clear(net, nft_trans_set(trans));
+- /* This avoids hitting -EBUSY when deleting the table
+- * from the transaction.
+- */
+- if (nft_set_is_anonymous(nft_trans_set(trans)) &&
+- !list_empty(&nft_trans_set(trans)->bindings))
+- trans->ctx.table->use--;
++ if (nft_trans_set_update(trans)) {
++ struct nft_set *set = nft_trans_set(trans);
+
++ WRITE_ONCE(set->timeout, nft_trans_set_timeout(trans));
++ WRITE_ONCE(set->gc_int, nft_trans_set_gc_int(trans));
++ } else {
++ nft_clear(net, nft_trans_set(trans));
++ /* This avoids hitting -EBUSY when deleting the table
++ * from the transaction.
++ */
++ if (nft_set_is_anonymous(nft_trans_set(trans)) &&
++ !list_empty(&nft_trans_set(trans)->bindings))
++ trans->ctx.table->use--;
++ }
+ nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
+ NFT_MSG_NEWSET, GFP_KERNEL);
+ nft_trans_destroy(trans);
+@@ -9000,6 +9085,10 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
+ nft_trans_destroy(trans);
+ break;
+ case NFT_MSG_NEWSET:
++ if (nft_trans_set_update(trans)) {
++ nft_trans_destroy(trans);
++ break;
++ }
+ trans->ctx.table->use--;
+ if (nft_trans_set_bound(trans)) {
+ nft_trans_destroy(trans);
+diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
+index a207f0b8137b0..d928d5a24bbc1 100644
+--- a/net/nfc/netlink.c
++++ b/net/nfc/netlink.c
+@@ -1497,6 +1497,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
+ u32 dev_idx, se_idx;
+ u8 *apdu;
+ size_t apdu_len;
++ int rc;
+
+ if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
+ !info->attrs[NFC_ATTR_SE_INDEX] ||
+@@ -1510,25 +1511,37 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
+ if (!dev)
+ return -ENODEV;
+
+- if (!dev->ops || !dev->ops->se_io)
+- return -ENOTSUPP;
++ if (!dev->ops || !dev->ops->se_io) {
++ rc = -EOPNOTSUPP;
++ goto put_dev;
++ }
+
+ apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
+- if (apdu_len == 0)
+- return -EINVAL;
++ if (apdu_len == 0) {
++ rc = -EINVAL;
++ goto put_dev;
++ }
+
+ apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
+- if (!apdu)
+- return -EINVAL;
++ if (!apdu) {
++ rc = -EINVAL;
++ goto put_dev;
++ }
+
+ ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
+- if (!ctx)
+- return -ENOMEM;
++ if (!ctx) {
++ rc = -ENOMEM;
++ goto put_dev;
++ }
+
+ ctx->dev_idx = dev_idx;
+ ctx->se_idx = se_idx;
+
+- return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
++ rc = nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
++
++put_dev:
++ nfc_put_device(dev);
++ return rc;
+ }
+
+ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+@@ -1551,14 +1564,21 @@ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+ subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
+
+ dev = nfc_get_device(dev_idx);
+- if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
++ if (!dev)
+ return -ENODEV;
+
++ if (!dev->vendor_cmds || !dev->n_vendor_cmds) {
++ err = -ENODEV;
++ goto put_dev;
++ }
++
+ if (info->attrs[NFC_ATTR_VENDOR_DATA]) {
+ data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
+ data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
+- if (data_len == 0)
+- return -EINVAL;
++ if (data_len == 0) {
++ err = -EINVAL;
++ goto put_dev;
++ }
+ } else {
+ data = NULL;
+ data_len = 0;
+@@ -1573,10 +1593,14 @@ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+ dev->cur_cmd_info = info;
+ err = cmd->doit(dev, data, data_len);
+ dev->cur_cmd_info = NULL;
+- return err;
++ goto put_dev;
+ }
+
+- return -EOPNOTSUPP;
++ err = -EOPNOTSUPP;
++
++put_dev:
++ nfc_put_device(dev);
++ return err;
+ }
+
+ /* message building helper */
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index ceca0d6c41b5b..7f9f2d0ef0e62 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1888,12 +1888,22 @@ oom:
+
+ static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
+ {
++ int depth;
++
+ if ((!skb->protocol || skb->protocol == htons(ETH_P_ALL)) &&
+ sock->type == SOCK_RAW) {
+ skb_reset_mac_header(skb);
+ skb->protocol = dev_parse_header_protocol(skb);
+ }
+
++ /* Move network header to the right position for VLAN tagged packets */
++ if (likely(skb->dev->type == ARPHRD_ETHER) &&
++ eth_type_vlan(skb->protocol) &&
++ __vlan_get_protocol(skb, skb->protocol, &depth) != 0) {
++ if (pskb_may_pull(skb, depth))
++ skb_set_network_header(skb, depth);
++ }
++
+ skb_probe_transport_header(skb);
+ }
+
+@@ -3008,6 +3018,11 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
+ skb->mark = sockc.mark;
+ skb->tstamp = sockc.transmit_time;
+
++ if (unlikely(extra_len == 4))
++ skb->no_fcs = 1;
++
++ packet_parse_headers(skb, sock);
++
+ if (has_vnet_hdr) {
+ err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
+ if (err)
+@@ -3016,11 +3031,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
+ virtio_net_hdr_set_proto(skb, &vnet_hdr);
+ }
+
+- packet_parse_headers(skb, sock);
+-
+- if (unlikely(extra_len == 4))
+- skb->no_fcs = 1;
+-
+ err = po->xmit(skb);
+ if (unlikely(err != 0)) {
+ if (err > 0)
+diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
+index 742c7d49a9581..8d1ef858db87d 100644
+--- a/net/sched/cls_tcindex.c
++++ b/net/sched/cls_tcindex.c
+@@ -332,7 +332,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ struct tcindex_filter_result *r, struct nlattr **tb,
+ struct nlattr *est, u32 flags, struct netlink_ext_ack *extack)
+ {
+- struct tcindex_filter_result new_filter_result, *old_r = r;
++ struct tcindex_filter_result new_filter_result;
+ struct tcindex_data *cp = NULL, *oldp;
+ struct tcindex_filter *f = NULL; /* make gcc behave */
+ struct tcf_result cr = {};
+@@ -401,7 +401,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ err = tcindex_filter_result_init(&new_filter_result, cp, net);
+ if (err < 0)
+ goto errout_alloc;
+- if (old_r)
++ if (r)
+ cr = r->res;
+
+ err = -EBUSY;
+@@ -478,14 +478,6 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ tcf_bind_filter(tp, &cr, base);
+ }
+
+- if (old_r && old_r != r) {
+- err = tcindex_filter_result_init(old_r, cp, net);
+- if (err < 0) {
+- kfree(f);
+- goto errout_alloc;
+- }
+- }
+-
+ oldp = p;
+ r->res = cr;
+ tcf_exts_change(&r->exts, &e);
+diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
+index 70fe1c5e44ad8..33737169cc2d3 100644
+--- a/net/sched/sch_atm.c
++++ b/net/sched/sch_atm.c
+@@ -397,10 +397,13 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ result = tcf_classify(skb, NULL, fl, &res, true);
+ if (result < 0)
+ continue;
++ if (result == TC_ACT_SHOT)
++ goto done;
++
+ flow = (struct atm_flow_data *)res.class;
+ if (!flow)
+ flow = lookup_flow(sch, res.classid);
+- goto done;
++ goto drop;
+ }
+ }
+ flow = NULL;
+diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
+index fd7e10567371c..46b3dd71777d1 100644
+--- a/net/sched/sch_cbq.c
++++ b/net/sched/sch_cbq.c
+@@ -231,6 +231,8 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ result = tcf_classify(skb, NULL, fl, &res, true);
+ if (!fl || result < 0)
+ goto fallback;
++ if (result == TC_ACT_SHOT)
++ return NULL;
+
+ cl = (void *)res.class;
+ if (!cl) {
+@@ -251,8 +253,6 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ case TC_ACT_TRAP:
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
+ fallthrough;
+- case TC_ACT_SHOT:
+- return NULL;
+ case TC_ACT_RECLASSIFY:
+ return cbq_reclassify(skb, cl);
+ }
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 5f42aa5fc6128..2ff66a6a7e54c 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -301,7 +301,7 @@ __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid, const struct gss_auth *auth
+ list_for_each_entry(pos, &pipe->in_downcall, list) {
+ if (!uid_eq(pos->uid, uid))
+ continue;
+- if (auth && pos->auth->service != auth->service)
++ if (pos->auth->service != auth->service)
+ continue;
+ refcount_inc(&pos->count);
+ return pos;
+@@ -685,6 +685,21 @@ out:
+ return err;
+ }
+
++static struct gss_upcall_msg *
++gss_find_downcall(struct rpc_pipe *pipe, kuid_t uid)
++{
++ struct gss_upcall_msg *pos;
++ list_for_each_entry(pos, &pipe->in_downcall, list) {
++ if (!uid_eq(pos->uid, uid))
++ continue;
++ if (!rpc_msg_is_inflight(&pos->msg))
++ continue;
++ refcount_inc(&pos->count);
++ return pos;
++ }
++ return NULL;
++}
++
+ #define MSG_BUF_MAXSIZE 1024
+
+ static ssize_t
+@@ -731,7 +746,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ err = -ENOENT;
+ /* Find a matching upcall */
+ spin_lock(&pipe->lock);
+- gss_msg = __gss_find_upcall(pipe, uid, NULL);
++ gss_msg = gss_find_downcall(pipe, uid);
+ if (gss_msg == NULL) {
+ spin_unlock(&pipe->lock);
+ goto err_put_ctx;
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 1f2817195549b..48b608cb5f5ec 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -1162,18 +1162,23 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp,
+ return res;
+
+ inlen = svc_getnl(argv);
+- if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
++ if (inlen > (argv->iov_len + rqstp->rq_arg.page_len)) {
++ kfree(in_handle->data);
+ return SVC_DENIED;
++ }
+
+ pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
+ in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
+- if (!in_token->pages)
++ if (!in_token->pages) {
++ kfree(in_handle->data);
+ return SVC_DENIED;
++ }
+ in_token->page_base = 0;
+ in_token->page_len = inlen;
+ for (i = 0; i < pages; i++) {
+ in_token->pages[i] = alloc_page(GFP_KERNEL);
+ if (!in_token->pages[i]) {
++ kfree(in_handle->data);
+ gss_free_in_token_pages(in_token);
+ return SVC_DENIED;
+ }
+diff --git a/security/device_cgroup.c b/security/device_cgroup.c
+index 04375df52fc9a..fe5cb7696993d 100644
+--- a/security/device_cgroup.c
++++ b/security/device_cgroup.c
+@@ -81,6 +81,17 @@ free_and_exit:
+ return -ENOMEM;
+ }
+
++static void dev_exceptions_move(struct list_head *dest, struct list_head *orig)
++{
++ struct dev_exception_item *ex, *tmp;
++
++ lockdep_assert_held(&devcgroup_mutex);
++
++ list_for_each_entry_safe(ex, tmp, orig, list) {
++ list_move_tail(&ex->list, dest);
++ }
++}
++
+ /*
+ * called under devcgroup_mutex
+ */
+@@ -603,11 +614,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
+ int count, rc = 0;
+ struct dev_exception_item ex;
+ struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent);
++ struct dev_cgroup tmp_devcgrp;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ memset(&ex, 0, sizeof(ex));
++ memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp));
+ b = buffer;
+
+ switch (*b) {
+@@ -619,15 +632,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
+
+ if (!may_allow_all(parent))
+ return -EPERM;
+- dev_exception_clean(devcgroup);
+- devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+- if (!parent)
++ if (!parent) {
++ devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
++ dev_exception_clean(devcgroup);
+ break;
++ }
+
++ INIT_LIST_HEAD(&tmp_devcgrp.exceptions);
++ rc = dev_exceptions_copy(&tmp_devcgrp.exceptions,
++ &devcgroup->exceptions);
++ if (rc)
++ return rc;
++ dev_exception_clean(devcgroup);
+ rc = dev_exceptions_copy(&devcgroup->exceptions,
+ &parent->exceptions);
+- if (rc)
++ if (rc) {
++ dev_exceptions_move(&devcgroup->exceptions,
++ &tmp_devcgrp.exceptions);
+ return rc;
++ }
++ devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
++ dev_exception_clean(&tmp_devcgrp);
+ break;
+ case DEVCG_DENY:
+ if (css_has_online_children(&devcgroup->css))
+diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
+index f84a0598e4f6a..31a8388e3dfae 100644
+--- a/security/integrity/ima/ima_template.c
++++ b/security/integrity/ima/ima_template.c
+@@ -336,8 +336,11 @@ static struct ima_template_desc *restore_template_fmt(char *template_name)
+
+ template_desc->name = "";
+ template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
+- if (!template_desc->fmt)
++ if (!template_desc->fmt) {
++ kfree(template_desc);
++ template_desc = NULL;
+ goto out;
++ }
+
+ spin_lock(&template_list);
+ list_add_tail_rcu(&template_desc->list, &defined_templates);
+diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
+index 185c609c6e380..d2f2c3936277a 100644
+--- a/security/integrity/platform_certs/load_uefi.c
++++ b/security/integrity/platform_certs/load_uefi.c
+@@ -34,6 +34,7 @@ static const struct dmi_system_id uefi_skip_cert[] = {
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
++ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") },
+ { }
+ };
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 79c65da1b4ee9..642e212278aca 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6709,6 +6709,34 @@ static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
+ }
+ }
+
++static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ static const struct hda_pintbl pincfgs[] = {
++ { 0x14, 0x90170151 },
++ { 0x17, 0x90170150 },
++ { }
++ };
++ static const hda_nid_t conn[] = { 0x02, 0x03 };
++ static const hda_nid_t preferred_pairs[] = {
++ 0x14, 0x02,
++ 0x17, 0x03,
++ 0x21, 0x02,
++ 0
++ };
++ struct alc_spec *spec = codec->spec;
++
++ alc_fixup_no_shutup(codec, fix, action);
++
++ switch (action) {
++ case HDA_FIXUP_ACT_PRE_PROBE:
++ snd_hda_apply_pincfgs(codec, pincfgs);
++ snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
++ spec->gen.preferred_dacs = preferred_pairs;
++ break;
++ }
++}
++
+ enum {
+ ALC269_FIXUP_GPIO2,
+ ALC269_FIXUP_SONY_VAIO,
+@@ -6940,6 +6968,8 @@ enum {
+ ALC285_FIXUP_LEGION_Y9000X_SPEAKERS,
+ ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
+ ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
++ ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
++ ALC236_FIXUP_DELL_DUAL_CODECS,
+ };
+
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -8766,6 +8796,18 @@ static const struct hda_fixup alc269_fixups[] = {
+ .chained = true,
+ .chain_id = ALC285_FIXUP_HP_MUTE_LED,
+ },
++ [ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc295_fixup_dell_inspiron_top_speakers,
++ .chained = true,
++ .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
++ },
++ [ALC236_FIXUP_DELL_DUAL_CODECS] = {
++ .type = HDA_FIXUP_PINS,
++ .v.func = alc1220_fixup_gb_dual_codecs,
++ .chained = true,
++ .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++ },
+ };
+
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -8865,6 +8907,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
+ SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
++ SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
++ SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
++ SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
+ SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
+index 390dd6c7f6a50..de5955db0a5f0 100644
+--- a/sound/soc/codecs/hdac_hda.c
++++ b/sound/soc/codecs/hdac_hda.c
+@@ -46,9 +46,8 @@ static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+ static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+-static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai,
+- unsigned int tx_mask, unsigned int rx_mask,
+- int slots, int slot_width);
++static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai, void *stream,
++ int direction);
+ static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,
+ struct snd_soc_dai *dai);
+
+@@ -58,7 +57,7 @@ static const struct snd_soc_dai_ops hdac_hda_dai_ops = {
+ .prepare = hdac_hda_dai_prepare,
+ .hw_params = hdac_hda_dai_hw_params,
+ .hw_free = hdac_hda_dai_hw_free,
+- .set_tdm_slot = hdac_hda_dai_set_tdm_slot,
++ .set_stream = hdac_hda_dai_set_stream,
+ };
+
+ static struct snd_soc_dai_driver hdac_hda_dais[] = {
+@@ -180,21 +179,22 @@ static struct snd_soc_dai_driver hdac_hda_dais[] = {
+
+ };
+
+-static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai,
+- unsigned int tx_mask, unsigned int rx_mask,
+- int slots, int slot_width)
++static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai,
++ void *stream, int direction)
+ {
+ struct snd_soc_component *component = dai->component;
+ struct hdac_hda_priv *hda_pvt;
+ struct hdac_hda_pcm *pcm;
++ struct hdac_stream *hstream;
++
++ if (!stream)
++ return -EINVAL;
+
+ hda_pvt = snd_soc_component_get_drvdata(component);
+ pcm = &hda_pvt->pcm[dai->id];
++ hstream = (struct hdac_stream *)stream;
+
+- if (tx_mask)
+- pcm->stream_tag[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
+- else
+- pcm->stream_tag[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
++ pcm->stream_tag[direction] = hstream->stream_tag;
+
+ return 0;
+ }
+diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c
+index 12323d4b5bfaa..97b64477dde67 100644
+--- a/sound/soc/codecs/max98373-sdw.c
++++ b/sound/soc/codecs/max98373-sdw.c
+@@ -741,7 +741,7 @@ static int max98373_sdw_set_tdm_slot(struct snd_soc_dai *dai,
+ static const struct snd_soc_dai_ops max98373_dai_sdw_ops = {
+ .hw_params = max98373_sdw_dai_hw_params,
+ .hw_free = max98373_pcm_hw_free,
+- .set_sdw_stream = max98373_set_sdw_stream,
++ .set_stream = max98373_set_sdw_stream,
+ .shutdown = max98373_shutdown,
+ .set_tdm_slot = max98373_sdw_set_tdm_slot,
+ };
+diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c
+index 8472d855c325e..03adf3324b81d 100644
+--- a/sound/soc/codecs/rt1308-sdw.c
++++ b/sound/soc/codecs/rt1308-sdw.c
+@@ -613,7 +613,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1308 = {
+ static const struct snd_soc_dai_ops rt1308_aif_dai_ops = {
+ .hw_params = rt1308_sdw_hw_params,
+ .hw_free = rt1308_sdw_pcm_hw_free,
+- .set_sdw_stream = rt1308_set_sdw_stream,
++ .set_stream = rt1308_set_sdw_stream,
+ .shutdown = rt1308_sdw_shutdown,
+ .set_tdm_slot = rt1308_sdw_set_tdm_slot,
+ };
+diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c
+index 09cf3ca86fa4a..1e04aa8ab1666 100644
+--- a/sound/soc/codecs/rt1316-sdw.c
++++ b/sound/soc/codecs/rt1316-sdw.c
+@@ -602,7 +602,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1316 = {
+ static const struct snd_soc_dai_ops rt1316_aif_dai_ops = {
+ .hw_params = rt1316_sdw_hw_params,
+ .hw_free = rt1316_sdw_pcm_hw_free,
+- .set_sdw_stream = rt1316_set_sdw_stream,
++ .set_stream = rt1316_set_sdw_stream,
+ .shutdown = rt1316_sdw_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
+index a030c9987b920..f04e18c32489d 100644
+--- a/sound/soc/codecs/rt5682-sdw.c
++++ b/sound/soc/codecs/rt5682-sdw.c
+@@ -272,7 +272,7 @@ static int rt5682_sdw_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops rt5682_sdw_ops = {
+ .hw_params = rt5682_sdw_hw_params,
+ .hw_free = rt5682_sdw_hw_free,
+- .set_sdw_stream = rt5682_set_sdw_stream,
++ .set_stream = rt5682_set_sdw_stream,
+ .shutdown = rt5682_sdw_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c
+index e049d672ccfd0..3de3406d653e4 100644
+--- a/sound/soc/codecs/rt700.c
++++ b/sound/soc/codecs/rt700.c
+@@ -1015,7 +1015,7 @@ static int rt700_pcm_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops rt700_ops = {
+ .hw_params = rt700_pcm_hw_params,
+ .hw_free = rt700_pcm_hw_free,
+- .set_sdw_stream = rt700_set_sdw_stream,
++ .set_stream = rt700_set_sdw_stream,
+ .shutdown = rt700_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
+index 3b5df3ea2f602..5ad53bbc85284 100644
+--- a/sound/soc/codecs/rt711-sdca.c
++++ b/sound/soc/codecs/rt711-sdca.c
+@@ -1361,7 +1361,7 @@ static int rt711_sdca_pcm_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops rt711_sdca_ops = {
+ .hw_params = rt711_sdca_pcm_hw_params,
+ .hw_free = rt711_sdca_pcm_hw_free,
+- .set_sdw_stream = rt711_sdca_set_sdw_stream,
++ .set_stream = rt711_sdca_set_sdw_stream,
+ .shutdown = rt711_sdca_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c
+index 51a98e730fc8f..286d882636e00 100644
+--- a/sound/soc/codecs/rt711.c
++++ b/sound/soc/codecs/rt711.c
+@@ -1092,7 +1092,7 @@ static int rt711_pcm_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops rt711_ops = {
+ .hw_params = rt711_pcm_hw_params,
+ .hw_free = rt711_pcm_hw_free,
+- .set_sdw_stream = rt711_set_sdw_stream,
++ .set_stream = rt711_set_sdw_stream,
+ .shutdown = rt711_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c
+index 66e166568c508..bfa536bd71960 100644
+--- a/sound/soc/codecs/rt715-sdca.c
++++ b/sound/soc/codecs/rt715-sdca.c
+@@ -938,7 +938,7 @@ static int rt715_sdca_pcm_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops rt715_sdca_ops = {
+ .hw_params = rt715_sdca_pcm_hw_params,
+ .hw_free = rt715_sdca_pcm_hw_free,
+- .set_sdw_stream = rt715_sdca_set_sdw_stream,
++ .set_stream = rt715_sdca_set_sdw_stream,
+ .shutdown = rt715_sdca_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c
+index 1352869cc0867..a64d11a747513 100644
+--- a/sound/soc/codecs/rt715.c
++++ b/sound/soc/codecs/rt715.c
+@@ -909,7 +909,7 @@ static int rt715_pcm_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops rt715_ops = {
+ .hw_params = rt715_pcm_hw_params,
+ .hw_free = rt715_pcm_hw_free,
+- .set_sdw_stream = rt715_set_sdw_stream,
++ .set_stream = rt715_set_sdw_stream,
+ .shutdown = rt715_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/sdw-mockup.c b/sound/soc/codecs/sdw-mockup.c
+index 8ea13cfa9f8ed..7c612aaf31c75 100644
+--- a/sound/soc/codecs/sdw-mockup.c
++++ b/sound/soc/codecs/sdw-mockup.c
+@@ -138,7 +138,7 @@ static int sdw_mockup_pcm_hw_free(struct snd_pcm_substream *substream,
+ static const struct snd_soc_dai_ops sdw_mockup_ops = {
+ .hw_params = sdw_mockup_pcm_hw_params,
+ .hw_free = sdw_mockup_pcm_hw_free,
+- .set_sdw_stream = sdw_mockup_set_sdw_stream,
++ .set_stream = sdw_mockup_set_sdw_stream,
+ .shutdown = sdw_mockup_shutdown,
+ };
+
+diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
+index 8cdc45e669f2d..b95cbae586414 100644
+--- a/sound/soc/codecs/wcd938x.c
++++ b/sound/soc/codecs/wcd938x.c
+@@ -4302,7 +4302,7 @@ static int wcd938x_codec_set_sdw_stream(struct snd_soc_dai *dai,
+ static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = {
+ .hw_params = wcd938x_codec_hw_params,
+ .hw_free = wcd938x_codec_free,
+- .set_sdw_stream = wcd938x_codec_set_sdw_stream,
++ .set_stream = wcd938x_codec_set_sdw_stream,
+ };
+
+ static struct snd_soc_dai_driver wcd938x_dais[] = {
+diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
+index 564b78f3cdd0a..0222370ff95de 100644
+--- a/sound/soc/codecs/wsa881x.c
++++ b/sound/soc/codecs/wsa881x.c
+@@ -1026,7 +1026,7 @@ static const struct snd_soc_dai_ops wsa881x_dai_ops = {
+ .hw_params = wsa881x_hw_params,
+ .hw_free = wsa881x_hw_free,
+ .mute_stream = wsa881x_digital_mute,
+- .set_sdw_stream = wsa881x_set_sdw_stream,
++ .set_stream = wsa881x_set_sdw_stream,
+ };
+
+ static struct snd_soc_dai_driver wsa881x_dais[] = {
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index f9c82ebc552cf..888e04c577579 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -570,6 +570,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+ BYT_RT5640_SSP0_AIF1 |
+ BYT_RT5640_MCLK_EN),
+ },
++ {
++ /* Advantech MICA-071 */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
++ },
++ /* OVCD Th = 1500uA to reliable detect head-phones vs -set */
++ .driver_data = (void *)(BYT_RT5640_IN3_MAP |
++ BYT_RT5640_JD_SRC_JD2_IN4N |
++ BYT_RT5640_OVCD_TH_1500UA |
++ BYT_RT5640_OVCD_SF_0P75 |
++ BYT_RT5640_MONO_SPEAKER |
++ BYT_RT5640_DIFF_MIC |
++ BYT_RT5640_MCLK_EN),
++ },
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 294e76d590ad3..2d53a707aff9c 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -291,7 +291,7 @@ int sdw_prepare(struct snd_pcm_substream *substream)
+ /* Find stream from first CPU DAI */
+ dai = asoc_rtd_to_cpu(rtd, 0);
+
+- sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
++ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
+@@ -311,7 +311,7 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
+ /* Find stream from first CPU DAI */
+ dai = asoc_rtd_to_cpu(rtd, 0);
+
+- sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
++ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
+@@ -350,7 +350,7 @@ int sdw_hw_free(struct snd_pcm_substream *substream)
+ /* Find stream from first CPU DAI */
+ dai = asoc_rtd_to_cpu(rtd, 0);
+
+- sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
++ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
+diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
+index e4aa366d356eb..db41bd7170650 100644
+--- a/sound/soc/intel/skylake/skl-pcm.c
++++ b/sound/soc/intel/skylake/skl-pcm.c
+@@ -562,11 +562,8 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
+
+ stream_tag = hdac_stream(link_dev)->stream_tag;
+
+- /* set the stream tag in the codec dai dma params */
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- snd_soc_dai_set_tdm_slot(codec_dai, stream_tag, 0, 0, 0);
+- else
+- snd_soc_dai_set_tdm_slot(codec_dai, 0, stream_tag, 0, 0);
++ /* set the hdac_stream in the codec dai */
++ snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream);
+
+ p_params.s_fmt = snd_pcm_format_width(params_format(params));
+ p_params.ch = params_channels(params);
+diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
+index 7ad5d9a924d80..4e1fc4ba5150a 100644
+--- a/sound/soc/jz4740/jz4740-i2s.c
++++ b/sound/soc/jz4740/jz4740-i2s.c
+@@ -56,7 +56,8 @@
+ #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
+ #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
+ #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
+-#define JZ_AIC_CTRL_FLUSH BIT(8)
++#define JZ_AIC_CTRL_TFLUSH BIT(8)
++#define JZ_AIC_CTRL_RFLUSH BIT(7)
+ #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
+ #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
+ #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
+@@ -91,6 +92,8 @@ enum jz47xx_i2s_version {
+ struct i2s_soc_info {
+ enum jz47xx_i2s_version version;
+ struct snd_soc_dai_driver *dai;
++
++ bool shared_fifo_flush;
+ };
+
+ struct jz4740_i2s {
+@@ -119,19 +122,44 @@ static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
+ writel(value, i2s->base + reg);
+ }
+
++static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s,
++ unsigned int reg, uint32_t bits)
++{
++ uint32_t value = jz4740_i2s_read(i2s, reg);
++ value |= bits;
++ jz4740_i2s_write(i2s, reg, value);
++}
++
+ static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+- uint32_t conf, ctrl;
++ uint32_t conf;
+ int ret;
+
++ /*
++ * When we can flush FIFOs independently, only flush the FIFO
++ * that is starting up. We can do this when the DAI is active
++ * because it does not disturb other active substreams.
++ */
++ if (!i2s->soc_info->shared_fifo_flush) {
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
++ else
++ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH);
++ }
++
+ if (snd_soc_dai_active(dai))
+ return 0;
+
+- ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
+- ctrl |= JZ_AIC_CTRL_FLUSH;
+- jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
++ /*
++ * When there is a shared flush bit for both FIFOs, the TFLUSH
++ * bit flushes both FIFOs. Flushing while the DAI is active would
++ * cause FIFO underruns in other active substreams so we have to
++ * guard this behind the snd_soc_dai_active() check.
++ */
++ if (i2s->soc_info->shared_fifo_flush)
++ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
+
+ ret = clk_prepare_enable(i2s->clk_i2s);
+ if (ret)
+@@ -462,6 +490,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
+ static const struct i2s_soc_info jz4740_i2s_soc_info = {
+ .version = JZ_I2S_JZ4740,
+ .dai = &jz4740_i2s_dai,
++ .shared_fifo_flush = true,
+ };
+
+ static const struct i2s_soc_info jz4760_i2s_soc_info = {
+diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
+index 0adfc57089492..4da5ad609fcea 100644
+--- a/sound/soc/qcom/sdm845.c
++++ b/sound/soc/qcom/sdm845.c
+@@ -56,8 +56,8 @@ static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
+ int ret = 0, i;
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+- sruntime = snd_soc_dai_get_sdw_stream(codec_dai,
+- substream->stream);
++ sruntime = snd_soc_dai_get_stream(codec_dai,
++ substream->stream);
+ if (sruntime != ERR_PTR(-ENOTSUPP))
+ pdata->sruntime[cpu_dai->id] = sruntime;
+
+diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
+index e5190aa588c63..feb6589171ca7 100644
+--- a/sound/soc/qcom/sm8250.c
++++ b/sound/soc/qcom/sm8250.c
+@@ -70,8 +70,8 @@ static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
+ switch (cpu_dai->id) {
+ case WSA_CODEC_DMA_RX_0:
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+- sruntime = snd_soc_dai_get_sdw_stream(codec_dai,
+- substream->stream);
++ sruntime = snd_soc_dai_get_stream(codec_dai,
++ substream->stream);
+ if (sruntime != ERR_PTR(-ENOTSUPP))
+ pdata->sruntime[cpu_dai->id] = sruntime;
+ }
+diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
+index 6704dbcd101cd..5f355b8d57a09 100644
+--- a/sound/soc/sof/intel/hda-dai.c
++++ b/sound/soc/sof/intel/hda-dai.c
+@@ -236,11 +236,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
+ if (!link)
+ return -EINVAL;
+
+- /* set the stream tag in the codec dai dma params */
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- snd_soc_dai_set_tdm_slot(codec_dai, stream_tag, 0, 0, 0);
+- else
+- snd_soc_dai_set_tdm_slot(codec_dai, 0, stream_tag, 0, 0);
++ /* set the hdac_stream in the codec dai */
++ snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream);
+
+ p_params.s_fmt = snd_pcm_format_width(params_format(params));
+ p_params.ch = params_channels(params);
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
+index 59faa5a9a7141..b67617b68e509 100644
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -304,7 +304,8 @@ static void line6_data_received(struct urb *urb)
+ for (;;) {
+ done =
+ line6_midibuf_read(mb, line6->buffer_message,
+- LINE6_MIDI_MESSAGE_MAXLEN);
++ LINE6_MIDI_MESSAGE_MAXLEN,
++ LINE6_MIDIBUF_READ_RX);
+
+ if (done <= 0)
+ break;
+diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
+index ba0e2b7e8fe19..0838632c788e4 100644
+--- a/sound/usb/line6/midi.c
++++ b/sound/usb/line6/midi.c
+@@ -44,7 +44,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+ int req, done;
+
+ for (;;) {
+- req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
++ req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
++ LINE6_FALLBACK_MAXPACKETSIZE);
+ done = snd_rawmidi_transmit_peek(substream, chunk, req);
+
+ if (done == 0)
+@@ -56,7 +57,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+
+ for (;;) {
+ done = line6_midibuf_read(mb, chunk,
+- LINE6_FALLBACK_MAXPACKETSIZE);
++ LINE6_FALLBACK_MAXPACKETSIZE,
++ LINE6_MIDIBUF_READ_TX);
+
+ if (done == 0)
+ break;
+diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c
+index 6a70463f82c4e..e7f830f7526c9 100644
+--- a/sound/usb/line6/midibuf.c
++++ b/sound/usb/line6/midibuf.c
+@@ -9,6 +9,7 @@
+
+ #include "midibuf.h"
+
++
+ static int midibuf_message_length(unsigned char code)
+ {
+ int message_length;
+@@ -20,12 +21,7 @@ static int midibuf_message_length(unsigned char code)
+
+ message_length = length[(code >> 4) - 8];
+ } else {
+- /*
+- Note that according to the MIDI specification 0xf2 is
+- the "Song Position Pointer", but this is used by Line 6
+- to send sysex messages to the host.
+- */
+- static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
++ static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
+ 1, 1, 1, -1, 1, 1
+ };
+ message_length = length[code & 0x0f];
+@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
+ }
+
+ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+- int length)
++ int length, int read_type)
+ {
+ int bytes_used;
+ int length1, length2;
+@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+
+ length1 = this->size - this->pos_read;
+
+- /* check MIDI command length */
+ command = this->buf[this->pos_read];
++ /*
++ PODxt always has status byte lower nibble set to 0010,
++ when it means to send 0000, so we correct if here so
++ that control/program changes come on channel 1 and
++ sysex message status byte is correct
++ */
++ if (read_type == LINE6_MIDIBUF_READ_RX) {
++ if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
++ unsigned char fixed = command & 0xf0;
++ this->buf[this->pos_read] = fixed;
++ command = fixed;
++ }
++ }
+
++ /* check MIDI command length */
+ if (command & 0x80) {
+ midi_length = midibuf_message_length(command);
+ this->command_prev = command;
+diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h
+index 124a8f9f7e96c..542e8d836f87d 100644
+--- a/sound/usb/line6/midibuf.h
++++ b/sound/usb/line6/midibuf.h
+@@ -8,6 +8,9 @@
+ #ifndef MIDIBUF_H
+ #define MIDIBUF_H
+
++#define LINE6_MIDIBUF_READ_TX 0
++#define LINE6_MIDIBUF_READ_RX 1
++
+ struct midi_buffer {
+ unsigned char *buf;
+ int size;
+@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
+ extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
+ extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
+ extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
+- int length);
++ int length, int read_type);
+ extern void line6_midibuf_reset(struct midi_buffer *mb);
+ extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
+ int length);
+diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
+index 16e644330c4d6..54be5ac919bfb 100644
+--- a/sound/usb/line6/pod.c
++++ b/sound/usb/line6/pod.c
+@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
+ .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
+ };
+
++
+ static const char pod_version_header[] = {
+- 0xf2, 0x7e, 0x7f, 0x06, 0x02
++ 0xf0, 0x7e, 0x7f, 0x06, 0x02
+ };
+
+ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index edac5aaa28024..308c8806ad94e 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -197,7 +197,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
+ return false;
+
+ insn = find_insn(file, func->sec, func->offset);
+- if (!insn->func)
++ if (!insn || !insn->func)
+ return false;
+
+ func_for_each_insn(file, func, insn) {
+diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
+index e99b41f9be45a..cd978c240e0dd 100644
+--- a/tools/perf/util/cgroup.c
++++ b/tools/perf/util/cgroup.c
+@@ -224,6 +224,19 @@ static int add_cgroup_name(const char *fpath, const struct stat *sb __maybe_unus
+ return 0;
+ }
+
++static int check_and_add_cgroup_name(const char *fpath)
++{
++ struct cgroup_name *cn;
++
++ list_for_each_entry(cn, &cgroup_list, list) {
++ if (!strcmp(cn->name, fpath))
++ return 0;
++ }
++
++ /* pretend if it's added by ftw() */
++ return add_cgroup_name(fpath, NULL, FTW_D, NULL);
++}
++
+ static void release_cgroup_list(void)
+ {
+ struct cgroup_name *cn;
+@@ -242,7 +255,7 @@ static int list_cgroups(const char *str)
+ struct cgroup_name *cn;
+ char *s;
+
+- /* use given name as is - for testing purpose */
++ /* use given name as is when no regex is given */
+ for (;;) {
+ p = strchr(str, ',');
+ e = p ? p : eos;
+@@ -253,13 +266,13 @@ static int list_cgroups(const char *str)
+ s = strndup(str, e - str);
+ if (!s)
+ return -1;
+- /* pretend if it's added by ftw() */
+- ret = add_cgroup_name(s, NULL, FTW_D, NULL);
++
++ ret = check_and_add_cgroup_name(s);
+ free(s);
+- if (ret)
++ if (ret < 0)
+ return -1;
+ } else {
+- if (add_cgroup_name("", NULL, FTW_D, NULL) < 0)
++ if (check_and_add_cgroup_name("/") < 0)
+ return -1;
+ }
+
+diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
+index 15a4547d608ec..090a76be522bb 100644
+--- a/tools/perf/util/data.c
++++ b/tools/perf/util/data.c
+@@ -127,6 +127,7 @@ int perf_data__open_dir(struct perf_data *data)
+ file->size = st.st_size;
+ }
+
++ closedir(dir);
+ if (!files)
+ return -EINVAL;
+
+@@ -135,6 +136,7 @@ int perf_data__open_dir(struct perf_data *data)
+ return 0;
+
+ out_err:
++ closedir(dir);
+ close_dir(files, nr);
+ return ret;
+ }
+diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
+index 609ca16715018..623527edeac1e 100644
+--- a/tools/perf/util/dwarf-aux.c
++++ b/tools/perf/util/dwarf-aux.c
+@@ -308,26 +308,13 @@ static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
+ {
+ Dwarf_Attribute attr;
+
+- if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
++ if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL ||
+ dwarf_formudata(&attr, result) != 0)
+ return -ENOENT;
+
+ return 0;
+ }
+
+-/* Get attribute and translate it as a sdata */
+-static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
+- Dwarf_Sword *result)
+-{
+- Dwarf_Attribute attr;
+-
+- if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
+- dwarf_formsdata(&attr, result) != 0)
+- return -ENOENT;
+-
+- return 0;
+-}
+-
+ /**
+ * die_is_signed_type - Check whether a type DIE is signed or not
+ * @tp_die: a DIE of a type
+@@ -467,9 +454,9 @@ int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
+ /* Get the call file index number in CU DIE */
+ static int die_get_call_fileno(Dwarf_Die *in_die)
+ {
+- Dwarf_Sword idx;
++ Dwarf_Word idx;
+
+- if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
++ if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0)
+ return (int)idx;
+ else
+ return -ENOENT;
+@@ -478,9 +465,9 @@ static int die_get_call_fileno(Dwarf_Die *in_die)
+ /* Get the declared file index number in CU DIE */
+ static int die_get_decl_fileno(Dwarf_Die *pdie)
+ {
+- Dwarf_Sword idx;
++ Dwarf_Word idx;
+
+- if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
++ if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0)
+ return (int)idx;
+ else
+ return -ENOENT;
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 09d1578f9d66f..1737c59e4ff67 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1963,7 +1963,7 @@ sub run_scp_mod {
+
+ sub _get_grub_index {
+
+- my ($command, $target, $skip) = @_;
++ my ($command, $target, $skip, $submenu) = @_;
+
+ return if (defined($grub_number) && defined($last_grub_menu) &&
+ $last_grub_menu eq $grub_menu && defined($last_machine) &&
+@@ -1980,11 +1980,16 @@ sub _get_grub_index {
+
+ my $found = 0;
+
++ my $submenu_number = 0;
++
+ while (<IN>) {
+ if (/$target/) {
+ $grub_number++;
+ $found = 1;
+ last;
++ } elsif (defined($submenu) && /$submenu/) {
++ $submenu_number++;
++ $grub_number = -1;
+ } elsif (/$skip/) {
+ $grub_number++;
+ }
+@@ -1993,6 +1998,9 @@ sub _get_grub_index {
+
+ dodie "Could not find '$grub_menu' through $command on $machine"
+ if (!$found);
++ if ($submenu_number > 0) {
++ $grub_number = "$submenu_number>$grub_number";
++ }
+ doprint "$grub_number\n";
+ $last_grub_menu = $grub_menu;
+ $last_machine = $machine;
+@@ -2003,6 +2011,7 @@ sub get_grub_index {
+ my $command;
+ my $target;
+ my $skip;
++ my $submenu;
+ my $grub_menu_qt;
+
+ if ($reboot_type !~ /^grub/) {
+@@ -2017,8 +2026,9 @@ sub get_grub_index {
+ $skip = '^\s*title\s';
+ } elsif ($reboot_type eq "grub2") {
+ $command = "cat $grub_file";
+- $target = '^menuentry.*' . $grub_menu_qt;
+- $skip = '^menuentry\s|^submenu\s';
++ $target = '^\s*menuentry.*' . $grub_menu_qt;
++ $skip = '^\s*menuentry';
++ $submenu = '^\s*submenu\s';
+ } elsif ($reboot_type eq "grub2bls") {
+ $command = $grub_bls_get;
+ $target = '^title=.*' . $grub_menu_qt;
+@@ -2027,7 +2037,7 @@ sub get_grub_index {
+ return;
+ }
+
+- _get_grub_index($command, $target, $skip);
++ _get_grub_index($command, $target, $skip, $submenu);
+ }
+
+ sub wait_for_input {
+@@ -2090,7 +2100,7 @@ sub reboot_to {
+ if ($reboot_type eq "grub") {
+ run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+ } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
+- run_ssh "$grub_reboot $grub_number";
++ run_ssh "$grub_reboot \"'$grub_number'\"";
+ } elsif ($reboot_type eq "syslinux") {
+ run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
+ } elsif (defined $reboot_script) {
+@@ -3768,9 +3778,10 @@ sub test_this_config {
+ # .config to make sure it is missing the config that
+ # we had before
+ my %configs = %min_configs;
+- delete $configs{$config};
++ $configs{$config} = "# $config is not set";
+ make_new_config ((values %configs), (values %keep_configs));
+ make_oldconfig;
++ delete $configs{$config};
+ undef %configs;
+ assign_configs \%configs, $output_config;
+
+diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
+index 14206d1d1efeb..56a4873a343cf 100644
+--- a/tools/testing/selftests/Makefile
++++ b/tools/testing/selftests/Makefile
+@@ -114,19 +114,27 @@ ifdef building_out_of_srctree
+ override LDFLAGS =
+ endif
+
+-ifneq ($(O),)
+- BUILD := $(O)/kselftest
++top_srcdir ?= ../../..
++
++ifeq ("$(origin O)", "command line")
++ KBUILD_OUTPUT := $(O)
++endif
++
++ifneq ($(KBUILD_OUTPUT),)
++ # Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
++ # expand a shell special character '~'. We use a somewhat tedious way here.
++ abs_objtree := $(shell cd $(top_srcdir) && mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
++ $(if $(abs_objtree),, \
++ $(error failed to create output directory "$(KBUILD_OUTPUT)"))
++ # $(realpath ...) resolves symlinks
++ abs_objtree := $(realpath $(abs_objtree))
++ BUILD := $(abs_objtree)/kselftest
+ else
+- ifneq ($(KBUILD_OUTPUT),)
+- BUILD := $(KBUILD_OUTPUT)/kselftest
+- else
+- BUILD := $(shell pwd)
+- DEFAULT_INSTALL_HDR_PATH := 1
+- endif
++ BUILD := $(CURDIR)
++ DEFAULT_INSTALL_HDR_PATH := 1
+ endif
+
+ # Prepare for headers install
+-top_srcdir ?= ../../..
+ include $(top_srcdir)/scripts/subarch.include
+ ARCH ?= $(SUBARCH)
+ export KSFT_KHDR_INSTALL_DONE := 1
+diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config
+index 4a2a47fcd6efd..5192305159ec1 100644
+--- a/tools/testing/selftests/bpf/config
++++ b/tools/testing/selftests/bpf/config
+@@ -46,7 +46,3 @@ CONFIG_IMA_READ_POLICY=y
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_FUNCTION_TRACER=y
+ CONFIG_DYNAMIC_FTRACE=y
+-CONFIG_NETFILTER=y
+-CONFIG_NF_DEFRAG_IPV4=y
+-CONFIG_NF_DEFRAG_IPV6=y
+-CONFIG_NF_CONNTRACK=y
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
+deleted file mode 100644
+index e3166a81e9892..0000000000000
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
++++ /dev/null
+@@ -1,48 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include <test_progs.h>
+-#include <network_helpers.h>
+-#include "test_bpf_nf.skel.h"
+-
+-enum {
+- TEST_XDP,
+- TEST_TC_BPF,
+-};
+-
+-void test_bpf_nf_ct(int mode)
+-{
+- struct test_bpf_nf *skel;
+- int prog_fd, err, retval;
+-
+- skel = test_bpf_nf__open_and_load();
+- if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load"))
+- return;
+-
+- if (mode == TEST_XDP)
+- prog_fd = bpf_program__fd(skel->progs.nf_xdp_ct_test);
+- else
+- prog_fd = bpf_program__fd(skel->progs.nf_skb_ct_test);
+-
+- err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), NULL, NULL,
+- (__u32 *)&retval, NULL);
+- if (!ASSERT_OK(err, "bpf_prog_test_run"))
+- goto end;
+-
+- ASSERT_EQ(skel->bss->test_einval_bpf_tuple, -EINVAL, "Test EINVAL for NULL bpf_tuple");
+- ASSERT_EQ(skel->bss->test_einval_reserved, -EINVAL, "Test EINVAL for reserved not set to 0");
+- ASSERT_EQ(skel->bss->test_einval_netns_id, -EINVAL, "Test EINVAL for netns_id < -1");
+- ASSERT_EQ(skel->bss->test_einval_len_opts, -EINVAL, "Test EINVAL for len__opts != NF_BPF_CT_OPTS_SZ");
+- ASSERT_EQ(skel->bss->test_eproto_l4proto, -EPROTO, "Test EPROTO for l4proto != TCP or UDP");
+- ASSERT_EQ(skel->bss->test_enonet_netns_id, -ENONET, "Test ENONET for bad but valid netns_id");
+- ASSERT_EQ(skel->bss->test_enoent_lookup, -ENOENT, "Test ENOENT for failed lookup");
+- ASSERT_EQ(skel->bss->test_eafnosupport, -EAFNOSUPPORT, "Test EAFNOSUPPORT for invalid len__tuple");
+-end:
+- test_bpf_nf__destroy(skel);
+-}
+-
+-void test_bpf_nf(void)
+-{
+- if (test__start_subtest("xdp-ct"))
+- test_bpf_nf_ct(TEST_XDP);
+- if (test__start_subtest("tc-bpf-ct"))
+- test_bpf_nf_ct(TEST_TC_BPF);
+-}
+diff --git a/tools/testing/selftests/bpf/progs/test_bpf_nf.c b/tools/testing/selftests/bpf/progs/test_bpf_nf.c
+deleted file mode 100644
+index 6f131c993c0b9..0000000000000
+--- a/tools/testing/selftests/bpf/progs/test_bpf_nf.c
++++ /dev/null
+@@ -1,109 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include <vmlinux.h>
+-#include <bpf/bpf_helpers.h>
+-
+-#define EAFNOSUPPORT 97
+-#define EPROTO 71
+-#define ENONET 64
+-#define EINVAL 22
+-#define ENOENT 2
+-
+-int test_einval_bpf_tuple = 0;
+-int test_einval_reserved = 0;
+-int test_einval_netns_id = 0;
+-int test_einval_len_opts = 0;
+-int test_eproto_l4proto = 0;
+-int test_enonet_netns_id = 0;
+-int test_enoent_lookup = 0;
+-int test_eafnosupport = 0;
+-
+-struct nf_conn *bpf_xdp_ct_lookup(struct xdp_md *, struct bpf_sock_tuple *, u32,
+- struct bpf_ct_opts *, u32) __ksym;
+-struct nf_conn *bpf_skb_ct_lookup(struct __sk_buff *, struct bpf_sock_tuple *, u32,
+- struct bpf_ct_opts *, u32) __ksym;
+-void bpf_ct_release(struct nf_conn *) __ksym;
+-
+-static __always_inline void
+-nf_ct_test(struct nf_conn *(*func)(void *, struct bpf_sock_tuple *, u32,
+- struct bpf_ct_opts *, u32),
+- void *ctx)
+-{
+- struct bpf_ct_opts opts_def = { .l4proto = IPPROTO_TCP, .netns_id = -1 };
+- struct bpf_sock_tuple bpf_tuple;
+- struct nf_conn *ct;
+-
+- __builtin_memset(&bpf_tuple, 0, sizeof(bpf_tuple.ipv4));
+-
+- ct = func(ctx, NULL, 0, &opts_def, sizeof(opts_def));
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_einval_bpf_tuple = opts_def.error;
+-
+- opts_def.reserved[0] = 1;
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def, sizeof(opts_def));
+- opts_def.reserved[0] = 0;
+- opts_def.l4proto = IPPROTO_TCP;
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_einval_reserved = opts_def.error;
+-
+- opts_def.netns_id = -2;
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def, sizeof(opts_def));
+- opts_def.netns_id = -1;
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_einval_netns_id = opts_def.error;
+-
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def, sizeof(opts_def) - 1);
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_einval_len_opts = opts_def.error;
+-
+- opts_def.l4proto = IPPROTO_ICMP;
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def, sizeof(opts_def));
+- opts_def.l4proto = IPPROTO_TCP;
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_eproto_l4proto = opts_def.error;
+-
+- opts_def.netns_id = 0xf00f;
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def, sizeof(opts_def));
+- opts_def.netns_id = -1;
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_enonet_netns_id = opts_def.error;
+-
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def, sizeof(opts_def));
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_enoent_lookup = opts_def.error;
+-
+- ct = func(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4) - 1, &opts_def, sizeof(opts_def));
+- if (ct)
+- bpf_ct_release(ct);
+- else
+- test_eafnosupport = opts_def.error;
+-}
+-
+-SEC("xdp")
+-int nf_xdp_ct_test(struct xdp_md *ctx)
+-{
+- nf_ct_test((void *)bpf_xdp_ct_lookup, ctx);
+- return 0;
+-}
+-
+-SEC("tc")
+-int nf_skb_ct_test(struct __sk_buff *ctx)
+-{
+- nf_ct_test((void *)bpf_skb_ct_lookup, ctx);
+- return 0;
+-}
+-
+-char _license[] SEC("license") = "GPL";
+diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
+index fe7ee2b0f29c2..a3df78b7702c1 100644
+--- a/tools/testing/selftests/lib.mk
++++ b/tools/testing/selftests/lib.mk
+@@ -129,6 +129,11 @@ endef
+ clean:
+ $(CLEAN)
+
++# Enables to extend CFLAGS and LDFLAGS from command line, e.g.
++# make USERCFLAGS=-Werror USERLDFLAGS=-static
++CFLAGS += $(USERCFLAGS)
++LDFLAGS += $(USERLDFLAGS)
++
+ # When make O= with kselftest target from main level
+ # the following aren't defined.
+ #