mirror of https://github.com/armbian/build.git
				
				
				
			
		
			
				
	
	
		
			9068 lines
		
	
	
		
			304 KiB
		
	
	
	
		
			Diff
		
	
	
	
			
		
		
	
	
			9068 lines
		
	
	
		
			304 KiB
		
	
	
	
		
			Diff
		
	
	
	
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
 | 
						|
index 315a817e338042..f95734ceb82b86 100644
 | 
						|
--- a/Documentation/admin-guide/kernel-parameters.txt
 | 
						|
+++ b/Documentation/admin-guide/kernel-parameters.txt
 | 
						|
@@ -5978,8 +5978,6 @@
 | 
						|
 
 | 
						|
 			Selecting 'on' will also enable the mitigation
 | 
						|
 			against user space to user space task attacks.
 | 
						|
-			Selecting specific mitigation does not force enable
 | 
						|
-			user mitigations.
 | 
						|
 
 | 
						|
 			Selecting 'off' will disable both the kernel and
 | 
						|
 			the user space protections.
 | 
						|
diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml
 | 
						|
index 424a4fc218b66b..2cb311ddd912a9 100644
 | 
						|
--- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml
 | 
						|
+++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml
 | 
						|
@@ -103,7 +103,10 @@ properties:
 | 
						|
 
 | 
						|
   resets:
 | 
						|
     items:
 | 
						|
-      - description: module reset
 | 
						|
+      - description:
 | 
						|
+          Module reset. This property is optional for controllers in Tegra194,
 | 
						|
+          Tegra234 etc where an internal software reset is available as an
 | 
						|
+          alternative.
 | 
						|
 
 | 
						|
   reset-names:
 | 
						|
     items:
 | 
						|
@@ -119,6 +122,13 @@ properties:
 | 
						|
       - const: rx
 | 
						|
       - const: tx
 | 
						|
 
 | 
						|
+required:
 | 
						|
+  - compatible
 | 
						|
+  - reg
 | 
						|
+  - interrupts
 | 
						|
+  - clocks
 | 
						|
+  - clock-names
 | 
						|
+
 | 
						|
 allOf:
 | 
						|
   - $ref: /schemas/i2c/i2c-controller.yaml
 | 
						|
   - if:
 | 
						|
@@ -172,6 +182,18 @@ allOf:
 | 
						|
           items:
 | 
						|
             - description: phandle to the VENC power domain
 | 
						|
 
 | 
						|
+  - if:
 | 
						|
+      not:
 | 
						|
+        properties:
 | 
						|
+          compatible:
 | 
						|
+            contains:
 | 
						|
+              enum:
 | 
						|
+                - nvidia,tegra194-i2c
 | 
						|
+    then:
 | 
						|
+      required:
 | 
						|
+        - resets
 | 
						|
+        - reset-names
 | 
						|
+
 | 
						|
 unevaluatedProperties: false
 | 
						|
 
 | 
						|
 examples:
 | 
						|
diff --git a/Makefile b/Makefile
 | 
						|
index 9625d9072c7781..679dff5e165c07 100644
 | 
						|
--- a/Makefile
 | 
						|
+++ b/Makefile
 | 
						|
@@ -1,7 +1,7 @@
 | 
						|
 # SPDX-License-Identifier: GPL-2.0
 | 
						|
 VERSION = 6
 | 
						|
 PATCHLEVEL = 6
 | 
						|
-SUBLEVEL = 94
 | 
						|
+SUBLEVEL = 95
 | 
						|
 EXTRAVERSION =
 | 
						|
 NAME = Pinguïn Aangedreven
 | 
						|
 
 | 
						|
diff --git a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
 | 
						|
index 96451c8a815ccd..27e73e745e25f2 100644
 | 
						|
--- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
 | 
						|
+++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
 | 
						|
@@ -385,7 +385,7 @@ ethphy0: ethernet-phy@0 {
 | 
						|
 		/* Support GPIO reset on revision C3 boards */
 | 
						|
 		reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 | 
						|
 		reset-assert-us = <300>;
 | 
						|
-		reset-deassert-us = <6500>;
 | 
						|
+		reset-deassert-us = <50000>;
 | 
						|
 	};
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
 | 
						|
index c36fb27212615a..86a2f9e5d0ef9d 100644
 | 
						|
--- a/arch/arm/mach-omap2/clockdomain.h
 | 
						|
+++ b/arch/arm/mach-omap2/clockdomain.h
 | 
						|
@@ -48,6 +48,7 @@
 | 
						|
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 | 
						|
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
 | 
						|
 #define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 | 
						|
+#define CLKDM_STANDBY_FORCE_WAKEUP		BIT(7)
 | 
						|
 
 | 
						|
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 | 
						|
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
 | 
						|
diff --git a/arch/arm/mach-omap2/clockdomains33xx_data.c b/arch/arm/mach-omap2/clockdomains33xx_data.c
 | 
						|
index 87f4e927eb1830..c05a3c07d44863 100644
 | 
						|
--- a/arch/arm/mach-omap2/clockdomains33xx_data.c
 | 
						|
+++ b/arch/arm/mach-omap2/clockdomains33xx_data.c
 | 
						|
@@ -19,7 +19,7 @@ static struct clockdomain l4ls_am33xx_clkdm = {
 | 
						|
 	.pwrdm		= { .name = "per_pwrdm" },
 | 
						|
 	.cm_inst	= AM33XX_CM_PER_MOD,
 | 
						|
 	.clkdm_offs	= AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET,
 | 
						|
-	.flags		= CLKDM_CAN_SWSUP,
 | 
						|
+	.flags		= CLKDM_CAN_SWSUP | CLKDM_STANDBY_FORCE_WAKEUP,
 | 
						|
 };
 | 
						|
 
 | 
						|
 static struct clockdomain l3s_am33xx_clkdm = {
 | 
						|
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
 | 
						|
index c824d4e3db632c..aaee67d097915c 100644
 | 
						|
--- a/arch/arm/mach-omap2/cm33xx.c
 | 
						|
+++ b/arch/arm/mach-omap2/cm33xx.c
 | 
						|
@@ -20,6 +20,9 @@
 | 
						|
 #include "cm-regbits-34xx.h"
 | 
						|
 #include "cm-regbits-33xx.h"
 | 
						|
 #include "prm33xx.h"
 | 
						|
+#if IS_ENABLED(CONFIG_SUSPEND)
 | 
						|
+#include <linux/suspend.h>
 | 
						|
+#endif
 | 
						|
 
 | 
						|
 /*
 | 
						|
  * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield:
 | 
						|
@@ -328,8 +331,17 @@ static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
 | 
						|
 {
 | 
						|
 	bool hwsup = false;
 | 
						|
 
 | 
						|
+#if IS_ENABLED(CONFIG_SUSPEND)
 | 
						|
+	/*
 | 
						|
+	 * In case of standby, Don't put the l4ls clk domain to sleep.
 | 
						|
+	 * Since CM3 PM FW doesn't wake-up/enable the l4ls clk domain
 | 
						|
+	 * upon wake-up, CM3 PM FW fails to wake-up th MPU.
 | 
						|
+	 */
 | 
						|
+	if (pm_suspend_target_state == PM_SUSPEND_STANDBY &&
 | 
						|
+	    (clkdm->flags & CLKDM_STANDBY_FORCE_WAKEUP))
 | 
						|
+		return 0;
 | 
						|
+#endif
 | 
						|
 	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
 | 
						|
-
 | 
						|
 	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
 | 
						|
 		am33xx_clkdm_sleep(clkdm);
 | 
						|
 
 | 
						|
diff --git a/arch/arm/mach-omap2/pmic-cpcap.c b/arch/arm/mach-omap2/pmic-cpcap.c
 | 
						|
index 668dc84fd31e04..527cf4b7e37874 100644
 | 
						|
--- a/arch/arm/mach-omap2/pmic-cpcap.c
 | 
						|
+++ b/arch/arm/mach-omap2/pmic-cpcap.c
 | 
						|
@@ -264,7 +264,11 @@ int __init omap4_cpcap_init(void)
 | 
						|
 
 | 
						|
 static int __init cpcap_late_init(void)
 | 
						|
 {
 | 
						|
-	omap4_vc_set_pmic_signaling(PWRDM_POWER_RET);
 | 
						|
+	if (!of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
+	if (soc_is_omap443x() || soc_is_omap446x() || soc_is_omap447x())
 | 
						|
+		omap4_vc_set_pmic_signaling(PWRDM_POWER_RET);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
 | 
						|
index 1c5aeba9bc27f3..7801c5bb775d90 100644
 | 
						|
--- a/arch/arm/mm/ioremap.c
 | 
						|
+++ b/arch/arm/mm/ioremap.c
 | 
						|
@@ -515,7 +515,5 @@ void __init early_ioremap_init(void)
 | 
						|
 bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
 | 
						|
 				 unsigned long flags)
 | 
						|
 {
 | 
						|
-	unsigned long pfn = PHYS_PFN(offset);
 | 
						|
-
 | 
						|
-	return memblock_is_map_memory(pfn);
 | 
						|
+	return memblock_is_map_memory(offset);
 | 
						|
 }
 | 
						|
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
 | 
						|
index d37db2f7a54cf0..6eeb56b6fac13e 100644
 | 
						|
--- a/arch/arm64/include/asm/tlbflush.h
 | 
						|
+++ b/arch/arm64/include/asm/tlbflush.h
 | 
						|
@@ -311,13 +311,14 @@ static inline void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *b
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
- * If mprotect/munmap/etc occurs during TLB batched flushing, we need to
 | 
						|
- * synchronise all the TLBI issued with a DSB to avoid the race mentioned in
 | 
						|
- * flush_tlb_batched_pending().
 | 
						|
+ * If mprotect/munmap/etc occurs during TLB batched flushing, we need to ensure
 | 
						|
+ * all the previously issued TLBIs targeting mm have completed. But since we
 | 
						|
+ * can be executing on a remote CPU, a DSB cannot guarantee this like it can
 | 
						|
+ * for arch_tlbbatch_flush(). Our only option is to flush the entire mm.
 | 
						|
  */
 | 
						|
 static inline void arch_flush_tlb_batched_pending(struct mm_struct *mm)
 | 
						|
 {
 | 
						|
-	dsb(ish);
 | 
						|
+	flush_tlb_mm(mm);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
 | 
						|
index a26293e0cc555d..c30f5a70bd18f4 100644
 | 
						|
--- a/arch/arm64/kernel/ptrace.c
 | 
						|
+++ b/arch/arm64/kernel/ptrace.c
 | 
						|
@@ -139,7 +139,7 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
 | 
						|
 
 | 
						|
 	addr += n;
 | 
						|
 	if (regs_within_kernel_stack(regs, (unsigned long)addr))
 | 
						|
-		return *addr;
 | 
						|
+		return READ_ONCE_NOCHECK(*addr);
 | 
						|
 	else
 | 
						|
 		return 0;
 | 
						|
 }
 | 
						|
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
 | 
						|
index bc97916a035a64..c8e83fe1cd5a73 100644
 | 
						|
--- a/arch/arm64/mm/mmu.c
 | 
						|
+++ b/arch/arm64/mm/mmu.c
 | 
						|
@@ -1253,7 +1253,8 @@ int pud_free_pmd_page(pud_t *pudp, unsigned long addr)
 | 
						|
 	next = addr;
 | 
						|
 	end = addr + PUD_SIZE;
 | 
						|
 	do {
 | 
						|
-		pmd_free_pte_page(pmdp, next);
 | 
						|
+		if (pmd_present(pmdp_get(pmdp)))
 | 
						|
+			pmd_free_pte_page(pmdp, next);
 | 
						|
 	} while (pmdp++, next += PMD_SIZE, next != end);
 | 
						|
 
 | 
						|
 	pud_clear(pudp);
 | 
						|
diff --git a/arch/loongarch/include/asm/irqflags.h b/arch/loongarch/include/asm/irqflags.h
 | 
						|
index 319a8c616f1f5b..003172b8406be7 100644
 | 
						|
--- a/arch/loongarch/include/asm/irqflags.h
 | 
						|
+++ b/arch/loongarch/include/asm/irqflags.h
 | 
						|
@@ -14,40 +14,48 @@
 | 
						|
 static inline void arch_local_irq_enable(void)
 | 
						|
 {
 | 
						|
 	u32 flags = CSR_CRMD_IE;
 | 
						|
+	register u32 mask asm("t0") = CSR_CRMD_IE;
 | 
						|
+
 | 
						|
 	__asm__ __volatile__(
 | 
						|
 		"csrxchg %[val], %[mask], %[reg]\n\t"
 | 
						|
 		: [val] "+r" (flags)
 | 
						|
-		: [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
+		: [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
 		: "memory");
 | 
						|
 }
 | 
						|
 
 | 
						|
 static inline void arch_local_irq_disable(void)
 | 
						|
 {
 | 
						|
 	u32 flags = 0;
 | 
						|
+	register u32 mask asm("t0") = CSR_CRMD_IE;
 | 
						|
+
 | 
						|
 	__asm__ __volatile__(
 | 
						|
 		"csrxchg %[val], %[mask], %[reg]\n\t"
 | 
						|
 		: [val] "+r" (flags)
 | 
						|
-		: [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
+		: [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
 		: "memory");
 | 
						|
 }
 | 
						|
 
 | 
						|
 static inline unsigned long arch_local_irq_save(void)
 | 
						|
 {
 | 
						|
 	u32 flags = 0;
 | 
						|
+	register u32 mask asm("t0") = CSR_CRMD_IE;
 | 
						|
+
 | 
						|
 	__asm__ __volatile__(
 | 
						|
 		"csrxchg %[val], %[mask], %[reg]\n\t"
 | 
						|
 		: [val] "+r" (flags)
 | 
						|
-		: [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
+		: [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
 		: "memory");
 | 
						|
 	return flags;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static inline void arch_local_irq_restore(unsigned long flags)
 | 
						|
 {
 | 
						|
+	register u32 mask asm("t0") = CSR_CRMD_IE;
 | 
						|
+
 | 
						|
 	__asm__ __volatile__(
 | 
						|
 		"csrxchg %[val], %[mask], %[reg]\n\t"
 | 
						|
 		: [val] "+r" (flags)
 | 
						|
-		: [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
+		: [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD)
 | 
						|
 		: "memory");
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c
 | 
						|
index 41308429f44612..58277fd9fb2f0e 100644
 | 
						|
--- a/arch/loongarch/mm/hugetlbpage.c
 | 
						|
+++ b/arch/loongarch/mm/hugetlbpage.c
 | 
						|
@@ -47,7 +47,8 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
 | 
						|
 				pmd = pmd_offset(pud, addr);
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
-	return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd;
 | 
						|
+
 | 
						|
+	return (!pmd || pmd_none(pmdp_get(pmd))) ? NULL : (pte_t *) pmd;
 | 
						|
 }
 | 
						|
 
 | 
						|
 int pmd_huge(pmd_t pmd)
 | 
						|
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
 | 
						|
index eb56581f6d734f..0a3249647401d4 100644
 | 
						|
--- a/arch/mips/vdso/Makefile
 | 
						|
+++ b/arch/mips/vdso/Makefile
 | 
						|
@@ -30,6 +30,7 @@ endif
 | 
						|
 # offsets.
 | 
						|
 cflags-vdso := $(ccflags-vdso) \
 | 
						|
 	$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
 | 
						|
+	$(filter -std=%,$(KBUILD_CFLAGS)) \
 | 
						|
 	-O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
 | 
						|
 	-mrelax-pic-calls $(call cc-option, -mexplicit-relocs) \
 | 
						|
 	-fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
 | 
						|
diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile
 | 
						|
index a294a1b58ee7ed..9fba12b70d1b31 100644
 | 
						|
--- a/arch/parisc/boot/compressed/Makefile
 | 
						|
+++ b/arch/parisc/boot/compressed/Makefile
 | 
						|
@@ -22,6 +22,7 @@ KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os
 | 
						|
 ifndef CONFIG_64BIT
 | 
						|
 KBUILD_CFLAGS += -mfast-indirect-calls
 | 
						|
 endif
 | 
						|
+KBUILD_CFLAGS += -std=gnu11
 | 
						|
 
 | 
						|
 LDFLAGS_vmlinux := -X -e startup --as-needed -T
 | 
						|
 $(obj)/vmlinux: $(obj)/vmlinux.lds $(addprefix $(obj)/, $(OBJECTS)) $(LIBGCC) FORCE
 | 
						|
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
 | 
						|
index a8e75e5b884a70..e673c71e16d97a 100644
 | 
						|
--- a/arch/parisc/kernel/unaligned.c
 | 
						|
+++ b/arch/parisc/kernel/unaligned.c
 | 
						|
@@ -24,7 +24,7 @@
 | 
						|
 #define DPRINTF(fmt, args...)
 | 
						|
 #endif
 | 
						|
 
 | 
						|
-#define RFMT "%#08lx"
 | 
						|
+#define RFMT "0x%08lx"
 | 
						|
 
 | 
						|
 /* 1111 1100 0000 0000 0001 0011 1100 0000 */
 | 
						|
 #define OPCODE1(a,b,c)	((a)<<26|(b)<<12|(c)<<6) 
 | 
						|
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
 | 
						|
index e7792aa135105a..fa792653286659 100644
 | 
						|
--- a/arch/powerpc/include/asm/ppc_asm.h
 | 
						|
+++ b/arch/powerpc/include/asm/ppc_asm.h
 | 
						|
@@ -183,7 +183,7 @@
 | 
						|
 /*
 | 
						|
  * Used to name C functions called from asm
 | 
						|
  */
 | 
						|
-#ifdef CONFIG_PPC_KERNEL_PCREL
 | 
						|
+#if defined(__powerpc64__) && defined(CONFIG_PPC_KERNEL_PCREL)
 | 
						|
 #define CFUNC(name) name@notoc
 | 
						|
 #else
 | 
						|
 #define CFUNC(name) name
 | 
						|
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
 | 
						|
index ab316e155ea9f5..2e286bba2f6456 100644
 | 
						|
--- a/arch/powerpc/kernel/eeh.c
 | 
						|
+++ b/arch/powerpc/kernel/eeh.c
 | 
						|
@@ -1516,6 +1516,8 @@ int eeh_pe_configure(struct eeh_pe *pe)
 | 
						|
 	/* Invalid PE ? */
 | 
						|
 	if (!pe)
 | 
						|
 		return -ENODEV;
 | 
						|
+	else
 | 
						|
+		ret = eeh_ops->configure_bridge(pe);
 | 
						|
 
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
 | 
						|
index d5defff8472da7..47a9533a4dc1d6 100644
 | 
						|
--- a/arch/powerpc/kernel/vdso/Makefile
 | 
						|
+++ b/arch/powerpc/kernel/vdso/Makefile
 | 
						|
@@ -50,7 +50,7 @@ ldflags-$(CONFIG_LD_ORPHAN_WARN) += -Wl,--orphan-handling=$(CONFIG_LD_ORPHAN_WAR
 | 
						|
 ldflags-y += $(filter-out $(CC_AUTO_VAR_INIT_ZERO_ENABLER) $(CC_FLAGS_FTRACE) -Wa$(comma)%, $(KBUILD_CFLAGS))
 | 
						|
 
 | 
						|
 CC32FLAGS := -m32
 | 
						|
-CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc
 | 
						|
+CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc -mpcrel
 | 
						|
 ifdef CONFIG_CC_IS_CLANG
 | 
						|
 # This flag is supported by clang for 64-bit but not 32-bit so it will cause
 | 
						|
 # an unused command line flag warning for this file.
 | 
						|
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
 | 
						|
index 423ee1d5bd9440..fdcf10cd4d1270 100644
 | 
						|
--- a/arch/powerpc/platforms/pseries/msi.c
 | 
						|
+++ b/arch/powerpc/platforms/pseries/msi.c
 | 
						|
@@ -519,7 +519,12 @@ static struct msi_domain_info pseries_msi_domain_info = {
 | 
						|
 
 | 
						|
 static void pseries_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
 | 
						|
 {
 | 
						|
-	__pci_read_msi_msg(irq_data_get_msi_desc(data), msg);
 | 
						|
+	struct pci_dev *dev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
 | 
						|
+
 | 
						|
+	if (dev->current_state == PCI_D0)
 | 
						|
+		__pci_read_msi_msg(irq_data_get_msi_desc(data), msg);
 | 
						|
+	else
 | 
						|
+		get_cached_msi_msg(data->irq, msg);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static struct irq_chip pseries_msi_irq_chip = {
 | 
						|
diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c
 | 
						|
index 87ec68ed52d762..36f5386c60db75 100644
 | 
						|
--- a/arch/riscv/kvm/vcpu_sbi_replace.c
 | 
						|
+++ b/arch/riscv/kvm/vcpu_sbi_replace.c
 | 
						|
@@ -103,7 +103,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run
 | 
						|
 		kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_FENCE_I_SENT);
 | 
						|
 		break;
 | 
						|
 	case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
 | 
						|
-		if (cp->a2 == 0 && cp->a3 == 0)
 | 
						|
+		if ((cp->a2 == 0 && cp->a3 == 0) || cp->a3 == -1UL)
 | 
						|
 			kvm_riscv_hfence_vvma_all(vcpu->kvm, hbase, hmask);
 | 
						|
 		else
 | 
						|
 			kvm_riscv_hfence_vvma_gva(vcpu->kvm, hbase, hmask,
 | 
						|
@@ -111,7 +111,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run
 | 
						|
 		kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_SENT);
 | 
						|
 		break;
 | 
						|
 	case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
 | 
						|
-		if (cp->a2 == 0 && cp->a3 == 0)
 | 
						|
+		if ((cp->a2 == 0 && cp->a3 == 0) || cp->a3 == -1UL)
 | 
						|
 			kvm_riscv_hfence_vvma_asid_all(vcpu->kvm,
 | 
						|
 						       hbase, hmask, cp->a4);
 | 
						|
 		else
 | 
						|
@@ -127,9 +127,9 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run
 | 
						|
 	case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID:
 | 
						|
 		/*
 | 
						|
 		 * Until nested virtualization is implemented, the
 | 
						|
-		 * SBI HFENCE calls should be treated as NOPs
 | 
						|
+		 * SBI HFENCE calls should return not supported
 | 
						|
+		 * hence fallthrough.
 | 
						|
 		 */
 | 
						|
-		break;
 | 
						|
 	default:
 | 
						|
 		retdata->err_val = SBI_ERR_NOT_SUPPORTED;
 | 
						|
 	}
 | 
						|
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
 | 
						|
index 090dc38334336b..969a5e15691923 100644
 | 
						|
--- a/arch/s390/kvm/gaccess.c
 | 
						|
+++ b/arch/s390/kvm/gaccess.c
 | 
						|
@@ -490,7 +490,7 @@ enum prot_type {
 | 
						|
 	PROT_TYPE_DAT  = 3,
 | 
						|
 	PROT_TYPE_IEP  = 4,
 | 
						|
 	/* Dummy value for passing an initialized value when code != PGM_PROTECTION */
 | 
						|
-	PROT_NONE,
 | 
						|
+	PROT_TYPE_DUMMY,
 | 
						|
 };
 | 
						|
 
 | 
						|
 static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar,
 | 
						|
@@ -506,7 +506,7 @@ static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva,
 | 
						|
 	switch (code) {
 | 
						|
 	case PGM_PROTECTION:
 | 
						|
 		switch (prot) {
 | 
						|
-		case PROT_NONE:
 | 
						|
+		case PROT_TYPE_DUMMY:
 | 
						|
 			/* We should never get here, acts like termination */
 | 
						|
 			WARN_ON_ONCE(1);
 | 
						|
 			break;
 | 
						|
@@ -976,7 +976,7 @@ static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
 | 
						|
 			gpa = kvm_s390_real_to_abs(vcpu, ga);
 | 
						|
 			if (kvm_is_error_gpa(vcpu->kvm, gpa)) {
 | 
						|
 				rc = PGM_ADDRESSING;
 | 
						|
-				prot = PROT_NONE;
 | 
						|
+				prot = PROT_TYPE_DUMMY;
 | 
						|
 			}
 | 
						|
 		}
 | 
						|
 		if (rc)
 | 
						|
@@ -1134,7 +1134,7 @@ int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
 | 
						|
 		if (rc == PGM_PROTECTION)
 | 
						|
 			prot = PROT_TYPE_KEYC;
 | 
						|
 		else
 | 
						|
-			prot = PROT_NONE;
 | 
						|
+			prot = PROT_TYPE_DUMMY;
 | 
						|
 		rc = trans_exc_ending(vcpu, rc, ga, ar, mode, prot, terminate);
 | 
						|
 	}
 | 
						|
 out_unlock:
 | 
						|
diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
 | 
						|
index a90499c087f0c5..2ee7b5a5016c7d 100644
 | 
						|
--- a/arch/s390/pci/pci_mmio.c
 | 
						|
+++ b/arch/s390/pci/pci_mmio.c
 | 
						|
@@ -223,7 +223,7 @@ static inline int __pcilg_mio_inuser(
 | 
						|
 		[ioaddr_len] "+&d" (ioaddr_len.pair),
 | 
						|
 		[cc] "+d" (cc), [val] "=d" (val),
 | 
						|
 		[dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp),
 | 
						|
-		[shift] "+d" (shift)
 | 
						|
+		[shift] "+a" (shift)
 | 
						|
 		:: "cc", "memory");
 | 
						|
 
 | 
						|
 	/* did we write everything to the user space buffer? */
 | 
						|
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
 | 
						|
index e9c4bcb38f4586..07b45bbf6348de 100644
 | 
						|
--- a/arch/x86/kernel/cpu/bugs.c
 | 
						|
+++ b/arch/x86/kernel/cpu/bugs.c
 | 
						|
@@ -1442,13 +1442,9 @@ static __ro_after_init enum spectre_v2_mitigation_cmd spectre_v2_cmd;
 | 
						|
 static enum spectre_v2_user_cmd __init
 | 
						|
 spectre_v2_parse_user_cmdline(void)
 | 
						|
 {
 | 
						|
-	enum spectre_v2_user_cmd mode;
 | 
						|
 	char arg[20];
 | 
						|
 	int ret, i;
 | 
						|
 
 | 
						|
-	mode = IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ?
 | 
						|
-		SPECTRE_V2_USER_CMD_AUTO : SPECTRE_V2_USER_CMD_NONE;
 | 
						|
-
 | 
						|
 	switch (spectre_v2_cmd) {
 | 
						|
 	case SPECTRE_V2_CMD_NONE:
 | 
						|
 		return SPECTRE_V2_USER_CMD_NONE;
 | 
						|
@@ -1461,7 +1457,7 @@ spectre_v2_parse_user_cmdline(void)
 | 
						|
 	ret = cmdline_find_option(boot_command_line, "spectre_v2_user",
 | 
						|
 				  arg, sizeof(arg));
 | 
						|
 	if (ret < 0)
 | 
						|
-		return mode;
 | 
						|
+		return SPECTRE_V2_USER_CMD_AUTO;
 | 
						|
 
 | 
						|
 	for (i = 0; i < ARRAY_SIZE(v2_user_options); i++) {
 | 
						|
 		if (match_option(arg, ret, v2_user_options[i].option)) {
 | 
						|
@@ -1471,8 +1467,8 @@ spectre_v2_parse_user_cmdline(void)
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	pr_err("Unknown user space protection option (%s). Switching to default\n", arg);
 | 
						|
-	return mode;
 | 
						|
+	pr_err("Unknown user space protection option (%s). Switching to AUTO select\n", arg);
 | 
						|
+	return SPECTRE_V2_USER_CMD_AUTO;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
 | 
						|
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
 | 
						|
index c7f8c3200e8d7f..0db6eeeeb67205 100644
 | 
						|
--- a/arch/x86/kernel/cpu/sgx/main.c
 | 
						|
+++ b/arch/x86/kernel/cpu/sgx/main.c
 | 
						|
@@ -718,6 +718,8 @@ int arch_memory_failure(unsigned long pfn, int flags)
 | 
						|
 		goto out;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	sgx_unmark_page_reclaimable(page);
 | 
						|
+
 | 
						|
 	/*
 | 
						|
 	 * TBD: Add additional plumbing to enable pre-emptive
 | 
						|
 	 * action for asynchronous poison notification. Until
 | 
						|
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
 | 
						|
index c84a1451f194c4..86c50747e15837 100644
 | 
						|
--- a/arch/x86/kvm/svm/svm.c
 | 
						|
+++ b/arch/x86/kvm/svm/svm.c
 | 
						|
@@ -1503,7 +1503,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb)
 | 
						|
 {
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
-	for_each_online_cpu(i)
 | 
						|
+	for_each_possible_cpu(i)
 | 
						|
 		cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL);
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
 | 
						|
index e5a2c230110ea4..e7f3b70f9114ae 100644
 | 
						|
--- a/arch/x86/kvm/vmx/vmx.c
 | 
						|
+++ b/arch/x86/kvm/vmx/vmx.c
 | 
						|
@@ -787,8 +787,11 @@ static void vmx_emergency_disable(void)
 | 
						|
 		return;
 | 
						|
 
 | 
						|
 	list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu),
 | 
						|
-			    loaded_vmcss_on_cpu_link)
 | 
						|
+			    loaded_vmcss_on_cpu_link) {
 | 
						|
 		vmcs_clear(v->vmcs);
 | 
						|
+		if (v->shadow_vmcs)
 | 
						|
+			vmcs_clear(v->shadow_vmcs);
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	kvm_cpu_vmxoff();
 | 
						|
 }
 | 
						|
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
 | 
						|
index fb9ed5e1da89dc..2bdae8a25e084d 100644
 | 
						|
--- a/drivers/acpi/acpica/dsutils.c
 | 
						|
+++ b/drivers/acpi/acpica/dsutils.c
 | 
						|
@@ -668,6 +668,8 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
 | 
						|
 	union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
 | 
						|
 	u32 arg_count = 0;
 | 
						|
 	u32 index = walk_state->num_operands;
 | 
						|
+	u32 prev_num_operands = walk_state->num_operands;
 | 
						|
+	u32 new_num_operands;
 | 
						|
 	u32 i;
 | 
						|
 
 | 
						|
 	ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
 | 
						|
@@ -696,6 +698,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
 | 
						|
 
 | 
						|
 	/* Create the interpreter arguments, in reverse order */
 | 
						|
 
 | 
						|
+	new_num_operands = index;
 | 
						|
 	index--;
 | 
						|
 	for (i = 0; i < arg_count; i++) {
 | 
						|
 		arg = arguments[index];
 | 
						|
@@ -720,7 +723,11 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
 | 
						|
 	 * pop everything off of the operand stack and delete those
 | 
						|
 	 * objects
 | 
						|
 	 */
 | 
						|
-	acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
 | 
						|
+	walk_state->num_operands = i;
 | 
						|
+	acpi_ds_obj_stack_pop_and_delete(new_num_operands, walk_state);
 | 
						|
+
 | 
						|
+	/* Restore operand count */
 | 
						|
+	walk_state->num_operands = prev_num_operands;
 | 
						|
 
 | 
						|
 	ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index));
 | 
						|
 	return_ACPI_STATUS(status);
 | 
						|
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
 | 
						|
index 54471083ba545e..0bce1baaa62b32 100644
 | 
						|
--- a/drivers/acpi/acpica/psobject.c
 | 
						|
+++ b/drivers/acpi/acpica/psobject.c
 | 
						|
@@ -636,7 +636,8 @@ acpi_status
 | 
						|
 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
 | 
						|
 			  union acpi_parse_object *op, acpi_status status)
 | 
						|
 {
 | 
						|
-	acpi_status status2;
 | 
						|
+	acpi_status return_status = status;
 | 
						|
+	u8 ascending = TRUE;
 | 
						|
 
 | 
						|
 	ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
 | 
						|
 
 | 
						|
@@ -650,7 +651,7 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
 | 
						|
 			  op));
 | 
						|
 	do {
 | 
						|
 		if (op) {
 | 
						|
-			if (walk_state->ascending_callback != NULL) {
 | 
						|
+			if (ascending && walk_state->ascending_callback != NULL) {
 | 
						|
 				walk_state->op = op;
 | 
						|
 				walk_state->op_info =
 | 
						|
 				    acpi_ps_get_opcode_info(op->common.
 | 
						|
@@ -672,49 +673,26 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
 | 
						|
 				}
 | 
						|
 
 | 
						|
 				if (status == AE_CTRL_TERMINATE) {
 | 
						|
-					status = AE_OK;
 | 
						|
-
 | 
						|
-					/* Clean up */
 | 
						|
-					do {
 | 
						|
-						if (op) {
 | 
						|
-							status2 =
 | 
						|
-							    acpi_ps_complete_this_op
 | 
						|
-							    (walk_state, op);
 | 
						|
-							if (ACPI_FAILURE
 | 
						|
-							    (status2)) {
 | 
						|
-								return_ACPI_STATUS
 | 
						|
-								    (status2);
 | 
						|
-							}
 | 
						|
-						}
 | 
						|
-
 | 
						|
-						acpi_ps_pop_scope(&
 | 
						|
-								  (walk_state->
 | 
						|
-								   parser_state),
 | 
						|
-								  &op,
 | 
						|
-								  &walk_state->
 | 
						|
-								  arg_types,
 | 
						|
-								  &walk_state->
 | 
						|
-								  arg_count);
 | 
						|
-
 | 
						|
-					} while (op);
 | 
						|
-
 | 
						|
-					return_ACPI_STATUS(status);
 | 
						|
+					ascending = FALSE;
 | 
						|
+					return_status = AE_CTRL_TERMINATE;
 | 
						|
 				}
 | 
						|
 
 | 
						|
 				else if (ACPI_FAILURE(status)) {
 | 
						|
 
 | 
						|
 					/* First error is most important */
 | 
						|
 
 | 
						|
-					(void)
 | 
						|
-					    acpi_ps_complete_this_op(walk_state,
 | 
						|
-								     op);
 | 
						|
-					return_ACPI_STATUS(status);
 | 
						|
+					ascending = FALSE;
 | 
						|
+					return_status = status;
 | 
						|
 				}
 | 
						|
 			}
 | 
						|
 
 | 
						|
-			status2 = acpi_ps_complete_this_op(walk_state, op);
 | 
						|
-			if (ACPI_FAILURE(status2)) {
 | 
						|
-				return_ACPI_STATUS(status2);
 | 
						|
+			status = acpi_ps_complete_this_op(walk_state, op);
 | 
						|
+			if (ACPI_FAILURE(status)) {
 | 
						|
+				ascending = FALSE;
 | 
						|
+				if (ACPI_SUCCESS(return_status) ||
 | 
						|
+				    return_status == AE_CTRL_TERMINATE) {
 | 
						|
+					return_status = status;
 | 
						|
+				}
 | 
						|
 			}
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -724,5 +702,5 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
 | 
						|
 
 | 
						|
 	} while (op);
 | 
						|
 
 | 
						|
-	return_ACPI_STATUS(status);
 | 
						|
+	return_ACPI_STATUS(return_status);
 | 
						|
 }
 | 
						|
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c
 | 
						|
index 42b30b9f93128e..7fad03c5252c35 100644
 | 
						|
--- a/drivers/acpi/acpica/utprint.c
 | 
						|
+++ b/drivers/acpi/acpica/utprint.c
 | 
						|
@@ -333,11 +333,8 @@ int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
 | 
						|
 
 | 
						|
 	pos = string;
 | 
						|
 
 | 
						|
-	if (size != ACPI_UINT32_MAX) {
 | 
						|
-		end = string + size;
 | 
						|
-	} else {
 | 
						|
-		end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX);
 | 
						|
-	}
 | 
						|
+	size = ACPI_MIN(size, ACPI_PTR_DIFF(ACPI_MAX_PTR, string));
 | 
						|
+	end = string + size;
 | 
						|
 
 | 
						|
 	for (; *format; ++format) {
 | 
						|
 		if (*format != '%') {
 | 
						|
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
 | 
						|
index e3cbaf3c3bbc15..cd3cbb7a36f855 100644
 | 
						|
--- a/drivers/acpi/battery.c
 | 
						|
+++ b/drivers/acpi/battery.c
 | 
						|
@@ -243,10 +243,23 @@ static int acpi_battery_get_property(struct power_supply *psy,
 | 
						|
 		break;
 | 
						|
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
 | 
						|
 	case POWER_SUPPLY_PROP_POWER_NOW:
 | 
						|
-		if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
 | 
						|
+		if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) {
 | 
						|
 			ret = -ENODEV;
 | 
						|
-		else
 | 
						|
-			val->intval = battery->rate_now * 1000;
 | 
						|
+			break;
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		val->intval = battery->rate_now * 1000;
 | 
						|
+		/*
 | 
						|
+		 * When discharging, the current should be reported as a
 | 
						|
+		 * negative number as per the power supply class interface
 | 
						|
+		 * definition.
 | 
						|
+		 */
 | 
						|
+		if (psp == POWER_SUPPLY_PROP_CURRENT_NOW &&
 | 
						|
+		    (battery->state & ACPI_BATTERY_STATE_DISCHARGING) &&
 | 
						|
+		    acpi_battery_handle_discharging(battery)
 | 
						|
+				== POWER_SUPPLY_STATUS_DISCHARGING)
 | 
						|
+			val->intval = -val->intval;
 | 
						|
+
 | 
						|
 		break;
 | 
						|
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 | 
						|
 	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
 | 
						|
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
 | 
						|
index a4aa53b7e2bb30..645464f02363f3 100644
 | 
						|
--- a/drivers/acpi/bus.c
 | 
						|
+++ b/drivers/acpi/bus.c
 | 
						|
@@ -1396,8 +1396,10 @@ static int __init acpi_init(void)
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
 | 
						|
-	if (!acpi_kobj)
 | 
						|
-		pr_debug("%s: kset create error\n", __func__);
 | 
						|
+	if (!acpi_kobj) {
 | 
						|
+		pr_err("Failed to register kobject\n");
 | 
						|
+		return -ENOMEM;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	init_prmt();
 | 
						|
 	acpi_init_pcc();
 | 
						|
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
 | 
						|
index 696b99720dcbda..d82728a01832b5 100644
 | 
						|
--- a/drivers/ata/pata_via.c
 | 
						|
+++ b/drivers/ata/pata_via.c
 | 
						|
@@ -368,7 +368,8 @@ static unsigned int via_mode_filter(struct ata_device *dev, unsigned int mask)
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (dev->class == ATA_DEV_ATAPI &&
 | 
						|
-	    dmi_check_system(no_atapi_dma_dmi_table)) {
 | 
						|
+	    (dmi_check_system(no_atapi_dma_dmi_table) ||
 | 
						|
+	     config->id == PCI_DEVICE_ID_VIA_6415)) {
 | 
						|
 		ata_dev_warn(dev, "controller locks up on ATAPI DMA, forcing PIO\n");
 | 
						|
 		mask &= ATA_MASK_PIO;
 | 
						|
 	}
 | 
						|
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
 | 
						|
index 96bea1ab1eccf4..ff558908897f3e 100644
 | 
						|
--- a/drivers/atm/atmtcp.c
 | 
						|
+++ b/drivers/atm/atmtcp.c
 | 
						|
@@ -288,7 +288,9 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
 | 
						|
 	struct sk_buff *new_skb;
 | 
						|
 	int result = 0;
 | 
						|
 
 | 
						|
-	if (!skb->len) return 0;
 | 
						|
+	if (skb->len < sizeof(struct atmtcp_hdr))
 | 
						|
+		goto done;
 | 
						|
+
 | 
						|
 	dev = vcc->dev_data;
 | 
						|
 	hdr = (struct atmtcp_hdr *) skb->data;
 | 
						|
 	if (hdr->length == ATMTCP_HDR_MAGIC) {
 | 
						|
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
 | 
						|
index 0af26cf8c0059f..0d43bf5b6cecbf 100644
 | 
						|
--- a/drivers/base/power/runtime.c
 | 
						|
+++ b/drivers/base/power/runtime.c
 | 
						|
@@ -1001,7 +1001,7 @@ static enum hrtimer_restart  pm_suspend_timer_fn(struct hrtimer *timer)
 | 
						|
 	 * If 'expires' is after the current time, we've been called
 | 
						|
 	 * too early.
 | 
						|
 	 */
 | 
						|
-	if (expires > 0 && expires < ktime_get_mono_fast_ns()) {
 | 
						|
+	if (expires > 0 && expires <= ktime_get_mono_fast_ns()) {
 | 
						|
 		dev->power.timer_expires = 0;
 | 
						|
 		rpm_suspend(dev, dev->power.timer_autosuspends ?
 | 
						|
 		    (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC);
 | 
						|
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
 | 
						|
index 079bd14bdedc7c..a7a3e3b66bb5ed 100644
 | 
						|
--- a/drivers/base/swnode.c
 | 
						|
+++ b/drivers/base/swnode.c
 | 
						|
@@ -518,7 +518,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
 | 
						|
 	if (prop->is_inline)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
-	if (index * sizeof(*ref) >= prop->length)
 | 
						|
+	if ((index + 1) * sizeof(*ref) > prop->length)
 | 
						|
 		return -ENOENT;
 | 
						|
 
 | 
						|
 	ref_array = prop->pointer;
 | 
						|
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
 | 
						|
index 3523dd82d7a002..280679bde3a506 100644
 | 
						|
--- a/drivers/block/aoe/aoedev.c
 | 
						|
+++ b/drivers/block/aoe/aoedev.c
 | 
						|
@@ -198,6 +198,7 @@ aoedev_downdev(struct aoedev *d)
 | 
						|
 {
 | 
						|
 	struct aoetgt *t, **tt, **te;
 | 
						|
 	struct list_head *head, *pos, *nx;
 | 
						|
+	struct request *rq, *rqnext;
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
 	d->flags &= ~DEVFL_UP;
 | 
						|
@@ -223,6 +224,13 @@ aoedev_downdev(struct aoedev *d)
 | 
						|
 	/* clean out the in-process request (if any) */
 | 
						|
 	aoe_failip(d);
 | 
						|
 
 | 
						|
+	/* clean out any queued block requests */
 | 
						|
+	list_for_each_entry_safe(rq, rqnext, &d->rq_list, queuelist) {
 | 
						|
+		list_del_init(&rq->queuelist);
 | 
						|
+		blk_mq_start_request(rq);
 | 
						|
+		blk_mq_end_request(rq, BLK_STS_IOERR);
 | 
						|
+	}
 | 
						|
+
 | 
						|
 	/* fast fail all pending I/O */
 | 
						|
 	if (d->blkq) {
 | 
						|
 		/* UP is cleared, freeze+quiesce to insure all are errored */
 | 
						|
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
 | 
						|
index 95095500f93afb..df3e5aab4b5ac9 100644
 | 
						|
--- a/drivers/block/ublk_drv.c
 | 
						|
+++ b/drivers/block/ublk_drv.c
 | 
						|
@@ -2323,6 +2323,9 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
 | 
						|
 	if (copy_from_user(&info, argp, sizeof(info)))
 | 
						|
 		return -EFAULT;
 | 
						|
 
 | 
						|
+	if (info.queue_depth > UBLK_MAX_QUEUE_DEPTH || info.nr_hw_queues > UBLK_MAX_NR_QUEUES)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	if (capable(CAP_SYS_ADMIN))
 | 
						|
 		info.flags &= ~UBLK_F_UNPRIVILEGED_DEV;
 | 
						|
 	else if (!(info.flags & UBLK_F_UNPRIVILEGED_DEV))
 | 
						|
diff --git a/drivers/bus/fsl-mc/fsl-mc-uapi.c b/drivers/bus/fsl-mc/fsl-mc-uapi.c
 | 
						|
index 9c4c1395fcdbf2..a376ec66165348 100644
 | 
						|
--- a/drivers/bus/fsl-mc/fsl-mc-uapi.c
 | 
						|
+++ b/drivers/bus/fsl-mc/fsl-mc-uapi.c
 | 
						|
@@ -275,13 +275,13 @@ static struct fsl_mc_cmd_desc fsl_mc_accepted_cmds[] = {
 | 
						|
 		.size = 8,
 | 
						|
 	},
 | 
						|
 	[DPSW_GET_TAILDROP] = {
 | 
						|
-		.cmdid_value = 0x0A80,
 | 
						|
+		.cmdid_value = 0x0A90,
 | 
						|
 		.cmdid_mask = 0xFFF0,
 | 
						|
 		.token = true,
 | 
						|
 		.size = 14,
 | 
						|
 	},
 | 
						|
 	[DPSW_SET_TAILDROP] = {
 | 
						|
-		.cmdid_value = 0x0A90,
 | 
						|
+		.cmdid_value = 0x0A80,
 | 
						|
 		.cmdid_mask = 0xFFF0,
 | 
						|
 		.token = true,
 | 
						|
 		.size = 24,
 | 
						|
diff --git a/drivers/bus/fsl-mc/mc-io.c b/drivers/bus/fsl-mc/mc-io.c
 | 
						|
index 95b10a6cf3073f..8b7a34f4db94bb 100644
 | 
						|
--- a/drivers/bus/fsl-mc/mc-io.c
 | 
						|
+++ b/drivers/bus/fsl-mc/mc-io.c
 | 
						|
@@ -214,12 +214,19 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
 | 
						|
 	if (error < 0)
 | 
						|
 		goto error_cleanup_resource;
 | 
						|
 
 | 
						|
-	dpmcp_dev->consumer_link = device_link_add(&mc_dev->dev,
 | 
						|
-						   &dpmcp_dev->dev,
 | 
						|
-						   DL_FLAG_AUTOREMOVE_CONSUMER);
 | 
						|
-	if (!dpmcp_dev->consumer_link) {
 | 
						|
-		error = -EINVAL;
 | 
						|
-		goto error_cleanup_mc_io;
 | 
						|
+	/* If the DPRC device itself tries to allocate a portal (usually for
 | 
						|
+	 * UAPI interaction), don't add a device link between them since the
 | 
						|
+	 * DPMCP device is an actual child device of the DPRC and a reverse
 | 
						|
+	 * dependency is not allowed.
 | 
						|
+	 */
 | 
						|
+	if (mc_dev != mc_bus_dev) {
 | 
						|
+		dpmcp_dev->consumer_link = device_link_add(&mc_dev->dev,
 | 
						|
+							   &dpmcp_dev->dev,
 | 
						|
+							   DL_FLAG_AUTOREMOVE_CONSUMER);
 | 
						|
+		if (!dpmcp_dev->consumer_link) {
 | 
						|
+			error = -EINVAL;
 | 
						|
+			goto error_cleanup_mc_io;
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	*new_mc_io = mc_io;
 | 
						|
diff --git a/drivers/bus/fsl-mc/mc-sys.c b/drivers/bus/fsl-mc/mc-sys.c
 | 
						|
index f2052cd0a05178..b22c59d57c8f0a 100644
 | 
						|
--- a/drivers/bus/fsl-mc/mc-sys.c
 | 
						|
+++ b/drivers/bus/fsl-mc/mc-sys.c
 | 
						|
@@ -19,7 +19,7 @@
 | 
						|
 /*
 | 
						|
  * Timeout in milliseconds to wait for the completion of an MC command
 | 
						|
  */
 | 
						|
-#define MC_CMD_COMPLETION_TIMEOUT_MS	500
 | 
						|
+#define MC_CMD_COMPLETION_TIMEOUT_MS	15000
 | 
						|
 
 | 
						|
 /*
 | 
						|
  * usleep_range() min and max values used to throttle down polling
 | 
						|
diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c
 | 
						|
index ba9f696d1aa80e..fedf26392e8d29 100644
 | 
						|
--- a/drivers/bus/mhi/ep/ring.c
 | 
						|
+++ b/drivers/bus/mhi/ep/ring.c
 | 
						|
@@ -131,19 +131,23 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	old_offset = ring->rd_offset;
 | 
						|
-	mhi_ep_ring_inc_index(ring);
 | 
						|
 
 | 
						|
 	dev_dbg(dev, "Adding an element to ring at offset (%zu)\n", ring->rd_offset);
 | 
						|
+	buf_info.host_addr = ring->rbase + (old_offset * sizeof(*el));
 | 
						|
+	buf_info.dev_addr = el;
 | 
						|
+	buf_info.size = sizeof(*el);
 | 
						|
+
 | 
						|
+	ret = mhi_cntrl->write_sync(mhi_cntrl, &buf_info);
 | 
						|
+	if (ret)
 | 
						|
+		return ret;
 | 
						|
+
 | 
						|
+	mhi_ep_ring_inc_index(ring);
 | 
						|
 
 | 
						|
 	/* Update rp in ring context */
 | 
						|
 	rp = cpu_to_le64(ring->rd_offset * sizeof(*el) + ring->rbase);
 | 
						|
 	memcpy_toio((void __iomem *) &ring->ring_ctx->generic.rp, &rp, sizeof(u64));
 | 
						|
 
 | 
						|
-	buf_info.host_addr = ring->rbase + (old_offset * sizeof(*el));
 | 
						|
-	buf_info.dev_addr = el;
 | 
						|
-	buf_info.size = sizeof(*el);
 | 
						|
-
 | 
						|
-	return mhi_cntrl->write_sync(mhi_cntrl, &buf_info);
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id)
 | 
						|
diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c
 | 
						|
index 27f8a40f288cfd..e48bf44c785c9b 100644
 | 
						|
--- a/drivers/bus/mhi/host/pm.c
 | 
						|
+++ b/drivers/bus/mhi/host/pm.c
 | 
						|
@@ -586,6 +586,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl)
 | 
						|
 	struct mhi_cmd *mhi_cmd;
 | 
						|
 	struct mhi_event_ctxt *er_ctxt;
 | 
						|
 	struct device *dev = &mhi_cntrl->mhi_dev->dev;
 | 
						|
+	bool reset_device = false;
 | 
						|
 	int ret, i;
 | 
						|
 
 | 
						|
 	dev_dbg(dev, "Transitioning from PM state: %s to: %s\n",
 | 
						|
@@ -614,8 +615,23 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl)
 | 
						|
 	/* Wake up threads waiting for state transition */
 | 
						|
 	wake_up_all(&mhi_cntrl->state_event);
 | 
						|
 
 | 
						|
-	/* Trigger MHI RESET so that the device will not access host memory */
 | 
						|
 	if (MHI_REG_ACCESS_VALID(prev_state)) {
 | 
						|
+		/*
 | 
						|
+		 * If the device is in PBL or SBL, it will only respond to
 | 
						|
+		 * RESET if the device is in SYSERR state. SYSERR might
 | 
						|
+		 * already be cleared at this point.
 | 
						|
+		 */
 | 
						|
+		enum mhi_state cur_state = mhi_get_mhi_state(mhi_cntrl);
 | 
						|
+		enum mhi_ee_type cur_ee = mhi_get_exec_env(mhi_cntrl);
 | 
						|
+
 | 
						|
+		if (cur_state == MHI_STATE_SYS_ERR)
 | 
						|
+			reset_device = true;
 | 
						|
+		else if (cur_ee != MHI_EE_PBL && cur_ee != MHI_EE_SBL)
 | 
						|
+			reset_device = true;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Trigger MHI RESET so that the device will not access host memory */
 | 
						|
+	if (reset_device) {
 | 
						|
 		u32 in_reset = -1;
 | 
						|
 		unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms);
 | 
						|
 
 | 
						|
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
 | 
						|
index 65163312dab8ac..46d7410f6f0fce 100644
 | 
						|
--- a/drivers/bus/ti-sysc.c
 | 
						|
+++ b/drivers/bus/ti-sysc.c
 | 
						|
@@ -667,51 +667,6 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata)
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
-/* Interconnect instances to probe before l4_per instances */
 | 
						|
-static struct resource early_bus_ranges[] = {
 | 
						|
-	/* am3/4 l4_wkup */
 | 
						|
-	{ .start = 0x44c00000, .end = 0x44c00000 + 0x300000, },
 | 
						|
-	/* omap4/5 and dra7 l4_cfg */
 | 
						|
-	{ .start = 0x4a000000, .end = 0x4a000000 + 0x300000, },
 | 
						|
-	/* omap4 l4_wkup */
 | 
						|
-	{ .start = 0x4a300000, .end = 0x4a300000 + 0x30000,  },
 | 
						|
-	/* omap5 and dra7 l4_wkup without dra7 dcan segment */
 | 
						|
-	{ .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000,  },
 | 
						|
-};
 | 
						|
-
 | 
						|
-static atomic_t sysc_defer = ATOMIC_INIT(10);
 | 
						|
-
 | 
						|
-/**
 | 
						|
- * sysc_defer_non_critical - defer non_critical interconnect probing
 | 
						|
- * @ddata: device driver data
 | 
						|
- *
 | 
						|
- * We want to probe l4_cfg and l4_wkup interconnect instances before any
 | 
						|
- * l4_per instances as l4_per instances depend on resources on l4_cfg and
 | 
						|
- * l4_wkup interconnects.
 | 
						|
- */
 | 
						|
-static int sysc_defer_non_critical(struct sysc *ddata)
 | 
						|
-{
 | 
						|
-	struct resource *res;
 | 
						|
-	int i;
 | 
						|
-
 | 
						|
-	if (!atomic_read(&sysc_defer))
 | 
						|
-		return 0;
 | 
						|
-
 | 
						|
-	for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) {
 | 
						|
-		res = &early_bus_ranges[i];
 | 
						|
-		if (ddata->module_pa >= res->start &&
 | 
						|
-		    ddata->module_pa <= res->end) {
 | 
						|
-			atomic_set(&sysc_defer, 0);
 | 
						|
-
 | 
						|
-			return 0;
 | 
						|
-		}
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	atomic_dec_if_positive(&sysc_defer);
 | 
						|
-
 | 
						|
-	return -EPROBE_DEFER;
 | 
						|
-}
 | 
						|
-
 | 
						|
 static struct device_node *stdout_path;
 | 
						|
 
 | 
						|
 static void sysc_init_stdout_path(struct sysc *ddata)
 | 
						|
@@ -937,10 +892,6 @@ static int sysc_map_and_check_registers(struct sysc *ddata)
 | 
						|
 	if (error)
 | 
						|
 		return error;
 | 
						|
 
 | 
						|
-	error = sysc_defer_non_critical(ddata);
 | 
						|
-	if (error)
 | 
						|
-		return error;
 | 
						|
-
 | 
						|
 	sysc_check_children(ddata);
 | 
						|
 
 | 
						|
 	if (!of_property_present(np, "reg"))
 | 
						|
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
 | 
						|
index 233ce4a4c1c2f1..69018efbf7f47b 100644
 | 
						|
--- a/drivers/clk/meson/g12a.c
 | 
						|
+++ b/drivers/clk/meson/g12a.c
 | 
						|
@@ -3971,6 +3971,7 @@ static const struct clk_parent_data spicc_sclk_parent_data[] = {
 | 
						|
 	{ .hw = &g12a_clk81.hw },
 | 
						|
 	{ .hw = &g12a_fclk_div4.hw },
 | 
						|
 	{ .hw = &g12a_fclk_div3.hw },
 | 
						|
+	{ .hw = &g12a_fclk_div2.hw },
 | 
						|
 	{ .hw = &g12a_fclk_div5.hw },
 | 
						|
 	{ .hw = &g12a_fclk_div7.hw },
 | 
						|
 };
 | 
						|
diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c
 | 
						|
index d644bc155ec6e5..f5f27535087a30 100644
 | 
						|
--- a/drivers/clk/rockchip/clk-rk3036.c
 | 
						|
+++ b/drivers/clk/rockchip/clk-rk3036.c
 | 
						|
@@ -431,6 +431,7 @@ static const char *const rk3036_critical_clocks[] __initconst = {
 | 
						|
 	"hclk_peri",
 | 
						|
 	"pclk_peri",
 | 
						|
 	"pclk_ddrupctl",
 | 
						|
+	"ddrphy",
 | 
						|
 };
 | 
						|
 
 | 
						|
 static void __init rk3036_clk_init(struct device_node *np)
 | 
						|
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
 | 
						|
index e4989764efe2a8..6ff77003a96eac 100644
 | 
						|
--- a/drivers/cpufreq/scmi-cpufreq.c
 | 
						|
+++ b/drivers/cpufreq/scmi-cpufreq.c
 | 
						|
@@ -299,6 +299,40 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
 | 
						|
 	.register_em	= scmi_cpufreq_register_em,
 | 
						|
 };
 | 
						|
 
 | 
						|
+static bool scmi_dev_used_by_cpus(struct device *scmi_dev)
 | 
						|
+{
 | 
						|
+	struct device_node *scmi_np = dev_of_node(scmi_dev);
 | 
						|
+	struct device_node *cpu_np, *np;
 | 
						|
+	struct device *cpu_dev;
 | 
						|
+	int cpu, idx;
 | 
						|
+
 | 
						|
+	if (!scmi_np)
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	for_each_possible_cpu(cpu) {
 | 
						|
+		cpu_dev = get_cpu_device(cpu);
 | 
						|
+		if (!cpu_dev)
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
+		cpu_np = dev_of_node(cpu_dev);
 | 
						|
+
 | 
						|
+		np = of_parse_phandle(cpu_np, "clocks", 0);
 | 
						|
+		of_node_put(np);
 | 
						|
+
 | 
						|
+		if (np == scmi_np)
 | 
						|
+			return true;
 | 
						|
+
 | 
						|
+		idx = of_property_match_string(cpu_np, "power-domain-names", "perf");
 | 
						|
+		np = of_parse_phandle(cpu_np, "power-domains", idx);
 | 
						|
+		of_node_put(np);
 | 
						|
+
 | 
						|
+		if (np == scmi_np)
 | 
						|
+			return true;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
 static int scmi_cpufreq_probe(struct scmi_device *sdev)
 | 
						|
 {
 | 
						|
 	int ret;
 | 
						|
@@ -307,7 +341,7 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev)
 | 
						|
 
 | 
						|
 	handle = sdev->handle;
 | 
						|
 
 | 
						|
-	if (!handle)
 | 
						|
+	if (!handle || !scmi_dev_used_by_cpus(dev))
 | 
						|
 		return -ENODEV;
 | 
						|
 
 | 
						|
 	perf_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PERF, &ph);
 | 
						|
diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c
 | 
						|
index 4e5b6f9a56d1b2..7b8fcfa55038bc 100644
 | 
						|
--- a/drivers/cpufreq/tegra186-cpufreq.c
 | 
						|
+++ b/drivers/cpufreq/tegra186-cpufreq.c
 | 
						|
@@ -73,18 +73,11 @@ static int tegra186_cpufreq_init(struct cpufreq_policy *policy)
 | 
						|
 {
 | 
						|
 	struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
 | 
						|
 	unsigned int cluster = data->cpus[policy->cpu].bpmp_cluster_id;
 | 
						|
-	u32 cpu;
 | 
						|
 
 | 
						|
 	policy->freq_table = data->clusters[cluster].table;
 | 
						|
 	policy->cpuinfo.transition_latency = 300 * 1000;
 | 
						|
 	policy->driver_data = NULL;
 | 
						|
 
 | 
						|
-	/* set same policy for all cpus in a cluster */
 | 
						|
-	for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) {
 | 
						|
-		if (data->cpus[cpu].bpmp_cluster_id == cluster)
 | 
						|
-			cpumask_set_cpu(cpu, policy->cpus);
 | 
						|
-	}
 | 
						|
-
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c
 | 
						|
index b61e35b932e590..76f34b81258dc3 100644
 | 
						|
--- a/drivers/crypto/marvell/cesa/cesa.c
 | 
						|
+++ b/drivers/crypto/marvell/cesa/cesa.c
 | 
						|
@@ -94,7 +94,7 @@ static int mv_cesa_std_process(struct mv_cesa_engine *engine, u32 status)
 | 
						|
 
 | 
						|
 static int mv_cesa_int_process(struct mv_cesa_engine *engine, u32 status)
 | 
						|
 {
 | 
						|
-	if (engine->chain.first && engine->chain.last)
 | 
						|
+	if (engine->chain_hw.first && engine->chain_hw.last)
 | 
						|
 		return mv_cesa_tdma_process(engine, status);
 | 
						|
 
 | 
						|
 	return mv_cesa_std_process(engine, status);
 | 
						|
diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h
 | 
						|
index d215a6bed6bc7b..50ca1039fdaa7a 100644
 | 
						|
--- a/drivers/crypto/marvell/cesa/cesa.h
 | 
						|
+++ b/drivers/crypto/marvell/cesa/cesa.h
 | 
						|
@@ -440,8 +440,10 @@ struct mv_cesa_dev {
 | 
						|
  *			SRAM
 | 
						|
  * @queue:		fifo of the pending crypto requests
 | 
						|
  * @load:		engine load counter, useful for load balancing
 | 
						|
- * @chain:		list of the current tdma descriptors being processed
 | 
						|
- *			by this engine.
 | 
						|
+ * @chain_hw:		list of the current tdma descriptors being processed
 | 
						|
+ *			by the hardware.
 | 
						|
+ * @chain_sw:		list of the current tdma descriptors that will be
 | 
						|
+ *			submitted to the hardware.
 | 
						|
  * @complete_queue:	fifo of the processed requests by the engine
 | 
						|
  *
 | 
						|
  * Structure storing CESA engine information.
 | 
						|
@@ -463,7 +465,8 @@ struct mv_cesa_engine {
 | 
						|
 	struct gen_pool *pool;
 | 
						|
 	struct crypto_queue queue;
 | 
						|
 	atomic_t load;
 | 
						|
-	struct mv_cesa_tdma_chain chain;
 | 
						|
+	struct mv_cesa_tdma_chain chain_hw;
 | 
						|
+	struct mv_cesa_tdma_chain chain_sw;
 | 
						|
 	struct list_head complete_queue;
 | 
						|
 	int irq;
 | 
						|
 };
 | 
						|
diff --git a/drivers/crypto/marvell/cesa/tdma.c b/drivers/crypto/marvell/cesa/tdma.c
 | 
						|
index 388a06e180d64a..243305354420c1 100644
 | 
						|
--- a/drivers/crypto/marvell/cesa/tdma.c
 | 
						|
+++ b/drivers/crypto/marvell/cesa/tdma.c
 | 
						|
@@ -38,6 +38,15 @@ void mv_cesa_dma_step(struct mv_cesa_req *dreq)
 | 
						|
 {
 | 
						|
 	struct mv_cesa_engine *engine = dreq->engine;
 | 
						|
 
 | 
						|
+	spin_lock_bh(&engine->lock);
 | 
						|
+	if (engine->chain_sw.first == dreq->chain.first) {
 | 
						|
+		engine->chain_sw.first = NULL;
 | 
						|
+		engine->chain_sw.last = NULL;
 | 
						|
+	}
 | 
						|
+	engine->chain_hw.first = dreq->chain.first;
 | 
						|
+	engine->chain_hw.last = dreq->chain.last;
 | 
						|
+	spin_unlock_bh(&engine->lock);
 | 
						|
+
 | 
						|
 	writel_relaxed(0, engine->regs + CESA_SA_CFG);
 | 
						|
 
 | 
						|
 	mv_cesa_set_int_mask(engine, CESA_SA_INT_ACC0_IDMA_DONE);
 | 
						|
@@ -96,25 +105,27 @@ void mv_cesa_dma_prepare(struct mv_cesa_req *dreq,
 | 
						|
 void mv_cesa_tdma_chain(struct mv_cesa_engine *engine,
 | 
						|
 			struct mv_cesa_req *dreq)
 | 
						|
 {
 | 
						|
-	if (engine->chain.first == NULL && engine->chain.last == NULL) {
 | 
						|
-		engine->chain.first = dreq->chain.first;
 | 
						|
-		engine->chain.last  = dreq->chain.last;
 | 
						|
-	} else {
 | 
						|
-		struct mv_cesa_tdma_desc *last;
 | 
						|
+	struct mv_cesa_tdma_desc *last = engine->chain_sw.last;
 | 
						|
 
 | 
						|
-		last = engine->chain.last;
 | 
						|
+	/*
 | 
						|
+	 * Break the DMA chain if the request being queued needs the IV
 | 
						|
+	 * regs to be set before lauching the request.
 | 
						|
+	 */
 | 
						|
+	if (!last || dreq->chain.first->flags & CESA_TDMA_SET_STATE)
 | 
						|
+		engine->chain_sw.first = dreq->chain.first;
 | 
						|
+	else {
 | 
						|
 		last->next = dreq->chain.first;
 | 
						|
-		engine->chain.last = dreq->chain.last;
 | 
						|
-
 | 
						|
-		/*
 | 
						|
-		 * Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on
 | 
						|
-		 * the last element of the current chain, or if the request
 | 
						|
-		 * being queued needs the IV regs to be set before lauching
 | 
						|
-		 * the request.
 | 
						|
-		 */
 | 
						|
-		if (!(last->flags & CESA_TDMA_BREAK_CHAIN) &&
 | 
						|
-		    !(dreq->chain.first->flags & CESA_TDMA_SET_STATE))
 | 
						|
-			last->next_dma = cpu_to_le32(dreq->chain.first->cur_dma);
 | 
						|
+		last->next_dma = cpu_to_le32(dreq->chain.first->cur_dma);
 | 
						|
+	}
 | 
						|
+	last = dreq->chain.last;
 | 
						|
+	engine->chain_sw.last = last;
 | 
						|
+	/*
 | 
						|
+	 * Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on
 | 
						|
+	 * the last element of the current chain.
 | 
						|
+	 */
 | 
						|
+	if (last->flags & CESA_TDMA_BREAK_CHAIN) {
 | 
						|
+		engine->chain_sw.first = NULL;
 | 
						|
+		engine->chain_sw.last = NULL;
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -127,7 +138,7 @@ int mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status)
 | 
						|
 
 | 
						|
 	tdma_cur = readl(engine->regs + CESA_TDMA_CUR);
 | 
						|
 
 | 
						|
-	for (tdma = engine->chain.first; tdma; tdma = next) {
 | 
						|
+	for (tdma = engine->chain_hw.first; tdma; tdma = next) {
 | 
						|
 		spin_lock_bh(&engine->lock);
 | 
						|
 		next = tdma->next;
 | 
						|
 		spin_unlock_bh(&engine->lock);
 | 
						|
@@ -149,12 +160,12 @@ int mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status)
 | 
						|
 								 &backlog);
 | 
						|
 
 | 
						|
 			/* Re-chaining to the next request */
 | 
						|
-			engine->chain.first = tdma->next;
 | 
						|
+			engine->chain_hw.first = tdma->next;
 | 
						|
 			tdma->next = NULL;
 | 
						|
 
 | 
						|
 			/* If this is the last request, clear the chain */
 | 
						|
-			if (engine->chain.first == NULL)
 | 
						|
-				engine->chain.last  = NULL;
 | 
						|
+			if (engine->chain_hw.first == NULL)
 | 
						|
+				engine->chain_hw.last  = NULL;
 | 
						|
 			spin_unlock_bh(&engine->lock);
 | 
						|
 
 | 
						|
 			ctx = crypto_tfm_ctx(req->tfm);
 | 
						|
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
 | 
						|
index 373282beeb6068..980975ffc55d3c 100644
 | 
						|
--- a/drivers/dma-buf/udmabuf.c
 | 
						|
+++ b/drivers/dma-buf/udmabuf.c
 | 
						|
@@ -161,8 +161,7 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
 | 
						|
 			ubuf->sg = NULL;
 | 
						|
 		}
 | 
						|
 	} else {
 | 
						|
-		dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
 | 
						|
-				    direction);
 | 
						|
+		dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	return ret;
 | 
						|
@@ -177,7 +176,7 @@ static int end_cpu_udmabuf(struct dma_buf *buf,
 | 
						|
 	if (!ubuf->sg)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
-	dma_sync_sg_for_device(dev, ubuf->sg->sgl, ubuf->sg->nents, direction);
 | 
						|
+	dma_sync_sgtable_for_device(dev, ubuf->sg, direction);
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
 | 
						|
index e04fd1a7e9aaea..54ec894150939a 100644
 | 
						|
--- a/drivers/edac/altera_edac.c
 | 
						|
+++ b/drivers/edac/altera_edac.c
 | 
						|
@@ -1756,9 +1756,9 @@ altr_edac_a10_device_trig(struct file *file, const char __user *user_buf,
 | 
						|
 
 | 
						|
 	local_irq_save(flags);
 | 
						|
 	if (trig_type == ALTR_UE_TRIGGER_CHAR)
 | 
						|
-		writel(priv->ue_set_mask, set_addr);
 | 
						|
+		writew(priv->ue_set_mask, set_addr);
 | 
						|
 	else
 | 
						|
-		writel(priv->ce_set_mask, set_addr);
 | 
						|
+		writew(priv->ce_set_mask, set_addr);
 | 
						|
 
 | 
						|
 	/* Ensure the interrupt test bits are set */
 | 
						|
 	wmb();
 | 
						|
@@ -1788,7 +1788,7 @@ altr_edac_a10_device_trig2(struct file *file, const char __user *user_buf,
 | 
						|
 
 | 
						|
 	local_irq_save(flags);
 | 
						|
 	if (trig_type == ALTR_UE_TRIGGER_CHAR) {
 | 
						|
-		writel(priv->ue_set_mask, set_addr);
 | 
						|
+		writew(priv->ue_set_mask, set_addr);
 | 
						|
 	} else {
 | 
						|
 		/* Setup read/write of 4 bytes */
 | 
						|
 		writel(ECC_WORD_WRITE, drvdata->base + ECC_BLK_DBYTECTRL_OFST);
 | 
						|
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
 | 
						|
index 9cd86390a16747..10119cf27ffde5 100644
 | 
						|
--- a/drivers/edac/amd64_edac.c
 | 
						|
+++ b/drivers/edac/amd64_edac.c
 | 
						|
@@ -4130,6 +4130,7 @@ static int per_family_init(struct amd64_pvt *pvt)
 | 
						|
 			break;
 | 
						|
 		case 0x70 ... 0x7f:
 | 
						|
 			pvt->ctl_name			= "F19h_M70h";
 | 
						|
+			pvt->max_mcs			= 4;
 | 
						|
 			pvt->flags.zn_regs_v2		= 1;
 | 
						|
 			break;
 | 
						|
 		case 0xa0 ... 0xaf:
 | 
						|
diff --git a/drivers/gpio/gpio-mlxbf3.c b/drivers/gpio/gpio-mlxbf3.c
 | 
						|
index 10ea71273c8915..9875e34bde72a4 100644
 | 
						|
--- a/drivers/gpio/gpio-mlxbf3.c
 | 
						|
+++ b/drivers/gpio/gpio-mlxbf3.c
 | 
						|
@@ -190,7 +190,9 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev)
 | 
						|
 	struct mlxbf3_gpio_context *gs;
 | 
						|
 	struct gpio_irq_chip *girq;
 | 
						|
 	struct gpio_chip *gc;
 | 
						|
+	char *colon_ptr;
 | 
						|
 	int ret, irq;
 | 
						|
+	long num;
 | 
						|
 
 | 
						|
 	gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL);
 | 
						|
 	if (!gs)
 | 
						|
@@ -227,25 +229,39 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev)
 | 
						|
 	gc->owner = THIS_MODULE;
 | 
						|
 	gc->add_pin_ranges = mlxbf3_gpio_add_pin_ranges;
 | 
						|
 
 | 
						|
-	irq = platform_get_irq(pdev, 0);
 | 
						|
-	if (irq >= 0) {
 | 
						|
-		girq = &gs->gc.irq;
 | 
						|
-		gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip);
 | 
						|
-		girq->default_type = IRQ_TYPE_NONE;
 | 
						|
-		/* This will let us handle the parent IRQ in the driver */
 | 
						|
-		girq->num_parents = 0;
 | 
						|
-		girq->parents = NULL;
 | 
						|
-		girq->parent_handler = NULL;
 | 
						|
-		girq->handler = handle_bad_irq;
 | 
						|
-
 | 
						|
-		/*
 | 
						|
-		 * Directly request the irq here instead of passing
 | 
						|
-		 * a flow-handler because the irq is shared.
 | 
						|
-		 */
 | 
						|
-		ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler,
 | 
						|
-				       IRQF_SHARED, dev_name(dev), gs);
 | 
						|
-		if (ret)
 | 
						|
-			return dev_err_probe(dev, ret, "failed to request IRQ");
 | 
						|
+	colon_ptr = strchr(dev_name(dev), ':');
 | 
						|
+	if (!colon_ptr) {
 | 
						|
+		dev_err(dev, "invalid device name format\n");
 | 
						|
+		return -EINVAL;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	ret = kstrtol(++colon_ptr, 16, &num);
 | 
						|
+	if (ret) {
 | 
						|
+		dev_err(dev, "invalid device instance\n");
 | 
						|
+		return ret;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (!num) {
 | 
						|
+		irq = platform_get_irq(pdev, 0);
 | 
						|
+		if (irq >= 0) {
 | 
						|
+			girq = &gs->gc.irq;
 | 
						|
+			gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip);
 | 
						|
+			girq->default_type = IRQ_TYPE_NONE;
 | 
						|
+			/* This will let us handle the parent IRQ in the driver */
 | 
						|
+			girq->num_parents = 0;
 | 
						|
+			girq->parents = NULL;
 | 
						|
+			girq->parent_handler = NULL;
 | 
						|
+			girq->handler = handle_bad_irq;
 | 
						|
+
 | 
						|
+			/*
 | 
						|
+			 * Directly request the irq here instead of passing
 | 
						|
+			 * a flow-handler because the irq is shared.
 | 
						|
+			 */
 | 
						|
+			ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler,
 | 
						|
+					       IRQF_SHARED, dev_name(dev), gs);
 | 
						|
+			if (ret)
 | 
						|
+				return dev_err_probe(dev, ret, "failed to request IRQ");
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	platform_set_drvdata(pdev, gs);
 | 
						|
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
 | 
						|
index a0a2a0f75bba46..c1e83b2926ae4d 100644
 | 
						|
--- a/drivers/gpio/gpiolib-of.c
 | 
						|
+++ b/drivers/gpio/gpiolib-of.c
 | 
						|
@@ -203,6 +203,15 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
 | 
						|
 		 */
 | 
						|
 		{ "lantiq,pci-xway",	"gpio-reset",	false },
 | 
						|
 #endif
 | 
						|
+#if IS_ENABLED(CONFIG_REGULATOR_S5M8767)
 | 
						|
+		/*
 | 
						|
+		 * According to S5M8767, the DVS and DS pin are
 | 
						|
+		 * active-high signals. However, exynos5250-spring.dts use
 | 
						|
+		 * active-low setting.
 | 
						|
+		 */
 | 
						|
+		{ "samsung,s5m8767-pmic", "s5m8767,pmic-buck-dvs-gpios", true },
 | 
						|
+		{ "samsung,s5m8767-pmic", "s5m8767,pmic-buck-ds-gpios", true },
 | 
						|
+#endif
 | 
						|
 #if IS_ENABLED(CONFIG_TOUCHSCREEN_TSC2005)
 | 
						|
 		/*
 | 
						|
 		 * DTS for Nokia N900 incorrectly specified "active high"
 | 
						|
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
 | 
						|
index 7b1076b5e748c5..33ab82c334a881 100644
 | 
						|
--- a/drivers/gpu/drm/i915/i915_pmu.c
 | 
						|
+++ b/drivers/gpu/drm/i915/i915_pmu.c
 | 
						|
@@ -105,7 +105,7 @@ static u32 config_mask(const u64 config)
 | 
						|
 {
 | 
						|
 	unsigned int bit = config_bit(config);
 | 
						|
 
 | 
						|
-	if (__builtin_constant_p(config))
 | 
						|
+	if (__builtin_constant_p(bit))
 | 
						|
 		BUILD_BUG_ON(bit >
 | 
						|
 			     BITS_PER_TYPE(typeof_member(struct i915_pmu,
 | 
						|
 							 enable)) - 1);
 | 
						|
@@ -114,7 +114,7 @@ static u32 config_mask(const u64 config)
 | 
						|
 			     BITS_PER_TYPE(typeof_member(struct i915_pmu,
 | 
						|
 							 enable)) - 1);
 | 
						|
 
 | 
						|
-	return BIT(config_bit(config));
 | 
						|
+	return BIT(bit);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static bool is_engine_event(struct perf_event *event)
 | 
						|
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
 | 
						|
index 20c8b9af7a2199..2cda9bbf68f965 100644
 | 
						|
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
 | 
						|
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
 | 
						|
@@ -93,17 +93,21 @@ static void drm_mode_to_intf_timing_params(
 | 
						|
 		timing->vsync_polarity = 0;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	/* for DP/EDP, Shift timings to align it to bottom right */
 | 
						|
-	if (phys_enc->hw_intf->cap->type == INTF_DP) {
 | 
						|
+	timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
 | 
						|
+	timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 *  For DP/EDP, Shift timings to align it to bottom right.
 | 
						|
+	 *  wide_bus_en is set for everything excluding SDM845 &
 | 
						|
+	 *  porch changes cause DisplayPort failure and HDMI tearing.
 | 
						|
+	 */
 | 
						|
+	if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) {
 | 
						|
 		timing->h_back_porch += timing->h_front_porch;
 | 
						|
 		timing->h_front_porch = 0;
 | 
						|
 		timing->v_back_porch += timing->v_front_porch;
 | 
						|
 		timing->v_front_porch = 0;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
 | 
						|
-	timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent);
 | 
						|
-
 | 
						|
 	/*
 | 
						|
 	 * for DP, divide the horizonal parameters by 2 when
 | 
						|
 	 * widebus is enabled
 | 
						|
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
 | 
						|
index 27b592c776a300..1c111969342a77 100644
 | 
						|
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
 | 
						|
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
 | 
						|
@@ -716,6 +716,13 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy)
 | 
						|
 	/* TODO: Remove this when we have proper display handover support */
 | 
						|
 	msm_dsi_phy_pll_save_state(phy);
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * Store also proper vco_current_rate, because its value will be used in
 | 
						|
+	 * dsi_10nm_pll_restore_state().
 | 
						|
+	 */
 | 
						|
+	if (!dsi_pll_10nm_vco_recalc_rate(&pll_10nm->clk_hw, VCO_REF_CLK_RATE))
 | 
						|
+		pll_10nm->vco_current_rate = pll_10nm->phy->cfg->min_pll_rate;
 | 
						|
+
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
 | 
						|
index 91b5ecc5753808..4e6f305c9e504d 100644
 | 
						|
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
 | 
						|
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
 | 
						|
@@ -42,7 +42,7 @@
 | 
						|
 #include "nouveau_acpi.h"
 | 
						|
 
 | 
						|
 static struct ida bl_ida;
 | 
						|
-#define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0'
 | 
						|
+#define BL_NAME_SIZE 24 // 12 for name + 11 for digits + 1 for '\0'
 | 
						|
 
 | 
						|
 static bool
 | 
						|
 nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE],
 | 
						|
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
 | 
						|
index f001ae880e1dbe..27306c17b0c4e4 100644
 | 
						|
--- a/drivers/hv/connection.c
 | 
						|
+++ b/drivers/hv/connection.c
 | 
						|
@@ -206,11 +206,20 @@ int vmbus_connect(void)
 | 
						|
 	INIT_LIST_HEAD(&vmbus_connection.chn_list);
 | 
						|
 	mutex_init(&vmbus_connection.channel_mutex);
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * The following Hyper-V interrupt and monitor pages can be used by
 | 
						|
+	 * UIO for mapping to user-space, so they should always be allocated on
 | 
						|
+	 * system page boundaries. The system page size must be >= the Hyper-V
 | 
						|
+	 * page size.
 | 
						|
+	 */
 | 
						|
+	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
 | 
						|
+
 | 
						|
 	/*
 | 
						|
 	 * Setup the vmbus event connection for channel interrupt
 | 
						|
 	 * abstraction stuff
 | 
						|
 	 */
 | 
						|
-	vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page();
 | 
						|
+	vmbus_connection.int_page =
 | 
						|
+		(void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 | 
						|
 	if (vmbus_connection.int_page == NULL) {
 | 
						|
 		ret = -ENOMEM;
 | 
						|
 		goto cleanup;
 | 
						|
@@ -225,8 +234,8 @@ int vmbus_connect(void)
 | 
						|
 	 * Setup the monitor notification facility. The 1st page for
 | 
						|
 	 * parent->child and the 2nd page for child->parent
 | 
						|
 	 */
 | 
						|
-	vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page();
 | 
						|
-	vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page();
 | 
						|
+	vmbus_connection.monitor_pages[0] = (void *)__get_free_page(GFP_KERNEL);
 | 
						|
+	vmbus_connection.monitor_pages[1] = (void *)__get_free_page(GFP_KERNEL);
 | 
						|
 	if ((vmbus_connection.monitor_pages[0] == NULL) ||
 | 
						|
 	    (vmbus_connection.monitor_pages[1] == NULL)) {
 | 
						|
 		ret = -ENOMEM;
 | 
						|
@@ -342,21 +351,23 @@ void vmbus_disconnect(void)
 | 
						|
 		destroy_workqueue(vmbus_connection.work_queue);
 | 
						|
 
 | 
						|
 	if (vmbus_connection.int_page) {
 | 
						|
-		hv_free_hyperv_page(vmbus_connection.int_page);
 | 
						|
+		free_page((unsigned long)vmbus_connection.int_page);
 | 
						|
 		vmbus_connection.int_page = NULL;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (vmbus_connection.monitor_pages[0]) {
 | 
						|
 		if (!set_memory_encrypted(
 | 
						|
 			(unsigned long)vmbus_connection.monitor_pages[0], 1))
 | 
						|
-			hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
 | 
						|
+			free_page((unsigned long)
 | 
						|
+				vmbus_connection.monitor_pages[0]);
 | 
						|
 		vmbus_connection.monitor_pages[0] = NULL;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (vmbus_connection.monitor_pages[1]) {
 | 
						|
 		if (!set_memory_encrypted(
 | 
						|
 			(unsigned long)vmbus_connection.monitor_pages[1], 1))
 | 
						|
-			hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
 | 
						|
+			free_page((unsigned long)
 | 
						|
+				vmbus_connection.monitor_pages[1]);
 | 
						|
 		vmbus_connection.monitor_pages[1] = NULL;
 | 
						|
 	}
 | 
						|
 }
 | 
						|
diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c
 | 
						|
index b74a2665e73321..27e5dd94b04f2c 100644
 | 
						|
--- a/drivers/hwmon/ftsteutates.c
 | 
						|
+++ b/drivers/hwmon/ftsteutates.c
 | 
						|
@@ -423,13 +423,16 @@ static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 | 
						|
 		break;
 | 
						|
 	case hwmon_pwm:
 | 
						|
 		switch (attr) {
 | 
						|
-		case hwmon_pwm_auto_channels_temp:
 | 
						|
-			if (data->fan_source[channel] == FTS_FAN_SOURCE_INVALID)
 | 
						|
+		case hwmon_pwm_auto_channels_temp: {
 | 
						|
+			u8 fan_source = data->fan_source[channel];
 | 
						|
+
 | 
						|
+			if (fan_source == FTS_FAN_SOURCE_INVALID || fan_source >= BITS_PER_LONG)
 | 
						|
 				*val = 0;
 | 
						|
 			else
 | 
						|
-				*val = BIT(data->fan_source[channel]);
 | 
						|
+				*val = BIT(fan_source);
 | 
						|
 
 | 
						|
 			return 0;
 | 
						|
+		}
 | 
						|
 		default:
 | 
						|
 			break;
 | 
						|
 		}
 | 
						|
diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c
 | 
						|
index dd690f700d4990..483f79b394298f 100644
 | 
						|
--- a/drivers/hwmon/occ/common.c
 | 
						|
+++ b/drivers/hwmon/occ/common.c
 | 
						|
@@ -459,12 +459,10 @@ static ssize_t occ_show_power_1(struct device *dev,
 | 
						|
 	return sysfs_emit(buf, "%llu\n", val);
 | 
						|
 }
 | 
						|
 
 | 
						|
-static u64 occ_get_powr_avg(u64 *accum, u32 *samples)
 | 
						|
+static u64 occ_get_powr_avg(u64 accum, u32 samples)
 | 
						|
 {
 | 
						|
-	u64 divisor = get_unaligned_be32(samples);
 | 
						|
-
 | 
						|
-	return (divisor == 0) ? 0 :
 | 
						|
-		div64_u64(get_unaligned_be64(accum) * 1000000ULL, divisor);
 | 
						|
+	return (samples == 0) ? 0 :
 | 
						|
+		mul_u64_u32_div(accum, 1000000UL, samples);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static ssize_t occ_show_power_2(struct device *dev,
 | 
						|
@@ -489,8 +487,8 @@ static ssize_t occ_show_power_2(struct device *dev,
 | 
						|
 				  get_unaligned_be32(&power->sensor_id),
 | 
						|
 				  power->function_id, power->apss_channel);
 | 
						|
 	case 1:
 | 
						|
-		val = occ_get_powr_avg(&power->accumulator,
 | 
						|
-				       &power->update_tag);
 | 
						|
+		val = occ_get_powr_avg(get_unaligned_be64(&power->accumulator),
 | 
						|
+				       get_unaligned_be32(&power->update_tag));
 | 
						|
 		break;
 | 
						|
 	case 2:
 | 
						|
 		val = (u64)get_unaligned_be32(&power->update_tag) *
 | 
						|
@@ -527,8 +525,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
 | 
						|
 		return sysfs_emit(buf, "%u_system\n",
 | 
						|
 				  get_unaligned_be32(&power->sensor_id));
 | 
						|
 	case 1:
 | 
						|
-		val = occ_get_powr_avg(&power->system.accumulator,
 | 
						|
-				       &power->system.update_tag);
 | 
						|
+		val = occ_get_powr_avg(get_unaligned_be64(&power->system.accumulator),
 | 
						|
+				       get_unaligned_be32(&power->system.update_tag));
 | 
						|
 		break;
 | 
						|
 	case 2:
 | 
						|
 		val = (u64)get_unaligned_be32(&power->system.update_tag) *
 | 
						|
@@ -541,8 +539,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
 | 
						|
 		return sysfs_emit(buf, "%u_proc\n",
 | 
						|
 				  get_unaligned_be32(&power->sensor_id));
 | 
						|
 	case 5:
 | 
						|
-		val = occ_get_powr_avg(&power->proc.accumulator,
 | 
						|
-				       &power->proc.update_tag);
 | 
						|
+		val = occ_get_powr_avg(get_unaligned_be64(&power->proc.accumulator),
 | 
						|
+				       get_unaligned_be32(&power->proc.update_tag));
 | 
						|
 		break;
 | 
						|
 	case 6:
 | 
						|
 		val = (u64)get_unaligned_be32(&power->proc.update_tag) *
 | 
						|
@@ -555,8 +553,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
 | 
						|
 		return sysfs_emit(buf, "%u_vdd\n",
 | 
						|
 				  get_unaligned_be32(&power->sensor_id));
 | 
						|
 	case 9:
 | 
						|
-		val = occ_get_powr_avg(&power->vdd.accumulator,
 | 
						|
-				       &power->vdd.update_tag);
 | 
						|
+		val = occ_get_powr_avg(get_unaligned_be64(&power->vdd.accumulator),
 | 
						|
+				       get_unaligned_be32(&power->vdd.update_tag));
 | 
						|
 		break;
 | 
						|
 	case 10:
 | 
						|
 		val = (u64)get_unaligned_be32(&power->vdd.update_tag) *
 | 
						|
@@ -569,8 +567,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
 | 
						|
 		return sysfs_emit(buf, "%u_vdn\n",
 | 
						|
 				  get_unaligned_be32(&power->sensor_id));
 | 
						|
 	case 13:
 | 
						|
-		val = occ_get_powr_avg(&power->vdn.accumulator,
 | 
						|
-				       &power->vdn.update_tag);
 | 
						|
+		val = occ_get_powr_avg(get_unaligned_be64(&power->vdn.accumulator),
 | 
						|
+				       get_unaligned_be32(&power->vdn.update_tag));
 | 
						|
 		break;
 | 
						|
 	case 14:
 | 
						|
 		val = (u64)get_unaligned_be32(&power->vdn.update_tag) *
 | 
						|
@@ -747,29 +745,30 @@ static ssize_t occ_show_extended(struct device *dev,
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
- * Some helper macros to make it easier to define an occ_attribute. Since these
 | 
						|
- * are dynamically allocated, we shouldn't use the existing kernel macros which
 | 
						|
+ * A helper to make it easier to define an occ_attribute. Since these
 | 
						|
+ * are dynamically allocated, we cannot use the existing kernel macros which
 | 
						|
  * stringify the name argument.
 | 
						|
  */
 | 
						|
-#define ATTR_OCC(_name, _mode, _show, _store) {				\
 | 
						|
-	.attr	= {							\
 | 
						|
-		.name = _name,						\
 | 
						|
-		.mode = VERIFY_OCTAL_PERMISSIONS(_mode),		\
 | 
						|
-	},								\
 | 
						|
-	.show	= _show,						\
 | 
						|
-	.store	= _store,						\
 | 
						|
-}
 | 
						|
-
 | 
						|
-#define SENSOR_ATTR_OCC(_name, _mode, _show, _store, _nr, _index) {	\
 | 
						|
-	.dev_attr	= ATTR_OCC(_name, _mode, _show, _store),	\
 | 
						|
-	.index		= _index,					\
 | 
						|
-	.nr		= _nr,						\
 | 
						|
+static void occ_init_attribute(struct occ_attribute *attr, int mode,
 | 
						|
+	ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf),
 | 
						|
+	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
 | 
						|
+				   const char *buf, size_t count),
 | 
						|
+	int nr, int index, const char *fmt, ...)
 | 
						|
+{
 | 
						|
+	va_list args;
 | 
						|
+
 | 
						|
+	va_start(args, fmt);
 | 
						|
+	vsnprintf(attr->name, sizeof(attr->name), fmt, args);
 | 
						|
+	va_end(args);
 | 
						|
+
 | 
						|
+	attr->sensor.dev_attr.attr.name = attr->name;
 | 
						|
+	attr->sensor.dev_attr.attr.mode = mode;
 | 
						|
+	attr->sensor.dev_attr.show = show;
 | 
						|
+	attr->sensor.dev_attr.store = store;
 | 
						|
+	attr->sensor.index = index;
 | 
						|
+	attr->sensor.nr = nr;
 | 
						|
 }
 | 
						|
 
 | 
						|
-#define OCC_INIT_ATTR(_name, _mode, _show, _store, _nr, _index)		\
 | 
						|
-	((struct sensor_device_attribute_2)				\
 | 
						|
-		SENSOR_ATTR_OCC(_name, _mode, _show, _store, _nr, _index))
 | 
						|
-
 | 
						|
 /*
 | 
						|
  * Allocate and instatiate sensor_device_attribute_2s. It's most efficient to
 | 
						|
  * use our own instead of the built-in hwmon attribute types.
 | 
						|
@@ -855,14 +854,15 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 		sensors->extended.num_sensors = 0;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	occ->attrs = devm_kzalloc(dev, sizeof(*occ->attrs) * num_attrs,
 | 
						|
+	occ->attrs = devm_kcalloc(dev, num_attrs, sizeof(*occ->attrs),
 | 
						|
 				  GFP_KERNEL);
 | 
						|
 	if (!occ->attrs)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
 	/* null-terminated list */
 | 
						|
-	occ->group.attrs = devm_kzalloc(dev, sizeof(*occ->group.attrs) *
 | 
						|
-					num_attrs + 1, GFP_KERNEL);
 | 
						|
+	occ->group.attrs = devm_kcalloc(dev, num_attrs + 1,
 | 
						|
+					sizeof(*occ->group.attrs),
 | 
						|
+					GFP_KERNEL);
 | 
						|
 	if (!occ->group.attrs)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
@@ -872,43 +872,33 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 		s = i + 1;
 | 
						|
 		temp = ((struct temp_sensor_2 *)sensors->temp.data) + i;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "temp%d_label", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL,
 | 
						|
-					     0, i);
 | 
						|
+		occ_init_attribute(attr, 0444, show_temp, NULL,
 | 
						|
+				   0, i, "temp%d_label", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
 		if (sensors->temp.version == 2 &&
 | 
						|
 		    temp->fru_type == OCC_FRU_TYPE_VRM) {
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "temp%d_alarm", s);
 | 
						|
+			occ_init_attribute(attr, 0444, show_temp, NULL,
 | 
						|
+					   1, i, "temp%d_alarm", s);
 | 
						|
 		} else {
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "temp%d_input", s);
 | 
						|
+			occ_init_attribute(attr, 0444, show_temp, NULL,
 | 
						|
+					   1, i, "temp%d_input", s);
 | 
						|
 		}
 | 
						|
 
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL,
 | 
						|
-					     1, i);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
 		if (sensors->temp.version > 1) {
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "temp%d_fru_type", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_temp, NULL, 2, i);
 | 
						|
+			occ_init_attribute(attr, 0444, show_temp, NULL,
 | 
						|
+					   2, i, "temp%d_fru_type", s);
 | 
						|
 			attr++;
 | 
						|
 
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "temp%d_fault", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_temp, NULL, 3, i);
 | 
						|
+			occ_init_attribute(attr, 0444, show_temp, NULL,
 | 
						|
+					   3, i, "temp%d_fault", s);
 | 
						|
 			attr++;
 | 
						|
 
 | 
						|
 			if (sensors->temp.version == 0x10) {
 | 
						|
-				snprintf(attr->name, sizeof(attr->name),
 | 
						|
-					 "temp%d_max", s);
 | 
						|
-				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-							     show_temp, NULL,
 | 
						|
-							     4, i);
 | 
						|
+				occ_init_attribute(attr, 0444, show_temp, NULL,
 | 
						|
+						   4, i, "temp%d_max", s);
 | 
						|
 				attr++;
 | 
						|
 			}
 | 
						|
 		}
 | 
						|
@@ -917,14 +907,12 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 	for (i = 0; i < sensors->freq.num_sensors; ++i) {
 | 
						|
 		s = i + 1;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "freq%d_label", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL,
 | 
						|
-					     0, i);
 | 
						|
+		occ_init_attribute(attr, 0444, show_freq, NULL,
 | 
						|
+				   0, i, "freq%d_label", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "freq%d_input", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL,
 | 
						|
-					     1, i);
 | 
						|
+		occ_init_attribute(attr, 0444, show_freq, NULL,
 | 
						|
+				   1, i, "freq%d_input", s);
 | 
						|
 		attr++;
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -940,32 +928,24 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 			s = (i * 4) + 1;
 | 
						|
 
 | 
						|
 			for (j = 0; j < 4; ++j) {
 | 
						|
-				snprintf(attr->name, sizeof(attr->name),
 | 
						|
-					 "power%d_label", s);
 | 
						|
-				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-							     show_power, NULL,
 | 
						|
-							     nr++, i);
 | 
						|
+				occ_init_attribute(attr, 0444, show_power,
 | 
						|
+						   NULL, nr++, i,
 | 
						|
+						   "power%d_label", s);
 | 
						|
 				attr++;
 | 
						|
 
 | 
						|
-				snprintf(attr->name, sizeof(attr->name),
 | 
						|
-					 "power%d_average", s);
 | 
						|
-				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-							     show_power, NULL,
 | 
						|
-							     nr++, i);
 | 
						|
+				occ_init_attribute(attr, 0444, show_power,
 | 
						|
+						   NULL, nr++, i,
 | 
						|
+						   "power%d_average", s);
 | 
						|
 				attr++;
 | 
						|
 
 | 
						|
-				snprintf(attr->name, sizeof(attr->name),
 | 
						|
-					 "power%d_average_interval", s);
 | 
						|
-				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-							     show_power, NULL,
 | 
						|
-							     nr++, i);
 | 
						|
+				occ_init_attribute(attr, 0444, show_power,
 | 
						|
+						   NULL, nr++, i,
 | 
						|
+						   "power%d_average_interval", s);
 | 
						|
 				attr++;
 | 
						|
 
 | 
						|
-				snprintf(attr->name, sizeof(attr->name),
 | 
						|
-					 "power%d_input", s);
 | 
						|
-				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-							     show_power, NULL,
 | 
						|
-							     nr++, i);
 | 
						|
+				occ_init_attribute(attr, 0444, show_power,
 | 
						|
+						   NULL, nr++, i,
 | 
						|
+						   "power%d_input", s);
 | 
						|
 				attr++;
 | 
						|
 
 | 
						|
 				s++;
 | 
						|
@@ -977,28 +957,20 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 		for (i = 0; i < sensors->power.num_sensors; ++i) {
 | 
						|
 			s = i + 1;
 | 
						|
 
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "power%d_label", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_power, NULL, 0, i);
 | 
						|
+			occ_init_attribute(attr, 0444, show_power, NULL,
 | 
						|
+					   0, i, "power%d_label", s);
 | 
						|
 			attr++;
 | 
						|
 
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "power%d_average", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_power, NULL, 1, i);
 | 
						|
+			occ_init_attribute(attr, 0444, show_power, NULL,
 | 
						|
+					   1, i, "power%d_average", s);
 | 
						|
 			attr++;
 | 
						|
 
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "power%d_average_interval", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_power, NULL, 2, i);
 | 
						|
+			occ_init_attribute(attr, 0444, show_power, NULL,
 | 
						|
+					   2, i, "power%d_average_interval", s);
 | 
						|
 			attr++;
 | 
						|
 
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "power%d_input", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_power, NULL, 3, i);
 | 
						|
+			occ_init_attribute(attr, 0444, show_power, NULL,
 | 
						|
+					   3, i, "power%d_input", s);
 | 
						|
 			attr++;
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -1006,56 +978,43 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (sensors->caps.num_sensors >= 1) {
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "power%d_label", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
 | 
						|
-					     0, 0);
 | 
						|
+		occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+				   0, 0, "power%d_label", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "power%d_cap", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
 | 
						|
-					     1, 0);
 | 
						|
+		occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+				   1, 0, "power%d_cap", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "power%d_input", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
 | 
						|
-					     2, 0);
 | 
						|
+		occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+				   2, 0, "power%d_input", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name),
 | 
						|
-			 "power%d_cap_not_redundant", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
 | 
						|
-					     3, 0);
 | 
						|
+		occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+				   3, 0, "power%d_cap_not_redundant", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "power%d_cap_max", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
 | 
						|
-					     4, 0);
 | 
						|
+		occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+				   4, 0, "power%d_cap_max", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "power%d_cap_min", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
 | 
						|
-					     5, 0);
 | 
						|
+		occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+				   5, 0, "power%d_cap_min", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "power%d_cap_user",
 | 
						|
-			 s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0644, show_caps,
 | 
						|
-					     occ_store_caps_user, 6, 0);
 | 
						|
+		occ_init_attribute(attr, 0644, show_caps, occ_store_caps_user,
 | 
						|
+				   6, 0, "power%d_cap_user", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
 		if (sensors->caps.version > 1) {
 | 
						|
-			snprintf(attr->name, sizeof(attr->name),
 | 
						|
-				 "power%d_cap_user_source", s);
 | 
						|
-			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-						     show_caps, NULL, 7, 0);
 | 
						|
+			occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+					   7, 0, "power%d_cap_user_source", s);
 | 
						|
 			attr++;
 | 
						|
 
 | 
						|
 			if (sensors->caps.version > 2) {
 | 
						|
-				snprintf(attr->name, sizeof(attr->name),
 | 
						|
-					 "power%d_cap_min_soft", s);
 | 
						|
-				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-							     show_caps, NULL,
 | 
						|
-							     8, 0);
 | 
						|
+				occ_init_attribute(attr, 0444, show_caps, NULL,
 | 
						|
+						   8, 0,
 | 
						|
+						   "power%d_cap_min_soft", s);
 | 
						|
 				attr++;
 | 
						|
 			}
 | 
						|
 		}
 | 
						|
@@ -1064,19 +1023,16 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
						|
 	for (i = 0; i < sensors->extended.num_sensors; ++i) {
 | 
						|
 		s = i + 1;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "extn%d_label", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-					     occ_show_extended, NULL, 0, i);
 | 
						|
+		occ_init_attribute(attr, 0444, occ_show_extended, NULL,
 | 
						|
+				   0, i, "extn%d_label", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "extn%d_flags", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-					     occ_show_extended, NULL, 1, i);
 | 
						|
+		occ_init_attribute(attr, 0444, occ_show_extended, NULL,
 | 
						|
+				   1, i, "extn%d_flags", s);
 | 
						|
 		attr++;
 | 
						|
 
 | 
						|
-		snprintf(attr->name, sizeof(attr->name), "extn%d_input", s);
 | 
						|
-		attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
						|
-					     occ_show_extended, NULL, 2, i);
 | 
						|
+		occ_init_attribute(attr, 0444, occ_show_extended, NULL,
 | 
						|
+				   2, i, "extn%d_input", s);
 | 
						|
 		attr++;
 | 
						|
 	}
 | 
						|
 
 | 
						|
diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c
 | 
						|
index 345b532a2b455d..ea4c4955fe2646 100644
 | 
						|
--- a/drivers/i2c/busses/i2c-designware-slave.c
 | 
						|
+++ b/drivers/i2c/busses/i2c-designware-slave.c
 | 
						|
@@ -91,7 +91,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave)
 | 
						|
 	i2c_dw_disable(dev);
 | 
						|
 	synchronize_irq(dev->irq);
 | 
						|
 	dev->slave = NULL;
 | 
						|
-	pm_runtime_put(dev->dev);
 | 
						|
+	pm_runtime_put_sync_suspend(dev->dev);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
 | 
						|
index 91f508d50e7ab4..5b3987460976e3 100644
 | 
						|
--- a/drivers/i2c/busses/i2c-npcm7xx.c
 | 
						|
+++ b/drivers/i2c/busses/i2c-npcm7xx.c
 | 
						|
@@ -1971,10 +1971,14 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode,
 | 
						|
 
 | 
						|
 	/* Check HW is OK: SDA and SCL should be high at this point. */
 | 
						|
 	if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) {
 | 
						|
-		dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num);
 | 
						|
-		dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap),
 | 
						|
-			npcm_i2c_get_SCL(&bus->adap));
 | 
						|
-		return -ENXIO;
 | 
						|
+		dev_warn(bus->dev, " I2C%d SDA=%d SCL=%d, attempting to recover\n", bus->num,
 | 
						|
+				 npcm_i2c_get_SDA(&bus->adap), npcm_i2c_get_SCL(&bus->adap));
 | 
						|
+		if (npcm_i2c_recovery_tgclk(&bus->adap)) {
 | 
						|
+			dev_err(bus->dev, "I2C%d init fail: SDA=%d SCL=%d\n",
 | 
						|
+				bus->num, npcm_i2c_get_SDA(&bus->adap),
 | 
						|
+				npcm_i2c_get_SCL(&bus->adap));
 | 
						|
+			return -ENXIO;
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	npcm_i2c_int_enable(bus, true);
 | 
						|
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
 | 
						|
index 91be04b534fe61..08a81daedc115e 100644
 | 
						|
--- a/drivers/i2c/busses/i2c-tegra.c
 | 
						|
+++ b/drivers/i2c/busses/i2c-tegra.c
 | 
						|
@@ -1397,6 +1397,11 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
 | 
						|
 			ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
 | 
						|
 			if (ret)
 | 
						|
 				break;
 | 
						|
+
 | 
						|
+			/* Validate message length before proceeding */
 | 
						|
+			if (msgs[i].buf[0] == 0 || msgs[i].buf[0] > I2C_SMBUS_BLOCK_MAX)
 | 
						|
+				break;
 | 
						|
+
 | 
						|
 			/* Set the msg length from first byte */
 | 
						|
 			msgs[i].len += msgs[i].buf[0];
 | 
						|
 			dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
 | 
						|
diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c
 | 
						|
index be8a15cb945fdf..17820b2c3a1dec 100644
 | 
						|
--- a/drivers/iio/accel/fxls8962af-core.c
 | 
						|
+++ b/drivers/iio/accel/fxls8962af-core.c
 | 
						|
@@ -20,6 +20,7 @@
 | 
						|
 #include <linux/pm_runtime.h>
 | 
						|
 #include <linux/regulator/consumer.h>
 | 
						|
 #include <linux/regmap.h>
 | 
						|
+#include <linux/units.h>
 | 
						|
 
 | 
						|
 #include <linux/iio/buffer.h>
 | 
						|
 #include <linux/iio/events.h>
 | 
						|
@@ -434,8 +435,16 @@ static int fxls8962af_read_raw(struct iio_dev *indio_dev,
 | 
						|
 		*val = FXLS8962AF_TEMP_CENTER_VAL;
 | 
						|
 		return IIO_VAL_INT;
 | 
						|
 	case IIO_CHAN_INFO_SCALE:
 | 
						|
-		*val = 0;
 | 
						|
-		return fxls8962af_read_full_scale(data, val2);
 | 
						|
+		switch (chan->type) {
 | 
						|
+		case IIO_TEMP:
 | 
						|
+			*val = MILLIDEGREE_PER_DEGREE;
 | 
						|
+			return IIO_VAL_INT;
 | 
						|
+		case IIO_ACCEL:
 | 
						|
+			*val = 0;
 | 
						|
+			return fxls8962af_read_full_scale(data, val2);
 | 
						|
+		default:
 | 
						|
+			return -EINVAL;
 | 
						|
+		}
 | 
						|
 	case IIO_CHAN_INFO_SAMP_FREQ:
 | 
						|
 		return fxls8962af_read_samp_freq(data, val, val2);
 | 
						|
 	default:
 | 
						|
@@ -734,9 +743,11 @@ static const struct iio_event_spec fxls8962af_event[] = {
 | 
						|
 	.type = IIO_TEMP, \
 | 
						|
 	.address = FXLS8962AF_TEMP_OUT, \
 | 
						|
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 | 
						|
+			      BIT(IIO_CHAN_INFO_SCALE) | \
 | 
						|
 			      BIT(IIO_CHAN_INFO_OFFSET),\
 | 
						|
 	.scan_index = -1, \
 | 
						|
 	.scan_type = { \
 | 
						|
+		.sign = 's', \
 | 
						|
 		.realbits = 8, \
 | 
						|
 		.storagebits = 8, \
 | 
						|
 	}, \
 | 
						|
diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c
 | 
						|
index 67c96572cecc40..df48464a115d03 100644
 | 
						|
--- a/drivers/iio/adc/ad7606_spi.c
 | 
						|
+++ b/drivers/iio/adc/ad7606_spi.c
 | 
						|
@@ -151,7 +151,7 @@ static int ad7606_spi_reg_write(struct ad7606_state *st,
 | 
						|
 	struct spi_device *spi = to_spi_device(st->dev);
 | 
						|
 
 | 
						|
 	st->d16[0] = cpu_to_be16((st->bops->rd_wr_cmd(addr, 1) << 8) |
 | 
						|
-				  (val & 0x1FF));
 | 
						|
+				  (val & 0xFF));
 | 
						|
 
 | 
						|
 	return spi_write(spi, &st->d16[0], sizeof(st->d16[0]));
 | 
						|
 }
 | 
						|
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
 | 
						|
index 213cce1c31110e..91f0f381082bda 100644
 | 
						|
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
 | 
						|
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
 | 
						|
@@ -67,16 +67,18 @@ int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev,
 | 
						|
 		return IIO_VAL_INT;
 | 
						|
 	/*
 | 
						|
 	 * T°C = (temp / 132.48) + 25
 | 
						|
-	 * Tm°C = 1000 * ((temp * 100 / 13248) + 25)
 | 
						|
+	 * Tm°C = 1000 * ((temp / 132.48) + 25)
 | 
						|
+	 * Tm°C = 7.548309 * temp + 25000
 | 
						|
+	 * Tm°C = (temp + 3312) * 7.548309
 | 
						|
 	 * scale: 100000 / 13248 ~= 7.548309
 | 
						|
-	 * offset: 25000
 | 
						|
+	 * offset: 3312
 | 
						|
 	 */
 | 
						|
 	case IIO_CHAN_INFO_SCALE:
 | 
						|
 		*val = 7;
 | 
						|
 		*val2 = 548309;
 | 
						|
 		return IIO_VAL_INT_PLUS_MICRO;
 | 
						|
 	case IIO_CHAN_INFO_OFFSET:
 | 
						|
-		*val = 25000;
 | 
						|
+		*val = 3312;
 | 
						|
 		return IIO_VAL_INT;
 | 
						|
 	default:
 | 
						|
 		return -EINVAL;
 | 
						|
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
 | 
						|
index 3e4941754b48d0..ce41f235af253c 100644
 | 
						|
--- a/drivers/infiniband/core/iwcm.c
 | 
						|
+++ b/drivers/infiniband/core/iwcm.c
 | 
						|
@@ -367,12 +367,9 @@ EXPORT_SYMBOL(iw_cm_disconnect);
 | 
						|
 /*
 | 
						|
  * CM_ID <-- DESTROYING
 | 
						|
  *
 | 
						|
- * Clean up all resources associated with the connection and release
 | 
						|
- * the initial reference taken by iw_create_cm_id.
 | 
						|
- *
 | 
						|
- * Returns true if and only if the last cm_id_priv reference has been dropped.
 | 
						|
+ * Clean up all resources associated with the connection.
 | 
						|
  */
 | 
						|
-static bool destroy_cm_id(struct iw_cm_id *cm_id)
 | 
						|
+static void destroy_cm_id(struct iw_cm_id *cm_id)
 | 
						|
 {
 | 
						|
 	struct iwcm_id_private *cm_id_priv;
 | 
						|
 	struct ib_qp *qp;
 | 
						|
@@ -441,20 +438,22 @@ static bool destroy_cm_id(struct iw_cm_id *cm_id)
 | 
						|
 		iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr);
 | 
						|
 		iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM);
 | 
						|
 	}
 | 
						|
-
 | 
						|
-	return iwcm_deref_id(cm_id_priv);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
- * This function is only called by the application thread and cannot
 | 
						|
- * be called by the event thread. The function will wait for all
 | 
						|
- * references to be released on the cm_id and then kfree the cm_id
 | 
						|
- * object.
 | 
						|
+ * Destroy cm_id. If the cm_id still has other references, wait for all
 | 
						|
+ * references to be released on the cm_id and then release the initial
 | 
						|
+ * reference taken by iw_create_cm_id.
 | 
						|
  */
 | 
						|
 void iw_destroy_cm_id(struct iw_cm_id *cm_id)
 | 
						|
 {
 | 
						|
-	if (!destroy_cm_id(cm_id))
 | 
						|
+	struct iwcm_id_private *cm_id_priv;
 | 
						|
+
 | 
						|
+	cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
 | 
						|
+	destroy_cm_id(cm_id);
 | 
						|
+	if (refcount_read(&cm_id_priv->refcount) > 1)
 | 
						|
 		flush_workqueue(iwcm_wq);
 | 
						|
+	iwcm_deref_id(cm_id_priv);
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL(iw_destroy_cm_id);
 | 
						|
 
 | 
						|
@@ -1037,8 +1036,10 @@ static void cm_work_handler(struct work_struct *_work)
 | 
						|
 
 | 
						|
 		if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
 | 
						|
 			ret = process_event(cm_id_priv, &levent);
 | 
						|
-			if (ret)
 | 
						|
-				WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id));
 | 
						|
+			if (ret) {
 | 
						|
+				destroy_cm_id(&cm_id_priv->id);
 | 
						|
+				WARN_ON_ONCE(iwcm_deref_id(cm_id_priv));
 | 
						|
+			}
 | 
						|
 		} else
 | 
						|
 			pr_debug("dropping event %d\n", levent.event);
 | 
						|
 		if (iwcm_deref_id(cm_id_priv))
 | 
						|
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
 | 
						|
index 2e7c2c046e675f..c5f4207fddce92 100644
 | 
						|
--- a/drivers/input/keyboard/gpio_keys.c
 | 
						|
+++ b/drivers/input/keyboard/gpio_keys.c
 | 
						|
@@ -455,6 +455,8 @@ static enum hrtimer_restart gpio_keys_irq_timer(struct hrtimer *t)
 | 
						|
 						      release_timer);
 | 
						|
 	struct input_dev *input = bdata->input;
 | 
						|
 
 | 
						|
+	guard(spinlock_irqsave)(&bdata->lock);
 | 
						|
+
 | 
						|
 	if (bdata->key_pressed) {
 | 
						|
 		input_report_key(input, *bdata->code, 0);
 | 
						|
 		input_sync(input);
 | 
						|
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
 | 
						|
index 180d90e46061e7..5cfe9b56978da0 100644
 | 
						|
--- a/drivers/input/misc/ims-pcu.c
 | 
						|
+++ b/drivers/input/misc/ims-pcu.c
 | 
						|
@@ -845,6 +845,12 @@ static int ims_pcu_flash_firmware(struct ims_pcu *pcu,
 | 
						|
 		addr = be32_to_cpu(rec->addr) / 2;
 | 
						|
 		len = be16_to_cpu(rec->len);
 | 
						|
 
 | 
						|
+		if (len > sizeof(pcu->cmd_buf) - 1 - sizeof(*fragment)) {
 | 
						|
+			dev_err(pcu->dev,
 | 
						|
+				"Invalid record length in firmware: %d\n", len);
 | 
						|
+			return -EINVAL;
 | 
						|
+		}
 | 
						|
+
 | 
						|
 		fragment = (void *)&pcu->cmd_buf[1];
 | 
						|
 		put_unaligned_le32(addr, &fragment->addr);
 | 
						|
 		fragment->len = len;
 | 
						|
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
 | 
						|
index e5dd84725c6e74..d715fd736426d1 100644
 | 
						|
--- a/drivers/input/misc/sparcspkr.c
 | 
						|
+++ b/drivers/input/misc/sparcspkr.c
 | 
						|
@@ -75,9 +75,14 @@ static int bbc_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
 | 
						|
 		return -1;
 | 
						|
 
 | 
						|
 	switch (code) {
 | 
						|
-		case SND_BELL: if (value) value = 1000;
 | 
						|
-		case SND_TONE: break;
 | 
						|
-		default: return -1;
 | 
						|
+	case SND_BELL:
 | 
						|
+		if (value)
 | 
						|
+			value = 1000;
 | 
						|
+		break;
 | 
						|
+	case SND_TONE:
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		return -1;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (value > 20 && value < 32767)
 | 
						|
@@ -113,9 +118,14 @@ static int grover_spkr_event(struct input_dev *dev, unsigned int type, unsigned
 | 
						|
 		return -1;
 | 
						|
 
 | 
						|
 	switch (code) {
 | 
						|
-		case SND_BELL: if (value) value = 1000;
 | 
						|
-		case SND_TONE: break;
 | 
						|
-		default: return -1;
 | 
						|
+	case SND_BELL:
 | 
						|
+		if (value)
 | 
						|
+			value = 1000;
 | 
						|
+		break;
 | 
						|
+	case SND_TONE:
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		return -1;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (value > 20 && value < 32767)
 | 
						|
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
 | 
						|
index 83c5d786686d07..a5d6d786dba523 100644
 | 
						|
--- a/drivers/iommu/amd/iommu.c
 | 
						|
+++ b/drivers/iommu/amd/iommu.c
 | 
						|
@@ -780,6 +780,14 @@ int amd_iommu_register_ga_log_notifier(int (*notifier)(u32))
 | 
						|
 {
 | 
						|
 	iommu_ga_log_notifier = notifier;
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * Ensure all in-flight IRQ handlers run to completion before returning
 | 
						|
+	 * to the caller, e.g. to ensure module code isn't unloaded while it's
 | 
						|
+	 * being executed in the IRQ handler.
 | 
						|
+	 */
 | 
						|
+	if (!notifier)
 | 
						|
+		synchronize_rcu();
 | 
						|
+
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL(amd_iommu_register_ga_log_notifier);
 | 
						|
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
 | 
						|
index 9511dae5b556a9..94b6c43dfa5cbd 100644
 | 
						|
--- a/drivers/md/dm-raid1.c
 | 
						|
+++ b/drivers/md/dm-raid1.c
 | 
						|
@@ -133,10 +133,9 @@ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
 | 
						|
 	spin_lock_irqsave(&ms->lock, flags);
 | 
						|
 	should_wake = !(bl->head);
 | 
						|
 	bio_list_add(bl, bio);
 | 
						|
-	spin_unlock_irqrestore(&ms->lock, flags);
 | 
						|
-
 | 
						|
 	if (should_wake)
 | 
						|
 		wakeup_mirrord(ms);
 | 
						|
+	spin_unlock_irqrestore(&ms->lock, flags);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void dispatch_bios(void *context, struct bio_list *bio_list)
 | 
						|
@@ -646,9 +645,9 @@ static void write_callback(unsigned long error, void *context)
 | 
						|
 	if (!ms->failures.head)
 | 
						|
 		should_wake = 1;
 | 
						|
 	bio_list_add(&ms->failures, bio);
 | 
						|
-	spin_unlock_irqrestore(&ms->lock, flags);
 | 
						|
 	if (should_wake)
 | 
						|
 		wakeup_mirrord(ms);
 | 
						|
+	spin_unlock_irqrestore(&ms->lock, flags);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void do_write(struct mirror_set *ms, struct bio *bio)
 | 
						|
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
 | 
						|
index 6a7a17c489c998..8007e2e2197295 100644
 | 
						|
--- a/drivers/md/dm-verity-fec.c
 | 
						|
+++ b/drivers/md/dm-verity-fec.c
 | 
						|
@@ -624,6 +624,10 @@ int verity_fec_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
 | 
						|
 	(*argc)--;
 | 
						|
 
 | 
						|
 	if (!strcasecmp(arg_name, DM_VERITY_OPT_FEC_DEV)) {
 | 
						|
+		if (v->fec->dev) {
 | 
						|
+			ti->error = "FEC device already specified";
 | 
						|
+			return -EINVAL;
 | 
						|
+		}
 | 
						|
 		r = dm_get_device(ti, arg_value, BLK_OPEN_READ, &v->fec->dev);
 | 
						|
 		if (r) {
 | 
						|
 			ti->error = "FEC device lookup failed";
 | 
						|
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
 | 
						|
index 6ae97da741bba3..60e74c0e02f1ab 100644
 | 
						|
--- a/drivers/md/dm-verity-target.c
 | 
						|
+++ b/drivers/md/dm-verity-target.c
 | 
						|
@@ -1043,6 +1043,9 @@ static int verity_alloc_most_once(struct dm_verity *v)
 | 
						|
 {
 | 
						|
 	struct dm_target *ti = v->ti;
 | 
						|
 
 | 
						|
+	if (v->validated_blocks)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
 	/* the bitset can only handle INT_MAX blocks */
 | 
						|
 	if (v->data_blocks > INT_MAX) {
 | 
						|
 		ti->error = "device too large to use check_at_most_once";
 | 
						|
@@ -1066,6 +1069,9 @@ static int verity_alloc_zero_digest(struct dm_verity *v)
 | 
						|
 	struct ahash_request *req;
 | 
						|
 	u8 *zero_data;
 | 
						|
 
 | 
						|
+	if (v->zero_digest)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
 	v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL);
 | 
						|
 
 | 
						|
 	if (!v->zero_digest)
 | 
						|
@@ -1405,7 +1411,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 | 
						|
 			goto bad;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	/* Root hash signature is  a optional parameter*/
 | 
						|
+	/* Root hash signature is an optional parameter */
 | 
						|
 	r = verity_verify_root_hash(root_hash_digest_to_validate,
 | 
						|
 				    strlen(root_hash_digest_to_validate),
 | 
						|
 				    verify_args.sig,
 | 
						|
diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
 | 
						|
index 4836508ea50c07..1ced2ef255f325 100644
 | 
						|
--- a/drivers/md/dm-verity-verify-sig.c
 | 
						|
+++ b/drivers/md/dm-verity-verify-sig.c
 | 
						|
@@ -71,9 +71,14 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
 | 
						|
 				     const char *arg_name)
 | 
						|
 {
 | 
						|
 	struct dm_target *ti = v->ti;
 | 
						|
-	int ret = 0;
 | 
						|
+	int ret;
 | 
						|
 	const char *sig_key = NULL;
 | 
						|
 
 | 
						|
+	if (v->signature_key_desc) {
 | 
						|
+		ti->error = DM_VERITY_VERIFY_ERR("root_hash_sig_key_desc already specified");
 | 
						|
+		return -EINVAL;
 | 
						|
+	}
 | 
						|
+
 | 
						|
 	if (!*argc) {
 | 
						|
 		ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified");
 | 
						|
 		return -EINVAL;
 | 
						|
@@ -83,14 +88,18 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
 | 
						|
 	(*argc)--;
 | 
						|
 
 | 
						|
 	ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
 | 
						|
-	if (ret < 0)
 | 
						|
+	if (ret < 0) {
 | 
						|
 		ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");
 | 
						|
+		return ret;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	v->signature_key_desc = kstrdup(sig_key, GFP_KERNEL);
 | 
						|
-	if (!v->signature_key_desc)
 | 
						|
+	if (!v->signature_key_desc) {
 | 
						|
+		ti->error = DM_VERITY_VERIFY_ERR("Could not allocate memory for signature key");
 | 
						|
 		return -ENOMEM;
 | 
						|
+	}
 | 
						|
 
 | 
						|
-	return ret;
 | 
						|
+	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
 | 
						|
index 6975a71d740f6d..a5aa6a2a028cb2 100644
 | 
						|
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
 | 
						|
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
 | 
						|
@@ -469,7 +469,7 @@ vb2_dma_sg_dmabuf_ops_begin_cpu_access(struct dma_buf *dbuf,
 | 
						|
 	struct vb2_dma_sg_buf *buf = dbuf->priv;
 | 
						|
 	struct sg_table *sgt = buf->dma_sgt;
 | 
						|
 
 | 
						|
-	dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
 | 
						|
+	dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir);
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -480,7 +480,7 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf,
 | 
						|
 	struct vb2_dma_sg_buf *buf = dbuf->priv;
 | 
						|
 	struct sg_table *sgt = buf->dma_sgt;
 | 
						|
 
 | 
						|
-	dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
 | 
						|
+	dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir);
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c
 | 
						|
index cf8858cb13d4ce..611c9823be8578 100644
 | 
						|
--- a/drivers/media/i2c/ccs-pll.c
 | 
						|
+++ b/drivers/media/i2c/ccs-pll.c
 | 
						|
@@ -312,6 +312,11 @@ __ccs_pll_calculate_vt_tree(struct device *dev,
 | 
						|
 	dev_dbg(dev, "more_mul2: %u\n", more_mul);
 | 
						|
 
 | 
						|
 	pll_fr->pll_multiplier = mul * more_mul;
 | 
						|
+	if (pll_fr->pll_multiplier > lim_fr->max_pll_multiplier) {
 | 
						|
+		dev_dbg(dev, "pll multiplier %u too high\n",
 | 
						|
+			pll_fr->pll_multiplier);
 | 
						|
+		return -EINVAL;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz >
 | 
						|
 	    lim_fr->max_pll_op_clk_freq_hz)
 | 
						|
@@ -397,6 +402,8 @@ static int ccs_pll_calculate_vt_tree(struct device *dev,
 | 
						|
 	min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
 | 
						|
 				    pll->ext_clk_freq_hz /
 | 
						|
 				    lim_fr->max_pll_ip_clk_freq_hz);
 | 
						|
+	if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
 | 
						|
+		min_pre_pll_clk_div = clk_div_even(min_pre_pll_clk_div);
 | 
						|
 
 | 
						|
 	dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
 | 
						|
 		min_pre_pll_clk_div, max_pre_pll_clk_div);
 | 
						|
@@ -792,7 +799,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
 | 
						|
 		op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
 | 
						|
 	max_op_pre_pll_clk_div =
 | 
						|
 		min_t(u16, op_lim_fr->max_pre_pll_clk_div,
 | 
						|
-		      clk_div_even(pll->ext_clk_freq_hz /
 | 
						|
+		      DIV_ROUND_UP(pll->ext_clk_freq_hz,
 | 
						|
 				   op_lim_fr->min_pll_ip_clk_freq_hz));
 | 
						|
 	min_op_pre_pll_clk_div =
 | 
						|
 		max_t(u16, op_lim_fr->min_pre_pll_clk_div,
 | 
						|
@@ -815,6 +822,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
 | 
						|
 			      one_or_more(
 | 
						|
 				      DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
 | 
						|
 						   pll->ext_clk_freq_hz))));
 | 
						|
+	if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
 | 
						|
+		min_op_pre_pll_clk_div = clk_div_even(min_op_pre_pll_clk_div);
 | 
						|
 	dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
 | 
						|
 		min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
 | 
						|
 
 | 
						|
diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
 | 
						|
index ae33d1ecf835df..6ec960d7914e9a 100644
 | 
						|
--- a/drivers/media/i2c/ds90ub913.c
 | 
						|
+++ b/drivers/media/i2c/ds90ub913.c
 | 
						|
@@ -453,10 +453,10 @@ static int ub913_set_fmt(struct v4l2_subdev *sd,
 | 
						|
 	if (!fmt)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
-	format->format.code = finfo->outcode;
 | 
						|
-
 | 
						|
 	*fmt = format->format;
 | 
						|
 
 | 
						|
+	fmt->code = finfo->outcode;
 | 
						|
+
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
 | 
						|
index c499e7e93c54b9..92c3e7951ee727 100644
 | 
						|
--- a/drivers/media/i2c/ov5675.c
 | 
						|
+++ b/drivers/media/i2c/ov5675.c
 | 
						|
@@ -1339,11 +1339,8 @@ static int ov5675_probe(struct i2c_client *client)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
 	ret = ov5675_get_hwcfg(ov5675, &client->dev);
 | 
						|
-	if (ret) {
 | 
						|
-		dev_err(&client->dev, "failed to get HW configuration: %d",
 | 
						|
-			ret);
 | 
						|
+	if (ret)
 | 
						|
 		return ret;
 | 
						|
-	}
 | 
						|
 
 | 
						|
 	v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
 | 
						|
 
 | 
						|
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
 | 
						|
index f053c3a7676a09..8c93fe6285f809 100644
 | 
						|
--- a/drivers/media/i2c/ov8856.c
 | 
						|
+++ b/drivers/media/i2c/ov8856.c
 | 
						|
@@ -2323,8 +2323,8 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
 | 
						|
 	if (!is_acpi_node(fwnode)) {
 | 
						|
 		ov8856->xvclk = devm_clk_get(dev, "xvclk");
 | 
						|
 		if (IS_ERR(ov8856->xvclk)) {
 | 
						|
-			dev_err(dev, "could not get xvclk clock (%pe)\n",
 | 
						|
-				ov8856->xvclk);
 | 
						|
+			dev_err_probe(dev, PTR_ERR(ov8856->xvclk),
 | 
						|
+				      "could not get xvclk clock\n");
 | 
						|
 			return PTR_ERR(ov8856->xvclk);
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -2429,11 +2429,8 @@ static int ov8856_probe(struct i2c_client *client)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
 	ret = ov8856_get_hwcfg(ov8856, &client->dev);
 | 
						|
-	if (ret) {
 | 
						|
-		dev_err(&client->dev, "failed to get HW configuration: %d",
 | 
						|
-			ret);
 | 
						|
+	if (ret)
 | 
						|
 		return ret;
 | 
						|
-	}
 | 
						|
 
 | 
						|
 	v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
 | 
						|
 
 | 
						|
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
 | 
						|
index 21836dd6ef85a3..bbf56016f70a22 100644
 | 
						|
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
 | 
						|
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
 | 
						|
@@ -821,7 +821,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst,
 | 
						|
 	inst->vsi_core->fb.y.dma_addr = y_fb_dma;
 | 
						|
 	inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[0];
 | 
						|
 	inst->vsi_core->fb.c.dma_addr = c_fb_dma;
 | 
						|
-	inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[1];
 | 
						|
+	inst->vsi_core->fb.c.size = ctx->picinfo.fb_sz[1];
 | 
						|
 
 | 
						|
 	inst->vsi_core->dec.vdec_fb_va = (unsigned long)fb;
 | 
						|
 
 | 
						|
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
 | 
						|
index 092d83b7e79549..dc3e0d2928104c 100644
 | 
						|
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
 | 
						|
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
 | 
						|
@@ -752,6 +752,32 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
 | 
						|
 	return -1;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
 | 
						|
+{
 | 
						|
+	/* free descriptor for decoding/encoding phase */
 | 
						|
+	dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
 | 
						|
+			  jpeg->slot_data.desc,
 | 
						|
+			  jpeg->slot_data.desc_handle);
 | 
						|
+	jpeg->slot_data.desc = NULL;
 | 
						|
+	jpeg->slot_data.desc_handle = 0;
 | 
						|
+
 | 
						|
+	/* free descriptor for encoder configuration phase / decoder DHT */
 | 
						|
+	dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
 | 
						|
+			  jpeg->slot_data.cfg_desc,
 | 
						|
+			  jpeg->slot_data.cfg_desc_handle);
 | 
						|
+	jpeg->slot_data.cfg_desc_handle = 0;
 | 
						|
+	jpeg->slot_data.cfg_desc = NULL;
 | 
						|
+
 | 
						|
+	/* free configuration stream */
 | 
						|
+	dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
 | 
						|
+			  jpeg->slot_data.cfg_stream_vaddr,
 | 
						|
+			  jpeg->slot_data.cfg_stream_handle);
 | 
						|
+	jpeg->slot_data.cfg_stream_vaddr = NULL;
 | 
						|
+	jpeg->slot_data.cfg_stream_handle = 0;
 | 
						|
+
 | 
						|
+	jpeg->slot_data.used = false;
 | 
						|
+}
 | 
						|
+
 | 
						|
 static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
 | 
						|
 {
 | 
						|
 	struct mxc_jpeg_desc *desc;
 | 
						|
@@ -794,30 +820,11 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
 | 
						|
 	return true;
 | 
						|
 err:
 | 
						|
 	dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
 | 
						|
+	mxc_jpeg_free_slot_data(jpeg);
 | 
						|
 
 | 
						|
 	return false;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
 | 
						|
-{
 | 
						|
-	/* free descriptor for decoding/encoding phase */
 | 
						|
-	dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
 | 
						|
-			  jpeg->slot_data.desc,
 | 
						|
-			  jpeg->slot_data.desc_handle);
 | 
						|
-
 | 
						|
-	/* free descriptor for encoder configuration phase / decoder DHT */
 | 
						|
-	dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
 | 
						|
-			  jpeg->slot_data.cfg_desc,
 | 
						|
-			  jpeg->slot_data.cfg_desc_handle);
 | 
						|
-
 | 
						|
-	/* free configuration stream */
 | 
						|
-	dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
 | 
						|
-			  jpeg->slot_data.cfg_stream_vaddr,
 | 
						|
-			  jpeg->slot_data.cfg_stream_handle);
 | 
						|
-
 | 
						|
-	jpeg->slot_data.used = false;
 | 
						|
-}
 | 
						|
-
 | 
						|
 static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
 | 
						|
 					       struct vb2_v4l2_buffer *src_buf,
 | 
						|
 					       struct vb2_v4l2_buffer *dst_buf)
 | 
						|
@@ -1913,9 +1920,19 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
 | 
						|
 	jpeg_src_buf = vb2_to_mxc_buf(vb);
 | 
						|
 	jpeg_src_buf->jpeg_parse_error = false;
 | 
						|
 	ret = mxc_jpeg_parse(ctx, vb);
 | 
						|
-	if (ret)
 | 
						|
+	if (ret) {
 | 
						|
 		jpeg_src_buf->jpeg_parse_error = true;
 | 
						|
 
 | 
						|
+		/*
 | 
						|
+		 * if the capture queue is not setup, the device_run() won't be scheduled,
 | 
						|
+		 * need to drop the error buffer, so that the decoding can continue
 | 
						|
+		 */
 | 
						|
+		if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) {
 | 
						|
+			v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
 | 
						|
+			return;
 | 
						|
+		}
 | 
						|
+	}
 | 
						|
+
 | 
						|
 end:
 | 
						|
 	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
 | 
						|
 }
 | 
						|
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
 | 
						|
index 9745d6219a1667..cd6c52e9d158a7 100644
 | 
						|
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
 | 
						|
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
 | 
						|
@@ -43,6 +43,7 @@ struct mxc_isi_m2m_ctx_queue_data {
 | 
						|
 	struct v4l2_pix_format_mplane format;
 | 
						|
 	const struct mxc_isi_format_info *info;
 | 
						|
 	u32 sequence;
 | 
						|
+	bool streaming;
 | 
						|
 };
 | 
						|
 
 | 
						|
 struct mxc_isi_m2m_ctx {
 | 
						|
@@ -486,15 +487,18 @@ static int mxc_isi_m2m_streamon(struct file *file, void *fh,
 | 
						|
 				enum v4l2_buf_type type)
 | 
						|
 {
 | 
						|
 	struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
 | 
						|
+	struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type);
 | 
						|
 	const struct v4l2_pix_format_mplane *out_pix = &ctx->queues.out.format;
 | 
						|
 	const struct v4l2_pix_format_mplane *cap_pix = &ctx->queues.cap.format;
 | 
						|
 	const struct mxc_isi_format_info *cap_info = ctx->queues.cap.info;
 | 
						|
 	const struct mxc_isi_format_info *out_info = ctx->queues.out.info;
 | 
						|
 	struct mxc_isi_m2m *m2m = ctx->m2m;
 | 
						|
 	bool bypass;
 | 
						|
-
 | 
						|
 	int ret;
 | 
						|
 
 | 
						|
+	if (q->streaming)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
 	mutex_lock(&m2m->lock);
 | 
						|
 
 | 
						|
 	if (m2m->usage_count == INT_MAX) {
 | 
						|
@@ -547,6 +551,8 @@ static int mxc_isi_m2m_streamon(struct file *file, void *fh,
 | 
						|
 		goto unchain;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	q->streaming = true;
 | 
						|
+
 | 
						|
 	return 0;
 | 
						|
 
 | 
						|
 unchain:
 | 
						|
@@ -569,10 +575,14 @@ static int mxc_isi_m2m_streamoff(struct file *file, void *fh,
 | 
						|
 				 enum v4l2_buf_type type)
 | 
						|
 {
 | 
						|
 	struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
 | 
						|
+	struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type);
 | 
						|
 	struct mxc_isi_m2m *m2m = ctx->m2m;
 | 
						|
 
 | 
						|
 	v4l2_m2m_ioctl_streamoff(file, fh, type);
 | 
						|
 
 | 
						|
+	if (!q->streaming)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
 	mutex_lock(&m2m->lock);
 | 
						|
 
 | 
						|
 	/*
 | 
						|
@@ -598,6 +608,8 @@ static int mxc_isi_m2m_streamoff(struct file *file, void *fh,
 | 
						|
 
 | 
						|
 	mutex_unlock(&m2m->lock);
 | 
						|
 
 | 
						|
+	q->streaming = false;
 | 
						|
+
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
 | 
						|
index b570eb8c37568f..47ce3365451d37 100644
 | 
						|
--- a/drivers/media/platform/qcom/venus/core.c
 | 
						|
+++ b/drivers/media/platform/qcom/venus/core.c
 | 
						|
@@ -348,7 +348,7 @@ static int venus_probe(struct platform_device *pdev)
 | 
						|
 
 | 
						|
 	ret = v4l2_device_register(dev, &core->v4l2_dev);
 | 
						|
 	if (ret)
 | 
						|
-		goto err_core_deinit;
 | 
						|
+		goto err_hfi_destroy;
 | 
						|
 
 | 
						|
 	platform_set_drvdata(pdev, core);
 | 
						|
 
 | 
						|
@@ -380,24 +380,24 @@ static int venus_probe(struct platform_device *pdev)
 | 
						|
 
 | 
						|
 	ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
 | 
						|
 	if (ret)
 | 
						|
-		goto err_venus_shutdown;
 | 
						|
+		goto err_core_deinit;
 | 
						|
 
 | 
						|
 	ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
 | 
						|
 	if (ret)
 | 
						|
-		goto err_venus_shutdown;
 | 
						|
+		goto err_core_deinit;
 | 
						|
 
 | 
						|
 	ret = pm_runtime_put_sync(dev);
 | 
						|
 	if (ret) {
 | 
						|
 		pm_runtime_get_noresume(dev);
 | 
						|
-		goto err_dev_unregister;
 | 
						|
+		goto err_core_deinit;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	venus_dbgfs_init(core);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 
 | 
						|
-err_dev_unregister:
 | 
						|
-	v4l2_device_unregister(&core->v4l2_dev);
 | 
						|
+err_core_deinit:
 | 
						|
+	hfi_core_deinit(core, false);
 | 
						|
 err_venus_shutdown:
 | 
						|
 	venus_shutdown(core);
 | 
						|
 err_firmware_deinit:
 | 
						|
@@ -408,9 +408,9 @@ static int venus_probe(struct platform_device *pdev)
 | 
						|
 	pm_runtime_put_noidle(dev);
 | 
						|
 	pm_runtime_disable(dev);
 | 
						|
 	pm_runtime_set_suspended(dev);
 | 
						|
+	v4l2_device_unregister(&core->v4l2_dev);
 | 
						|
+err_hfi_destroy:
 | 
						|
 	hfi_destroy(core);
 | 
						|
-err_core_deinit:
 | 
						|
-	hfi_core_deinit(core, false);
 | 
						|
 err_core_put:
 | 
						|
 	if (core->pm_ops->core_put)
 | 
						|
 		core->pm_ops->core_put(core);
 | 
						|
diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
 | 
						|
index 63cdfed37bc9bc..fa9679abf7a483 100644
 | 
						|
--- a/drivers/media/platform/ti/davinci/vpif.c
 | 
						|
+++ b/drivers/media/platform/ti/davinci/vpif.c
 | 
						|
@@ -505,7 +505,7 @@ static int vpif_probe(struct platform_device *pdev)
 | 
						|
 	pdev_display = kzalloc(sizeof(*pdev_display), GFP_KERNEL);
 | 
						|
 	if (!pdev_display) {
 | 
						|
 		ret = -ENOMEM;
 | 
						|
-		goto err_put_pdev_capture;
 | 
						|
+		goto err_del_pdev_capture;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	pdev_display->name = "vpif_display";
 | 
						|
@@ -528,6 +528,8 @@ static int vpif_probe(struct platform_device *pdev)
 | 
						|
 
 | 
						|
 err_put_pdev_display:
 | 
						|
 	platform_device_put(pdev_display);
 | 
						|
+err_del_pdev_capture:
 | 
						|
+	platform_device_del(pdev_capture);
 | 
						|
 err_put_pdev_capture:
 | 
						|
 	platform_device_put(pdev_capture);
 | 
						|
 err_put_rpm:
 | 
						|
diff --git a/drivers/media/platform/ti/omap3isp/ispccdc.c b/drivers/media/platform/ti/omap3isp/ispccdc.c
 | 
						|
index 2fe42aa9180049..6eb387ea1dae10 100644
 | 
						|
--- a/drivers/media/platform/ti/omap3isp/ispccdc.c
 | 
						|
+++ b/drivers/media/platform/ti/omap3isp/ispccdc.c
 | 
						|
@@ -446,8 +446,8 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
 | 
						|
 		if (ret < 0)
 | 
						|
 			goto done;
 | 
						|
 
 | 
						|
-		dma_sync_sg_for_cpu(isp->dev, req->table.sgt.sgl,
 | 
						|
-				    req->table.sgt.nents, DMA_TO_DEVICE);
 | 
						|
+		dma_sync_sgtable_for_cpu(isp->dev, &req->table.sgt,
 | 
						|
+					 DMA_TO_DEVICE);
 | 
						|
 
 | 
						|
 		if (copy_from_user(req->table.addr, config->lsc,
 | 
						|
 				   req->config.size)) {
 | 
						|
@@ -455,8 +455,8 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
 | 
						|
 			goto done;
 | 
						|
 		}
 | 
						|
 
 | 
						|
-		dma_sync_sg_for_device(isp->dev, req->table.sgt.sgl,
 | 
						|
-				       req->table.sgt.nents, DMA_TO_DEVICE);
 | 
						|
+		dma_sync_sgtable_for_device(isp->dev, &req->table.sgt,
 | 
						|
+					    DMA_TO_DEVICE);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
 | 
						|
diff --git a/drivers/media/platform/ti/omap3isp/ispstat.c b/drivers/media/platform/ti/omap3isp/ispstat.c
 | 
						|
index 68cf68dbcace28..dc496ca9748a6c 100644
 | 
						|
--- a/drivers/media/platform/ti/omap3isp/ispstat.c
 | 
						|
+++ b/drivers/media/platform/ti/omap3isp/ispstat.c
 | 
						|
@@ -161,8 +161,7 @@ static void isp_stat_buf_sync_for_device(struct ispstat *stat,
 | 
						|
 	if (ISP_STAT_USES_DMAENGINE(stat))
 | 
						|
 		return;
 | 
						|
 
 | 
						|
-	dma_sync_sg_for_device(stat->isp->dev, buf->sgt.sgl,
 | 
						|
-			       buf->sgt.nents, DMA_FROM_DEVICE);
 | 
						|
+	dma_sync_sgtable_for_device(stat->isp->dev, &buf->sgt, DMA_FROM_DEVICE);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void isp_stat_buf_sync_for_cpu(struct ispstat *stat,
 | 
						|
@@ -171,8 +170,7 @@ static void isp_stat_buf_sync_for_cpu(struct ispstat *stat,
 | 
						|
 	if (ISP_STAT_USES_DMAENGINE(stat))
 | 
						|
 		return;
 | 
						|
 
 | 
						|
-	dma_sync_sg_for_cpu(stat->isp->dev, buf->sgt.sgl,
 | 
						|
-			    buf->sgt.nents, DMA_FROM_DEVICE);
 | 
						|
+	dma_sync_sgtable_for_cpu(stat->isp->dev, &buf->sgt, DMA_FROM_DEVICE);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void isp_stat_buf_clear(struct ispstat *stat)
 | 
						|
diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c
 | 
						|
index 7838e62727128f..f3023e91b3ebc8 100644
 | 
						|
--- a/drivers/media/test-drivers/vidtv/vidtv_channel.c
 | 
						|
+++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c
 | 
						|
@@ -497,7 +497,7 @@ int vidtv_channel_si_init(struct vidtv_mux *m)
 | 
						|
 	vidtv_psi_sdt_table_destroy(m->si.sdt);
 | 
						|
 free_pat:
 | 
						|
 	vidtv_psi_pat_table_destroy(m->si.pat);
 | 
						|
-	return 0;
 | 
						|
+	return -EINVAL;
 | 
						|
 }
 | 
						|
 
 | 
						|
 void vidtv_channel_si_destroy(struct vidtv_mux *m)
 | 
						|
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
 | 
						|
index 9443dbb04699a3..0ab47fb8696bd0 100644
 | 
						|
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
 | 
						|
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
 | 
						|
@@ -954,8 +954,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
 | 
						|
 			if (dev->has_compose_cap) {
 | 
						|
 				v4l2_rect_set_min_size(compose, &min_rect);
 | 
						|
 				v4l2_rect_set_max_size(compose, &max_rect);
 | 
						|
-				v4l2_rect_map_inside(compose, &fmt);
 | 
						|
 			}
 | 
						|
+			v4l2_rect_map_inside(compose, &fmt);
 | 
						|
 			dev->fmt_cap_rect = fmt;
 | 
						|
 			tpg_s_buf_height(&dev->tpg, fmt.height);
 | 
						|
 		} else if (dev->has_compose_cap) {
 | 
						|
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
 | 
						|
index 1d98d3465e28d4..ce52c936cb9310 100644
 | 
						|
--- a/drivers/media/usb/dvb-usb/cxusb.c
 | 
						|
+++ b/drivers/media/usb/dvb-usb/cxusb.c
 | 
						|
@@ -119,9 +119,8 @@ static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
 | 
						|
 
 | 
						|
 	o[0] = GPIO_TUNER;
 | 
						|
 	o[1] = onoff;
 | 
						|
-	cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
 | 
						|
 
 | 
						|
-	if (i != 0x01)
 | 
						|
+	if (!cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1) && i != 0x01)
 | 
						|
 		dev_info(&d->udev->dev, "gpio_write failed.\n");
 | 
						|
 
 | 
						|
 	st->gpio_write_state[GPIO_TUNER] = onoff;
 | 
						|
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
 | 
						|
index 5a47dcbf1c8e55..303b055fefea98 100644
 | 
						|
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
 | 
						|
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
 | 
						|
@@ -520,12 +520,13 @@ static int hdcs_init(struct sd *sd)
 | 
						|
 static int hdcs_dump(struct sd *sd)
 | 
						|
 {
 | 
						|
 	u16 reg, val;
 | 
						|
+	int err = 0;
 | 
						|
 
 | 
						|
 	pr_info("Dumping sensor registers:\n");
 | 
						|
 
 | 
						|
-	for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) {
 | 
						|
-		stv06xx_read_sensor(sd, reg, &val);
 | 
						|
+	for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH && !err; reg++) {
 | 
						|
+		err = stv06xx_read_sensor(sd, reg, &val);
 | 
						|
 		pr_info("reg 0x%02x = 0x%02x\n", reg, val);
 | 
						|
 	}
 | 
						|
-	return 0;
 | 
						|
+	return (err < 0) ? err : 0;
 | 
						|
 }
 | 
						|
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
 | 
						|
index 5926a9dfb0b1f8..59e21746f55073 100644
 | 
						|
--- a/drivers/media/usb/uvc/uvc_ctrl.c
 | 
						|
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
 | 
						|
@@ -1642,7 +1642,9 @@ static bool uvc_ctrl_xctrls_has_control(const struct v4l2_ext_control *xctrls,
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void uvc_ctrl_send_events(struct uvc_fh *handle,
 | 
						|
-	const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
 | 
						|
+				 struct uvc_entity *entity,
 | 
						|
+				 const struct v4l2_ext_control *xctrls,
 | 
						|
+				 unsigned int xctrls_count)
 | 
						|
 {
 | 
						|
 	struct uvc_control_mapping *mapping;
 | 
						|
 	struct uvc_control *ctrl;
 | 
						|
@@ -1653,6 +1655,9 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle,
 | 
						|
 		u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
 | 
						|
 
 | 
						|
 		ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
 | 
						|
+		if (ctrl->entity != entity)
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
 		if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
 | 
						|
 			/* Notification will be sent from an Interrupt event. */
 | 
						|
 			continue;
 | 
						|
@@ -1783,12 +1788,17 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
 | 
						|
 	return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
+/*
 | 
						|
+ * Returns the number of uvc controls that have been correctly set, or a
 | 
						|
+ * negative number if there has been an error.
 | 
						|
+ */
 | 
						|
 static int uvc_ctrl_commit_entity(struct uvc_device *dev,
 | 
						|
 				  struct uvc_fh *handle,
 | 
						|
 				  struct uvc_entity *entity,
 | 
						|
 				  int rollback,
 | 
						|
 				  struct uvc_control **err_ctrl)
 | 
						|
 {
 | 
						|
+	unsigned int processed_ctrls = 0;
 | 
						|
 	struct uvc_control *ctrl;
 | 
						|
 	unsigned int i;
 | 
						|
 	int ret;
 | 
						|
@@ -1823,6 +1833,9 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
 | 
						|
 		else
 | 
						|
 			ret = 0;
 | 
						|
 
 | 
						|
+		if (!ret)
 | 
						|
+			processed_ctrls++;
 | 
						|
+
 | 
						|
 		if (rollback || ret < 0)
 | 
						|
 			memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
 | 
						|
 			       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
 | 
						|
@@ -1841,7 +1854,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
 | 
						|
 			uvc_ctrl_set_handle(handle, ctrl, handle);
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return processed_ctrls;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
 | 
						|
@@ -1883,11 +1896,13 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
 | 
						|
 					uvc_ctrl_find_ctrl_idx(entity, ctrls,
 | 
						|
 							       err_ctrl);
 | 
						|
 			goto done;
 | 
						|
+		} else if (ret > 0 && !rollback) {
 | 
						|
+			uvc_ctrl_send_events(handle, entity,
 | 
						|
+					     ctrls->controls, ctrls->count);
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	if (!rollback)
 | 
						|
-		uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
 | 
						|
+	ret = 0;
 | 
						|
 done:
 | 
						|
 	mutex_unlock(&chain->ctrl_mutex);
 | 
						|
 	return ret;
 | 
						|
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
 | 
						|
index 02cfa12b9cb902..76f18557f37bd4 100644
 | 
						|
--- a/drivers/media/usb/uvc/uvc_driver.c
 | 
						|
+++ b/drivers/media/usb/uvc/uvc_driver.c
 | 
						|
@@ -2217,13 +2217,16 @@ static int uvc_probe(struct usb_interface *intf,
 | 
						|
 #endif
 | 
						|
 
 | 
						|
 	/* Parse the Video Class control descriptor. */
 | 
						|
-	if (uvc_parse_control(dev) < 0) {
 | 
						|
+	ret = uvc_parse_control(dev);
 | 
						|
+	if (ret < 0) {
 | 
						|
+		ret = -ENODEV;
 | 
						|
 		uvc_dbg(dev, PROBE, "Unable to parse UVC descriptors\n");
 | 
						|
 		goto error;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* Parse the associated GPIOs. */
 | 
						|
-	if (uvc_gpio_parse(dev) < 0) {
 | 
						|
+	ret = uvc_gpio_parse(dev);
 | 
						|
+	if (ret < 0) {
 | 
						|
 		uvc_dbg(dev, PROBE, "Unable to parse UVC GPIOs\n");
 | 
						|
 		goto error;
 | 
						|
 	}
 | 
						|
@@ -2249,24 +2252,32 @@ static int uvc_probe(struct usb_interface *intf,
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* Register the V4L2 device. */
 | 
						|
-	if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
 | 
						|
+	ret = v4l2_device_register(&intf->dev, &dev->vdev);
 | 
						|
+	if (ret < 0)
 | 
						|
 		goto error;
 | 
						|
 
 | 
						|
 	/* Scan the device for video chains. */
 | 
						|
-	if (uvc_scan_device(dev) < 0)
 | 
						|
+	if (uvc_scan_device(dev) < 0) {
 | 
						|
+		ret = -ENODEV;
 | 
						|
 		goto error;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	/* Initialize controls. */
 | 
						|
-	if (uvc_ctrl_init_device(dev) < 0)
 | 
						|
+	if (uvc_ctrl_init_device(dev) < 0) {
 | 
						|
+		ret = -ENODEV;
 | 
						|
 		goto error;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	/* Register video device nodes. */
 | 
						|
-	if (uvc_register_chains(dev) < 0)
 | 
						|
+	if (uvc_register_chains(dev) < 0) {
 | 
						|
+		ret = -ENODEV;
 | 
						|
 		goto error;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 #ifdef CONFIG_MEDIA_CONTROLLER
 | 
						|
 	/* Register the media device node */
 | 
						|
-	if (media_device_register(&dev->mdev) < 0)
 | 
						|
+	ret = media_device_register(&dev->mdev);
 | 
						|
+	if (ret < 0)
 | 
						|
 		goto error;
 | 
						|
 #endif
 | 
						|
 	/* Save our data pointer in the interface data. */
 | 
						|
@@ -2300,7 +2311,7 @@ static int uvc_probe(struct usb_interface *intf,
 | 
						|
 error:
 | 
						|
 	uvc_unregister_video(dev);
 | 
						|
 	kref_put(&dev->ref, uvc_delete);
 | 
						|
-	return -ENODEV;
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void uvc_disconnect(struct usb_interface *intf)
 | 
						|
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
 | 
						|
index 77bbf276ae89df..c4d3d110c5007e 100644
 | 
						|
--- a/drivers/media/v4l2-core/v4l2-dev.c
 | 
						|
+++ b/drivers/media/v4l2-core/v4l2-dev.c
 | 
						|
@@ -1033,25 +1033,25 @@ int __video_register_device(struct video_device *vdev,
 | 
						|
 	vdev->dev.class = &video_class;
 | 
						|
 	vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
 | 
						|
 	vdev->dev.parent = vdev->dev_parent;
 | 
						|
+	vdev->dev.release = v4l2_device_release;
 | 
						|
 	dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
 | 
						|
+
 | 
						|
+	/* Increase v4l2_device refcount */
 | 
						|
+	v4l2_device_get(vdev->v4l2_dev);
 | 
						|
+
 | 
						|
 	mutex_lock(&videodev_lock);
 | 
						|
 	ret = device_register(&vdev->dev);
 | 
						|
 	if (ret < 0) {
 | 
						|
 		mutex_unlock(&videodev_lock);
 | 
						|
 		pr_err("%s: device_register failed\n", __func__);
 | 
						|
-		goto cleanup;
 | 
						|
+		put_device(&vdev->dev);
 | 
						|
+		return ret;
 | 
						|
 	}
 | 
						|
-	/* Register the release callback that will be called when the last
 | 
						|
-	   reference to the device goes away. */
 | 
						|
-	vdev->dev.release = v4l2_device_release;
 | 
						|
 
 | 
						|
 	if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
 | 
						|
 		pr_warn("%s: requested %s%d, got %s\n", __func__,
 | 
						|
 			name_base, nr, video_device_node_name(vdev));
 | 
						|
 
 | 
						|
-	/* Increase v4l2_device refcount */
 | 
						|
-	v4l2_device_get(vdev->v4l2_dev);
 | 
						|
-
 | 
						|
 	/* Part 5: Register the entity. */
 | 
						|
 	ret = video_register_media_controller(vdev);
 | 
						|
 
 | 
						|
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h
 | 
						|
index 8476754b1b170c..fe0b2fa3bb89dc 100644
 | 
						|
--- a/drivers/mmc/core/card.h
 | 
						|
+++ b/drivers/mmc/core/card.h
 | 
						|
@@ -86,6 +86,7 @@ struct mmc_fixup {
 | 
						|
 #define CID_MANFID_MICRON       0x13
 | 
						|
 #define CID_MANFID_SAMSUNG      0x15
 | 
						|
 #define CID_MANFID_APACER       0x27
 | 
						|
+#define CID_MANFID_SWISSBIT     0x5D
 | 
						|
 #define CID_MANFID_KINGSTON     0x70
 | 
						|
 #define CID_MANFID_HYNIX	0x90
 | 
						|
 #define CID_MANFID_KINGSTON_SD	0x9F
 | 
						|
@@ -291,4 +292,9 @@ static inline int mmc_card_broken_sd_poweroff_notify(const struct mmc_card *c)
 | 
						|
 	return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline int mmc_card_no_uhs_ddr50_tuning(const struct mmc_card *c)
 | 
						|
+{
 | 
						|
+	return c->quirks & MMC_QUIRK_NO_UHS_DDR50_TUNING;
 | 
						|
+}
 | 
						|
+
 | 
						|
 #endif
 | 
						|
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
 | 
						|
index 89b512905be140..7f893bafaa607d 100644
 | 
						|
--- a/drivers/mmc/core/quirks.h
 | 
						|
+++ b/drivers/mmc/core/quirks.h
 | 
						|
@@ -34,6 +34,16 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
 | 
						|
 		   MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY,
 | 
						|
 		   EXT_CSD_REV_ANY),
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * Swissbit series S46-u cards throw I/O errors during tuning requests
 | 
						|
+	 * after the initial tuning request expectedly times out. This has
 | 
						|
+	 * only been observed on cards manufactured on 01/2019 that are using
 | 
						|
+	 * Bay Trail host controllers.
 | 
						|
+	 */
 | 
						|
+	_FIXUP_EXT("0016G", CID_MANFID_SWISSBIT, 0x5342, 2019, 1,
 | 
						|
+		   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
 | 
						|
+		   MMC_QUIRK_NO_UHS_DDR50_TUNING, EXT_CSD_REV_ANY),
 | 
						|
+
 | 
						|
 	END_FIXUP
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
 | 
						|
index f02c3e5eb5c851..a06f3011e2b58c 100644
 | 
						|
--- a/drivers/mmc/core/sd.c
 | 
						|
+++ b/drivers/mmc/core/sd.c
 | 
						|
@@ -618,6 +618,29 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
+/*
 | 
						|
+ * Determine if the card should tune or not.
 | 
						|
+ */
 | 
						|
+static bool mmc_sd_use_tuning(struct mmc_card *card)
 | 
						|
+{
 | 
						|
+	/*
 | 
						|
+	 * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
 | 
						|
+	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
 | 
						|
+	 */
 | 
						|
+	if (mmc_host_is_spi(card->host))
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	switch (card->host->ios.timing) {
 | 
						|
+	case MMC_TIMING_UHS_SDR50:
 | 
						|
+	case MMC_TIMING_UHS_SDR104:
 | 
						|
+		return true;
 | 
						|
+	case MMC_TIMING_UHS_DDR50:
 | 
						|
+		return !mmc_card_no_uhs_ddr50_tuning(card);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+
 | 
						|
 /*
 | 
						|
  * UHS-I specific initialization procedure
 | 
						|
  */
 | 
						|
@@ -661,14 +684,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
 | 
						|
 	if (err)
 | 
						|
 		goto out;
 | 
						|
 
 | 
						|
-	/*
 | 
						|
-	 * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
 | 
						|
-	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
 | 
						|
-	 */
 | 
						|
-	if (!mmc_host_is_spi(card->host) &&
 | 
						|
-		(card->host->ios.timing == MMC_TIMING_UHS_SDR50 ||
 | 
						|
-		 card->host->ios.timing == MMC_TIMING_UHS_DDR50 ||
 | 
						|
-		 card->host->ios.timing == MMC_TIMING_UHS_SDR104)) {
 | 
						|
+	if (mmc_sd_use_tuning(card)) {
 | 
						|
 		err = mmc_execute_tuning(card);
 | 
						|
 
 | 
						|
 		/*
 | 
						|
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
 | 
						|
index b8cff9240b286c..beafca6ba0df4d 100644
 | 
						|
--- a/drivers/mtd/nand/raw/qcom_nandc.c
 | 
						|
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
 | 
						|
@@ -2917,7 +2917,7 @@ static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
 | 
						|
 		write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	nandc->buf_count = len;
 | 
						|
+	nandc->buf_count = 512;
 | 
						|
 	memset(nandc->data_buffer, 0xff, nandc->buf_count);
 | 
						|
 
 | 
						|
 	config_nand_single_cw_page_read(chip, false, 0);
 | 
						|
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
 | 
						|
index 9abf38049d35f3..4469618ee60331 100644
 | 
						|
--- a/drivers/mtd/nand/raw/sunxi_nand.c
 | 
						|
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
 | 
						|
@@ -817,6 +817,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand,
 | 
						|
 	if (ret)
 | 
						|
 		return ret;
 | 
						|
 
 | 
						|
+	sunxi_nfc_randomizer_config(nand, page, false);
 | 
						|
 	sunxi_nfc_randomizer_enable(nand);
 | 
						|
 	writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
 | 
						|
 	       nfc->regs + NFC_REG_CMD);
 | 
						|
@@ -1049,6 +1050,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand,
 | 
						|
 	if (ret)
 | 
						|
 		return ret;
 | 
						|
 
 | 
						|
+	sunxi_nfc_randomizer_config(nand, page, false);
 | 
						|
 	sunxi_nfc_randomizer_enable(nand);
 | 
						|
 	sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, 0, bbm, page);
 | 
						|
 
 | 
						|
diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
 | 
						|
index ae8c42f5debd4d..4d440ecfc211c1 100644
 | 
						|
--- a/drivers/net/can/m_can/tcan4x5x-core.c
 | 
						|
+++ b/drivers/net/can/m_can/tcan4x5x-core.c
 | 
						|
@@ -385,10 +385,11 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
 | 
						|
 	priv = cdev_to_priv(mcan_class);
 | 
						|
 
 | 
						|
 	priv->power = devm_regulator_get_optional(&spi->dev, "vsup");
 | 
						|
-	if (PTR_ERR(priv->power) == -EPROBE_DEFER) {
 | 
						|
-		ret = -EPROBE_DEFER;
 | 
						|
-		goto out_m_can_class_free_dev;
 | 
						|
-	} else {
 | 
						|
+	if (IS_ERR(priv->power)) {
 | 
						|
+		if (PTR_ERR(priv->power) == -EPROBE_DEFER) {
 | 
						|
+			ret = -EPROBE_DEFER;
 | 
						|
+			goto out_m_can_class_free_dev;
 | 
						|
+		}
 | 
						|
 		priv->power = NULL;
 | 
						|
 	}
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
 | 
						|
index 0b2a52199914b7..75d436c9069689 100644
 | 
						|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
 | 
						|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
 | 
						|
@@ -123,7 +123,6 @@ static netdev_tx_t aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *nd
 | 
						|
 	}
 | 
						|
 #endif
 | 
						|
 
 | 
						|
-	skb_tx_timestamp(skb);
 | 
						|
 	return aq_nic_xmit(aq_nic, skb);
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
 | 
						|
index c9b0d57696a487..07392174f6437e 100644
 | 
						|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
 | 
						|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
 | 
						|
@@ -898,6 +898,8 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
 | 
						|
 
 | 
						|
 	frags = aq_nic_map_skb(self, skb, ring);
 | 
						|
 
 | 
						|
+	skb_tx_timestamp(skb);
 | 
						|
+
 | 
						|
 	if (likely(frags)) {
 | 
						|
 		err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
 | 
						|
 						       ring, frags);
 | 
						|
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
 | 
						|
index 6f45f4d9fba71f..534e7f7bca4c2f 100644
 | 
						|
--- a/drivers/net/ethernet/cadence/macb_main.c
 | 
						|
+++ b/drivers/net/ethernet/cadence/macb_main.c
 | 
						|
@@ -5070,7 +5070,11 @@ static int macb_probe(struct platform_device *pdev)
 | 
						|
 
 | 
						|
 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
 | 
						|
 	if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) {
 | 
						|
-		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
 | 
						|
+		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
 | 
						|
+		if (err) {
 | 
						|
+			dev_err(&pdev->dev, "failed to set DMA mask\n");
 | 
						|
+			goto err_out_free_netdev;
 | 
						|
+		}
 | 
						|
 		bp->hw_dma_cap |= HW_DMA_CAP_64B;
 | 
						|
 	}
 | 
						|
 #endif
 | 
						|
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
 | 
						|
index 5af98fba74803e..fce2ff1e1d8348 100644
 | 
						|
--- a/drivers/net/ethernet/cortina/gemini.c
 | 
						|
+++ b/drivers/net/ethernet/cortina/gemini.c
 | 
						|
@@ -1148,6 +1148,7 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb,
 | 
						|
 	struct gmac_txdesc *txd;
 | 
						|
 	skb_frag_t *skb_frag;
 | 
						|
 	dma_addr_t mapping;
 | 
						|
+	bool tcp = false;
 | 
						|
 	void *buffer;
 | 
						|
 	u16 mss;
 | 
						|
 	int ret;
 | 
						|
@@ -1155,6 +1156,13 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb,
 | 
						|
 	word1 = skb->len;
 | 
						|
 	word3 = SOF_BIT;
 | 
						|
 
 | 
						|
+	/* Determine if we are doing TCP */
 | 
						|
+	if (skb->protocol == htons(ETH_P_IP))
 | 
						|
+		tcp = (ip_hdr(skb)->protocol == IPPROTO_TCP);
 | 
						|
+	else
 | 
						|
+		/* IPv6 */
 | 
						|
+		tcp = (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP);
 | 
						|
+
 | 
						|
 	mss = skb_shinfo(skb)->gso_size;
 | 
						|
 	if (mss) {
 | 
						|
 		/* This means we are dealing with TCP and skb->len is the
 | 
						|
@@ -1167,8 +1175,26 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb,
 | 
						|
 			   mss, skb->len);
 | 
						|
 		word1 |= TSS_MTU_ENABLE_BIT;
 | 
						|
 		word3 |= mss;
 | 
						|
+	} else if (tcp) {
 | 
						|
+		/* Even if we are not using TSO, use the hardware offloader
 | 
						|
+		 * for transferring the TCP frame: this hardware has partial
 | 
						|
+		 * TCP awareness (called TOE - TCP Offload Engine) and will
 | 
						|
+		 * according to the datasheet put packets belonging to the
 | 
						|
+		 * same TCP connection in the same queue for the TOE/TSO
 | 
						|
+		 * engine to process. The engine will deal with chopping
 | 
						|
+		 * up frames that exceed ETH_DATA_LEN which the
 | 
						|
+		 * checksumming engine cannot handle (see below) into
 | 
						|
+		 * manageable chunks. It flawlessly deals with quite big
 | 
						|
+		 * frames and frames containing custom DSA EtherTypes.
 | 
						|
+		 */
 | 
						|
+		mss = netdev->mtu + skb_tcp_all_headers(skb);
 | 
						|
+		mss = min(mss, skb->len);
 | 
						|
+		netdev_dbg(netdev, "TOE/TSO len %04x mtu %04x mss %04x\n",
 | 
						|
+			   skb->len, netdev->mtu, mss);
 | 
						|
+		word1 |= TSS_MTU_ENABLE_BIT;
 | 
						|
+		word3 |= mss;
 | 
						|
 	} else if (skb->len >= ETH_FRAME_LEN) {
 | 
						|
-		/* Hardware offloaded checksumming isn't working on frames
 | 
						|
+		/* Hardware offloaded checksumming isn't working on non-TCP frames
 | 
						|
 		 * bigger than 1514 bytes. A hypothesis about this is that the
 | 
						|
 		 * checksum buffer is only 1518 bytes, so when the frames get
 | 
						|
 		 * bigger they get truncated, or the last few bytes get
 | 
						|
@@ -1185,21 +1211,16 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb,
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 | 
						|
-		int tcp = 0;
 | 
						|
-
 | 
						|
 		/* We do not switch off the checksumming on non TCP/UDP
 | 
						|
 		 * frames: as is shown from tests, the checksumming engine
 | 
						|
 		 * is smart enough to see that a frame is not actually TCP
 | 
						|
 		 * or UDP and then just pass it through without any changes
 | 
						|
 		 * to the frame.
 | 
						|
 		 */
 | 
						|
-		if (skb->protocol == htons(ETH_P_IP)) {
 | 
						|
+		if (skb->protocol == htons(ETH_P_IP))
 | 
						|
 			word1 |= TSS_IP_CHKSUM_BIT;
 | 
						|
-			tcp = ip_hdr(skb)->protocol == IPPROTO_TCP;
 | 
						|
-		} else { /* IPv6 */
 | 
						|
+		else
 | 
						|
 			word1 |= TSS_IPV6_ENABLE_BIT;
 | 
						|
-			tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP;
 | 
						|
-		}
 | 
						|
 
 | 
						|
 		word1 |= tcp ? TSS_TCP_CHKSUM_BIT : TSS_UDP_CHKSUM_BIT;
 | 
						|
 	}
 | 
						|
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
 | 
						|
index ce46f3ac3b5a18..fad5a72d3b1671 100644
 | 
						|
--- a/drivers/net/ethernet/dlink/dl2k.c
 | 
						|
+++ b/drivers/net/ethernet/dlink/dl2k.c
 | 
						|
@@ -146,6 +146,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
 | 
						|
 	np->ioaddr = ioaddr;
 | 
						|
 	np->chip_id = chip_idx;
 | 
						|
 	np->pdev = pdev;
 | 
						|
+
 | 
						|
+	spin_lock_init(&np->stats_lock);
 | 
						|
 	spin_lock_init (&np->tx_lock);
 | 
						|
 	spin_lock_init (&np->rx_lock);
 | 
						|
 
 | 
						|
@@ -866,7 +868,6 @@ tx_error (struct net_device *dev, int tx_status)
 | 
						|
 	frame_id = (tx_status & 0xffff0000);
 | 
						|
 	printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
 | 
						|
 		dev->name, tx_status, frame_id);
 | 
						|
-	dev->stats.tx_errors++;
 | 
						|
 	/* Ttransmit Underrun */
 | 
						|
 	if (tx_status & 0x10) {
 | 
						|
 		dev->stats.tx_fifo_errors++;
 | 
						|
@@ -903,9 +904,15 @@ tx_error (struct net_device *dev, int tx_status)
 | 
						|
 		rio_set_led_mode(dev);
 | 
						|
 		/* Let TxStartThresh stay default value */
 | 
						|
 	}
 | 
						|
+
 | 
						|
+	spin_lock(&np->stats_lock);
 | 
						|
 	/* Maximum Collisions */
 | 
						|
 	if (tx_status & 0x08)
 | 
						|
 		dev->stats.collisions++;
 | 
						|
+
 | 
						|
+	dev->stats.tx_errors++;
 | 
						|
+	spin_unlock(&np->stats_lock);
 | 
						|
+
 | 
						|
 	/* Restart the Tx */
 | 
						|
 	dw32(MACCtrl, dr16(MACCtrl) | TxEnable);
 | 
						|
 }
 | 
						|
@@ -1074,7 +1081,9 @@ get_stats (struct net_device *dev)
 | 
						|
 	int i;
 | 
						|
 #endif
 | 
						|
 	unsigned int stat_reg;
 | 
						|
+	unsigned long flags;
 | 
						|
 
 | 
						|
+	spin_lock_irqsave(&np->stats_lock, flags);
 | 
						|
 	/* All statistics registers need to be acknowledged,
 | 
						|
 	   else statistic overflow could cause problems */
 | 
						|
 
 | 
						|
@@ -1124,6 +1133,9 @@ get_stats (struct net_device *dev)
 | 
						|
 	dr16(TCPCheckSumErrors);
 | 
						|
 	dr16(UDPCheckSumErrors);
 | 
						|
 	dr16(IPCheckSumErrors);
 | 
						|
+
 | 
						|
+	spin_unlock_irqrestore(&np->stats_lock, flags);
 | 
						|
+
 | 
						|
 	return &dev->stats;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h
 | 
						|
index 0e33e2eaae9606..56aff2f0bdbfa0 100644
 | 
						|
--- a/drivers/net/ethernet/dlink/dl2k.h
 | 
						|
+++ b/drivers/net/ethernet/dlink/dl2k.h
 | 
						|
@@ -372,6 +372,8 @@ struct netdev_private {
 | 
						|
 	struct pci_dev *pdev;
 | 
						|
 	void __iomem *ioaddr;
 | 
						|
 	void __iomem *eeprom_addr;
 | 
						|
+	// To ensure synchronization when stats are updated.
 | 
						|
+	spinlock_t stats_lock;
 | 
						|
 	spinlock_t tx_lock;
 | 
						|
 	spinlock_t rx_lock;
 | 
						|
 	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
 | 
						|
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
 | 
						|
index 51b8377edd1d04..a89aa4ac0a064a 100644
 | 
						|
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
 | 
						|
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
 | 
						|
@@ -1609,7 +1609,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
 | 
						|
 	/* version 1 of the cmd is not supported only by BE2 */
 | 
						|
 	if (BE2_chip(adapter))
 | 
						|
 		hdr->version = 0;
 | 
						|
-	if (BE3_chip(adapter) || lancer_chip(adapter))
 | 
						|
+	else if (BE3_chip(adapter) || lancer_chip(adapter))
 | 
						|
 		hdr->version = 1;
 | 
						|
 	else
 | 
						|
 		hdr->version = 2;
 | 
						|
diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig
 | 
						|
index c699bd6bcbb938..474073c7f94d74 100644
 | 
						|
--- a/drivers/net/ethernet/faraday/Kconfig
 | 
						|
+++ b/drivers/net/ethernet/faraday/Kconfig
 | 
						|
@@ -31,6 +31,7 @@ config FTGMAC100
 | 
						|
 	depends on ARM || COMPILE_TEST
 | 
						|
 	depends on !64BIT || BROKEN
 | 
						|
 	select PHYLIB
 | 
						|
+	select FIXED_PHY
 | 
						|
 	select MDIO_ASPEED if MACH_ASPEED_G6
 | 
						|
 	select CRC32
 | 
						|
 	help
 | 
						|
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
 | 
						|
index 721c098f2bb1b2..7e4fea0e186b6e 100644
 | 
						|
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
 | 
						|
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
 | 
						|
@@ -3540,9 +3540,6 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
 | 
						|
 	case e1000_pch_cnp:
 | 
						|
 	case e1000_pch_tgp:
 | 
						|
 	case e1000_pch_adp:
 | 
						|
-	case e1000_pch_mtp:
 | 
						|
-	case e1000_pch_lnp:
 | 
						|
-	case e1000_pch_ptp:
 | 
						|
 	case e1000_pch_nvp:
 | 
						|
 		if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
 | 
						|
 			/* Stable 24MHz frequency */
 | 
						|
@@ -3558,6 +3555,17 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
 | 
						|
 			adapter->cc.shift = shift;
 | 
						|
 		}
 | 
						|
 		break;
 | 
						|
+	case e1000_pch_mtp:
 | 
						|
+	case e1000_pch_lnp:
 | 
						|
+	case e1000_pch_ptp:
 | 
						|
+		/* System firmware can misreport this value, so set it to a
 | 
						|
+		 * stable 38400KHz frequency.
 | 
						|
+		 */
 | 
						|
+		incperiod = INCPERIOD_38400KHZ;
 | 
						|
+		incvalue = INCVALUE_38400KHZ;
 | 
						|
+		shift = INCVALUE_SHIFT_38400KHZ;
 | 
						|
+		adapter->cc.shift = shift;
 | 
						|
+		break;
 | 
						|
 	case e1000_82574:
 | 
						|
 	case e1000_82583:
 | 
						|
 		/* Stable 25MHz frequency */
 | 
						|
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c
 | 
						|
index bbcfd529399b0f..d039dea48ca324 100644
 | 
						|
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
 | 
						|
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
 | 
						|
@@ -294,15 +294,17 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)
 | 
						|
 	case e1000_pch_cnp:
 | 
						|
 	case e1000_pch_tgp:
 | 
						|
 	case e1000_pch_adp:
 | 
						|
-	case e1000_pch_mtp:
 | 
						|
-	case e1000_pch_lnp:
 | 
						|
-	case e1000_pch_ptp:
 | 
						|
 	case e1000_pch_nvp:
 | 
						|
 		if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)
 | 
						|
 			adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ;
 | 
						|
 		else
 | 
						|
 			adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ;
 | 
						|
 		break;
 | 
						|
+	case e1000_pch_mtp:
 | 
						|
+	case e1000_pch_lnp:
 | 
						|
+	case e1000_pch_ptp:
 | 
						|
+		adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ;
 | 
						|
+		break;
 | 
						|
 	case e1000_82574:
 | 
						|
 	case e1000_82583:
 | 
						|
 		adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ;
 | 
						|
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
 | 
						|
index 4d7caa11997199..5d46a8e5376dac 100644
 | 
						|
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
 | 
						|
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
 | 
						|
@@ -1067,10 +1067,11 @@ int i40e_pf_reset(struct i40e_hw *hw)
 | 
						|
 void i40e_clear_hw(struct i40e_hw *hw)
 | 
						|
 {
 | 
						|
 	u32 num_queues, base_queue;
 | 
						|
-	u32 num_pf_int;
 | 
						|
-	u32 num_vf_int;
 | 
						|
+	s32 num_pf_int;
 | 
						|
+	s32 num_vf_int;
 | 
						|
 	u32 num_vfs;
 | 
						|
-	u32 i, j;
 | 
						|
+	s32 i;
 | 
						|
+	u32 j;
 | 
						|
 	u32 val;
 | 
						|
 	u32 eol = 0x7ff;
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c
 | 
						|
index d7e0116f67737b..7036070bc0208b 100644
 | 
						|
--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
 | 
						|
+++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
 | 
						|
@@ -376,6 +376,50 @@ ice_arfs_is_perfect_flow_set(struct ice_hw *hw, __be16 l3_proto, u8 l4_proto)
 | 
						|
 	return false;
 | 
						|
 }
 | 
						|
 
 | 
						|
+/**
 | 
						|
+ * ice_arfs_cmp - Check if aRFS filter matches this flow.
 | 
						|
+ * @fltr_info: filter info of the saved ARFS entry.
 | 
						|
+ * @fk: flow dissector keys.
 | 
						|
+ * @n_proto:  One of htons(ETH_P_IP) or htons(ETH_P_IPV6).
 | 
						|
+ * @ip_proto: One of IPPROTO_TCP or IPPROTO_UDP.
 | 
						|
+ *
 | 
						|
+ * Since this function assumes limited values for n_proto and ip_proto, it
 | 
						|
+ * is meant to be called only from ice_rx_flow_steer().
 | 
						|
+ *
 | 
						|
+ * Return:
 | 
						|
+ * * true	- fltr_info refers to the same flow as fk.
 | 
						|
+ * * false	- fltr_info and fk refer to different flows.
 | 
						|
+ */
 | 
						|
+static bool
 | 
						|
+ice_arfs_cmp(const struct ice_fdir_fltr *fltr_info, const struct flow_keys *fk,
 | 
						|
+	     __be16 n_proto, u8 ip_proto)
 | 
						|
+{
 | 
						|
+	/* Determine if the filter is for IPv4 or IPv6 based on flow_type,
 | 
						|
+	 * which is one of ICE_FLTR_PTYPE_NONF_IPV{4,6}_{TCP,UDP}.
 | 
						|
+	 */
 | 
						|
+	bool is_v4 = fltr_info->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
 | 
						|
+		     fltr_info->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP;
 | 
						|
+
 | 
						|
+	/* Following checks are arranged in the quickest and most discriminative
 | 
						|
+	 * fields first for early failure.
 | 
						|
+	 */
 | 
						|
+	if (is_v4)
 | 
						|
+		return n_proto == htons(ETH_P_IP) &&
 | 
						|
+			fltr_info->ip.v4.src_port == fk->ports.src &&
 | 
						|
+			fltr_info->ip.v4.dst_port == fk->ports.dst &&
 | 
						|
+			fltr_info->ip.v4.src_ip == fk->addrs.v4addrs.src &&
 | 
						|
+			fltr_info->ip.v4.dst_ip == fk->addrs.v4addrs.dst &&
 | 
						|
+			fltr_info->ip.v4.proto == ip_proto;
 | 
						|
+
 | 
						|
+	return fltr_info->ip.v6.src_port == fk->ports.src &&
 | 
						|
+		fltr_info->ip.v6.dst_port == fk->ports.dst &&
 | 
						|
+		fltr_info->ip.v6.proto == ip_proto &&
 | 
						|
+		!memcmp(&fltr_info->ip.v6.src_ip, &fk->addrs.v6addrs.src,
 | 
						|
+			sizeof(struct in6_addr)) &&
 | 
						|
+		!memcmp(&fltr_info->ip.v6.dst_ip, &fk->addrs.v6addrs.dst,
 | 
						|
+			sizeof(struct in6_addr));
 | 
						|
+}
 | 
						|
+
 | 
						|
 /**
 | 
						|
  * ice_rx_flow_steer - steer the Rx flow to where application is being run
 | 
						|
  * @netdev: ptr to the netdev being adjusted
 | 
						|
@@ -447,6 +491,10 @@ ice_rx_flow_steer(struct net_device *netdev, const struct sk_buff *skb,
 | 
						|
 			continue;
 | 
						|
 
 | 
						|
 		fltr_info = &arfs_entry->fltr_info;
 | 
						|
+
 | 
						|
+		if (!ice_arfs_cmp(fltr_info, &fk, n_proto, ip_proto))
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
 		ret = fltr_info->fltr_id;
 | 
						|
 
 | 
						|
 		if (fltr_info->q_index == rxq_idx ||
 | 
						|
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
 | 
						|
index 19f730a68fa21c..ac004ef1d724d3 100644
 | 
						|
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
 | 
						|
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
 | 
						|
@@ -3024,7 +3024,7 @@ ice_add_update_vsi_list(struct ice_hw *hw,
 | 
						|
 		u16 vsi_handle_arr[2];
 | 
						|
 
 | 
						|
 		/* A rule already exists with the new VSI being added */
 | 
						|
-		if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
 | 
						|
+		if (cur_fltr->vsi_handle == new_fltr->vsi_handle)
 | 
						|
 			return -EEXIST;
 | 
						|
 
 | 
						|
 		vsi_handle_arr[0] = cur_fltr->vsi_handle;
 | 
						|
@@ -5991,7 +5991,7 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw,
 | 
						|
 
 | 
						|
 		/* A rule already exists with the new VSI being added */
 | 
						|
 		if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
 | 
						|
-			return 0;
 | 
						|
+			return -EEXIST;
 | 
						|
 
 | 
						|
 		/* Update the previously created VSI list set with
 | 
						|
 		 * the new VSI ID passed in
 | 
						|
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
 | 
						|
index 7417087b6db597..a2807a1e4f4a62 100644
 | 
						|
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
 | 
						|
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
 | 
						|
@@ -352,9 +352,12 @@ int cn10k_free_matchall_ipolicer(struct otx2_nic *pfvf)
 | 
						|
 	mutex_lock(&pfvf->mbox.lock);
 | 
						|
 
 | 
						|
 	/* Remove RQ's policer mapping */
 | 
						|
-	for (qidx = 0; qidx < hw->rx_queues; qidx++)
 | 
						|
-		cn10k_map_unmap_rq_policer(pfvf, qidx,
 | 
						|
-					   hw->matchall_ipolicer, false);
 | 
						|
+	for (qidx = 0; qidx < hw->rx_queues; qidx++) {
 | 
						|
+		rc = cn10k_map_unmap_rq_policer(pfvf, qidx, hw->matchall_ipolicer, false);
 | 
						|
+		if (rc)
 | 
						|
+			dev_warn(pfvf->dev, "Failed to unmap RQ %d's policer (error %d).",
 | 
						|
+				 qidx, rc);
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	rc = cn10k_free_leaf_profile(pfvf, hw->matchall_ipolicer);
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
 | 
						|
index 164a13272faa2f..07dced3c2b1c00 100644
 | 
						|
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
 | 
						|
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
 | 
						|
@@ -1916,6 +1916,7 @@ static int mlx4_en_get_ts_info(struct net_device *dev,
 | 
						|
 	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) {
 | 
						|
 		info->so_timestamping |=
 | 
						|
 			SOF_TIMESTAMPING_TX_HARDWARE |
 | 
						|
+			SOF_TIMESTAMPING_TX_SOFTWARE |
 | 
						|
 			SOF_TIMESTAMPING_RX_HARDWARE |
 | 
						|
 			SOF_TIMESTAMPING_RAW_HARDWARE;
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
 | 
						|
index 21753f32786850..06b5265b6e6db2 100644
 | 
						|
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
 | 
						|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
 | 
						|
@@ -444,19 +444,22 @@ int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
 | 
						|
 {
 | 
						|
 	u32 *out;
 | 
						|
 	int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 | 
						|
+	int err;
 | 
						|
 
 | 
						|
 	out = kvzalloc(outlen, GFP_KERNEL);
 | 
						|
 	if (!out)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
-	mlx5_query_nic_vport_context(mdev, 0, out);
 | 
						|
+	err = mlx5_query_nic_vport_context(mdev, 0, out);
 | 
						|
+	if (err)
 | 
						|
+		goto out;
 | 
						|
 
 | 
						|
 	*node_guid = MLX5_GET64(query_nic_vport_context_out, out,
 | 
						|
 				nic_vport_context.node_guid);
 | 
						|
-
 | 
						|
+out:
 | 
						|
 	kvfree(out);
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return err;
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid);
 | 
						|
 
 | 
						|
@@ -498,19 +501,22 @@ int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
 | 
						|
 {
 | 
						|
 	u32 *out;
 | 
						|
 	int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 | 
						|
+	int err;
 | 
						|
 
 | 
						|
 	out = kvzalloc(outlen, GFP_KERNEL);
 | 
						|
 	if (!out)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
-	mlx5_query_nic_vport_context(mdev, 0, out);
 | 
						|
+	err = mlx5_query_nic_vport_context(mdev, 0, out);
 | 
						|
+	if (err)
 | 
						|
+		goto out;
 | 
						|
 
 | 
						|
 	*qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out,
 | 
						|
 				   nic_vport_context.qkey_violation_counter);
 | 
						|
-
 | 
						|
+out:
 | 
						|
 	kvfree(out);
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return err;
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr);
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
 | 
						|
index 72b3092d35f712..39a58c3578a028 100644
 | 
						|
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
 | 
						|
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
 | 
						|
@@ -18,6 +18,8 @@
 | 
						|
 #define EEPROM_MAC_OFFSET		    (0x01)
 | 
						|
 #define MAX_EEPROM_SIZE			    (512)
 | 
						|
 #define MAX_OTP_SIZE			    (1024)
 | 
						|
+#define MAX_HS_OTP_SIZE			    (8 * 1024)
 | 
						|
+#define MAX_HS_EEPROM_SIZE		    (64 * 1024)
 | 
						|
 #define OTP_INDICATOR_1			    (0xF3)
 | 
						|
 #define OTP_INDICATOR_2			    (0xF7)
 | 
						|
 
 | 
						|
@@ -272,6 +274,9 @@ static int lan743x_hs_otp_read(struct lan743x_adapter *adapter, u32 offset,
 | 
						|
 	int ret;
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
+	if (offset + length > MAX_HS_OTP_SIZE)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
 | 
						|
 	if (ret < 0)
 | 
						|
 		return ret;
 | 
						|
@@ -320,6 +325,9 @@ static int lan743x_hs_otp_write(struct lan743x_adapter *adapter, u32 offset,
 | 
						|
 	int ret;
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
+	if (offset + length > MAX_HS_OTP_SIZE)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
 | 
						|
 	if (ret < 0)
 | 
						|
 		return ret;
 | 
						|
@@ -497,6 +505,9 @@ static int lan743x_hs_eeprom_read(struct lan743x_adapter *adapter,
 | 
						|
 	u32 val;
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
+	if (offset + length > MAX_HS_EEPROM_SIZE)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
 | 
						|
 	if (retval < 0)
 | 
						|
 		return retval;
 | 
						|
@@ -539,6 +550,9 @@ static int lan743x_hs_eeprom_write(struct lan743x_adapter *adapter,
 | 
						|
 	u32 val;
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
+	if (offset + length > MAX_HS_EEPROM_SIZE)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
 | 
						|
 	if (retval < 0)
 | 
						|
 		return retval;
 | 
						|
@@ -604,9 +618,9 @@ static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev)
 | 
						|
 	struct lan743x_adapter *adapter = netdev_priv(netdev);
 | 
						|
 
 | 
						|
 	if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
 | 
						|
-		return MAX_OTP_SIZE;
 | 
						|
+		return adapter->is_pci11x1x ? MAX_HS_OTP_SIZE : MAX_OTP_SIZE;
 | 
						|
 
 | 
						|
-	return MAX_EEPROM_SIZE;
 | 
						|
+	return adapter->is_pci11x1x ? MAX_HS_EEPROM_SIZE : MAX_EEPROM_SIZE;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int lan743x_ethtool_get_eeprom(struct net_device *netdev,
 | 
						|
diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c
 | 
						|
index 39e1066ecd5ff0..47f2531198f62a 100644
 | 
						|
--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
 | 
						|
+++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
 | 
						|
@@ -58,7 +58,7 @@ int lan743x_gpio_init(struct lan743x_adapter *adapter)
 | 
						|
 static void lan743x_ptp_wait_till_cmd_done(struct lan743x_adapter *adapter,
 | 
						|
 					   u32 bit_mask)
 | 
						|
 {
 | 
						|
-	int timeout = 1000;
 | 
						|
+	int timeout = PTP_CMD_CTL_TIMEOUT_CNT;
 | 
						|
 	u32 data = 0;
 | 
						|
 
 | 
						|
 	while (timeout &&
 | 
						|
diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.h b/drivers/net/ethernet/microchip/lan743x_ptp.h
 | 
						|
index e26d4eff713361..225e8232474d73 100644
 | 
						|
--- a/drivers/net/ethernet/microchip/lan743x_ptp.h
 | 
						|
+++ b/drivers/net/ethernet/microchip/lan743x_ptp.h
 | 
						|
@@ -18,9 +18,10 @@
 | 
						|
  */
 | 
						|
 #define LAN743X_PTP_N_EVENT_CHAN	2
 | 
						|
 #define LAN743X_PTP_N_PEROUT		LAN743X_PTP_N_EVENT_CHAN
 | 
						|
-#define LAN743X_PTP_N_EXTTS		4
 | 
						|
-#define LAN743X_PTP_N_PPS		0
 | 
						|
 #define PCI11X1X_PTP_IO_MAX_CHANNELS	8
 | 
						|
+#define LAN743X_PTP_N_EXTTS		PCI11X1X_PTP_IO_MAX_CHANNELS
 | 
						|
+#define LAN743X_PTP_N_PPS		0
 | 
						|
+#define PTP_CMD_CTL_TIMEOUT_CNT		50
 | 
						|
 
 | 
						|
 struct lan743x_adapter;
 | 
						|
 
 | 
						|
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c
 | 
						|
index 3ca6893d1bf26a..2869922cffe2e1 100644
 | 
						|
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
 | 
						|
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
 | 
						|
@@ -464,9 +464,9 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
 | 
						|
 	unsigned long start_time;
 | 
						|
 	unsigned long max_wait;
 | 
						|
 	unsigned long duration;
 | 
						|
-	int done = 0;
 | 
						|
 	bool fw_up;
 | 
						|
 	int opcode;
 | 
						|
+	bool done;
 | 
						|
 	int err;
 | 
						|
 
 | 
						|
 	/* Wait for dev cmd to complete, retrying if we get EAGAIN,
 | 
						|
@@ -474,6 +474,7 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
 | 
						|
 	 */
 | 
						|
 	max_wait = jiffies + (max_seconds * HZ);
 | 
						|
 try_again:
 | 
						|
+	done = false;
 | 
						|
 	opcode = idev->opcode;
 | 
						|
 	start_time = jiffies;
 | 
						|
 	for (fw_up = ionic_is_fw_running(idev);
 | 
						|
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
 | 
						|
index c379a958380ce0..28cc23736a69bb 100644
 | 
						|
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
 | 
						|
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
 | 
						|
@@ -2089,7 +2089,9 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
 | 
						|
 			goto of_node_put;
 | 
						|
 
 | 
						|
 		ret = of_get_mac_address(port_np, port->slave.mac_addr);
 | 
						|
-		if (ret) {
 | 
						|
+		if (ret == -EPROBE_DEFER) {
 | 
						|
+			goto of_node_put;
 | 
						|
+		} else if (ret) {
 | 
						|
 			am65_cpsw_am654_get_efuse_macid(port_np,
 | 
						|
 							port->port_id,
 | 
						|
 							port->slave.mac_addr);
 | 
						|
@@ -2949,6 +2951,16 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
 | 
						|
 		return ret;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	am65_cpsw_nuss_get_ver(common);
 | 
						|
+
 | 
						|
+	ret = am65_cpsw_nuss_init_host_p(common);
 | 
						|
+	if (ret)
 | 
						|
+		goto err_pm_clear;
 | 
						|
+
 | 
						|
+	ret = am65_cpsw_nuss_init_slave_ports(common);
 | 
						|
+	if (ret)
 | 
						|
+		goto err_pm_clear;
 | 
						|
+
 | 
						|
 	node = of_get_child_by_name(dev->of_node, "mdio");
 | 
						|
 	if (!node) {
 | 
						|
 		dev_warn(dev, "MDIO node not found\n");
 | 
						|
@@ -2965,16 +2977,6 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
 | 
						|
 	}
 | 
						|
 	of_node_put(node);
 | 
						|
 
 | 
						|
-	am65_cpsw_nuss_get_ver(common);
 | 
						|
-
 | 
						|
-	ret = am65_cpsw_nuss_init_host_p(common);
 | 
						|
-	if (ret)
 | 
						|
-		goto err_of_clear;
 | 
						|
-
 | 
						|
-	ret = am65_cpsw_nuss_init_slave_ports(common);
 | 
						|
-	if (ret)
 | 
						|
-		goto err_of_clear;
 | 
						|
-
 | 
						|
 	/* init common data */
 | 
						|
 	ale_params.dev = dev;
 | 
						|
 	ale_params.ale_ageout = AM65_CPSW_ALE_AGEOUT_DEFAULT;
 | 
						|
diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c
 | 
						|
index 060a566bc6aae1..c902f8761d5d4d 100644
 | 
						|
--- a/drivers/net/ethernet/vertexcom/mse102x.c
 | 
						|
+++ b/drivers/net/ethernet/vertexcom/mse102x.c
 | 
						|
@@ -306,7 +306,7 @@ static void mse102x_dump_packet(const char *msg, int len, const char *data)
 | 
						|
 		       data, len, true);
 | 
						|
 }
 | 
						|
 
 | 
						|
-static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
 | 
						|
+static irqreturn_t mse102x_rx_pkt_spi(struct mse102x_net *mse)
 | 
						|
 {
 | 
						|
 	struct sk_buff *skb;
 | 
						|
 	unsigned int rxalign;
 | 
						|
@@ -327,7 +327,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
 | 
						|
 		mse102x_tx_cmd_spi(mse, CMD_CTR);
 | 
						|
 		ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx);
 | 
						|
 		if (ret)
 | 
						|
-			return;
 | 
						|
+			return IRQ_NONE;
 | 
						|
 
 | 
						|
 		cmd_resp = be16_to_cpu(rx);
 | 
						|
 		if ((cmd_resp & CMD_MASK) != CMD_RTS) {
 | 
						|
@@ -360,7 +360,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
 | 
						|
 	rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);
 | 
						|
 	skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);
 | 
						|
 	if (!skb)
 | 
						|
-		return;
 | 
						|
+		return IRQ_NONE;
 | 
						|
 
 | 
						|
 	/* 2 bytes Start of frame (before ethernet header)
 | 
						|
 	 * 2 bytes Data frame tail (after ethernet frame)
 | 
						|
@@ -370,7 +370,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
 | 
						|
 	if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) {
 | 
						|
 		mse->ndev->stats.rx_errors++;
 | 
						|
 		dev_kfree_skb(skb);
 | 
						|
-		return;
 | 
						|
+		return IRQ_HANDLED;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (netif_msg_pktdata(mse))
 | 
						|
@@ -381,6 +381,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
 | 
						|
 
 | 
						|
 	mse->ndev->stats.rx_packets++;
 | 
						|
 	mse->ndev->stats.rx_bytes += rxlen;
 | 
						|
+
 | 
						|
+	return IRQ_HANDLED;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int mse102x_tx_pkt_spi(struct mse102x_net *mse, struct sk_buff *txb,
 | 
						|
@@ -512,12 +514,13 @@ static irqreturn_t mse102x_irq(int irq, void *_mse)
 | 
						|
 {
 | 
						|
 	struct mse102x_net *mse = _mse;
 | 
						|
 	struct mse102x_net_spi *mses = to_mse102x_spi(mse);
 | 
						|
+	irqreturn_t ret;
 | 
						|
 
 | 
						|
 	mutex_lock(&mses->lock);
 | 
						|
-	mse102x_rx_pkt_spi(mse);
 | 
						|
+	ret = mse102x_rx_pkt_spi(mse);
 | 
						|
 	mutex_unlock(&mses->lock);
 | 
						|
 
 | 
						|
-	return IRQ_HANDLED;
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int mse102x_net_open(struct net_device *ndev)
 | 
						|
diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h
 | 
						|
index 74162190bccc10..8531b804021aa4 100644
 | 
						|
--- a/drivers/net/usb/asix.h
 | 
						|
+++ b/drivers/net/usb/asix.h
 | 
						|
@@ -224,7 +224,6 @@ int asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm);
 | 
						|
 
 | 
						|
 u16 asix_read_medium_status(struct usbnet *dev, int in_pm);
 | 
						|
 int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm);
 | 
						|
-void asix_adjust_link(struct net_device *netdev);
 | 
						|
 
 | 
						|
 int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm);
 | 
						|
 
 | 
						|
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
 | 
						|
index 72ffc89b477ad8..7fd763917ae2cf 100644
 | 
						|
--- a/drivers/net/usb/asix_common.c
 | 
						|
+++ b/drivers/net/usb/asix_common.c
 | 
						|
@@ -414,28 +414,6 @@ int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm)
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
-/* set MAC link settings according to information from phylib */
 | 
						|
-void asix_adjust_link(struct net_device *netdev)
 | 
						|
-{
 | 
						|
-	struct phy_device *phydev = netdev->phydev;
 | 
						|
-	struct usbnet *dev = netdev_priv(netdev);
 | 
						|
-	u16 mode = 0;
 | 
						|
-
 | 
						|
-	if (phydev->link) {
 | 
						|
-		mode = AX88772_MEDIUM_DEFAULT;
 | 
						|
-
 | 
						|
-		if (phydev->duplex == DUPLEX_HALF)
 | 
						|
-			mode &= ~AX_MEDIUM_FD;
 | 
						|
-
 | 
						|
-		if (phydev->speed != SPEED_100)
 | 
						|
-			mode &= ~AX_MEDIUM_PS;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	asix_write_medium_mode(dev, mode, 0);
 | 
						|
-	phy_print_status(phydev);
 | 
						|
-	usbnet_link_change(dev, phydev->link, 0);
 | 
						|
-}
 | 
						|
-
 | 
						|
 int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm)
 | 
						|
 {
 | 
						|
 	int ret;
 | 
						|
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
 | 
						|
index ec4dcf89cbedd2..119295f5f3b351 100644
 | 
						|
--- a/drivers/net/usb/asix_devices.c
 | 
						|
+++ b/drivers/net/usb/asix_devices.c
 | 
						|
@@ -752,7 +752,6 @@ static void ax88772_mac_link_down(struct phylink_config *config,
 | 
						|
 	struct usbnet *dev = netdev_priv(to_net_dev(config->dev));
 | 
						|
 
 | 
						|
 	asix_write_medium_mode(dev, 0, 0);
 | 
						|
-	usbnet_link_change(dev, false, false);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void ax88772_mac_link_up(struct phylink_config *config,
 | 
						|
@@ -783,7 +782,6 @@ static void ax88772_mac_link_up(struct phylink_config *config,
 | 
						|
 		m |= AX_MEDIUM_RFC;
 | 
						|
 
 | 
						|
 	asix_write_medium_mode(dev, m, 0);
 | 
						|
-	usbnet_link_change(dev, true, false);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static const struct phylink_mac_ops ax88772_phylink_mac_ops = {
 | 
						|
@@ -1350,10 +1348,9 @@ static const struct driver_info ax88772_info = {
 | 
						|
 	.description = "ASIX AX88772 USB 2.0 Ethernet",
 | 
						|
 	.bind = ax88772_bind,
 | 
						|
 	.unbind = ax88772_unbind,
 | 
						|
-	.status = asix_status,
 | 
						|
 	.reset = ax88772_reset,
 | 
						|
 	.stop = ax88772_stop,
 | 
						|
-	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET,
 | 
						|
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET,
 | 
						|
 	.rx_fixup = asix_rx_fixup_common,
 | 
						|
 	.tx_fixup = asix_tx_fixup,
 | 
						|
 };
 | 
						|
@@ -1362,11 +1359,9 @@ static const struct driver_info ax88772b_info = {
 | 
						|
 	.description = "ASIX AX88772B USB 2.0 Ethernet",
 | 
						|
 	.bind = ax88772_bind,
 | 
						|
 	.unbind = ax88772_unbind,
 | 
						|
-	.status = asix_status,
 | 
						|
 	.reset = ax88772_reset,
 | 
						|
 	.stop = ax88772_stop,
 | 
						|
-	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
 | 
						|
-	         FLAG_MULTI_PACKET,
 | 
						|
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET,
 | 
						|
 	.rx_fixup = asix_rx_fixup_common,
 | 
						|
 	.tx_fixup = asix_tx_fixup,
 | 
						|
 	.data = FLAG_EEPROM_MAC,
 | 
						|
@@ -1376,11 +1371,9 @@ static const struct driver_info lxausb_t1l_info = {
 | 
						|
 	.description = "Linux Automation GmbH USB 10Base-T1L",
 | 
						|
 	.bind = ax88772_bind,
 | 
						|
 	.unbind = ax88772_unbind,
 | 
						|
-	.status = asix_status,
 | 
						|
 	.reset = ax88772_reset,
 | 
						|
 	.stop = ax88772_stop,
 | 
						|
-	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
 | 
						|
-		 FLAG_MULTI_PACKET,
 | 
						|
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET,
 | 
						|
 	.rx_fixup = asix_rx_fixup_common,
 | 
						|
 	.tx_fixup = asix_tx_fixup,
 | 
						|
 	.data = FLAG_EEPROM_MAC,
 | 
						|
@@ -1412,10 +1405,8 @@ static const struct driver_info hg20f9_info = {
 | 
						|
 	.description = "HG20F9 USB 2.0 Ethernet",
 | 
						|
 	.bind = ax88772_bind,
 | 
						|
 	.unbind = ax88772_unbind,
 | 
						|
-	.status = asix_status,
 | 
						|
 	.reset = ax88772_reset,
 | 
						|
-	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
 | 
						|
-	         FLAG_MULTI_PACKET,
 | 
						|
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET,
 | 
						|
 	.rx_fixup = asix_rx_fixup_common,
 | 
						|
 	.tx_fixup = asix_tx_fixup,
 | 
						|
 	.data = FLAG_EEPROM_MAC,
 | 
						|
diff --git a/drivers/net/usb/ch9200.c b/drivers/net/usb/ch9200.c
 | 
						|
index f69d9b902da04a..a206ffa76f1b93 100644
 | 
						|
--- a/drivers/net/usb/ch9200.c
 | 
						|
+++ b/drivers/net/usb/ch9200.c
 | 
						|
@@ -178,6 +178,7 @@ static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc)
 | 
						|
 {
 | 
						|
 	struct usbnet *dev = netdev_priv(netdev);
 | 
						|
 	unsigned char buff[2];
 | 
						|
+	int ret;
 | 
						|
 
 | 
						|
 	netdev_dbg(netdev, "%s phy_id:%02x loc:%02x\n",
 | 
						|
 		   __func__, phy_id, loc);
 | 
						|
@@ -185,8 +186,10 @@ static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc)
 | 
						|
 	if (phy_id != 0)
 | 
						|
 		return -ENODEV;
 | 
						|
 
 | 
						|
-	control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02,
 | 
						|
-		     CONTROL_TIMEOUT_MS);
 | 
						|
+	ret = control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02,
 | 
						|
+			   CONTROL_TIMEOUT_MS);
 | 
						|
+	if (ret < 0)
 | 
						|
+		return ret;
 | 
						|
 
 | 
						|
 	return (buff[0] | buff[1] << 8);
 | 
						|
 }
 | 
						|
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
 | 
						|
index 2ed879a0abc6ce..1b6b6acd34894b 100644
 | 
						|
--- a/drivers/net/vxlan/vxlan_core.c
 | 
						|
+++ b/drivers/net/vxlan/vxlan_core.c
 | 
						|
@@ -606,10 +606,10 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
 | 
						|
 	if (rd == NULL)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
-	if (dst_cache_init(&rd->dst_cache, GFP_ATOMIC)) {
 | 
						|
-		kfree(rd);
 | 
						|
-		return -ENOMEM;
 | 
						|
-	}
 | 
						|
+	/* The driver can work correctly without a dst cache, so do not treat
 | 
						|
+	 * dst cache initialization errors as fatal.
 | 
						|
+	 */
 | 
						|
+	dst_cache_init(&rd->dst_cache, GFP_ATOMIC | __GFP_NOWARN);
 | 
						|
 
 | 
						|
 	rd->remote_ip = *ip;
 | 
						|
 	rd->remote_port = port;
 | 
						|
diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c
 | 
						|
index e66e86bdec20ff..9d8efec46508a1 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath11k/ce.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath11k/ce.c
 | 
						|
@@ -393,11 +393,10 @@ static int ath11k_ce_completed_recv_next(struct ath11k_ce_pipe *pipe,
 | 
						|
 		goto err;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	/* Make sure descriptor is read after the head pointer. */
 | 
						|
+	dma_rmb();
 | 
						|
+
 | 
						|
 	*nbytes = ath11k_hal_ce_dst_status_get_length(desc);
 | 
						|
-	if (*nbytes == 0) {
 | 
						|
-		ret = -EIO;
 | 
						|
-		goto err;
 | 
						|
-	}
 | 
						|
 
 | 
						|
 	*skb = pipe->dest_ring->skb[sw_index];
 | 
						|
 	pipe->dest_ring->skb[sw_index] = NULL;
 | 
						|
@@ -430,8 +429,8 @@ static void ath11k_ce_recv_process_cb(struct ath11k_ce_pipe *pipe)
 | 
						|
 		dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr,
 | 
						|
 				 max_nbytes, DMA_FROM_DEVICE);
 | 
						|
 
 | 
						|
-		if (unlikely(max_nbytes < nbytes)) {
 | 
						|
-			ath11k_warn(ab, "rxed more than expected (nbytes %d, max %d)",
 | 
						|
+		if (unlikely(max_nbytes < nbytes || nbytes == 0)) {
 | 
						|
+			ath11k_warn(ab, "unexpected rx length (nbytes %d, max %d)",
 | 
						|
 				    nbytes, max_nbytes);
 | 
						|
 			dev_kfree_skb_any(skb);
 | 
						|
 			continue;
 | 
						|
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
 | 
						|
index 609d8387c41f3e..0e8ff839cae234 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath11k/core.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath11k/core.c
 | 
						|
@@ -704,6 +704,52 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 | 
						|
 	},
 | 
						|
 };
 | 
						|
 
 | 
						|
+static const struct dmi_system_id ath11k_pm_quirk_table[] = {
 | 
						|
+	{
 | 
						|
+		.driver_data = (void *)ATH11K_PM_WOW,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "21J4"),
 | 
						|
+		},
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.driver_data = (void *)ATH11K_PM_WOW,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "21K4"),
 | 
						|
+		},
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.driver_data = (void *)ATH11K_PM_WOW,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "21K6"),
 | 
						|
+		},
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.driver_data = (void *)ATH11K_PM_WOW,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "21K8"),
 | 
						|
+		},
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.driver_data = (void *)ATH11K_PM_WOW,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "21KA"),
 | 
						|
+		},
 | 
						|
+	},
 | 
						|
+	{
 | 
						|
+		.driver_data = (void *)ATH11K_PM_WOW,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "21F9"),
 | 
						|
+		},
 | 
						|
+	},
 | 
						|
+	{}
 | 
						|
+};
 | 
						|
+
 | 
						|
 static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
 | 
						|
 {
 | 
						|
 	WARN_ON(!ab->hw_params.single_pdev_only);
 | 
						|
@@ -2018,8 +2064,17 @@ EXPORT_SYMBOL(ath11k_core_pre_init);
 | 
						|
 
 | 
						|
 int ath11k_core_init(struct ath11k_base *ab)
 | 
						|
 {
 | 
						|
+	const struct dmi_system_id *dmi_id;
 | 
						|
 	int ret;
 | 
						|
 
 | 
						|
+	dmi_id = dmi_first_match(ath11k_pm_quirk_table);
 | 
						|
+	if (dmi_id)
 | 
						|
+		ab->pm_policy = (kernel_ulong_t)dmi_id->driver_data;
 | 
						|
+	else
 | 
						|
+		ab->pm_policy = ATH11K_PM_DEFAULT;
 | 
						|
+
 | 
						|
+	ath11k_dbg(ab, ATH11K_DBG_BOOT, "pm policy %u\n", ab->pm_policy);
 | 
						|
+
 | 
						|
 	ret = ath11k_core_soc_create(ab);
 | 
						|
 	if (ret) {
 | 
						|
 		ath11k_err(ab, "failed to create soc core: %d\n", ret);
 | 
						|
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
 | 
						|
index 555deafd8399ac..812a174f74c0b3 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath11k/core.h
 | 
						|
+++ b/drivers/net/wireless/ath/ath11k/core.h
 | 
						|
@@ -842,6 +842,11 @@ struct ath11k_msi_config {
 | 
						|
 	u16 hw_rev;
 | 
						|
 };
 | 
						|
 
 | 
						|
+enum ath11k_pm_policy {
 | 
						|
+	ATH11K_PM_DEFAULT,
 | 
						|
+	ATH11K_PM_WOW,
 | 
						|
+};
 | 
						|
+
 | 
						|
 /* Master structure to hold the hw data which may be used in core module */
 | 
						|
 struct ath11k_base {
 | 
						|
 	enum ath11k_hw_rev hw_rev;
 | 
						|
@@ -994,6 +999,8 @@ struct ath11k_base {
 | 
						|
 	} testmode;
 | 
						|
 #endif
 | 
						|
 
 | 
						|
+	enum ath11k_pm_policy pm_policy;
 | 
						|
+
 | 
						|
 	/* must be last */
 | 
						|
 	u8 drv_priv[] __aligned(sizeof(void *));
 | 
						|
 };
 | 
						|
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
 | 
						|
index 4c70366ac56eb0..2b7bee66647286 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
 | 
						|
@@ -2649,7 +2649,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 | 
						|
 	struct ath11k *ar;
 | 
						|
 	struct hal_reo_dest_ring *desc;
 | 
						|
 	enum hal_reo_dest_ring_push_reason push_reason;
 | 
						|
-	u32 cookie;
 | 
						|
+	u32 cookie, info0, rx_msdu_info0, rx_mpdu_info0;
 | 
						|
 	int i;
 | 
						|
 
 | 
						|
 	for (i = 0; i < MAX_RADIOS; i++)
 | 
						|
@@ -2662,11 +2662,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 | 
						|
 try_again:
 | 
						|
 	ath11k_hal_srng_access_begin(ab, srng);
 | 
						|
 
 | 
						|
+	/* Make sure descriptor is read after the head pointer. */
 | 
						|
+	dma_rmb();
 | 
						|
+
 | 
						|
 	while (likely(desc =
 | 
						|
 	      (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
 | 
						|
 									     srng))) {
 | 
						|
 		cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
 | 
						|
-				   desc->buf_addr_info.info1);
 | 
						|
+				   READ_ONCE(desc->buf_addr_info.info1));
 | 
						|
 		buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
 | 
						|
 				   cookie);
 | 
						|
 		mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
 | 
						|
@@ -2695,8 +2698,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 | 
						|
 
 | 
						|
 		num_buffs_reaped[mac_id]++;
 | 
						|
 
 | 
						|
+		info0 = READ_ONCE(desc->info0);
 | 
						|
 		push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
 | 
						|
-					desc->info0);
 | 
						|
+					info0);
 | 
						|
 		if (unlikely(push_reason !=
 | 
						|
 			     HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
 | 
						|
 			dev_kfree_skb_any(msdu);
 | 
						|
@@ -2704,18 +2708,21 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 | 
						|
 			continue;
 | 
						|
 		}
 | 
						|
 
 | 
						|
-		rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
 | 
						|
+		rx_msdu_info0 = READ_ONCE(desc->rx_msdu_info.info0);
 | 
						|
+		rx_mpdu_info0 = READ_ONCE(desc->rx_mpdu_info.info0);
 | 
						|
+
 | 
						|
+		rxcb->is_first_msdu = !!(rx_msdu_info0 &
 | 
						|
 					 RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
 | 
						|
-		rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
 | 
						|
+		rxcb->is_last_msdu = !!(rx_msdu_info0 &
 | 
						|
 					RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
 | 
						|
-		rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
 | 
						|
+		rxcb->is_continuation = !!(rx_msdu_info0 &
 | 
						|
 					   RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
 | 
						|
 		rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
 | 
						|
-					  desc->rx_mpdu_info.meta_data);
 | 
						|
+					  READ_ONCE(desc->rx_mpdu_info.meta_data));
 | 
						|
 		rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
 | 
						|
-					 desc->rx_mpdu_info.info0);
 | 
						|
+					 rx_mpdu_info0);
 | 
						|
 		rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
 | 
						|
-				      desc->info0);
 | 
						|
+				      info0);
 | 
						|
 
 | 
						|
 		rxcb->mac_id = mac_id;
 | 
						|
 		__skb_queue_tail(&msdu_list[mac_id], msdu);
 | 
						|
diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c
 | 
						|
index ae5f7e401e21b7..f32fa104ded9de 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath11k/hal.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath11k/hal.c
 | 
						|
@@ -601,7 +601,7 @@ u32 ath11k_hal_ce_dst_status_get_length(void *buf)
 | 
						|
 		(struct hal_ce_srng_dst_status_desc *)buf;
 | 
						|
 	u32 len;
 | 
						|
 
 | 
						|
-	len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);
 | 
						|
+	len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, READ_ONCE(desc->flags));
 | 
						|
 	desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN;
 | 
						|
 
 | 
						|
 	return len;
 | 
						|
@@ -802,7 +802,7 @@ void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng)
 | 
						|
 		srng->u.src_ring.cached_tp =
 | 
						|
 			*(volatile u32 *)srng->u.src_ring.tp_addr;
 | 
						|
 	} else {
 | 
						|
-		srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
 | 
						|
+		srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr);
 | 
						|
 
 | 
						|
 		/* Try to prefetch the next descriptor in the ring */
 | 
						|
 		if (srng->flags & HAL_SRNG_FLAGS_CACHED)
 | 
						|
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
 | 
						|
index fa46e645009cf6..91e31f30d2c80f 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath11k/qmi.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
 | 
						|
@@ -1989,6 +1989,15 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
 | 
						|
 			    chunk->prev_size == chunk->size)
 | 
						|
 				continue;
 | 
						|
 
 | 
						|
+			if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
 | 
						|
+				ath11k_dbg(ab, ATH11K_DBG_QMI,
 | 
						|
+					   "size/type mismatch (current %d %u) (prev %d %u), try later with small size\n",
 | 
						|
+					    chunk->size, chunk->type,
 | 
						|
+					    chunk->prev_size, chunk->prev_type);
 | 
						|
+				ab->qmi.target_mem_delayed = true;
 | 
						|
+				return 0;
 | 
						|
+			}
 | 
						|
+
 | 
						|
 			/* cannot reuse the existing chunk */
 | 
						|
 			dma_free_coherent(ab->dev, chunk->prev_size,
 | 
						|
 					  chunk->vaddr, chunk->paddr);
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c
 | 
						|
index be0d669d31fcce..740586fe49d1f9 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/ce.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/ce.c
 | 
						|
@@ -343,11 +343,10 @@ static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe,
 | 
						|
 		goto err;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	/* Make sure descriptor is read after the head pointer. */
 | 
						|
+	dma_rmb();
 | 
						|
+
 | 
						|
 	*nbytes = ath12k_hal_ce_dst_status_get_length(desc);
 | 
						|
-	if (*nbytes == 0) {
 | 
						|
-		ret = -EIO;
 | 
						|
-		goto err;
 | 
						|
-	}
 | 
						|
 
 | 
						|
 	*skb = pipe->dest_ring->skb[sw_index];
 | 
						|
 	pipe->dest_ring->skb[sw_index] = NULL;
 | 
						|
@@ -380,8 +379,8 @@ static void ath12k_ce_recv_process_cb(struct ath12k_ce_pipe *pipe)
 | 
						|
 		dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr,
 | 
						|
 				 max_nbytes, DMA_FROM_DEVICE);
 | 
						|
 
 | 
						|
-		if (unlikely(max_nbytes < nbytes)) {
 | 
						|
-			ath12k_warn(ab, "rxed more than expected (nbytes %d, max %d)",
 | 
						|
+		if (unlikely(max_nbytes < nbytes || nbytes == 0)) {
 | 
						|
+			ath12k_warn(ab, "unexpected rx length (nbytes %d, max %d)",
 | 
						|
 				    nbytes, max_nbytes);
 | 
						|
 			dev_kfree_skb_any(skb);
 | 
						|
 			continue;
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h
 | 
						|
index 857bc5f9e946a9..f9547a3945e44b 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/ce.h
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/ce.h
 | 
						|
@@ -1,7 +1,7 @@
 | 
						|
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 | 
						|
 /*
 | 
						|
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
 | 
						|
- * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
 | 
						|
+ * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
 | 
						|
  */
 | 
						|
 
 | 
						|
 #ifndef ATH12K_CE_H
 | 
						|
@@ -39,8 +39,8 @@
 | 
						|
 #define PIPEDIR_INOUT_H2H	4 /* bidirectional, host to host */
 | 
						|
 
 | 
						|
 /* CE address/mask */
 | 
						|
-#define CE_HOST_IE_ADDRESS	0x00A1803C
 | 
						|
-#define CE_HOST_IE_2_ADDRESS	0x00A18040
 | 
						|
+#define CE_HOST_IE_ADDRESS	0x75804C
 | 
						|
+#define CE_HOST_IE_2_ADDRESS	0x758050
 | 
						|
 #define CE_HOST_IE_3_ADDRESS	CE_HOST_IE_ADDRESS
 | 
						|
 
 | 
						|
 #define CE_HOST_IE_3_SHIFT	0xC
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
 | 
						|
index 35f22a4a16cf20..69bf75ebd7518a 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
 | 
						|
@@ -1077,6 +1077,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
 | 
						|
 	bool is_mcbc = rxcb->is_mcbc;
 | 
						|
 	bool is_eapol_tkip = rxcb->is_eapol;
 | 
						|
 
 | 
						|
+	status->link_valid = 0;
 | 
						|
+
 | 
						|
 	if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) &&
 | 
						|
 	    !(status->flag & RX_FLAG_SKIP_MONITOR)) {
 | 
						|
 		he = skb_push(msdu, sizeof(known));
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
 | 
						|
index 0b5a91ab0df49c..169e16c6ed650f 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/hal.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/hal.c
 | 
						|
@@ -1565,7 +1565,7 @@ u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc
 | 
						|
 {
 | 
						|
 	u32 len;
 | 
						|
 
 | 
						|
-	len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
 | 
						|
+	len = le32_get_bits(READ_ONCE(desc->flags), HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
 | 
						|
 	desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
 | 
						|
 
 | 
						|
 	return len;
 | 
						|
@@ -1734,7 +1734,7 @@ void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng)
 | 
						|
 		srng->u.src_ring.cached_tp =
 | 
						|
 			*(volatile u32 *)srng->u.src_ring.tp_addr;
 | 
						|
 	else
 | 
						|
-		srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
 | 
						|
+		srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin()
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/hal_desc.h
 | 
						|
index 1bb840c2bef577..5fd9232ad101ee 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/hal_desc.h
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/hal_desc.h
 | 
						|
@@ -683,7 +683,7 @@ enum hal_rx_msdu_desc_reo_dest_ind {
 | 
						|
 #define RX_MSDU_DESC_INFO0_DECAP_FORMAT		GENMASK(30, 29)
 | 
						|
 
 | 
						|
 #define HAL_RX_MSDU_PKT_LENGTH_GET(val)		\
 | 
						|
-	(u32_get_bits((val), RX_MSDU_DESC_INFO0_MSDU_LENGTH))
 | 
						|
+	(le32_get_bits((val), RX_MSDU_DESC_INFO0_MSDU_LENGTH))
 | 
						|
 
 | 
						|
 struct rx_msdu_desc {
 | 
						|
 	__le32 info0;
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
 | 
						|
index 5fd80f90ecafed..7dfbabf0637d23 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/pci.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/pci.c
 | 
						|
@@ -1153,6 +1153,9 @@ void ath12k_pci_power_down(struct ath12k_base *ab)
 | 
						|
 {
 | 
						|
 	struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
 | 
						|
 
 | 
						|
+	if (!test_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
 	/* restore aspm in case firmware bootup fails */
 | 
						|
 	ath12k_pci_aspm_restore(ab_pci);
 | 
						|
 
 | 
						|
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
 | 
						|
index a0ac2f350934f9..958ac4ed5c3491 100644
 | 
						|
--- a/drivers/net/wireless/ath/ath12k/wmi.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
 | 
						|
@@ -951,14 +951,24 @@ int ath12k_wmi_vdev_down(struct ath12k *ar, u8 vdev_id)
 | 
						|
 static void ath12k_wmi_put_wmi_channel(struct ath12k_wmi_channel_params *chan,
 | 
						|
 				       struct wmi_vdev_start_req_arg *arg)
 | 
						|
 {
 | 
						|
+	u32 center_freq1 = arg->band_center_freq1;
 | 
						|
+
 | 
						|
 	memset(chan, 0, sizeof(*chan));
 | 
						|
 
 | 
						|
 	chan->mhz = cpu_to_le32(arg->freq);
 | 
						|
-	chan->band_center_freq1 = cpu_to_le32(arg->band_center_freq1);
 | 
						|
-	if (arg->mode == MODE_11AC_VHT80_80)
 | 
						|
+	chan->band_center_freq1 = cpu_to_le32(center_freq1);
 | 
						|
+	if (arg->mode == MODE_11BE_EHT160) {
 | 
						|
+		if (arg->freq > center_freq1)
 | 
						|
+			chan->band_center_freq1 = cpu_to_le32(center_freq1 + 40);
 | 
						|
+		else
 | 
						|
+			chan->band_center_freq1 = cpu_to_le32(center_freq1 - 40);
 | 
						|
+
 | 
						|
+		chan->band_center_freq2 = cpu_to_le32(center_freq1);
 | 
						|
+	} else if (arg->mode == MODE_11BE_EHT80_80) {
 | 
						|
 		chan->band_center_freq2 = cpu_to_le32(arg->band_center_freq2);
 | 
						|
-	else
 | 
						|
+	} else {
 | 
						|
 		chan->band_center_freq2 = 0;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	chan->info |= le32_encode_bits(arg->mode, WMI_CHAN_INFO_MODE);
 | 
						|
 	if (arg->passive)
 | 
						|
@@ -5503,7 +5513,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
 | 
						|
 		goto fallback;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	spin_lock(&ab->base_lock);
 | 
						|
+	spin_lock_bh(&ab->base_lock);
 | 
						|
 	if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) {
 | 
						|
 		/* Once mac is registered, ar is valid and all CC events from
 | 
						|
 		 * fw is considered to be received due to user requests
 | 
						|
@@ -5527,7 +5537,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
 | 
						|
 		ab->default_regd[pdev_idx] = regd;
 | 
						|
 	}
 | 
						|
 	ab->dfs_region = reg_info->dfs_region;
 | 
						|
-	spin_unlock(&ab->base_lock);
 | 
						|
+	spin_unlock_bh(&ab->base_lock);
 | 
						|
 
 | 
						|
 	goto mem_free;
 | 
						|
 
 | 
						|
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
 | 
						|
index a5265997b5767c..debac4699687e1 100644
 | 
						|
--- a/drivers/net/wireless/ath/carl9170/usb.c
 | 
						|
+++ b/drivers/net/wireless/ath/carl9170/usb.c
 | 
						|
@@ -438,14 +438,21 @@ static void carl9170_usb_rx_complete(struct urb *urb)
 | 
						|
 
 | 
						|
 		if (atomic_read(&ar->rx_anch_urbs) == 0) {
 | 
						|
 			/*
 | 
						|
-			 * The system is too slow to cope with
 | 
						|
-			 * the enormous workload. We have simply
 | 
						|
-			 * run out of active rx urbs and this
 | 
						|
-			 * unfortunately leads to an unpredictable
 | 
						|
-			 * device.
 | 
						|
+			 * At this point, either the system is too slow to
 | 
						|
+			 * cope with the enormous workload (so we have simply
 | 
						|
+			 * run out of active rx urbs and this unfortunately
 | 
						|
+			 * leads to an unpredictable device), or the device
 | 
						|
+			 * is not fully functional after an unsuccessful
 | 
						|
+			 * firmware loading attempts (so it doesn't pass
 | 
						|
+			 * ieee80211_register_hw() and there is no internal
 | 
						|
+			 * workqueue at all).
 | 
						|
 			 */
 | 
						|
 
 | 
						|
-			ieee80211_queue_work(ar->hw, &ar->ping_work);
 | 
						|
+			if (ar->registered)
 | 
						|
+				ieee80211_queue_work(ar->hw, &ar->ping_work);
 | 
						|
+			else
 | 
						|
+				pr_warn_once("device %s is not registered\n",
 | 
						|
+					     dev_name(&ar->udev->dev));
 | 
						|
 		}
 | 
						|
 	} else {
 | 
						|
 		/*
 | 
						|
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
 | 
						|
index d594694206b33a..906f2790f56197 100644
 | 
						|
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
 | 
						|
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
 | 
						|
@@ -44,6 +44,8 @@
 | 
						|
 	IWL_QU_C_HR_B_FW_PRE "-" __stringify(api) ".ucode"
 | 
						|
 #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
 | 
						|
 	IWL_QU_B_JF_B_FW_PRE "-" __stringify(api) ".ucode"
 | 
						|
+#define IWL_QU_C_JF_B_MODULE_FIRMWARE(api) \
 | 
						|
+	IWL_QU_C_JF_B_FW_PRE "-" __stringify(api) ".ucode"
 | 
						|
 #define IWL_CC_A_MODULE_FIRMWARE(api)			\
 | 
						|
 	IWL_CC_A_FW_PRE "-" __stringify(api) ".ucode"
 | 
						|
 
 | 
						|
@@ -423,6 +425,7 @@ const struct iwl_cfg iwl_cfg_quz_a0_hr_b0 = {
 | 
						|
 MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
 MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
 MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
+MODULE_FIRMWARE(IWL_QU_C_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
 MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
 MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
 MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 | 
						|
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
 | 
						|
index e9807fcca6ad10..5c2e8d28839765 100644
 | 
						|
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
 | 
						|
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
 | 
						|
@@ -2701,6 +2701,8 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
 | 
						|
 	for (i = 0; i < trans->num_rx_queues && pos < bufsz; i++) {
 | 
						|
 		struct iwl_rxq *rxq = &trans_pcie->rxq[i];
 | 
						|
 
 | 
						|
+		spin_lock_bh(&rxq->lock);
 | 
						|
+
 | 
						|
 		pos += scnprintf(buf + pos, bufsz - pos, "queue#: %2d\n",
 | 
						|
 				 i);
 | 
						|
 		pos += scnprintf(buf + pos, bufsz - pos, "\tread: %u\n",
 | 
						|
@@ -2721,6 +2723,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
 | 
						|
 			pos += scnprintf(buf + pos, bufsz - pos,
 | 
						|
 					 "\tclosed_rb_num: Not Allocated\n");
 | 
						|
 		}
 | 
						|
+		spin_unlock_bh(&rxq->lock);
 | 
						|
 	}
 | 
						|
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 | 
						|
 	kfree(buf);
 | 
						|
@@ -3385,8 +3388,11 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans,
 | 
						|
 		/* Dump RBs is supported only for pre-9000 devices (1 queue) */
 | 
						|
 		struct iwl_rxq *rxq = &trans_pcie->rxq[0];
 | 
						|
 		/* RBs */
 | 
						|
+		spin_lock_bh(&rxq->lock);
 | 
						|
 		num_rbs = iwl_get_closed_rb_stts(trans, rxq);
 | 
						|
 		num_rbs = (num_rbs - rxq->read) & RX_QUEUE_MASK;
 | 
						|
+		spin_unlock_bh(&rxq->lock);
 | 
						|
+
 | 
						|
 		len += num_rbs * (sizeof(*data) +
 | 
						|
 				  sizeof(struct iwl_fw_error_dump_rb) +
 | 
						|
 				  (PAGE_SIZE << trans_pcie->rx_page_order));
 | 
						|
diff --git a/drivers/net/wireless/intersil/p54/fwio.c b/drivers/net/wireless/intersil/p54/fwio.c
 | 
						|
index b52cce38115d0a..06e5df90b43ece 100644
 | 
						|
--- a/drivers/net/wireless/intersil/p54/fwio.c
 | 
						|
+++ b/drivers/net/wireless/intersil/p54/fwio.c
 | 
						|
@@ -231,6 +231,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
 | 
						|
 
 | 
						|
 	mutex_lock(&priv->eeprom_mutex);
 | 
						|
 	priv->eeprom = buf;
 | 
						|
+	priv->eeprom_slice_size = len;
 | 
						|
 	eeprom_hdr = skb_put(skb, eeprom_hdr_size + len);
 | 
						|
 
 | 
						|
 	if (priv->fw_var < 0x509) {
 | 
						|
@@ -253,6 +254,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
 | 
						|
 		ret = -EBUSY;
 | 
						|
 	}
 | 
						|
 	priv->eeprom = NULL;
 | 
						|
+	priv->eeprom_slice_size = 0;
 | 
						|
 	mutex_unlock(&priv->eeprom_mutex);
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
diff --git a/drivers/net/wireless/intersil/p54/p54.h b/drivers/net/wireless/intersil/p54/p54.h
 | 
						|
index 3356ea708d8163..97fc863fef810f 100644
 | 
						|
--- a/drivers/net/wireless/intersil/p54/p54.h
 | 
						|
+++ b/drivers/net/wireless/intersil/p54/p54.h
 | 
						|
@@ -258,6 +258,7 @@ struct p54_common {
 | 
						|
 
 | 
						|
 	/* eeprom handling */
 | 
						|
 	void *eeprom;
 | 
						|
+	size_t eeprom_slice_size;
 | 
						|
 	struct completion eeprom_comp;
 | 
						|
 	struct mutex eeprom_mutex;
 | 
						|
 };
 | 
						|
diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
 | 
						|
index 8414aa208655f6..2deb1bb54f24bd 100644
 | 
						|
--- a/drivers/net/wireless/intersil/p54/txrx.c
 | 
						|
+++ b/drivers/net/wireless/intersil/p54/txrx.c
 | 
						|
@@ -496,14 +496,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
 | 
						|
 		return ;
 | 
						|
 
 | 
						|
 	if (priv->fw_var >= 0x509) {
 | 
						|
-		memcpy(priv->eeprom, eeprom->v2.data,
 | 
						|
-		       le16_to_cpu(eeprom->v2.len));
 | 
						|
+		if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
 | 
						|
+			return;
 | 
						|
+
 | 
						|
+		memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
 | 
						|
 	} else {
 | 
						|
-		memcpy(priv->eeprom, eeprom->v1.data,
 | 
						|
-		       le16_to_cpu(eeprom->v1.len));
 | 
						|
+		if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
 | 
						|
+			return;
 | 
						|
+
 | 
						|
+		memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	priv->eeprom = NULL;
 | 
						|
+	priv->eeprom_slice_size = 0;
 | 
						|
 	tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
 | 
						|
 	dev_kfree_skb_any(tmp);
 | 
						|
 	complete(&priv->eeprom_comp);
 | 
						|
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
 | 
						|
index 70d3895762b4cd..00248e2b21ea70 100644
 | 
						|
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
 | 
						|
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
 | 
						|
@@ -17,6 +17,8 @@ static const struct usb_device_id mt76x2u_device_table[] = {
 | 
						|
 	{ USB_DEVICE(0x057c, 0x8503) },	/* Avm FRITZ!WLAN AC860 */
 | 
						|
 	{ USB_DEVICE(0x7392, 0xb711) },	/* Edimax EW 7722 UAC */
 | 
						|
 	{ USB_DEVICE(0x0e8d, 0x7632) },	/* HC-M7662BU1 */
 | 
						|
+	{ USB_DEVICE(0x0471, 0x2126) }, /* LiteOn WN4516R module, nonstandard USB connector */
 | 
						|
+	{ USB_DEVICE(0x0471, 0x7600) }, /* LiteOn WN4519R module, nonstandard USB connector */
 | 
						|
 	{ USB_DEVICE(0x2c4e, 0x0103) },	/* Mercury UD13 */
 | 
						|
 	{ USB_DEVICE(0x0846, 0x9053) },	/* Netgear A6210 */
 | 
						|
 	{ USB_DEVICE(0x045e, 0x02e6) },	/* XBox One Wireless Adapter */
 | 
						|
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
 | 
						|
index 33a14365ec9b98..3b556281151158 100644
 | 
						|
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
 | 
						|
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
 | 
						|
@@ -191,6 +191,7 @@ int mt76x2u_register_device(struct mt76x02_dev *dev)
 | 
						|
 {
 | 
						|
 	struct ieee80211_hw *hw = mt76_hw(dev);
 | 
						|
 	struct mt76_usb *usb = &dev->mt76.usb;
 | 
						|
+	bool vht;
 | 
						|
 	int err;
 | 
						|
 
 | 
						|
 	INIT_DELAYED_WORK(&dev->cal_work, mt76x2u_phy_calibrate);
 | 
						|
@@ -217,7 +218,17 @@ int mt76x2u_register_device(struct mt76x02_dev *dev)
 | 
						|
 
 | 
						|
 	/* check hw sg support in order to enable AMSDU */
 | 
						|
 	hw->max_tx_fragments = dev->mt76.usb.sg_en ? MT_TX_SG_MAX_SIZE : 1;
 | 
						|
-	err = mt76_register_device(&dev->mt76, true, mt76x02_rates,
 | 
						|
+	switch (dev->mt76.rev) {
 | 
						|
+	case 0x76320044:
 | 
						|
+		/* these ASIC revisions do not support VHT */
 | 
						|
+		vht = false;
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		vht = true;
 | 
						|
+		break;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	err = mt76_register_device(&dev->mt76, vht, mt76x02_rates,
 | 
						|
 				   ARRAY_SIZE(mt76x02_rates));
 | 
						|
 	if (err)
 | 
						|
 		goto fail;
 | 
						|
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
 | 
						|
index 31ef58e2a3d2a3..8e2ec395633171 100644
 | 
						|
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
 | 
						|
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
 | 
						|
@@ -83,6 +83,11 @@ mt7921_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band,
 | 
						|
 			he_cap_elem->phy_cap_info[9] |=
 | 
						|
 				IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
 | 
						|
 				IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
 | 
						|
+
 | 
						|
+			if (is_mt7922(phy->mt76->dev)) {
 | 
						|
+				he_cap_elem->phy_cap_info[0] |=
 | 
						|
+					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
 | 
						|
+			}
 | 
						|
 			break;
 | 
						|
 		case NL80211_IFTYPE_STATION:
 | 
						|
 			he_cap_elem->mac_cap_info[1] |=
 | 
						|
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
 | 
						|
index 35d9673ec0d8fc..8fa16f95e6a7b3 100644
 | 
						|
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
 | 
						|
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
 | 
						|
@@ -650,6 +650,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
 | 
						|
 		status->last_amsdu = amsdu_info == MT_RXD4_LAST_AMSDU_FRAME;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	/* IEEE 802.11 fragmentation can only be applied to unicast frames.
 | 
						|
+	 * Hence, drop fragments with multicast/broadcast RA.
 | 
						|
+	 * This check fixes vulnerabilities, like CVE-2020-26145.
 | 
						|
+	 */
 | 
						|
+	if ((ieee80211_has_morefrags(fc) || seq_ctrl & IEEE80211_SCTL_FRAG) &&
 | 
						|
+	    FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) != MT_RXD3_NORMAL_U2M)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
 | 
						|
 	if (hdr_trans && ieee80211_has_morefrags(fc)) {
 | 
						|
 		if (mt7996_reverse_frag0_hdr_trans(skb, hdr_gap))
 | 
						|
diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c
 | 
						|
index 311676c1ece0ac..8151bc5e00ccc8 100644
 | 
						|
--- a/drivers/net/wireless/purelifi/plfxlc/usb.c
 | 
						|
+++ b/drivers/net/wireless/purelifi/plfxlc/usb.c
 | 
						|
@@ -503,8 +503,10 @@ int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer,
 | 
						|
 			  (void *)buffer, buffer_len, complete_fn, context);
 | 
						|
 
 | 
						|
 	r = usb_submit_urb(urb, GFP_ATOMIC);
 | 
						|
-	if (r)
 | 
						|
+	if (r) {
 | 
						|
+		usb_free_urb(urb);
 | 
						|
 		dev_err(&udev->dev, "Async write submit failed (%d)\n", r);
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	return r;
 | 
						|
 }
 | 
						|
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
 | 
						|
index 3abd0c4c954bc1..3645f212021f92 100644
 | 
						|
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
 | 
						|
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
 | 
						|
@@ -155,6 +155,16 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
 | 
						|
 	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
 | 
						|
 	    init_aspm == 0x43)
 | 
						|
 		ppsc->support_aspm = false;
 | 
						|
+
 | 
						|
+	/* RTL8723BE found on some ASUSTek laptops, such as F441U and
 | 
						|
+	 * X555UQ with subsystem ID 11ad:1723 are known to output large
 | 
						|
+	 * amounts of PCIe AER errors during and after boot up, causing
 | 
						|
+	 * heavy lags, poor network throughput, and occasional lock-ups.
 | 
						|
+	 */
 | 
						|
+	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8723BE &&
 | 
						|
+	    (rtlpci->pdev->subsystem_vendor == 0x11ad &&
 | 
						|
+	     rtlpci->pdev->subsystem_device == 0x1723))
 | 
						|
+		ppsc->support_aspm = false;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static bool _rtl_pci_platform_switch_device_pci_aspm(
 | 
						|
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
 | 
						|
index 8f1d653282b7ec..eba3a2ee747f9c 100644
 | 
						|
--- a/drivers/net/wireless/realtek/rtw88/usb.c
 | 
						|
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
 | 
						|
@@ -133,7 +133,7 @@ static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len)
 | 
						|
 
 | 
						|
 	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 | 
						|
 			      RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE,
 | 
						|
-			      addr, 0, data, len, 30000);
 | 
						|
+			      addr, 0, data, len, 500);
 | 
						|
 	if (ret < 0 && ret != -ENODEV && count++ < 4)
 | 
						|
 		rtw_err(rtwdev, "write register 0x%x failed with %d\n",
 | 
						|
 			addr, ret);
 | 
						|
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
 | 
						|
index f5301c2bbf133d..9a0ffaddb83606 100644
 | 
						|
--- a/drivers/net/wireless/realtek/rtw89/cam.c
 | 
						|
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
 | 
						|
@@ -6,6 +6,7 @@
 | 
						|
 #include "debug.h"
 | 
						|
 #include "fw.h"
 | 
						|
 #include "mac.h"
 | 
						|
+#include "ps.h"
 | 
						|
 
 | 
						|
 static struct sk_buff *
 | 
						|
 rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev,
 | 
						|
@@ -333,9 +334,11 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
 | 
						|
 
 | 
						|
 	switch (key->cipher) {
 | 
						|
 	case WLAN_CIPHER_SUITE_WEP40:
 | 
						|
+		rtw89_leave_ips_by_hwflags(rtwdev);
 | 
						|
 		hw_key_type = RTW89_SEC_KEY_TYPE_WEP40;
 | 
						|
 		break;
 | 
						|
 	case WLAN_CIPHER_SUITE_WEP104:
 | 
						|
+		rtw89_leave_ips_by_hwflags(rtwdev);
 | 
						|
 		hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
 | 
						|
 		break;
 | 
						|
 	case WLAN_CIPHER_SUITE_CCMP:
 | 
						|
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
 | 
						|
index 30cc6e03c355e8..33b2543ee4d230 100644
 | 
						|
--- a/drivers/net/wireless/realtek/rtw89/pci.c
 | 
						|
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
 | 
						|
@@ -1822,22 +1822,87 @@ static int rtw89_write16_mdio_clr(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static int rtw89_dbi_write8(struct rtw89_dev *rtwdev, u16 addr, u8 data)
 | 
						|
+{
 | 
						|
+	u16 addr_2lsb = addr & B_AX_DBI_2LSB;
 | 
						|
+	u16 write_addr;
 | 
						|
+	u8 flag;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	write_addr = addr & B_AX_DBI_ADDR_MSK;
 | 
						|
+	write_addr |= u16_encode_bits(BIT(addr_2lsb), B_AX_DBI_WREN_MSK);
 | 
						|
+	rtw89_write8(rtwdev, R_AX_DBI_WDATA + addr_2lsb, data);
 | 
						|
+	rtw89_write16(rtwdev, R_AX_DBI_FLAG, write_addr);
 | 
						|
+	rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_WFLAG >> 16);
 | 
						|
+
 | 
						|
+	ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10,
 | 
						|
+				       10 * RTW89_PCI_WR_RETRY_CNT, false,
 | 
						|
+				       rtwdev, R_AX_DBI_FLAG + 2);
 | 
						|
+	if (ret)
 | 
						|
+		rtw89_err(rtwdev, "failed to write DBI register, addr=0x%X\n",
 | 
						|
+			  addr);
 | 
						|
+
 | 
						|
+	return ret;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int rtw89_dbi_read8(struct rtw89_dev *rtwdev, u16 addr, u8 *value)
 | 
						|
+{
 | 
						|
+	u16 read_addr = addr & B_AX_DBI_ADDR_MSK;
 | 
						|
+	u8 flag;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	rtw89_write16(rtwdev, R_AX_DBI_FLAG, read_addr);
 | 
						|
+	rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_RFLAG >> 16);
 | 
						|
+
 | 
						|
+	ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10,
 | 
						|
+				       10 * RTW89_PCI_WR_RETRY_CNT, false,
 | 
						|
+				       rtwdev, R_AX_DBI_FLAG + 2);
 | 
						|
+	if (ret) {
 | 
						|
+		rtw89_err(rtwdev, "failed to read DBI register, addr=0x%X\n",
 | 
						|
+			  addr);
 | 
						|
+		return ret;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	read_addr = R_AX_DBI_RDATA + (addr & 3);
 | 
						|
+	*value = rtw89_read8(rtwdev, read_addr);
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
 static int rtw89_pci_write_config_byte(struct rtw89_dev *rtwdev, u16 addr,
 | 
						|
 				       u8 data)
 | 
						|
 {
 | 
						|
 	struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
 | 
						|
+	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
 | 
						|
 	struct pci_dev *pdev = rtwpci->pdev;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	ret = pci_write_config_byte(pdev, addr, data);
 | 
						|
+	if (!ret)
 | 
						|
+		return 0;
 | 
						|
 
 | 
						|
-	return pci_write_config_byte(pdev, addr, data);
 | 
						|
+	if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
 | 
						|
+		ret = rtw89_dbi_write8(rtwdev, addr, data);
 | 
						|
+
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int rtw89_pci_read_config_byte(struct rtw89_dev *rtwdev, u16 addr,
 | 
						|
 				      u8 *value)
 | 
						|
 {
 | 
						|
 	struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
 | 
						|
+	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
 | 
						|
 	struct pci_dev *pdev = rtwpci->pdev;
 | 
						|
+	int ret;
 | 
						|
 
 | 
						|
-	return pci_read_config_byte(pdev, addr, value);
 | 
						|
+	ret = pci_read_config_byte(pdev, addr, value);
 | 
						|
+	if (!ret)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
+	if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
 | 
						|
+		ret = rtw89_dbi_read8(rtwdev, addr, value);
 | 
						|
+
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int rtw89_pci_config_byte_set(struct rtw89_dev *rtwdev, u16 addr,
 | 
						|
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
 | 
						|
index 4259b79b138fb4..119c0608b91a8a 100644
 | 
						|
--- a/drivers/net/wireless/realtek/rtw89/pci.h
 | 
						|
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
 | 
						|
@@ -42,6 +42,7 @@
 | 
						|
 #define B_AX_DBI_WFLAG			BIT(16)
 | 
						|
 #define B_AX_DBI_WREN_MSK		GENMASK(15, 12)
 | 
						|
 #define B_AX_DBI_ADDR_MSK		GENMASK(11, 2)
 | 
						|
+#define B_AX_DBI_2LSB			GENMASK(1, 0)
 | 
						|
 #define R_AX_DBI_WDATA			0x1094
 | 
						|
 #define R_AX_DBI_RDATA			0x1098
 | 
						|
 
 | 
						|
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
 | 
						|
index d86a1bd7aab089..f5f48f7e6d26e3 100644
 | 
						|
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
 | 
						|
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
 | 
						|
@@ -1201,6 +1201,11 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
 | 
						|
 	/* MLD not supported here */
 | 
						|
 	u32 bcn_int = data->link_data[0].beacon_int;
 | 
						|
 	u64 delta = abs(tsf - now);
 | 
						|
+	struct ieee80211_bss_conf *conf;
 | 
						|
+
 | 
						|
+	conf = link_conf_dereference_protected(vif, data->link_data[0].link_id);
 | 
						|
+	if (conf && !conf->enable_beacon)
 | 
						|
+		return;
 | 
						|
 
 | 
						|
 	/* adjust after beaconing with new timestamp at old TBTT */
 | 
						|
 	if (tsf > now) {
 | 
						|
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
 | 
						|
index a87dab9abba26f..08fb16918043f4 100644
 | 
						|
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
 | 
						|
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
 | 
						|
@@ -294,13 +294,14 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 | 
						|
 	struct cdns_pcie *pcie = &ep->pcie;
 | 
						|
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
 | 
						|
 	u32 val, reg;
 | 
						|
+	u16 actual_interrupts = interrupts + 1;
 | 
						|
 
 | 
						|
 	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
 | 
						|
 
 | 
						|
 	reg = cap + PCI_MSIX_FLAGS;
 | 
						|
 	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
 | 
						|
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
 | 
						|
-	val |= interrupts;
 | 
						|
+	val |= interrupts; /* 0's based value */
 | 
						|
 	cdns_pcie_ep_fn_writew(pcie, fn, reg, val);
 | 
						|
 
 | 
						|
 	/* Set MSIX BAR and offset */
 | 
						|
@@ -310,7 +311,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 | 
						|
 
 | 
						|
 	/* Set PBA BAR and offset.  BAR must match MSIX BAR */
 | 
						|
 	reg = cap + PCI_MSIX_PBA;
 | 
						|
-	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
 | 
						|
+	val = (offset + (actual_interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
 | 
						|
 	cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
 | 
						|
index 9b1256da096cb6..8af7a837a0612c 100644
 | 
						|
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
 | 
						|
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
 | 
						|
@@ -275,8 +275,8 @@ static int rockchip_pcie_phy_init(struct rockchip_pcie *rockchip)
 | 
						|
 
 | 
						|
 static void rockchip_pcie_phy_deinit(struct rockchip_pcie *rockchip)
 | 
						|
 {
 | 
						|
-	phy_exit(rockchip->phy);
 | 
						|
 	phy_power_off(rockchip->phy);
 | 
						|
+	phy_exit(rockchip->phy);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static const struct dw_pcie_ops dw_pcie_ops = {
 | 
						|
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
 | 
						|
index 503304aba9eac1..4541dfbf0e1b63 100644
 | 
						|
--- a/drivers/pci/pci.c
 | 
						|
+++ b/drivers/pci/pci.c
 | 
						|
@@ -5823,7 +5823,8 @@ static void pci_slot_unlock(struct pci_slot *slot)
 | 
						|
 			continue;
 | 
						|
 		if (dev->subordinate)
 | 
						|
 			pci_bus_unlock(dev->subordinate);
 | 
						|
-		pci_dev_unlock(dev);
 | 
						|
+		else
 | 
						|
+			pci_dev_unlock(dev);
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
 | 
						|
index 70f484b811dea7..d67ea16e69e6ac 100644
 | 
						|
--- a/drivers/pci/quirks.c
 | 
						|
+++ b/drivers/pci/quirks.c
 | 
						|
@@ -4988,6 +4988,18 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
 | 
						|
 		PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
 | 
						|
 }
 | 
						|
 
 | 
						|
+static int pci_quirk_loongson_acs(struct pci_dev *dev, u16 acs_flags)
 | 
						|
+{
 | 
						|
+	/*
 | 
						|
+	 * Loongson PCIe Root Ports don't advertise an ACS capability, but
 | 
						|
+	 * they do not allow peer-to-peer transactions between Root Ports.
 | 
						|
+	 * Allow each Root Port to be in a separate IOMMU group by masking
 | 
						|
+	 * SV/RR/CR/UF bits.
 | 
						|
+	 */
 | 
						|
+	return pci_acs_ctrl_enabled(acs_flags,
 | 
						|
+		PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
 | 
						|
+}
 | 
						|
+
 | 
						|
 /*
 | 
						|
  * Wangxun 40G/25G/10G/1G NICs have no ACS capability, but on
 | 
						|
  * multi-function devices, the hardware isolates the functions by
 | 
						|
@@ -5121,6 +5133,17 @@ static const struct pci_dev_acs_enabled {
 | 
						|
 	{ PCI_VENDOR_ID_BROADCOM, 0x1762, pci_quirk_mf_endpoint_acs },
 | 
						|
 	{ PCI_VENDOR_ID_BROADCOM, 0x1763, pci_quirk_mf_endpoint_acs },
 | 
						|
 	{ PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },
 | 
						|
+	/* Loongson PCIe Root Ports */
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x3C09, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x3C19, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x3C29, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A09, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A19, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A29, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A39, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A49, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A59, pci_quirk_loongson_acs },
 | 
						|
+	{ PCI_VENDOR_ID_LOONGSON, 0x7A69, pci_quirk_loongson_acs },
 | 
						|
 	/* Amazon Annapurna Labs */
 | 
						|
 	{ PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
 | 
						|
 	/* Zhaoxin multi-function devices */
 | 
						|
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
 | 
						|
index adc6394626ce83..f914f016b3d2ce 100644
 | 
						|
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
 | 
						|
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
 | 
						|
@@ -95,12 +95,12 @@ static u32 phy_tx_preemp_amp_tune_from_property(u32 microamp)
 | 
						|
 static u32 phy_tx_vboost_level_from_property(u32 microvolt)
 | 
						|
 {
 | 
						|
 	switch (microvolt) {
 | 
						|
-	case 0 ... 960:
 | 
						|
-		return 0;
 | 
						|
-	case 961 ... 1160:
 | 
						|
-		return 2;
 | 
						|
-	default:
 | 
						|
+	case 1156:
 | 
						|
+		return 5;
 | 
						|
+	case 844:
 | 
						|
 		return 3;
 | 
						|
+	default:
 | 
						|
+		return 4;
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
 | 
						|
index 1a39fd97a9005a..ef87a6045e073a 100644
 | 
						|
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
 | 
						|
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
 | 
						|
@@ -358,9 +358,7 @@ static int armada_37xx_pmx_set_by_name(struct pinctrl_dev *pctldev,
 | 
						|
 
 | 
						|
 	val = grp->val[func];
 | 
						|
 
 | 
						|
-	regmap_update_bits(info->regmap, reg, mask, val);
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
+	return regmap_update_bits(info->regmap, reg, mask, val);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
 | 
						|
@@ -402,10 +400,13 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip,
 | 
						|
 	struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
 | 
						|
 	unsigned int reg = OUTPUT_EN;
 | 
						|
 	unsigned int val, mask;
 | 
						|
+	int ret;
 | 
						|
 
 | 
						|
 	armada_37xx_update_reg(®, &offset);
 | 
						|
 	mask = BIT(offset);
 | 
						|
-	regmap_read(info->regmap, reg, &val);
 | 
						|
+	ret = regmap_read(info->regmap, reg, &val);
 | 
						|
+	if (ret)
 | 
						|
+		return ret;
 | 
						|
 
 | 
						|
 	if (val & mask)
 | 
						|
 		return GPIO_LINE_DIRECTION_OUT;
 | 
						|
@@ -442,11 +443,14 @@ static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset)
 | 
						|
 	struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
 | 
						|
 	unsigned int reg = INPUT_VAL;
 | 
						|
 	unsigned int val, mask;
 | 
						|
+	int ret;
 | 
						|
 
 | 
						|
 	armada_37xx_update_reg(®, &offset);
 | 
						|
 	mask = BIT(offset);
 | 
						|
 
 | 
						|
-	regmap_read(info->regmap, reg, &val);
 | 
						|
+	ret = regmap_read(info->regmap, reg, &val);
 | 
						|
+	if (ret)
 | 
						|
+		return ret;
 | 
						|
 
 | 
						|
 	return (val & mask) != 0;
 | 
						|
 }
 | 
						|
@@ -471,16 +475,17 @@ static int armada_37xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 | 
						|
 {
 | 
						|
 	struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 | 
						|
 	struct gpio_chip *chip = range->gc;
 | 
						|
+	int ret;
 | 
						|
 
 | 
						|
 	dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
 | 
						|
 		offset, range->name, offset, input ? "input" : "output");
 | 
						|
 
 | 
						|
 	if (input)
 | 
						|
-		armada_37xx_gpio_direction_input(chip, offset);
 | 
						|
+		ret = armada_37xx_gpio_direction_input(chip, offset);
 | 
						|
 	else
 | 
						|
-		armada_37xx_gpio_direction_output(chip, offset, 0);
 | 
						|
+		ret = armada_37xx_gpio_direction_output(chip, offset, 0);
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev,
 | 
						|
diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c
 | 
						|
index fd97b6ee2a8d11..ca45c1f36a89bd 100644
 | 
						|
--- a/drivers/pinctrl/pinctrl-mcp23s08.c
 | 
						|
+++ b/drivers/pinctrl/pinctrl-mcp23s08.c
 | 
						|
@@ -612,6 +612,14 @@ int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
 | 
						|
 
 | 
						|
 	mcp->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * Reset the chip - we don't really know what state it's in, so reset
 | 
						|
+	 * all pins to input first to prevent surprises.
 | 
						|
+	 */
 | 
						|
+	ret = mcp_write(mcp, MCP_IODIR, mcp->chip.ngpio == 16 ? 0xFFFF : 0xFF);
 | 
						|
+	if (ret < 0)
 | 
						|
+		return ret;
 | 
						|
+
 | 
						|
 	/* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
 | 
						|
 	 * and MCP_IOCON.HAEN = 1, so we work with all chips.
 | 
						|
 	 */
 | 
						|
diff --git a/drivers/platform/loongarch/loongson-laptop.c b/drivers/platform/loongarch/loongson-laptop.c
 | 
						|
index 99203584949daa..5fcfa3a7970b75 100644
 | 
						|
--- a/drivers/platform/loongarch/loongson-laptop.c
 | 
						|
+++ b/drivers/platform/loongarch/loongson-laptop.c
 | 
						|
@@ -56,8 +56,7 @@ static struct input_dev *generic_inputdev;
 | 
						|
 static acpi_handle hotkey_handle;
 | 
						|
 static struct key_entry hotkey_keycode_map[GENERIC_HOTKEY_MAP_MAX];
 | 
						|
 
 | 
						|
-int loongson_laptop_turn_on_backlight(void);
 | 
						|
-int loongson_laptop_turn_off_backlight(void);
 | 
						|
+static bool bl_powered;
 | 
						|
 static int loongson_laptop_backlight_update(struct backlight_device *bd);
 | 
						|
 
 | 
						|
 /* 2. ACPI Helpers and device model */
 | 
						|
@@ -354,16 +353,42 @@ static int ec_backlight_level(u8 level)
 | 
						|
 	return level;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static int ec_backlight_set_power(bool state)
 | 
						|
+{
 | 
						|
+	int status;
 | 
						|
+	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 | 
						|
+	struct acpi_object_list args = { 1, &arg0 };
 | 
						|
+
 | 
						|
+	arg0.integer.value = state;
 | 
						|
+	status = acpi_evaluate_object(NULL, "\\BLSW", &args, NULL);
 | 
						|
+	if (ACPI_FAILURE(status)) {
 | 
						|
+		pr_info("Loongson lvds error: 0x%x\n", status);
 | 
						|
+		return -EIO;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
 static int loongson_laptop_backlight_update(struct backlight_device *bd)
 | 
						|
 {
 | 
						|
-	int lvl = ec_backlight_level(bd->props.brightness);
 | 
						|
+	bool target_powered = !backlight_is_blank(bd);
 | 
						|
+	int ret = 0, lvl = ec_backlight_level(bd->props.brightness);
 | 
						|
 
 | 
						|
 	if (lvl < 0)
 | 
						|
 		return -EIO;
 | 
						|
+
 | 
						|
 	if (ec_set_brightness(lvl))
 | 
						|
 		return -EIO;
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	if (target_powered != bl_powered) {
 | 
						|
+		ret = ec_backlight_set_power(target_powered);
 | 
						|
+		if (ret < 0)
 | 
						|
+			return ret;
 | 
						|
+
 | 
						|
+		bl_powered = target_powered;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int loongson_laptop_get_brightness(struct backlight_device *bd)
 | 
						|
@@ -384,7 +409,7 @@ static const struct backlight_ops backlight_laptop_ops = {
 | 
						|
 
 | 
						|
 static int laptop_backlight_register(void)
 | 
						|
 {
 | 
						|
-	int status = 0;
 | 
						|
+	int status = 0, ret;
 | 
						|
 	struct backlight_properties props;
 | 
						|
 
 | 
						|
 	memset(&props, 0, sizeof(props));
 | 
						|
@@ -392,44 +417,20 @@ static int laptop_backlight_register(void)
 | 
						|
 	if (!acpi_evalf(hotkey_handle, &status, "ECLL", "d"))
 | 
						|
 		return -EIO;
 | 
						|
 
 | 
						|
-	props.brightness = 1;
 | 
						|
+	ret = ec_backlight_set_power(true);
 | 
						|
+	if (ret)
 | 
						|
+		return ret;
 | 
						|
+
 | 
						|
+	bl_powered = true;
 | 
						|
+
 | 
						|
 	props.max_brightness = status;
 | 
						|
+	props.brightness = ec_get_brightness();
 | 
						|
+	props.power = FB_BLANK_UNBLANK;
 | 
						|
 	props.type = BACKLIGHT_PLATFORM;
 | 
						|
 
 | 
						|
 	backlight_device_register("loongson_laptop",
 | 
						|
 				NULL, NULL, &backlight_laptop_ops, &props);
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
-int loongson_laptop_turn_on_backlight(void)
 | 
						|
-{
 | 
						|
-	int status;
 | 
						|
-	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 | 
						|
-	struct acpi_object_list args = { 1, &arg0 };
 | 
						|
-
 | 
						|
-	arg0.integer.value = 1;
 | 
						|
-	status = acpi_evaluate_object(NULL, "\\BLSW", &args, NULL);
 | 
						|
-	if (ACPI_FAILURE(status)) {
 | 
						|
-		pr_info("Loongson lvds error: 0x%x\n", status);
 | 
						|
-		return -ENODEV;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
-int loongson_laptop_turn_off_backlight(void)
 | 
						|
-{
 | 
						|
-	int status;
 | 
						|
-	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 | 
						|
-	struct acpi_object_list args = { 1, &arg0 };
 | 
						|
-
 | 
						|
-	arg0.integer.value = 0;
 | 
						|
-	status = acpi_evaluate_object(NULL, "\\BLSW", &args, NULL);
 | 
						|
-	if (ACPI_FAILURE(status)) {
 | 
						|
-		pr_info("Loongson lvds error: 0x%x\n", status);
 | 
						|
-		return -ENODEV;
 | 
						|
-	}
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
@@ -611,11 +612,17 @@ static int __init generic_acpi_laptop_init(void)
 | 
						|
 
 | 
						|
 static void __exit generic_acpi_laptop_exit(void)
 | 
						|
 {
 | 
						|
+	int i;
 | 
						|
+
 | 
						|
 	if (generic_inputdev) {
 | 
						|
-		if (input_device_registered)
 | 
						|
-			input_unregister_device(generic_inputdev);
 | 
						|
-		else
 | 
						|
+		if (!input_device_registered) {
 | 
						|
 			input_free_device(generic_inputdev);
 | 
						|
+		} else {
 | 
						|
+			input_unregister_device(generic_inputdev);
 | 
						|
+
 | 
						|
+			for (i = 0; i < ARRAY_SIZE(generic_sub_drivers); i++)
 | 
						|
+				generic_subdriver_exit(&generic_sub_drivers[i]);
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c
 | 
						|
index 946a546cd9dd01..af5cc8aa7988c1 100644
 | 
						|
--- a/drivers/platform/x86/amd/pmc/pmc.c
 | 
						|
+++ b/drivers/platform/x86/amd/pmc/pmc.c
 | 
						|
@@ -332,6 +332,8 @@ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
 | 
						|
 			return -ENOMEM;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	memset_io(dev->smu_virt_addr, 0, sizeof(struct smu_metrics));
 | 
						|
+
 | 
						|
 	/* Start the logging */
 | 
						|
 	amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_RESET, false);
 | 
						|
 	amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, false);
 | 
						|
diff --git a/drivers/platform/x86/dell/dell_rbu.c b/drivers/platform/x86/dell/dell_rbu.c
 | 
						|
index 9f51e0fcab04e1..fee20866b41e41 100644
 | 
						|
--- a/drivers/platform/x86/dell/dell_rbu.c
 | 
						|
+++ b/drivers/platform/x86/dell/dell_rbu.c
 | 
						|
@@ -292,7 +292,7 @@ static int packet_read_list(char *data, size_t * pread_length)
 | 
						|
 	remaining_bytes = *pread_length;
 | 
						|
 	bytes_read = rbu_data.packet_read_count;
 | 
						|
 
 | 
						|
-	list_for_each_entry(newpacket, (&packet_data_head.list)->next, list) {
 | 
						|
+	list_for_each_entry(newpacket, &packet_data_head.list, list) {
 | 
						|
 		bytes_copied = do_packet_read(pdest, newpacket,
 | 
						|
 			remaining_bytes, bytes_read, &temp_count);
 | 
						|
 		remaining_bytes -= bytes_copied;
 | 
						|
@@ -315,14 +315,14 @@ static void packet_empty_list(void)
 | 
						|
 {
 | 
						|
 	struct packet_data *newpacket, *tmp;
 | 
						|
 
 | 
						|
-	list_for_each_entry_safe(newpacket, tmp, (&packet_data_head.list)->next, list) {
 | 
						|
+	list_for_each_entry_safe(newpacket, tmp, &packet_data_head.list, list) {
 | 
						|
 		list_del(&newpacket->list);
 | 
						|
 
 | 
						|
 		/*
 | 
						|
 		 * zero out the RBU packet memory before freeing
 | 
						|
 		 * to make sure there are no stale RBU packets left in memory
 | 
						|
 		 */
 | 
						|
-		memset(newpacket->data, 0, rbu_data.packetsize);
 | 
						|
+		memset(newpacket->data, 0, newpacket->length);
 | 
						|
 		set_memory_wb((unsigned long)newpacket->data,
 | 
						|
 			1 << newpacket->ordernum);
 | 
						|
 		free_pages((unsigned long) newpacket->data,
 | 
						|
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
 | 
						|
index 88eefccb6ed276..50013af0537c36 100644
 | 
						|
--- a/drivers/platform/x86/ideapad-laptop.c
 | 
						|
+++ b/drivers/platform/x86/ideapad-laptop.c
 | 
						|
@@ -1101,6 +1101,9 @@ static const struct key_entry ideapad_keymap[] = {
 | 
						|
 	{ KE_KEY,	0x27 | IDEAPAD_WMI_KEY, { KEY_HELP } },
 | 
						|
 	/* Refresh Rate Toggle */
 | 
						|
 	{ KE_KEY,	0x0a | IDEAPAD_WMI_KEY, { KEY_DISPLAYTOGGLE } },
 | 
						|
+	/* Specific to some newer models */
 | 
						|
+	{ KE_KEY,	0x3e | IDEAPAD_WMI_KEY, { KEY_MICMUTE } },
 | 
						|
+	{ KE_KEY,	0x3f | IDEAPAD_WMI_KEY, { KEY_RFKILL } },
 | 
						|
 
 | 
						|
 	{ KE_END },
 | 
						|
 };
 | 
						|
diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
 | 
						|
index 10502216454824..5be3b26876151c 100644
 | 
						|
--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
 | 
						|
+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
 | 
						|
@@ -269,10 +269,13 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_
 | 
						|
 
 | 
						|
 	/* Get the package ID from the TPMI core */
 | 
						|
 	plat_info = tpmi_get_platform_data(auxdev);
 | 
						|
-	if (plat_info)
 | 
						|
-		pkg = plat_info->package_id;
 | 
						|
-	else
 | 
						|
+	if (unlikely(!plat_info)) {
 | 
						|
 		dev_info(&auxdev->dev, "Platform information is NULL\n");
 | 
						|
+		ret = -ENODEV;
 | 
						|
+		goto err_rem_common;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	pkg = plat_info->package_id;
 | 
						|
 
 | 
						|
 	for (i = 0; i < num_resources; ++i) {
 | 
						|
 		struct tpmi_uncore_power_domain_info *pd_info;
 | 
						|
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
 | 
						|
index 23c87365675742..e51fa2c694bc6d 100644
 | 
						|
--- a/drivers/power/supply/bq27xxx_battery.c
 | 
						|
+++ b/drivers/power/supply/bq27xxx_battery.c
 | 
						|
@@ -2044,7 +2044,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
 | 
						|
 	mutex_unlock(&di->lock);
 | 
						|
 
 | 
						|
 	if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
 | 
						|
-		return -ENODEV;
 | 
						|
+		return di->cache.flags;
 | 
						|
 
 | 
						|
 	switch (psp) {
 | 
						|
 	case POWER_SUPPLY_PROP_STATUS:
 | 
						|
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
 | 
						|
index 886e0a8e2abd1e..8877fa333cd02e 100644
 | 
						|
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
 | 
						|
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
 | 
						|
@@ -6,6 +6,7 @@
 | 
						|
  *	Andrew F. Davis <afd@ti.com>
 | 
						|
  */
 | 
						|
 
 | 
						|
+#include <linux/delay.h>
 | 
						|
 #include <linux/i2c.h>
 | 
						|
 #include <linux/interrupt.h>
 | 
						|
 #include <linux/module.h>
 | 
						|
@@ -32,6 +33,7 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
 | 
						|
 	struct i2c_msg msg[2];
 | 
						|
 	u8 data[2];
 | 
						|
 	int ret;
 | 
						|
+	int retry = 0;
 | 
						|
 
 | 
						|
 	if (!client->adapter)
 | 
						|
 		return -ENODEV;
 | 
						|
@@ -48,7 +50,16 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
 | 
						|
 	else
 | 
						|
 		msg[1].len = 2;
 | 
						|
 
 | 
						|
-	ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
 | 
						|
+	do {
 | 
						|
+		ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
 | 
						|
+		if (ret == -EBUSY && ++retry < 3) {
 | 
						|
+			/* sleep 10 milliseconds when busy */
 | 
						|
+			usleep_range(10000, 11000);
 | 
						|
+			continue;
 | 
						|
+		}
 | 
						|
+		break;
 | 
						|
+	} while (1);
 | 
						|
+
 | 
						|
 	if (ret < 0)
 | 
						|
 		return ret;
 | 
						|
 
 | 
						|
diff --git a/drivers/power/supply/collie_battery.c b/drivers/power/supply/collie_battery.c
 | 
						|
index 68390bd1004f04..3daf7befc0bf64 100644
 | 
						|
--- a/drivers/power/supply/collie_battery.c
 | 
						|
+++ b/drivers/power/supply/collie_battery.c
 | 
						|
@@ -440,6 +440,7 @@ static int collie_bat_probe(struct ucb1x00_dev *dev)
 | 
						|
 
 | 
						|
 static void collie_bat_remove(struct ucb1x00_dev *dev)
 | 
						|
 {
 | 
						|
+	device_init_wakeup(&ucb->dev, 0);
 | 
						|
 	free_irq(gpiod_to_irq(collie_bat_main.gpio_full), &collie_bat_main);
 | 
						|
 	power_supply_unregister(collie_bat_bu.psy);
 | 
						|
 	power_supply_unregister(collie_bat_main.psy);
 | 
						|
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
 | 
						|
index 6b7e8b7ebcef5e..b7fc260ed43bc4 100644
 | 
						|
--- a/drivers/ptp/ptp_clock.c
 | 
						|
+++ b/drivers/ptp/ptp_clock.c
 | 
						|
@@ -104,7 +104,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
 | 
						|
 	struct ptp_clock_info *ops;
 | 
						|
 	int err = -EOPNOTSUPP;
 | 
						|
 
 | 
						|
-	if (ptp_clock_freerun(ptp)) {
 | 
						|
+	if (tx->modes & (ADJ_SETOFFSET | ADJ_FREQUENCY | ADJ_OFFSET) &&
 | 
						|
+	    ptp_clock_freerun(ptp)) {
 | 
						|
 		pr_err("ptp: physical clock is free running\n");
 | 
						|
 		return -EBUSY;
 | 
						|
 	}
 | 
						|
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
 | 
						|
index d0eb4555720eba..a54124269c2f49 100644
 | 
						|
--- a/drivers/ptp/ptp_private.h
 | 
						|
+++ b/drivers/ptp/ptp_private.h
 | 
						|
@@ -89,7 +89,27 @@ static inline int queue_cnt(const struct timestamp_event_queue *q)
 | 
						|
 /* Check if ptp virtual clock is in use */
 | 
						|
 static inline bool ptp_vclock_in_use(struct ptp_clock *ptp)
 | 
						|
 {
 | 
						|
-	return !ptp->is_virtual_clock;
 | 
						|
+	bool in_use = false;
 | 
						|
+
 | 
						|
+	/* Virtual clocks can't be stacked on top of virtual clocks.
 | 
						|
+	 * Avoid acquiring the n_vclocks_mux on virtual clocks, to allow this
 | 
						|
+	 * function to be called from code paths where the n_vclocks_mux of the
 | 
						|
+	 * parent physical clock is already held. Functionally that's not an
 | 
						|
+	 * issue, but lockdep would complain, because they have the same lock
 | 
						|
+	 * class.
 | 
						|
+	 */
 | 
						|
+	if (ptp->is_virtual_clock)
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
 | 
						|
+		return true;
 | 
						|
+
 | 
						|
+	if (ptp->n_vclocks)
 | 
						|
+		in_use = true;
 | 
						|
+
 | 
						|
+	mutex_unlock(&ptp->n_vclocks_mux);
 | 
						|
+
 | 
						|
+	return in_use;
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* Check if ptp clock shall be free running */
 | 
						|
diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c
 | 
						|
index 49f8d111e54623..897642e62068a3 100644
 | 
						|
--- a/drivers/rapidio/rio_cm.c
 | 
						|
+++ b/drivers/rapidio/rio_cm.c
 | 
						|
@@ -787,6 +787,9 @@ static int riocm_ch_send(u16 ch_id, void *buf, int len)
 | 
						|
 	if (buf == NULL || ch_id == 0 || len == 0 || len > RIO_MAX_MSG_SIZE)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
+	if (len < sizeof(struct rio_ch_chan_hdr))
 | 
						|
+		return -EINVAL;		/* insufficient data from user */
 | 
						|
+
 | 
						|
 	ch = riocm_get_channel(ch_id);
 | 
						|
 	if (!ch) {
 | 
						|
 		riocm_error("%s(%d) ch_%d not found", current->comm,
 | 
						|
diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c
 | 
						|
index 5e7171b9065ae7..41fd15adfd1fdd 100644
 | 
						|
--- a/drivers/regulator/max14577-regulator.c
 | 
						|
+++ b/drivers/regulator/max14577-regulator.c
 | 
						|
@@ -40,11 +40,14 @@ static int max14577_reg_get_current_limit(struct regulator_dev *rdev)
 | 
						|
 	struct max14577 *max14577 = rdev_get_drvdata(rdev);
 | 
						|
 	const struct maxim_charger_current *limits =
 | 
						|
 		&maxim_charger_currents[max14577->dev_type];
 | 
						|
+	int ret;
 | 
						|
 
 | 
						|
 	if (rdev_get_id(rdev) != MAX14577_CHARGER)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
-	max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, ®_data);
 | 
						|
+	ret = max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, ®_data);
 | 
						|
+	if (ret < 0)
 | 
						|
+		return ret;
 | 
						|
 
 | 
						|
 	if ((reg_data & CHGCTRL4_MBCICHWRCL_MASK) == 0)
 | 
						|
 		return limits->min;
 | 
						|
diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c
 | 
						|
index 1cf04d1efb3313..8fcca52026bf15 100644
 | 
						|
--- a/drivers/regulator/max20086-regulator.c
 | 
						|
+++ b/drivers/regulator/max20086-regulator.c
 | 
						|
@@ -29,7 +29,7 @@
 | 
						|
 #define	MAX20086_REG_ADC4		0x09
 | 
						|
 
 | 
						|
 /* DEVICE IDs */
 | 
						|
-#define MAX20086_DEVICE_ID_MAX20086	0x40
 | 
						|
+#define MAX20086_DEVICE_ID_MAX20086	0x30
 | 
						|
 #define MAX20086_DEVICE_ID_MAX20087	0x20
 | 
						|
 #define MAX20086_DEVICE_ID_MAX20088	0x10
 | 
						|
 #define MAX20086_DEVICE_ID_MAX20089	0x00
 | 
						|
@@ -264,7 +264,7 @@ static int max20086_i2c_probe(struct i2c_client *i2c)
 | 
						|
 	 * shutdown.
 | 
						|
 	 */
 | 
						|
 	flags = boot_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
 | 
						|
-	chip->ena_gpiod = devm_gpiod_get(chip->dev, "enable", flags);
 | 
						|
+	chip->ena_gpiod = devm_gpiod_get_optional(chip->dev, "enable", flags);
 | 
						|
 	if (IS_ERR(chip->ena_gpiod)) {
 | 
						|
 		ret = PTR_ERR(chip->ena_gpiod);
 | 
						|
 		dev_err(chip->dev, "Failed to get enable GPIO: %d\n", ret);
 | 
						|
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
 | 
						|
index 0c363ca566ffdb..2d4ae3b5af86f6 100644
 | 
						|
--- a/drivers/remoteproc/remoteproc_core.c
 | 
						|
+++ b/drivers/remoteproc/remoteproc_core.c
 | 
						|
@@ -1616,7 +1616,7 @@ static int rproc_attach(struct rproc *rproc)
 | 
						|
 	ret = rproc_set_rsc_table(rproc);
 | 
						|
 	if (ret) {
 | 
						|
 		dev_err(dev, "can't load resource table: %d\n", ret);
 | 
						|
-		goto unprepare_device;
 | 
						|
+		goto clean_up_resources;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* reset max_notifyid */
 | 
						|
@@ -1633,7 +1633,7 @@ static int rproc_attach(struct rproc *rproc)
 | 
						|
 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
 | 
						|
 	if (ret) {
 | 
						|
 		dev_err(dev, "Failed to process resources: %d\n", ret);
 | 
						|
-		goto unprepare_device;
 | 
						|
+		goto clean_up_resources;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* Allocate carveout resources associated to rproc */
 | 
						|
@@ -1652,9 +1652,9 @@ static int rproc_attach(struct rproc *rproc)
 | 
						|
 
 | 
						|
 clean_up_resources:
 | 
						|
 	rproc_resource_cleanup(rproc);
 | 
						|
-unprepare_device:
 | 
						|
 	/* release HW resources if needed */
 | 
						|
 	rproc_unprepare_device(rproc);
 | 
						|
+	kfree(rproc->clean_table);
 | 
						|
 disable_iommu:
 | 
						|
 	rproc_disable_iommu(rproc);
 | 
						|
 	return ret;
 | 
						|
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
 | 
						|
index cb67fa80fb12c8..a95da6768f6656 100644
 | 
						|
--- a/drivers/s390/scsi/zfcp_sysfs.c
 | 
						|
+++ b/drivers/s390/scsi/zfcp_sysfs.c
 | 
						|
@@ -450,6 +450,8 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
 | 
						|
 	if (kstrtoull(buf, 0, (unsigned long long *) &fcp_lun))
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
+	flush_work(&port->rport_work);
 | 
						|
+
 | 
						|
 	retval = zfcp_unit_add(port, fcp_lun);
 | 
						|
 	if (retval)
 | 
						|
 		return retval;
 | 
						|
diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c
 | 
						|
index 5a5525054d71c8..5b079b8b7a082b 100644
 | 
						|
--- a/drivers/scsi/elx/efct/efct_hw.c
 | 
						|
+++ b/drivers/scsi/elx/efct/efct_hw.c
 | 
						|
@@ -1120,7 +1120,7 @@ int
 | 
						|
 efct_hw_parse_filter(struct efct_hw *hw, void *value)
 | 
						|
 {
 | 
						|
 	int rc = 0;
 | 
						|
-	char *p = NULL;
 | 
						|
+	char *p = NULL, *pp = NULL;
 | 
						|
 	char *token;
 | 
						|
 	u32 idx = 0;
 | 
						|
 
 | 
						|
@@ -1132,6 +1132,7 @@ efct_hw_parse_filter(struct efct_hw *hw, void *value)
 | 
						|
 		efc_log_err(hw->os, "p is NULL\n");
 | 
						|
 		return -ENOMEM;
 | 
						|
 	}
 | 
						|
+	pp = p;
 | 
						|
 
 | 
						|
 	idx = 0;
 | 
						|
 	while ((token = strsep(&p, ",")) && *token) {
 | 
						|
@@ -1144,7 +1145,7 @@ efct_hw_parse_filter(struct efct_hw *hw, void *value)
 | 
						|
 		if (idx == ARRAY_SIZE(hw->config.filter_def))
 | 
						|
 			break;
 | 
						|
 	}
 | 
						|
-	kfree(p);
 | 
						|
+	kfree(pp);
 | 
						|
 
 | 
						|
 	return rc;
 | 
						|
 }
 | 
						|
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
 | 
						|
index 5c9bc8af3c2df8..ff442833387713 100644
 | 
						|
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
 | 
						|
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
 | 
						|
@@ -5101,7 +5101,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba *phba,
 | 
						|
 		case CMD_GEN_REQUEST64_CR:
 | 
						|
 			if (iocb->ndlp == ndlp)
 | 
						|
 				return 1;
 | 
						|
-			fallthrough;
 | 
						|
+			break;
 | 
						|
 		case CMD_ELS_REQUEST64_CR:
 | 
						|
 			if (remote_id == ndlp->nlp_DID)
 | 
						|
 				return 1;
 | 
						|
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
 | 
						|
index 4a9fa00eeb798e..4cf935b7223af2 100644
 | 
						|
--- a/drivers/scsi/lpfc/lpfc_sli.c
 | 
						|
+++ b/drivers/scsi/lpfc/lpfc_sli.c
 | 
						|
@@ -6014,9 +6014,9 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba)
 | 
						|
 	phba->sli4_hba.flash_id = bf_get(lpfc_cntl_attr_flash_id, cntl_attr);
 | 
						|
 	phba->sli4_hba.asic_rev = bf_get(lpfc_cntl_attr_asic_rev, cntl_attr);
 | 
						|
 
 | 
						|
-	memset(phba->BIOSVersion, 0, sizeof(phba->BIOSVersion));
 | 
						|
-	strlcat(phba->BIOSVersion, (char *)cntl_attr->bios_ver_str,
 | 
						|
+	memcpy(phba->BIOSVersion, cntl_attr->bios_ver_str,
 | 
						|
 		sizeof(phba->BIOSVersion));
 | 
						|
+	phba->BIOSVersion[sizeof(phba->BIOSVersion) - 1] = '\0';
 | 
						|
 
 | 
						|
 	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
 | 
						|
 			"3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s, "
 | 
						|
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
 | 
						|
index 48b0ca92b44fb3..954a1cc50ba746 100644
 | 
						|
--- a/drivers/scsi/storvsc_drv.c
 | 
						|
+++ b/drivers/scsi/storvsc_drv.c
 | 
						|
@@ -362,7 +362,7 @@ MODULE_PARM_DESC(ring_avail_percent_lowater,
 | 
						|
 /*
 | 
						|
  * Timeout in seconds for all devices managed by this driver.
 | 
						|
  */
 | 
						|
-static int storvsc_timeout = 180;
 | 
						|
+static const int storvsc_timeout = 180;
 | 
						|
 
 | 
						|
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
 | 
						|
 static struct scsi_transport_template *fc_transport_template;
 | 
						|
@@ -768,7 +768,7 @@ static void  handle_multichannel_storage(struct hv_device *device, int max_chns)
 | 
						|
 		return;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	t = wait_for_completion_timeout(&request->wait_event, 10*HZ);
 | 
						|
+	t = wait_for_completion_timeout(&request->wait_event, storvsc_timeout * HZ);
 | 
						|
 	if (t == 0) {
 | 
						|
 		dev_err(dev, "Failed to create sub-channel: timed out\n");
 | 
						|
 		return;
 | 
						|
@@ -833,7 +833,7 @@ static int storvsc_execute_vstor_op(struct hv_device *device,
 | 
						|
 	if (ret != 0)
 | 
						|
 		return ret;
 | 
						|
 
 | 
						|
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 | 
						|
+	t = wait_for_completion_timeout(&request->wait_event, storvsc_timeout * HZ);
 | 
						|
 	if (t == 0)
 | 
						|
 		return -ETIMEDOUT;
 | 
						|
 
 | 
						|
@@ -1351,6 +1351,8 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size,
 | 
						|
 		return ret;
 | 
						|
 
 | 
						|
 	ret = storvsc_channel_init(device, is_fc);
 | 
						|
+	if (ret)
 | 
						|
+		vmbus_close(device->channel);
 | 
						|
 
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
@@ -1668,7 +1670,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
 | 
						|
 	if (ret != 0)
 | 
						|
 		return FAILED;
 | 
						|
 
 | 
						|
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 | 
						|
+	t = wait_for_completion_timeout(&request->wait_event, storvsc_timeout * HZ);
 | 
						|
 	if (t == 0)
 | 
						|
 		return TIMEOUT_ERROR;
 | 
						|
 
 | 
						|
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
 | 
						|
index 2d0883a6408277..31d82a042dad20 100644
 | 
						|
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
 | 
						|
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
 | 
						|
@@ -412,7 +412,7 @@ static ssize_t ad5933_store(struct device *dev,
 | 
						|
 		ret = ad5933_cmd(st, 0);
 | 
						|
 		break;
 | 
						|
 	case AD5933_OUT_SETTLING_CYCLES:
 | 
						|
-		val = clamp(val, (u16)0, (u16)0x7FF);
 | 
						|
+		val = clamp(val, (u16)0, (u16)0x7FC);
 | 
						|
 		st->settling_cycles = val;
 | 
						|
 
 | 
						|
 		/* 2x, 4x handling, see datasheet */
 | 
						|
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
 | 
						|
index 0eb342de0b0018..d7ad16f262b2eb 100644
 | 
						|
--- a/drivers/tee/tee_core.c
 | 
						|
+++ b/drivers/tee/tee_core.c
 | 
						|
@@ -10,6 +10,7 @@
 | 
						|
 #include <linux/fs.h>
 | 
						|
 #include <linux/idr.h>
 | 
						|
 #include <linux/module.h>
 | 
						|
+#include <linux/overflow.h>
 | 
						|
 #include <linux/slab.h>
 | 
						|
 #include <linux/tee_drv.h>
 | 
						|
 #include <linux/uaccess.h>
 | 
						|
@@ -19,7 +20,7 @@
 | 
						|
 
 | 
						|
 #define TEE_NUM_DEVICES	32
 | 
						|
 
 | 
						|
-#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
 | 
						|
+#define TEE_IOCTL_PARAM_SIZE(x) (size_mul(sizeof(struct tee_param), (x)))
 | 
						|
 
 | 
						|
 #define TEE_UUID_NS_NAME_SIZE	128
 | 
						|
 
 | 
						|
@@ -487,7 +488,7 @@ static int tee_ioctl_open_session(struct tee_context *ctx,
 | 
						|
 	if (copy_from_user(&arg, uarg, sizeof(arg)))
 | 
						|
 		return -EFAULT;
 | 
						|
 
 | 
						|
-	if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
 | 
						|
+	if (size_add(sizeof(arg), TEE_IOCTL_PARAM_SIZE(arg.num_params)) != buf.buf_len)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
 	if (arg.num_params) {
 | 
						|
@@ -565,7 +566,7 @@ static int tee_ioctl_invoke(struct tee_context *ctx,
 | 
						|
 	if (copy_from_user(&arg, uarg, sizeof(arg)))
 | 
						|
 		return -EFAULT;
 | 
						|
 
 | 
						|
-	if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
 | 
						|
+	if (size_add(sizeof(arg), TEE_IOCTL_PARAM_SIZE(arg.num_params)) != buf.buf_len)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
 	if (arg.num_params) {
 | 
						|
@@ -699,7 +700,7 @@ static int tee_ioctl_supp_recv(struct tee_context *ctx,
 | 
						|
 	if (get_user(num_params, &uarg->num_params))
 | 
						|
 		return -EFAULT;
 | 
						|
 
 | 
						|
-	if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) != buf.buf_len)
 | 
						|
+	if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) != buf.buf_len)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
 	params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL);
 | 
						|
@@ -798,7 +799,7 @@ static int tee_ioctl_supp_send(struct tee_context *ctx,
 | 
						|
 	    get_user(num_params, &uarg->num_params))
 | 
						|
 		return -EFAULT;
 | 
						|
 
 | 
						|
-	if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) > buf.buf_len)
 | 
						|
+	if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) > buf.buf_len)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
 	params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL);
 | 
						|
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
 | 
						|
index be7e57e1d1e36a..dab5658d9d54a6 100644
 | 
						|
--- a/drivers/tty/serial/sh-sci.c
 | 
						|
+++ b/drivers/tty/serial/sh-sci.c
 | 
						|
@@ -3424,6 +3424,22 @@ static int sci_probe_single(struct platform_device *dev,
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
 | 
						|
+		/*
 | 
						|
+		 * In case:
 | 
						|
+		 * - this is the earlycon port (mapped on index 0 in sci_ports[]) and
 | 
						|
+		 * - it now maps to an alias other than zero and
 | 
						|
+		 * - the earlycon is still alive (e.g., "earlycon keep_bootcon" is
 | 
						|
+		 *   available in bootargs)
 | 
						|
+		 *
 | 
						|
+		 * we need to avoid disabling clocks and PM domains through the runtime
 | 
						|
+		 * PM APIs called in __device_attach(). For this, increment the runtime
 | 
						|
+		 * PM reference counter (the clocks and PM domains were already enabled
 | 
						|
+		 * by the bootloader). Otherwise the earlycon may access the HW when it
 | 
						|
+		 * has no clocks enabled leading to failures (infinite loop in
 | 
						|
+		 * sci_poll_put_char()).
 | 
						|
+		 */
 | 
						|
+		pm_runtime_get_noresume(&dev->dev);
 | 
						|
+
 | 
						|
 		/*
 | 
						|
 		 * Skip cleanup the sci_port[0] in early_console_exit(), this
 | 
						|
 		 * port is the same as the earlycon one.
 | 
						|
diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
 | 
						|
index a2c7abf8c289ef..2804a4f749750a 100644
 | 
						|
--- a/drivers/uio/uio_hv_generic.c
 | 
						|
+++ b/drivers/uio/uio_hv_generic.c
 | 
						|
@@ -288,13 +288,13 @@ hv_uio_probe(struct hv_device *dev,
 | 
						|
 	pdata->info.mem[INT_PAGE_MAP].name = "int_page";
 | 
						|
 	pdata->info.mem[INT_PAGE_MAP].addr
 | 
						|
 		= (uintptr_t)vmbus_connection.int_page;
 | 
						|
-	pdata->info.mem[INT_PAGE_MAP].size = PAGE_SIZE;
 | 
						|
+	pdata->info.mem[INT_PAGE_MAP].size = HV_HYP_PAGE_SIZE;
 | 
						|
 	pdata->info.mem[INT_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
 | 
						|
 
 | 
						|
 	pdata->info.mem[MON_PAGE_MAP].name = "monitor_page";
 | 
						|
 	pdata->info.mem[MON_PAGE_MAP].addr
 | 
						|
 		= (uintptr_t)vmbus_connection.monitor_pages[1];
 | 
						|
-	pdata->info.mem[MON_PAGE_MAP].size = PAGE_SIZE;
 | 
						|
+	pdata->info.mem[MON_PAGE_MAP].size = HV_HYP_PAGE_SIZE;
 | 
						|
 	pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
 | 
						|
 
 | 
						|
 	pdata->recv_buf = vzalloc(RECV_BUFFER_SIZE);
 | 
						|
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
 | 
						|
index 7ad047bcae1711..c9ec89649b0552 100644
 | 
						|
--- a/drivers/video/console/vgacon.c
 | 
						|
+++ b/drivers/video/console/vgacon.c
 | 
						|
@@ -1139,7 +1139,7 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
 | 
						|
 				     c->vc_screenbuf_size - delta);
 | 
						|
 			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
 | 
						|
 			vga_rolled_over = 0;
 | 
						|
-		} else
 | 
						|
+		} else if (oldo - delta >= (unsigned long)c->vc_screenbuf)
 | 
						|
 			c->vc_origin -= delta;
 | 
						|
 		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
 | 
						|
 		scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char,
 | 
						|
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
 | 
						|
index 7a6f9a3cb3ba34..75996ef9992e41 100644
 | 
						|
--- a/drivers/video/fbdev/core/fbcon.c
 | 
						|
+++ b/drivers/video/fbdev/core/fbcon.c
 | 
						|
@@ -115,9 +115,14 @@ static signed char con2fb_map_boot[MAX_NR_CONSOLES];
 | 
						|
 
 | 
						|
 static struct fb_info *fbcon_info_from_console(int console)
 | 
						|
 {
 | 
						|
+	signed char fb;
 | 
						|
 	WARN_CONSOLE_UNLOCKED();
 | 
						|
 
 | 
						|
-	return fbcon_registered_fb[con2fb_map[console]];
 | 
						|
+	fb = con2fb_map[console];
 | 
						|
+	if (fb < 0 || fb >= ARRAY_SIZE(fbcon_registered_fb))
 | 
						|
+		return NULL;
 | 
						|
+
 | 
						|
+	return fbcon_registered_fb[fb];
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int logo_lines;
 | 
						|
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
 | 
						|
index ee44a46a66be1c..52bd3af5436908 100644
 | 
						|
--- a/drivers/video/fbdev/core/fbmem.c
 | 
						|
+++ b/drivers/video/fbdev/core/fbmem.c
 | 
						|
@@ -868,8 +868,10 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
 | 
						|
 	    !list_empty(&info->modelist))
 | 
						|
 		ret = fb_add_videomode(&mode, &info->modelist);
 | 
						|
 
 | 
						|
-	if (ret)
 | 
						|
+	if (ret) {
 | 
						|
+		info->var = old_var;
 | 
						|
 		return ret;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	event.info = info;
 | 
						|
 	event.data = &mode;
 | 
						|
@@ -928,7 +930,7 @@ static int fb_check_foreignness(struct fb_info *fi)
 | 
						|
 
 | 
						|
 static int do_register_framebuffer(struct fb_info *fb_info)
 | 
						|
 {
 | 
						|
-	int i;
 | 
						|
+	int i, err = 0;
 | 
						|
 	struct fb_videomode mode;
 | 
						|
 
 | 
						|
 	if (fb_check_foreignness(fb_info))
 | 
						|
@@ -937,10 +939,18 @@ static int do_register_framebuffer(struct fb_info *fb_info)
 | 
						|
 	if (num_registered_fb == FB_MAX)
 | 
						|
 		return -ENXIO;
 | 
						|
 
 | 
						|
-	num_registered_fb++;
 | 
						|
 	for (i = 0 ; i < FB_MAX; i++)
 | 
						|
 		if (!registered_fb[i])
 | 
						|
 			break;
 | 
						|
+
 | 
						|
+	if (!fb_info->modelist.prev || !fb_info->modelist.next)
 | 
						|
+		INIT_LIST_HEAD(&fb_info->modelist);
 | 
						|
+
 | 
						|
+	fb_var_to_videomode(&mode, &fb_info->var);
 | 
						|
+	err = fb_add_videomode(&mode, &fb_info->modelist);
 | 
						|
+	if (err < 0)
 | 
						|
+		return err;
 | 
						|
+
 | 
						|
 	fb_info->node = i;
 | 
						|
 	refcount_set(&fb_info->count, 1);
 | 
						|
 	mutex_init(&fb_info->lock);
 | 
						|
@@ -966,16 +976,12 @@ static int do_register_framebuffer(struct fb_info *fb_info)
 | 
						|
 	if (!fb_info->pixmap.blit_y)
 | 
						|
 		fb_info->pixmap.blit_y = ~(u32)0;
 | 
						|
 
 | 
						|
-	if (!fb_info->modelist.prev || !fb_info->modelist.next)
 | 
						|
-		INIT_LIST_HEAD(&fb_info->modelist);
 | 
						|
-
 | 
						|
 	if (fb_info->skip_vt_switch)
 | 
						|
 		pm_vt_switch_required(fb_info->device, false);
 | 
						|
 	else
 | 
						|
 		pm_vt_switch_required(fb_info->device, true);
 | 
						|
 
 | 
						|
-	fb_var_to_videomode(&mode, &fb_info->var);
 | 
						|
-	fb_add_videomode(&mode, &fb_info->modelist);
 | 
						|
+	num_registered_fb++;
 | 
						|
 	registered_fb[i] = fb_info;
 | 
						|
 
 | 
						|
 #ifdef CONFIG_GUMSTIX_AM200EPD
 | 
						|
diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c
 | 
						|
index 6c583351714100..66bfc1d0a6dc82 100644
 | 
						|
--- a/drivers/video/screen_info_pci.c
 | 
						|
+++ b/drivers/video/screen_info_pci.c
 | 
						|
@@ -7,8 +7,8 @@
 | 
						|
 
 | 
						|
 static struct pci_dev *screen_info_lfb_pdev;
 | 
						|
 static size_t screen_info_lfb_bar;
 | 
						|
-static resource_size_t screen_info_lfb_offset;
 | 
						|
-static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0);
 | 
						|
+static resource_size_t screen_info_lfb_res_start; // original start of resource
 | 
						|
+static resource_size_t screen_info_lfb_offset; // framebuffer offset within resource
 | 
						|
 
 | 
						|
 static bool __screen_info_relocation_is_valid(const struct screen_info *si, struct resource *pr)
 | 
						|
 {
 | 
						|
@@ -31,7 +31,7 @@ void screen_info_apply_fixups(void)
 | 
						|
 	if (screen_info_lfb_pdev) {
 | 
						|
 		struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar];
 | 
						|
 
 | 
						|
-		if (pr->start != screen_info_lfb_res.start) {
 | 
						|
+		if (pr->start != screen_info_lfb_res_start) {
 | 
						|
 			if (__screen_info_relocation_is_valid(si, pr)) {
 | 
						|
 				/*
 | 
						|
 				 * Only update base if we have an actual
 | 
						|
@@ -47,46 +47,67 @@ void screen_info_apply_fixups(void)
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
+static int __screen_info_lfb_pci_bus_region(const struct screen_info *si, unsigned int type,
 | 
						|
+					    struct pci_bus_region *r)
 | 
						|
+{
 | 
						|
+	u64 base, size;
 | 
						|
+
 | 
						|
+	base = __screen_info_lfb_base(si);
 | 
						|
+	if (!base)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
+	size = __screen_info_lfb_size(si, type);
 | 
						|
+	if (!size)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
+	r->start = base;
 | 
						|
+	r->end = base + size - 1;
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
 static void screen_info_fixup_lfb(struct pci_dev *pdev)
 | 
						|
 {
 | 
						|
 	unsigned int type;
 | 
						|
-	struct resource res[SCREEN_INFO_MAX_RESOURCES];
 | 
						|
-	size_t i, numres;
 | 
						|
+	struct pci_bus_region bus_region;
 | 
						|
 	int ret;
 | 
						|
+	struct resource r = {
 | 
						|
+		.flags = IORESOURCE_MEM,
 | 
						|
+	};
 | 
						|
+	const struct resource *pr;
 | 
						|
 	const struct screen_info *si = &screen_info;
 | 
						|
 
 | 
						|
 	if (screen_info_lfb_pdev)
 | 
						|
 		return; // already found
 | 
						|
 
 | 
						|
 	type = screen_info_video_type(si);
 | 
						|
-	if (type != VIDEO_TYPE_EFI)
 | 
						|
-		return; // only applies to EFI
 | 
						|
+	if (!__screen_info_has_lfb(type))
 | 
						|
+		return; // only applies to EFI; maybe VESA
 | 
						|
 
 | 
						|
-	ret = screen_info_resources(si, res, ARRAY_SIZE(res));
 | 
						|
+	ret = __screen_info_lfb_pci_bus_region(si, type, &bus_region);
 | 
						|
 	if (ret < 0)
 | 
						|
 		return;
 | 
						|
-	numres = ret;
 | 
						|
 
 | 
						|
-	for (i = 0; i < numres; ++i) {
 | 
						|
-		struct resource *r = &res[i];
 | 
						|
-		const struct resource *pr;
 | 
						|
-
 | 
						|
-		if (!(r->flags & IORESOURCE_MEM))
 | 
						|
-			continue;
 | 
						|
-		pr = pci_find_resource(pdev, r);
 | 
						|
-		if (!pr)
 | 
						|
-			continue;
 | 
						|
-
 | 
						|
-		/*
 | 
						|
-		 * We've found a PCI device with the framebuffer
 | 
						|
-		 * resource. Store away the parameters to track
 | 
						|
-		 * relocation of the framebuffer aperture.
 | 
						|
-		 */
 | 
						|
-		screen_info_lfb_pdev = pdev;
 | 
						|
-		screen_info_lfb_bar = pr - pdev->resource;
 | 
						|
-		screen_info_lfb_offset = r->start - pr->start;
 | 
						|
-		memcpy(&screen_info_lfb_res, r, sizeof(screen_info_lfb_res));
 | 
						|
-	}
 | 
						|
+	/*
 | 
						|
+	 * Translate the PCI bus address to resource. Account
 | 
						|
+	 * for an offset if the framebuffer is behind a PCI host
 | 
						|
+	 * bridge.
 | 
						|
+	 */
 | 
						|
+	pcibios_bus_to_resource(pdev->bus, &r, &bus_region);
 | 
						|
+
 | 
						|
+	pr = pci_find_resource(pdev, &r);
 | 
						|
+	if (!pr)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * We've found a PCI device with the framebuffer
 | 
						|
+	 * resource. Store away the parameters to track
 | 
						|
+	 * relocation of the framebuffer aperture.
 | 
						|
+	 */
 | 
						|
+	screen_info_lfb_pdev = pdev;
 | 
						|
+	screen_info_lfb_bar = pr - pdev->resource;
 | 
						|
+	screen_info_lfb_offset = r.start - pr->start;
 | 
						|
+	screen_info_lfb_res_start = bus_region.start;
 | 
						|
 }
 | 
						|
 DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16,
 | 
						|
 			       screen_info_fixup_lfb);
 | 
						|
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
 | 
						|
index d708c091bf1b1e..180526220d8c42 100644
 | 
						|
--- a/drivers/watchdog/da9052_wdt.c
 | 
						|
+++ b/drivers/watchdog/da9052_wdt.c
 | 
						|
@@ -164,6 +164,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
 | 
						|
 	da9052_wdt = &driver_data->wdt;
 | 
						|
 
 | 
						|
 	da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
 | 
						|
+	da9052_wdt->min_hw_heartbeat_ms = DA9052_TWDMIN;
 | 
						|
 	da9052_wdt->info = &da9052_wdt_info;
 | 
						|
 	da9052_wdt->ops = &da9052_wdt_ops;
 | 
						|
 	da9052_wdt->parent = dev;
 | 
						|
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
 | 
						|
index 29026ba4f02290..84e855e8929b03 100644
 | 
						|
--- a/fs/ceph/super.c
 | 
						|
+++ b/fs/ceph/super.c
 | 
						|
@@ -1220,6 +1220,7 @@ static int ceph_set_super(struct super_block *s, struct fs_context *fc)
 | 
						|
 	s->s_time_min = 0;
 | 
						|
 	s->s_time_max = U32_MAX;
 | 
						|
 	s->s_flags |= SB_NODIRATIME | SB_NOATIME;
 | 
						|
+	s->s_magic = CEPH_SUPER_MAGIC;
 | 
						|
 
 | 
						|
 	ceph_fscrypt_set_ops(s);
 | 
						|
 
 | 
						|
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
 | 
						|
index 18677cd4e62f54..2df99cd1034d4e 100644
 | 
						|
--- a/fs/configfs/dir.c
 | 
						|
+++ b/fs/configfs/dir.c
 | 
						|
@@ -593,7 +593,7 @@ static int populate_attrs(struct config_item *item)
 | 
						|
 				break;
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
-	if (t->ct_bin_attrs) {
 | 
						|
+	if (!error && t->ct_bin_attrs) {
 | 
						|
 		for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) {
 | 
						|
 			error = configfs_create_bin_file(item, bin_attr);
 | 
						|
 			if (error)
 | 
						|
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
 | 
						|
index 81fe87fcbfa068..b55d5e2abeb3cb 100644
 | 
						|
--- a/fs/ext4/ext4.h
 | 
						|
+++ b/fs/ext4/ext4.h
 | 
						|
@@ -3351,6 +3351,13 @@ static inline unsigned int ext4_flex_bg_size(struct ext4_sb_info *sbi)
 | 
						|
 	return 1 << sbi->s_log_groups_per_flex;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline loff_t ext4_get_maxbytes(struct inode *inode)
 | 
						|
+{
 | 
						|
+	if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
 | 
						|
+		return inode->i_sb->s_maxbytes;
 | 
						|
+	return EXT4_SB(inode->i_sb)->s_bitmap_maxbytes;
 | 
						|
+}
 | 
						|
+
 | 
						|
 #define ext4_std_error(sb, errno)				\
 | 
						|
 do {								\
 | 
						|
 	if ((errno))						\
 | 
						|
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
 | 
						|
index 39e3661a80c433..a3d3c9fc64262f 100644
 | 
						|
--- a/fs/ext4/extents.c
 | 
						|
+++ b/fs/ext4/extents.c
 | 
						|
@@ -2374,18 +2374,19 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
 | 
						|
 int ext4_ext_index_trans_blocks(struct inode *inode, int extents)
 | 
						|
 {
 | 
						|
 	int index;
 | 
						|
-	int depth;
 | 
						|
 
 | 
						|
 	/* If we are converting the inline data, only one is needed here. */
 | 
						|
 	if (ext4_has_inline_data(inode))
 | 
						|
 		return 1;
 | 
						|
 
 | 
						|
-	depth = ext_depth(inode);
 | 
						|
-
 | 
						|
+	/*
 | 
						|
+	 * Extent tree can change between the time we estimate credits and
 | 
						|
+	 * the time we actually modify the tree. Assume the worst case.
 | 
						|
+	 */
 | 
						|
 	if (extents <= 1)
 | 
						|
-		index = depth * 2;
 | 
						|
+		index = EXT4_MAX_EXTENT_DEPTH * 2;
 | 
						|
 	else
 | 
						|
-		index = depth * 3;
 | 
						|
+		index = EXT4_MAX_EXTENT_DEPTH * 3;
 | 
						|
 
 | 
						|
 	return index;
 | 
						|
 }
 | 
						|
@@ -4969,12 +4970,7 @@ static const struct iomap_ops ext4_iomap_xattr_ops = {
 | 
						|
 
 | 
						|
 static int ext4_fiemap_check_ranges(struct inode *inode, u64 start, u64 *len)
 | 
						|
 {
 | 
						|
-	u64 maxbytes;
 | 
						|
-
 | 
						|
-	if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
 | 
						|
-		maxbytes = inode->i_sb->s_maxbytes;
 | 
						|
-	else
 | 
						|
-		maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes;
 | 
						|
+	u64 maxbytes = ext4_get_maxbytes(inode);
 | 
						|
 
 | 
						|
 	if (*len == 0)
 | 
						|
 		return -EINVAL;
 | 
						|
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
 | 
						|
index c71af675e310af..b37e0e4a71bfbe 100644
 | 
						|
--- a/fs/ext4/file.c
 | 
						|
+++ b/fs/ext4/file.c
 | 
						|
@@ -898,12 +898,7 @@ static int ext4_file_open(struct inode *inode, struct file *filp)
 | 
						|
 loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
 | 
						|
 {
 | 
						|
 	struct inode *inode = file->f_mapping->host;
 | 
						|
-	loff_t maxbytes;
 | 
						|
-
 | 
						|
-	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
 | 
						|
-		maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes;
 | 
						|
-	else
 | 
						|
-		maxbytes = inode->i_sb->s_maxbytes;
 | 
						|
+	loff_t maxbytes = ext4_get_maxbytes(inode);
 | 
						|
 
 | 
						|
 	switch (whence) {
 | 
						|
 	default:
 | 
						|
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
 | 
						|
index 3f363276ddd360..c85647a0ba09fb 100644
 | 
						|
--- a/fs/ext4/inline.c
 | 
						|
+++ b/fs/ext4/inline.c
 | 
						|
@@ -392,7 +392,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode,
 | 
						|
-				    unsigned int len)
 | 
						|
+				    loff_t len)
 | 
						|
 {
 | 
						|
 	int ret, size, no_expand;
 | 
						|
 	struct ext4_inode_info *ei = EXT4_I(inode);
 | 
						|
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
 | 
						|
index 86245e27be18db..9694ef6b996e47 100644
 | 
						|
--- a/fs/ext4/inode.c
 | 
						|
+++ b/fs/ext4/inode.c
 | 
						|
@@ -1011,7 +1011,12 @@ int ext4_walk_page_buffers(handle_t *handle, struct inode *inode,
 | 
						|
  */
 | 
						|
 static int ext4_dirty_journalled_data(handle_t *handle, struct buffer_head *bh)
 | 
						|
 {
 | 
						|
-	folio_mark_dirty(bh->b_folio);
 | 
						|
+	struct folio *folio = bh->b_folio;
 | 
						|
+	struct inode *inode = folio->mapping->host;
 | 
						|
+
 | 
						|
+	/* only regular files have a_ops */
 | 
						|
+	if (S_ISREG(inode->i_mode))
 | 
						|
+		folio_mark_dirty(folio);
 | 
						|
 	return ext4_handle_dirty_metadata(handle, NULL, bh);
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -4939,7 +4944,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
 | 
						|
 		ei->i_file_acl |=
 | 
						|
 			((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
 | 
						|
 	inode->i_size = ext4_isize(sb, raw_inode);
 | 
						|
-	if ((size = i_size_read(inode)) < 0) {
 | 
						|
+	size = i_size_read(inode);
 | 
						|
+	if (size < 0 || size > ext4_get_maxbytes(inode)) {
 | 
						|
 		ext4_error_inode(inode, function, line, 0,
 | 
						|
 				 "iget: bad i_size value: %lld", size);
 | 
						|
 		ret = -EFSCORRUPTED;
 | 
						|
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
 | 
						|
index f7ef69f44f3d84..e962de4ecaa2f6 100644
 | 
						|
--- a/fs/f2fs/compress.c
 | 
						|
+++ b/fs/f2fs/compress.c
 | 
						|
@@ -176,8 +176,7 @@ void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page)
 | 
						|
 #ifdef CONFIG_F2FS_FS_LZO
 | 
						|
 static int lzo_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 {
 | 
						|
-	cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
 | 
						|
-				LZO1X_MEM_COMPRESS, GFP_NOFS);
 | 
						|
+	cc->private = f2fs_vmalloc(LZO1X_MEM_COMPRESS);
 | 
						|
 	if (!cc->private)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
@@ -187,7 +186,7 @@ static int lzo_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 
 | 
						|
 static void lzo_destroy_compress_ctx(struct compress_ctx *cc)
 | 
						|
 {
 | 
						|
-	kvfree(cc->private);
 | 
						|
+	vfree(cc->private);
 | 
						|
 	cc->private = NULL;
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -244,7 +243,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 		size = LZ4HC_MEM_COMPRESS;
 | 
						|
 #endif
 | 
						|
 
 | 
						|
-	cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS);
 | 
						|
+	cc->private = f2fs_vmalloc(size);
 | 
						|
 	if (!cc->private)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
@@ -259,7 +258,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 
 | 
						|
 static void lz4_destroy_compress_ctx(struct compress_ctx *cc)
 | 
						|
 {
 | 
						|
-	kvfree(cc->private);
 | 
						|
+	vfree(cc->private);
 | 
						|
 	cc->private = NULL;
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -340,8 +339,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 	params = zstd_get_params(level, cc->rlen);
 | 
						|
 	workspace_size = zstd_cstream_workspace_bound(¶ms.cParams);
 | 
						|
 
 | 
						|
-	workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
 | 
						|
-					workspace_size, GFP_NOFS);
 | 
						|
+	workspace = f2fs_vmalloc(workspace_size);
 | 
						|
 	if (!workspace)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
@@ -349,7 +347,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 	if (!stream) {
 | 
						|
 		f2fs_err_ratelimited(F2FS_I_SB(cc->inode),
 | 
						|
 				"%s zstd_init_cstream failed", __func__);
 | 
						|
-		kvfree(workspace);
 | 
						|
+		vfree(workspace);
 | 
						|
 		return -EIO;
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -362,7 +360,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
 | 
						|
 
 | 
						|
 static void zstd_destroy_compress_ctx(struct compress_ctx *cc)
 | 
						|
 {
 | 
						|
-	kvfree(cc->private);
 | 
						|
+	vfree(cc->private);
 | 
						|
 	cc->private = NULL;
 | 
						|
 	cc->private2 = NULL;
 | 
						|
 }
 | 
						|
@@ -421,8 +419,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)
 | 
						|
 
 | 
						|
 	workspace_size = zstd_dstream_workspace_bound(max_window_size);
 | 
						|
 
 | 
						|
-	workspace = f2fs_kvmalloc(F2FS_I_SB(dic->inode),
 | 
						|
-					workspace_size, GFP_NOFS);
 | 
						|
+	workspace = f2fs_vmalloc(workspace_size);
 | 
						|
 	if (!workspace)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
@@ -430,7 +427,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)
 | 
						|
 	if (!stream) {
 | 
						|
 		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
 | 
						|
 				"%s zstd_init_dstream failed", __func__);
 | 
						|
-		kvfree(workspace);
 | 
						|
+		vfree(workspace);
 | 
						|
 		return -EIO;
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -442,7 +439,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)
 | 
						|
 
 | 
						|
 static void zstd_destroy_decompress_ctx(struct decompress_io_ctx *dic)
 | 
						|
 {
 | 
						|
-	kvfree(dic->private);
 | 
						|
+	vfree(dic->private);
 | 
						|
 	dic->private = NULL;
 | 
						|
 	dic->private2 = NULL;
 | 
						|
 }
 | 
						|
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
 | 
						|
index 911c4c64d729d3..2d9a86129bd8de 100644
 | 
						|
--- a/fs/f2fs/f2fs.h
 | 
						|
+++ b/fs/f2fs/f2fs.h
 | 
						|
@@ -3449,6 +3449,11 @@ static inline void *f2fs_kvzalloc(struct f2fs_sb_info *sbi,
 | 
						|
 	return f2fs_kvmalloc(sbi, size, flags | __GFP_ZERO);
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline void *f2fs_vmalloc(size_t size)
 | 
						|
+{
 | 
						|
+	return vmalloc(size);
 | 
						|
+}
 | 
						|
+
 | 
						|
 static inline int get_extra_isize(struct inode *inode)
 | 
						|
 {
 | 
						|
 	return F2FS_I(inode)->i_extra_isize / sizeof(__le32);
 | 
						|
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
 | 
						|
index 06941705e8939f..66721c2093c023 100644
 | 
						|
--- a/fs/f2fs/inode.c
 | 
						|
+++ b/fs/f2fs/inode.c
 | 
						|
@@ -35,7 +35,9 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync)
 | 
						|
 	if (f2fs_inode_dirtied(inode, sync))
 | 
						|
 		return;
 | 
						|
 
 | 
						|
-	if (f2fs_is_atomic_file(inode))
 | 
						|
+	/* only atomic file w/ FI_ATOMIC_COMMITTED can be set vfs dirty */
 | 
						|
+	if (f2fs_is_atomic_file(inode) &&
 | 
						|
+			!is_inode_flag_set(inode, FI_ATOMIC_COMMITTED))
 | 
						|
 		return;
 | 
						|
 
 | 
						|
 	mark_inode_dirty_sync(inode);
 | 
						|
@@ -285,6 +287,12 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
 | 
						|
 		return false;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	if (ino_of_node(node_page) == fi->i_xattr_nid) {
 | 
						|
+		f2fs_warn(sbi, "%s: corrupted inode i_ino=%lx, xnid=%x, run fsck to fix.",
 | 
						|
+			  __func__, inode->i_ino, fi->i_xattr_nid);
 | 
						|
+		return false;
 | 
						|
+	}
 | 
						|
+
 | 
						|
 	if (f2fs_has_extra_attr(inode)) {
 | 
						|
 		if (!f2fs_sb_has_extra_attr(sbi)) {
 | 
						|
 			f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off",
 | 
						|
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
 | 
						|
index 4d6f0a6365fe19..523009bc273209 100644
 | 
						|
--- a/fs/f2fs/namei.c
 | 
						|
+++ b/fs/f2fs/namei.c
 | 
						|
@@ -560,6 +560,15 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
 | 
						|
 		goto fail;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	if (unlikely(inode->i_nlink == 0)) {
 | 
						|
+		f2fs_warn(F2FS_I_SB(inode), "%s: inode (ino=%lx) has zero i_nlink",
 | 
						|
+			  __func__, inode->i_ino);
 | 
						|
+		err = -EFSCORRUPTED;
 | 
						|
+		set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
 | 
						|
+		f2fs_put_page(page, 0);
 | 
						|
+		goto fail;
 | 
						|
+	}
 | 
						|
+
 | 
						|
 	f2fs_balance_fs(sbi, true);
 | 
						|
 
 | 
						|
 	f2fs_lock_op(sbi);
 | 
						|
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
 | 
						|
index 156d92b945258a..c7714e954cb540 100644
 | 
						|
--- a/fs/f2fs/segment.c
 | 
						|
+++ b/fs/f2fs/segment.c
 | 
						|
@@ -372,7 +372,13 @@ static int __f2fs_commit_atomic_write(struct inode *inode)
 | 
						|
 	} else {
 | 
						|
 		sbi->committed_atomic_block += fi->atomic_write_cnt;
 | 
						|
 		set_inode_flag(inode, FI_ATOMIC_COMMITTED);
 | 
						|
+
 | 
						|
+		/*
 | 
						|
+		 * inode may has no FI_ATOMIC_DIRTIED flag due to no write
 | 
						|
+		 * before commit.
 | 
						|
+		 */
 | 
						|
 		if (is_inode_flag_set(inode, FI_ATOMIC_DIRTIED)) {
 | 
						|
+			/* clear atomic dirty status and set vfs dirty status */
 | 
						|
 			clear_inode_flag(inode, FI_ATOMIC_DIRTIED);
 | 
						|
 			f2fs_mark_inode_dirty_sync(inode, true);
 | 
						|
 		}
 | 
						|
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
 | 
						|
index 6b3cafbe98672e..702137eafaa675 100644
 | 
						|
--- a/fs/f2fs/super.c
 | 
						|
+++ b/fs/f2fs/super.c
 | 
						|
@@ -1500,7 +1500,9 @@ int f2fs_inode_dirtied(struct inode *inode, bool sync)
 | 
						|
 	}
 | 
						|
 	spin_unlock(&sbi->inode_lock[DIRTY_META]);
 | 
						|
 
 | 
						|
-	if (!ret && f2fs_is_atomic_file(inode))
 | 
						|
+	/* if atomic write is not committed, set inode w/ atomic dirty */
 | 
						|
+	if (!ret && f2fs_is_atomic_file(inode) &&
 | 
						|
+			!is_inode_flag_set(inode, FI_ATOMIC_COMMITTED))
 | 
						|
 		set_inode_flag(inode, FI_ATOMIC_DIRTIED);
 | 
						|
 
 | 
						|
 	return ret;
 | 
						|
@@ -3608,6 +3610,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
 | 
						|
 	block_t user_block_count, valid_user_blocks;
 | 
						|
 	block_t avail_node_count, valid_node_count;
 | 
						|
 	unsigned int nat_blocks, nat_bits_bytes, nat_bits_blocks;
 | 
						|
+	unsigned int sit_blk_cnt;
 | 
						|
 	int i, j;
 | 
						|
 
 | 
						|
 	total = le32_to_cpu(raw_super->segment_count);
 | 
						|
@@ -3719,6 +3722,13 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
 | 
						|
 		return 1;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	sit_blk_cnt = DIV_ROUND_UP(main_segs, SIT_ENTRY_PER_BLOCK);
 | 
						|
+	if (sit_bitmap_size * 8 < sit_blk_cnt) {
 | 
						|
+		f2fs_err(sbi, "Wrong bitmap size: sit: %u, sit_blk_cnt:%u",
 | 
						|
+			 sit_bitmap_size, sit_blk_cnt);
 | 
						|
+		return 1;
 | 
						|
+	}
 | 
						|
+
 | 
						|
 	cp_pack_start_sum = __start_sum_addr(sbi);
 | 
						|
 	cp_payload = __cp_payload(sbi);
 | 
						|
 	if (cp_pack_start_sum < cp_payload + 1 ||
 | 
						|
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
 | 
						|
index e028e55e67d95f..07aac73377d8fe 100644
 | 
						|
--- a/fs/gfs2/lock_dlm.c
 | 
						|
+++ b/fs/gfs2/lock_dlm.c
 | 
						|
@@ -959,14 +959,15 @@ static int control_mount(struct gfs2_sbd *sdp)
 | 
						|
 		if (sdp->sd_args.ar_spectator) {
 | 
						|
 			fs_info(sdp, "Recovery is required. Waiting for a "
 | 
						|
 				"non-spectator to mount.\n");
 | 
						|
+			spin_unlock(&ls->ls_recover_spin);
 | 
						|
 			msleep_interruptible(1000);
 | 
						|
 		} else {
 | 
						|
 			fs_info(sdp, "control_mount wait1 block %u start %u "
 | 
						|
 				"mount %u lvb %u flags %lx\n", block_gen,
 | 
						|
 				start_gen, mount_gen, lvb_gen,
 | 
						|
 				ls->ls_recover_flags);
 | 
						|
+			spin_unlock(&ls->ls_recover_spin);
 | 
						|
 		}
 | 
						|
-		spin_unlock(&ls->ls_recover_spin);
 | 
						|
 		goto restart;
 | 
						|
 	}
 | 
						|
 
 | 
						|
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
 | 
						|
index 76adab83cac368..c2b8ad0b24c443 100644
 | 
						|
--- a/fs/jbd2/transaction.c
 | 
						|
+++ b/fs/jbd2/transaction.c
 | 
						|
@@ -1499,7 +1499,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
 | 
						|
 				jh->b_next_transaction == transaction);
 | 
						|
 		spin_unlock(&jh->b_state_lock);
 | 
						|
 	}
 | 
						|
-	if (jh->b_modified == 1) {
 | 
						|
+	if (data_race(jh->b_modified == 1)) {
 | 
						|
 		/* If it's in our transaction it must be in BJ_Metadata list. */
 | 
						|
 		if (data_race(jh->b_transaction == transaction &&
 | 
						|
 		    jh->b_jlist != BJ_Metadata)) {
 | 
						|
@@ -1518,7 +1518,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
 | 
						|
 		goto out;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	journal = transaction->t_journal;
 | 
						|
 	spin_lock(&jh->b_state_lock);
 | 
						|
 
 | 
						|
 	if (is_handle_aborted(handle)) {
 | 
						|
@@ -1533,6 +1532,8 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
 | 
						|
 		goto out_unlock_bh;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	journal = transaction->t_journal;
 | 
						|
+
 | 
						|
 	if (jh->b_modified == 0) {
 | 
						|
 		/*
 | 
						|
 		 * This buffer's got modified and becoming part
 | 
						|
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
 | 
						|
index ef3a1e1b6cb065..fda9f4d6093f94 100644
 | 
						|
--- a/fs/jffs2/erase.c
 | 
						|
+++ b/fs/jffs2/erase.c
 | 
						|
@@ -425,7 +425,9 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
 | 
						|
 			.totlen =	cpu_to_je32(c->cleanmarker_size)
 | 
						|
 		};
 | 
						|
 
 | 
						|
-		jffs2_prealloc_raw_node_refs(c, jeb, 1);
 | 
						|
+		ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
 | 
						|
+		if (ret)
 | 
						|
+			goto filebad;
 | 
						|
 
 | 
						|
 		marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
 | 
						|
 
 | 
						|
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
 | 
						|
index 29671e33a1714c..62879c218d4b11 100644
 | 
						|
--- a/fs/jffs2/scan.c
 | 
						|
+++ b/fs/jffs2/scan.c
 | 
						|
@@ -256,7 +256,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
 | 
						|
 
 | 
						|
 		jffs2_dbg(1, "%s(): Skipping %d bytes in nextblock to ensure page alignment\n",
 | 
						|
 			  __func__, skip);
 | 
						|
-		jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
 | 
						|
+		ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
 | 
						|
+		if (ret)
 | 
						|
+			goto out;
 | 
						|
 		jffs2_scan_dirty_space(c, c->nextblock, skip);
 | 
						|
 	}
 | 
						|
 #endif
 | 
						|
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
 | 
						|
index 4fe64519870f1a..d83372d3e1a07b 100644
 | 
						|
--- a/fs/jffs2/summary.c
 | 
						|
+++ b/fs/jffs2/summary.c
 | 
						|
@@ -858,7 +858,10 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
 | 
						|
 	spin_unlock(&c->erase_completion_lock);
 | 
						|
 
 | 
						|
 	jeb = c->nextblock;
 | 
						|
-	jffs2_prealloc_raw_node_refs(c, jeb, 1);
 | 
						|
+	ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
 | 
						|
+
 | 
						|
+	if (ret)
 | 
						|
+		goto out;
 | 
						|
 
 | 
						|
 	if (!c->summary->sum_num || !c->summary->sum_list_head) {
 | 
						|
 		JFFS2_WARNING("Empty summary info!!!\n");
 | 
						|
@@ -872,6 +875,8 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
 | 
						|
 	datasize += padsize;
 | 
						|
 
 | 
						|
 	ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
 | 
						|
+
 | 
						|
+out:
 | 
						|
 	spin_lock(&c->erase_completion_lock);
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
 | 
						|
index a142287d86f68e..688a24e9bc8bb8 100644
 | 
						|
--- a/fs/nfs/read.c
 | 
						|
+++ b/fs/nfs/read.c
 | 
						|
@@ -56,7 +56,8 @@ static int nfs_return_empty_folio(struct folio *folio)
 | 
						|
 {
 | 
						|
 	folio_zero_segment(folio, 0, folio_size(folio));
 | 
						|
 	folio_mark_uptodate(folio);
 | 
						|
-	folio_unlock(folio);
 | 
						|
+	if (nfs_netfs_folio_unlock(folio))
 | 
						|
+		folio_unlock(folio);
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
 | 
						|
index b3eca08f15b13e..b2bbf3d6d177e8 100644
 | 
						|
--- a/fs/nfsd/nfs4proc.c
 | 
						|
+++ b/fs/nfsd/nfs4proc.c
 | 
						|
@@ -3580,7 +3580,8 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
 | 
						|
 	struct nfs4_op_map *allow = &cstate->clp->cl_spo_must_allow;
 | 
						|
 	u32 opiter;
 | 
						|
 
 | 
						|
-	if (!cstate->minorversion)
 | 
						|
+	if (rqstp->rq_procinfo != &nfsd_version4.vs_proc[NFSPROC4_COMPOUND] ||
 | 
						|
+	    cstate->minorversion == 0)
 | 
						|
 		return false;
 | 
						|
 
 | 
						|
 	if (cstate->spo_must_allowed)
 | 
						|
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
 | 
						|
index 710a54c7dffc54..623f522b156599 100644
 | 
						|
--- a/fs/nfsd/nfssvc.c
 | 
						|
+++ b/fs/nfsd/nfssvc.c
 | 
						|
@@ -432,13 +432,13 @@ static int nfsd_startup_net(struct net *net, const struct cred *cred)
 | 
						|
 	if (ret)
 | 
						|
 		goto out_filecache;
 | 
						|
 
 | 
						|
+#ifdef CONFIG_NFSD_V4_2_INTER_SSC
 | 
						|
+	nfsd4_ssc_init_umount_work(nn);
 | 
						|
+#endif
 | 
						|
 	ret = nfs4_state_start_net(net);
 | 
						|
 	if (ret)
 | 
						|
 		goto out_reply_cache;
 | 
						|
 
 | 
						|
-#ifdef CONFIG_NFSD_V4_2_INTER_SSC
 | 
						|
-	nfsd4_ssc_init_umount_work(nn);
 | 
						|
-#endif
 | 
						|
 	nn->nfsd_net_up = true;
 | 
						|
 	return 0;
 | 
						|
 
 | 
						|
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
 | 
						|
index 74979466729535..d64742ba371aa5 100644
 | 
						|
--- a/fs/smb/client/cached_dir.c
 | 
						|
+++ b/fs/smb/client/cached_dir.c
 | 
						|
@@ -484,8 +484,17 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
 | 
						|
 		spin_lock(&cfids->cfid_list_lock);
 | 
						|
 		list_for_each_entry(cfid, &cfids->entries, entry) {
 | 
						|
 			tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC);
 | 
						|
-			if (tmp_list == NULL)
 | 
						|
-				break;
 | 
						|
+			if (tmp_list == NULL) {
 | 
						|
+				/*
 | 
						|
+				 * If the malloc() fails, we won't drop all
 | 
						|
+				 * dentries, and unmounting is likely to trigger
 | 
						|
+				 * a 'Dentry still in use' error.
 | 
						|
+				 */
 | 
						|
+				cifs_tcon_dbg(VFS, "Out of memory while dropping dentries\n");
 | 
						|
+				spin_unlock(&cfids->cfid_list_lock);
 | 
						|
+				spin_unlock(&cifs_sb->tlink_tree_lock);
 | 
						|
+				goto done;
 | 
						|
+			}
 | 
						|
 			spin_lock(&cfid->fid_lock);
 | 
						|
 			tmp_list->dentry = cfid->dentry;
 | 
						|
 			cfid->dentry = NULL;
 | 
						|
@@ -497,6 +506,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
 | 
						|
 	}
 | 
						|
 	spin_unlock(&cifs_sb->tlink_tree_lock);
 | 
						|
 
 | 
						|
+done:
 | 
						|
 	list_for_each_entry_safe(tmp_list, q, &entry, entry) {
 | 
						|
 		list_del(&tmp_list->entry);
 | 
						|
 		dput(tmp_list->dentry);
 | 
						|
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
 | 
						|
index 1dfe79d947a62f..bc8a812ff95f8b 100644
 | 
						|
--- a/fs/smb/client/cached_dir.h
 | 
						|
+++ b/fs/smb/client/cached_dir.h
 | 
						|
@@ -21,10 +21,10 @@ struct cached_dirent {
 | 
						|
 struct cached_dirents {
 | 
						|
 	bool is_valid:1;
 | 
						|
 	bool is_failed:1;
 | 
						|
-	struct dir_context *ctx; /*
 | 
						|
-				  * Only used to make sure we only take entries
 | 
						|
-				  * from a single context. Never dereferenced.
 | 
						|
-				  */
 | 
						|
+	struct file *file; /*
 | 
						|
+			    * Used to associate the cache with a single
 | 
						|
+			    * open file instance.
 | 
						|
+			    */
 | 
						|
 	struct mutex de_mutex;
 | 
						|
 	int pos;		 /* Expected ctx->pos */
 | 
						|
 	struct list_head entries;
 | 
						|
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
 | 
						|
index 39117343b703fa..6a4ed99e162c5d 100644
 | 
						|
--- a/fs/smb/client/cifsglob.h
 | 
						|
+++ b/fs/smb/client/cifsglob.h
 | 
						|
@@ -1053,6 +1053,7 @@ struct cifs_chan {
 | 
						|
 };
 | 
						|
 
 | 
						|
 #define CIFS_SES_FLAG_SCALE_CHANNELS (0x1)
 | 
						|
+#define CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES (0x2)
 | 
						|
 
 | 
						|
 /*
 | 
						|
  * Session structure.  One of these for each uid session with a particular host
 | 
						|
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
 | 
						|
index 3faaee33ad4558..8fa5fe0a8c5c59 100644
 | 
						|
--- a/fs/smb/client/connect.c
 | 
						|
+++ b/fs/smb/client/connect.c
 | 
						|
@@ -132,13 +132,9 @@ static void smb2_query_server_interfaces(struct work_struct *work)
 | 
						|
 	rc = server->ops->query_server_interfaces(xid, tcon, false);
 | 
						|
 	free_xid(xid);
 | 
						|
 
 | 
						|
-	if (rc) {
 | 
						|
-		if (rc == -EOPNOTSUPP)
 | 
						|
-			return;
 | 
						|
-
 | 
						|
+	if (rc)
 | 
						|
 		cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
 | 
						|
 				__func__, rc);
 | 
						|
-	}
 | 
						|
 
 | 
						|
 	queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
 | 
						|
 			   (SMB_INTERFACE_POLL_INTERVAL * HZ));
 | 
						|
@@ -393,6 +389,13 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
 | 
						|
 	if (!cifs_tcp_ses_needs_reconnect(server, 1))
 | 
						|
 		return 0;
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * if smb session has been marked for reconnect, also reconnect all
 | 
						|
+	 * connections. This way, the other connections do not end up bad.
 | 
						|
+	 */
 | 
						|
+	if (mark_smb_session)
 | 
						|
+		cifs_signal_cifsd_for_reconnect(server, mark_smb_session);
 | 
						|
+
 | 
						|
 	cifs_mark_tcp_ses_conns_for_reconnect(server, mark_smb_session);
 | 
						|
 
 | 
						|
 	cifs_abort_connection(server);
 | 
						|
@@ -401,7 +404,8 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
 | 
						|
 		try_to_freeze();
 | 
						|
 		cifs_server_lock(server);
 | 
						|
 
 | 
						|
-		if (!cifs_swn_set_server_dstaddr(server)) {
 | 
						|
+		if (!cifs_swn_set_server_dstaddr(server) &&
 | 
						|
+		    !SERVER_IS_CHAN(server)) {
 | 
						|
 			/* resolve the hostname again to make sure that IP address is up-to-date */
 | 
						|
 			rc = reconn_set_ipaddr_from_hostname(server);
 | 
						|
 			cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n", __func__, rc);
 | 
						|
@@ -3978,6 +3982,7 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
 | 
						|
 		return 0;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	server->lstrp = jiffies;
 | 
						|
 	server->tcpStatus = CifsInNegotiate;
 | 
						|
 	spin_unlock(&server->srv_lock);
 | 
						|
 
 | 
						|
diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c
 | 
						|
index 830f2a292bb00d..ec58c0e507244b 100644
 | 
						|
--- a/fs/smb/client/namespace.c
 | 
						|
+++ b/fs/smb/client/namespace.c
 | 
						|
@@ -146,6 +146,9 @@ static char *automount_fullpath(struct dentry *dentry, void *page)
 | 
						|
 	}
 | 
						|
 	spin_unlock(&tcon->tc_lock);
 | 
						|
 
 | 
						|
+	if (unlikely(!page))
 | 
						|
+		return ERR_PTR(-ENOMEM);
 | 
						|
+
 | 
						|
 	s = dentry_path_raw(dentry, page, PATH_MAX);
 | 
						|
 	if (IS_ERR(s))
 | 
						|
 		return s;
 | 
						|
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
 | 
						|
index e616be8196deda..222348ae625866 100644
 | 
						|
--- a/fs/smb/client/readdir.c
 | 
						|
+++ b/fs/smb/client/readdir.c
 | 
						|
@@ -850,9 +850,9 @@ static bool emit_cached_dirents(struct cached_dirents *cde,
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void update_cached_dirents_count(struct cached_dirents *cde,
 | 
						|
-					struct dir_context *ctx)
 | 
						|
+					struct file *file)
 | 
						|
 {
 | 
						|
-	if (cde->ctx != ctx)
 | 
						|
+	if (cde->file != file)
 | 
						|
 		return;
 | 
						|
 	if (cde->is_valid || cde->is_failed)
 | 
						|
 		return;
 | 
						|
@@ -861,9 +861,9 @@ static void update_cached_dirents_count(struct cached_dirents *cde,
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void finished_cached_dirents_count(struct cached_dirents *cde,
 | 
						|
-					struct dir_context *ctx)
 | 
						|
+					struct dir_context *ctx, struct file *file)
 | 
						|
 {
 | 
						|
-	if (cde->ctx != ctx)
 | 
						|
+	if (cde->file != file)
 | 
						|
 		return;
 | 
						|
 	if (cde->is_valid || cde->is_failed)
 | 
						|
 		return;
 | 
						|
@@ -876,11 +876,12 @@ static void finished_cached_dirents_count(struct cached_dirents *cde,
 | 
						|
 static void add_cached_dirent(struct cached_dirents *cde,
 | 
						|
 			      struct dir_context *ctx,
 | 
						|
 			      const char *name, int namelen,
 | 
						|
-			      struct cifs_fattr *fattr)
 | 
						|
+			      struct cifs_fattr *fattr,
 | 
						|
+				  struct file *file)
 | 
						|
 {
 | 
						|
 	struct cached_dirent *de;
 | 
						|
 
 | 
						|
-	if (cde->ctx != ctx)
 | 
						|
+	if (cde->file != file)
 | 
						|
 		return;
 | 
						|
 	if (cde->is_valid || cde->is_failed)
 | 
						|
 		return;
 | 
						|
@@ -910,7 +911,8 @@ static void add_cached_dirent(struct cached_dirents *cde,
 | 
						|
 static bool cifs_dir_emit(struct dir_context *ctx,
 | 
						|
 			  const char *name, int namelen,
 | 
						|
 			  struct cifs_fattr *fattr,
 | 
						|
-			  struct cached_fid *cfid)
 | 
						|
+			  struct cached_fid *cfid,
 | 
						|
+			  struct file *file)
 | 
						|
 {
 | 
						|
 	bool rc;
 | 
						|
 	ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
 | 
						|
@@ -922,7 +924,7 @@ static bool cifs_dir_emit(struct dir_context *ctx,
 | 
						|
 	if (cfid) {
 | 
						|
 		mutex_lock(&cfid->dirents.de_mutex);
 | 
						|
 		add_cached_dirent(&cfid->dirents, ctx, name, namelen,
 | 
						|
-				  fattr);
 | 
						|
+				  fattr, file);
 | 
						|
 		mutex_unlock(&cfid->dirents.de_mutex);
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -1022,7 +1024,7 @@ static int cifs_filldir(char *find_entry, struct file *file,
 | 
						|
 	cifs_prime_dcache(file_dentry(file), &name, &fattr);
 | 
						|
 
 | 
						|
 	return !cifs_dir_emit(ctx, name.name, name.len,
 | 
						|
-			      &fattr, cfid);
 | 
						|
+			      &fattr, cfid, file);
 | 
						|
 }
 | 
						|
 
 | 
						|
 
 | 
						|
@@ -1073,8 +1075,8 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
 | 
						|
 	 * we need to initialize scanning and storing the
 | 
						|
 	 * directory content.
 | 
						|
 	 */
 | 
						|
-	if (ctx->pos == 0 && cfid->dirents.ctx == NULL) {
 | 
						|
-		cfid->dirents.ctx = ctx;
 | 
						|
+	if (ctx->pos == 0 && cfid->dirents.file == NULL) {
 | 
						|
+		cfid->dirents.file = file;
 | 
						|
 		cfid->dirents.pos = 2;
 | 
						|
 	}
 | 
						|
 	/*
 | 
						|
@@ -1142,7 +1144,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
 | 
						|
 	} else {
 | 
						|
 		if (cfid) {
 | 
						|
 			mutex_lock(&cfid->dirents.de_mutex);
 | 
						|
-			finished_cached_dirents_count(&cfid->dirents, ctx);
 | 
						|
+			finished_cached_dirents_count(&cfid->dirents, ctx, file);
 | 
						|
 			mutex_unlock(&cfid->dirents.de_mutex);
 | 
						|
 		}
 | 
						|
 		cifs_dbg(FYI, "Could not find entry\n");
 | 
						|
@@ -1183,7 +1185,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
 | 
						|
 		ctx->pos++;
 | 
						|
 		if (cfid) {
 | 
						|
 			mutex_lock(&cfid->dirents.de_mutex);
 | 
						|
-			update_cached_dirents_count(&cfid->dirents, ctx);
 | 
						|
+			update_cached_dirents_count(&cfid->dirents, file);
 | 
						|
 			mutex_unlock(&cfid->dirents.de_mutex);
 | 
						|
 		}
 | 
						|
 
 | 
						|
diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
 | 
						|
index b6556fe3dfa11a..4d45c31336df17 100644
 | 
						|
--- a/fs/smb/client/reparse.c
 | 
						|
+++ b/fs/smb/client/reparse.c
 | 
						|
@@ -738,7 +738,6 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 | 
						|
 	if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK))
 | 
						|
 		return false;
 | 
						|
 
 | 
						|
-	fattr->cf_dtype = S_DT(fattr->cf_mode);
 | 
						|
 	return true;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
 | 
						|
index f04922eb45d4c9..8959206a0353eb 100644
 | 
						|
--- a/fs/smb/client/sess.c
 | 
						|
+++ b/fs/smb/client/sess.c
 | 
						|
@@ -485,6 +485,10 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
 | 
						|
 
 | 
						|
 	ses->chans[chan_index].iface = iface;
 | 
						|
 	spin_unlock(&ses->chan_lock);
 | 
						|
+
 | 
						|
+	spin_lock(&server->srv_lock);
 | 
						|
+	memcpy(&server->dstaddr, &iface->sockaddr, sizeof(server->dstaddr));
 | 
						|
+	spin_unlock(&server->srv_lock);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
@@ -554,8 +558,7 @@ cifs_ses_add_channel(struct cifs_ses *ses,
 | 
						|
 	ctx->domainauto = ses->domainAuto;
 | 
						|
 	ctx->domainname = ses->domainName;
 | 
						|
 
 | 
						|
-	/* no hostname for extra channels */
 | 
						|
-	ctx->server_hostname = "";
 | 
						|
+	ctx->server_hostname = ses->server->hostname;
 | 
						|
 
 | 
						|
 	ctx->username = ses->user_name;
 | 
						|
 	ctx->password = ses->password;
 | 
						|
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
 | 
						|
index 3e88e8b3c16ec2..e0f58600933059 100644
 | 
						|
--- a/fs/smb/client/smb2pdu.c
 | 
						|
+++ b/fs/smb/client/smb2pdu.c
 | 
						|
@@ -425,14 +425,23 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
 | 
						|
 	if (!rc &&
 | 
						|
 	    (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
 | 
						|
 	    server->ops->query_server_interfaces) {
 | 
						|
-		mutex_unlock(&ses->session_mutex);
 | 
						|
-
 | 
						|
 		/*
 | 
						|
-		 * query server network interfaces, in case they change
 | 
						|
+		 * query server network interfaces, in case they change.
 | 
						|
+		 * Also mark the session as pending this update while the query
 | 
						|
+		 * is in progress. This will be used to avoid calling
 | 
						|
+		 * smb2_reconnect recursively.
 | 
						|
 		 */
 | 
						|
+		ses->flags |= CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
 | 
						|
 		xid = get_xid();
 | 
						|
 		rc = server->ops->query_server_interfaces(xid, tcon, false);
 | 
						|
 		free_xid(xid);
 | 
						|
+		ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
 | 
						|
+
 | 
						|
+		/* regardless of rc value, setup polling */
 | 
						|
+		queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
 | 
						|
+				   (SMB_INTERFACE_POLL_INTERVAL * HZ));
 | 
						|
+
 | 
						|
+		mutex_unlock(&ses->session_mutex);
 | 
						|
 
 | 
						|
 		if (rc == -EOPNOTSUPP && ses->chan_count > 1) {
 | 
						|
 			/*
 | 
						|
@@ -452,11 +461,8 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
 | 
						|
 		if (ses->chan_max > ses->chan_count &&
 | 
						|
 		    ses->iface_count &&
 | 
						|
 		    !SERVER_IS_CHAN(server)) {
 | 
						|
-			if (ses->chan_count == 1) {
 | 
						|
+			if (ses->chan_count == 1)
 | 
						|
 				cifs_server_dbg(VFS, "supports multichannel now\n");
 | 
						|
-				queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
 | 
						|
-						 (SMB_INTERFACE_POLL_INTERVAL * HZ));
 | 
						|
-			}
 | 
						|
 
 | 
						|
 			cifs_try_adding_channels(ses);
 | 
						|
 		}
 | 
						|
@@ -574,11 +580,18 @@ static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
 | 
						|
 			       struct TCP_Server_Info *server,
 | 
						|
 			       void **request_buf, unsigned int *total_len)
 | 
						|
 {
 | 
						|
-	/* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
 | 
						|
-	if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
 | 
						|
+	/*
 | 
						|
+	 * Skip reconnect in one of the following cases:
 | 
						|
+	 * 1. For FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs
 | 
						|
+	 * 2. For FSCTL_QUERY_NETWORK_INTERFACE_INFO IOCTL when called from
 | 
						|
+	 * smb2_reconnect (indicated by CIFS_SES_FLAG_SCALE_CHANNELS ses flag)
 | 
						|
+	 */
 | 
						|
+	if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO ||
 | 
						|
+	    (opcode == FSCTL_QUERY_NETWORK_INTERFACE_INFO &&
 | 
						|
+	     (tcon->ses->flags & CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES)))
 | 
						|
 		return __smb2_plain_req_init(SMB2_IOCTL, tcon, server,
 | 
						|
 					     request_buf, total_len);
 | 
						|
-	}
 | 
						|
+
 | 
						|
 	return smb2_plain_req_init(SMB2_IOCTL, tcon, server,
 | 
						|
 				   request_buf, total_len);
 | 
						|
 }
 | 
						|
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
 | 
						|
index 2269963e500819..7b2560612bd6aa 100644
 | 
						|
--- a/fs/smb/client/transport.c
 | 
						|
+++ b/fs/smb/client/transport.c
 | 
						|
@@ -1025,14 +1025,16 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
 | 
						|
 	uint index = 0;
 | 
						|
 	unsigned int min_in_flight = UINT_MAX, max_in_flight = 0;
 | 
						|
 	struct TCP_Server_Info *server = NULL;
 | 
						|
-	int i;
 | 
						|
+	int i, start, cur;
 | 
						|
 
 | 
						|
 	if (!ses)
 | 
						|
 		return NULL;
 | 
						|
 
 | 
						|
 	spin_lock(&ses->chan_lock);
 | 
						|
+	start = atomic_inc_return(&ses->chan_seq);
 | 
						|
 	for (i = 0; i < ses->chan_count; i++) {
 | 
						|
-		server = ses->chans[i].server;
 | 
						|
+		cur = (start + i) % ses->chan_count;
 | 
						|
+		server = ses->chans[cur].server;
 | 
						|
 		if (!server || server->terminate)
 | 
						|
 			continue;
 | 
						|
 
 | 
						|
@@ -1049,17 +1051,15 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
 | 
						|
 		 */
 | 
						|
 		if (server->in_flight < min_in_flight) {
 | 
						|
 			min_in_flight = server->in_flight;
 | 
						|
-			index = i;
 | 
						|
+			index = cur;
 | 
						|
 		}
 | 
						|
 		if (server->in_flight > max_in_flight)
 | 
						|
 			max_in_flight = server->in_flight;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* if all channels are equally loaded, fall back to round-robin */
 | 
						|
-	if (min_in_flight == max_in_flight) {
 | 
						|
-		index = (uint)atomic_inc_return(&ses->chan_seq);
 | 
						|
-		index %= ses->chan_count;
 | 
						|
-	}
 | 
						|
+	if (min_in_flight == max_in_flight)
 | 
						|
+		index = (uint)start % ses->chan_count;
 | 
						|
 
 | 
						|
 	server = ses->chans[index].server;
 | 
						|
 	spin_unlock(&ses->chan_lock);
 | 
						|
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
 | 
						|
index 9bd817427a345a..d8325504a1624b 100644
 | 
						|
--- a/fs/smb/server/smb2pdu.c
 | 
						|
+++ b/fs/smb/server/smb2pdu.c
 | 
						|
@@ -1599,17 +1599,18 @@ static int krb5_authenticate(struct ksmbd_work *work,
 | 
						|
 	out_len = work->response_sz -
 | 
						|
 		(le16_to_cpu(rsp->SecurityBufferOffset) + 4);
 | 
						|
 
 | 
						|
-	/* Check previous session */
 | 
						|
-	prev_sess_id = le64_to_cpu(req->PreviousSessionId);
 | 
						|
-	if (prev_sess_id && prev_sess_id != sess->id)
 | 
						|
-		destroy_previous_session(conn, sess->user, prev_sess_id);
 | 
						|
-
 | 
						|
 	retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
 | 
						|
 					 out_blob, &out_len);
 | 
						|
 	if (retval) {
 | 
						|
 		ksmbd_debug(SMB, "krb5 authentication failed\n");
 | 
						|
 		return -EINVAL;
 | 
						|
 	}
 | 
						|
+
 | 
						|
+	/* Check previous session */
 | 
						|
+	prev_sess_id = le64_to_cpu(req->PreviousSessionId);
 | 
						|
+	if (prev_sess_id && prev_sess_id != sess->id)
 | 
						|
+		destroy_previous_session(conn, sess->user, prev_sess_id);
 | 
						|
+
 | 
						|
 	rsp->SecurityBufferLength = cpu_to_le16(out_len);
 | 
						|
 
 | 
						|
 	if ((conn->sign || server_conf.enforced_signing) ||
 | 
						|
diff --git a/fs/xattr.c b/fs/xattr.c
 | 
						|
index 5fed22c22a2be8..7574d24b982ef6 100644
 | 
						|
--- a/fs/xattr.c
 | 
						|
+++ b/fs/xattr.c
 | 
						|
@@ -1342,6 +1342,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
 | 
						|
 		buffer += err;
 | 
						|
 	}
 | 
						|
 	remaining_size -= err;
 | 
						|
+	err = 0;
 | 
						|
 
 | 
						|
 	read_lock(&xattrs->lock);
 | 
						|
 	for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {
 | 
						|
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
 | 
						|
index 85c2dcf2b70484..0a242008524151 100644
 | 
						|
--- a/include/acpi/actypes.h
 | 
						|
+++ b/include/acpi/actypes.h
 | 
						|
@@ -527,7 +527,7 @@ typedef u64 acpi_integer;
 | 
						|
 
 | 
						|
 /* Support for the special RSDP signature (8 characters) */
 | 
						|
 
 | 
						|
-#define ACPI_VALIDATE_RSDP_SIG(a)       (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
 | 
						|
+#define ACPI_VALIDATE_RSDP_SIG(a)       (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, (sizeof(a) < 8) ? ACPI_NAMESEG_SIZE : 8))
 | 
						|
 #define ACPI_MAKE_RSDP_SIG(dest)        (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
 | 
						|
 
 | 
						|
 /* Support for OEMx signature (x can be any character) */
 | 
						|
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
 | 
						|
index 1b76d2f83eac6a..7c6f4006389daa 100644
 | 
						|
--- a/include/linux/acpi.h
 | 
						|
+++ b/include/linux/acpi.h
 | 
						|
@@ -1098,13 +1098,13 @@ void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
 | 
						|
 
 | 
						|
 acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state,
 | 
						|
 					   u32 val_a, u32 val_b);
 | 
						|
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_X86)
 | 
						|
 struct acpi_s2idle_dev_ops {
 | 
						|
 	struct list_head list_node;
 | 
						|
 	void (*prepare)(void);
 | 
						|
 	void (*check)(void);
 | 
						|
 	void (*restore)(void);
 | 
						|
 };
 | 
						|
+#if defined(CONFIG_SUSPEND) && defined(CONFIG_X86)
 | 
						|
 int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg);
 | 
						|
 void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg);
 | 
						|
 int acpi_get_lps0_constraint(struct acpi_device *adev);
 | 
						|
@@ -1113,6 +1113,13 @@ static inline int acpi_get_lps0_constraint(struct device *dev)
 | 
						|
 {
 | 
						|
 	return ACPI_STATE_UNKNOWN;
 | 
						|
 }
 | 
						|
+static inline int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)
 | 
						|
+{
 | 
						|
+	return -ENODEV;
 | 
						|
+}
 | 
						|
+static inline void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg)
 | 
						|
+{
 | 
						|
+}
 | 
						|
 #endif /* CONFIG_SUSPEND && CONFIG_X86 */
 | 
						|
 #ifndef CONFIG_IA64
 | 
						|
 void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
 | 
						|
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
 | 
						|
index 9b02961d65ee66..45f2f278b50a8a 100644
 | 
						|
--- a/include/linux/atmdev.h
 | 
						|
+++ b/include/linux/atmdev.h
 | 
						|
@@ -249,6 +249,12 @@ static inline void atm_account_tx(struct atm_vcc *vcc, struct sk_buff *skb)
 | 
						|
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline void atm_return_tx(struct atm_vcc *vcc, struct sk_buff *skb)
 | 
						|
+{
 | 
						|
+	WARN_ON_ONCE(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize,
 | 
						|
+					   &sk_atm(vcc)->sk_wmem_alloc));
 | 
						|
+}
 | 
						|
+
 | 
						|
 static inline void atm_force_charge(struct atm_vcc *vcc,int truesize)
 | 
						|
 {
 | 
						|
 	atomic_add(truesize, &sk_atm(vcc)->sk_rmem_alloc);
 | 
						|
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
 | 
						|
index fc2023d07f6931..8b051b8c40345d 100644
 | 
						|
--- a/include/linux/hugetlb.h
 | 
						|
+++ b/include/linux/hugetlb.h
 | 
						|
@@ -281,6 +281,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma,
 | 
						|
 
 | 
						|
 bool is_hugetlb_entry_migration(pte_t pte);
 | 
						|
 void hugetlb_unshare_all_pmds(struct vm_area_struct *vma);
 | 
						|
+void hugetlb_split(struct vm_area_struct *vma, unsigned long addr);
 | 
						|
 
 | 
						|
 #else /* !CONFIG_HUGETLB_PAGE */
 | 
						|
 
 | 
						|
@@ -491,6 +492,8 @@ static inline vm_fault_t hugetlb_fault(struct mm_struct *mm,
 | 
						|
 
 | 
						|
 static inline void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) { }
 | 
						|
 
 | 
						|
+static inline void hugetlb_split(struct vm_area_struct *vma, unsigned long addr) {}
 | 
						|
+
 | 
						|
 #endif /* !CONFIG_HUGETLB_PAGE */
 | 
						|
 /*
 | 
						|
  * hugepages at page global directory. If arch support
 | 
						|
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
 | 
						|
index afa575e362a473..7c6da19fff9f06 100644
 | 
						|
--- a/include/linux/mmc/card.h
 | 
						|
+++ b/include/linux/mmc/card.h
 | 
						|
@@ -297,6 +297,7 @@ struct mmc_card {
 | 
						|
 #define MMC_QUIRK_BROKEN_SD_CACHE	(1<<15)	/* Disable broken SD cache support */
 | 
						|
 #define MMC_QUIRK_BROKEN_CACHE_FLUSH	(1<<16)	/* Don't flush cache until the write has occurred */
 | 
						|
 #define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY	(1<<17) /* Disable broken SD poweroff notify support */
 | 
						|
+#define MMC_QUIRK_NO_UHS_DDR50_TUNING	(1<<18) /* Disable DDR50 tuning */
 | 
						|
 
 | 
						|
 	bool			written_flag;	/* Indicates eMMC has been written since power on */
 | 
						|
 	bool			reenable_cmdq;	/* Re-enable Command Queue */
 | 
						|
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
 | 
						|
index 0b0a172337dbac..030d9de2ba2d23 100644
 | 
						|
--- a/include/linux/netdevice.h
 | 
						|
+++ b/include/linux/netdevice.h
 | 
						|
@@ -3036,7 +3036,8 @@ extern rwlock_t				dev_base_lock;		/* Device list lock */
 | 
						|
 #define net_device_entry(lh)	list_entry(lh, struct net_device, dev_list)
 | 
						|
 
 | 
						|
 #define for_each_netdev_dump(net, d, ifindex)				\
 | 
						|
-	xa_for_each_start(&(net)->dev_by_index, (ifindex), (d), (ifindex))
 | 
						|
+	for (; (d = xa_find(&(net)->dev_by_index, &ifindex,		\
 | 
						|
+			    ULONG_MAX, XA_PRESENT)); ifindex++)
 | 
						|
 
 | 
						|
 static inline struct net_device *next_net_device(struct net_device *dev)
 | 
						|
 {
 | 
						|
diff --git a/include/net/checksum.h b/include/net/checksum.h
 | 
						|
index 1338cb92c8e72a..28b101f26636e8 100644
 | 
						|
--- a/include/net/checksum.h
 | 
						|
+++ b/include/net/checksum.h
 | 
						|
@@ -158,7 +158,7 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
 | 
						|
 			       const __be32 *from, const __be32 *to,
 | 
						|
 			       bool pseudohdr);
 | 
						|
 void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
 | 
						|
-				     __wsum diff, bool pseudohdr);
 | 
						|
+				     __wsum diff, bool pseudohdr, bool ipv6);
 | 
						|
 
 | 
						|
 static __always_inline
 | 
						|
 void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
 | 
						|
diff --git a/include/trace/events/erofs.h b/include/trace/events/erofs.h
 | 
						|
index e18684b02c3dfa..0179af103d0f42 100644
 | 
						|
--- a/include/trace/events/erofs.h
 | 
						|
+++ b/include/trace/events/erofs.h
 | 
						|
@@ -237,24 +237,6 @@ DEFINE_EVENT(erofs__map_blocks_exit, z_erofs_map_blocks_iter_exit,
 | 
						|
 	TP_ARGS(inode, map, flags, ret)
 | 
						|
 );
 | 
						|
 
 | 
						|
-TRACE_EVENT(erofs_destroy_inode,
 | 
						|
-	TP_PROTO(struct inode *inode),
 | 
						|
-
 | 
						|
-	TP_ARGS(inode),
 | 
						|
-
 | 
						|
-	TP_STRUCT__entry(
 | 
						|
-		__field(	dev_t,		dev		)
 | 
						|
-		__field(	erofs_nid_t,	nid		)
 | 
						|
-	),
 | 
						|
-
 | 
						|
-	TP_fast_assign(
 | 
						|
-		__entry->dev	= inode->i_sb->s_dev;
 | 
						|
-		__entry->nid	= EROFS_I(inode)->nid;
 | 
						|
-	),
 | 
						|
-
 | 
						|
-	TP_printk("dev = (%d,%d), nid = %llu", show_dev_nid(__entry))
 | 
						|
-);
 | 
						|
-
 | 
						|
 #endif /* _TRACE_EROFS_H */
 | 
						|
 
 | 
						|
  /* This part must be outside protection */
 | 
						|
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
 | 
						|
index c7f904a72af217..08a0494736e6e3 100644
 | 
						|
--- a/include/uapi/linux/bpf.h
 | 
						|
+++ b/include/uapi/linux/bpf.h
 | 
						|
@@ -1913,6 +1913,7 @@ union bpf_attr {
 | 
						|
  * 		for updates resulting in a null checksum the value is set to
 | 
						|
  * 		**CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
 | 
						|
  * 		the checksum is to be computed against a pseudo-header.
 | 
						|
+ * 		Flag **BPF_F_IPV6** should be set for IPv6 packets.
 | 
						|
  *
 | 
						|
  * 		This helper works in combination with **bpf_csum_diff**\ (),
 | 
						|
  * 		which does not update the checksum in-place, but offers more
 | 
						|
@@ -5920,6 +5921,7 @@ enum {
 | 
						|
 	BPF_F_PSEUDO_HDR		= (1ULL << 4),
 | 
						|
 	BPF_F_MARK_MANGLED_0		= (1ULL << 5),
 | 
						|
 	BPF_F_MARK_ENFORCE		= (1ULL << 6),
 | 
						|
+	BPF_F_IPV6			= (1ULL << 7),
 | 
						|
 };
 | 
						|
 
 | 
						|
 /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
 | 
						|
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
 | 
						|
index 93f3e4d1df853e..1c4ef4e4eb52b2 100644
 | 
						|
--- a/io_uring/io-wq.c
 | 
						|
+++ b/io_uring/io-wq.c
 | 
						|
@@ -1206,8 +1206,10 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
 | 
						|
 	atomic_set(&wq->worker_refs, 1);
 | 
						|
 	init_completion(&wq->worker_done);
 | 
						|
 	ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node);
 | 
						|
-	if (ret)
 | 
						|
+	if (ret) {
 | 
						|
+		put_task_struct(wq->task);
 | 
						|
 		goto err;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	return wq;
 | 
						|
 err:
 | 
						|
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
 | 
						|
index ff1a93d405e99e..897f07014c0193 100644
 | 
						|
--- a/io_uring/io_uring.c
 | 
						|
+++ b/io_uring/io_uring.c
 | 
						|
@@ -1808,7 +1808,7 @@ static __cold void io_drain_req(struct io_kiocb *req)
 | 
						|
 	spin_unlock(&ctx->completion_lock);
 | 
						|
 
 | 
						|
 	io_prep_async_link(req);
 | 
						|
-	de = kmalloc(sizeof(*de), GFP_KERNEL);
 | 
						|
+	de = kmalloc(sizeof(*de), GFP_KERNEL_ACCOUNT);
 | 
						|
 	if (!de) {
 | 
						|
 		ret = -ENOMEM;
 | 
						|
 		io_req_defer_failed(req, ret);
 | 
						|
diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
 | 
						|
index addd7c97365727..b2c381634393d2 100644
 | 
						|
--- a/io_uring/kbuf.c
 | 
						|
+++ b/io_uring/kbuf.c
 | 
						|
@@ -560,7 +560,7 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
 | 
						|
 		io_destroy_bl(ctx, bl);
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
 | 
						|
+	free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL_ACCOUNT);
 | 
						|
 	if (!bl)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
diff --git a/ipc/shm.c b/ipc/shm.c
 | 
						|
index 576a543b7cfff9..c4845689b7f68b 100644
 | 
						|
--- a/ipc/shm.c
 | 
						|
+++ b/ipc/shm.c
 | 
						|
@@ -430,8 +430,11 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
 | 
						|
 void shm_destroy_orphaned(struct ipc_namespace *ns)
 | 
						|
 {
 | 
						|
 	down_write(&shm_ids(ns).rwsem);
 | 
						|
-	if (shm_ids(ns).in_use)
 | 
						|
+	if (shm_ids(ns).in_use) {
 | 
						|
+		rcu_read_lock();
 | 
						|
 		idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns);
 | 
						|
+		rcu_read_unlock();
 | 
						|
+	}
 | 
						|
 	up_write(&shm_ids(ns).rwsem);
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
 | 
						|
index 41d62405c85214..8f0b62b04deebe 100644
 | 
						|
--- a/kernel/bpf/helpers.c
 | 
						|
+++ b/kernel/bpf/helpers.c
 | 
						|
@@ -128,7 +128,8 @@ const struct bpf_func_proto bpf_map_peek_elem_proto = {
 | 
						|
 
 | 
						|
 BPF_CALL_3(bpf_map_lookup_percpu_elem, struct bpf_map *, map, void *, key, u32, cpu)
 | 
						|
 {
 | 
						|
-	WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
 | 
						|
+	WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() &&
 | 
						|
+		     !rcu_read_lock_bh_held());
 | 
						|
 	return (unsigned long) map->ops->map_lookup_percpu_elem(map, key, cpu);
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c
 | 
						|
index 66d1708042a72b..a3e13e6d5ee40d 100644
 | 
						|
--- a/kernel/cgroup/legacy_freezer.c
 | 
						|
+++ b/kernel/cgroup/legacy_freezer.c
 | 
						|
@@ -189,13 +189,12 @@ static void freezer_attach(struct cgroup_taskset *tset)
 | 
						|
 		if (!(freezer->state & CGROUP_FREEZING)) {
 | 
						|
 			__thaw_task(task);
 | 
						|
 		} else {
 | 
						|
-			freeze_task(task);
 | 
						|
-
 | 
						|
 			/* clear FROZEN and propagate upwards */
 | 
						|
 			while (freezer && (freezer->state & CGROUP_FROZEN)) {
 | 
						|
 				freezer->state &= ~CGROUP_FROZEN;
 | 
						|
 				freezer = parent_freezer(freezer);
 | 
						|
 			}
 | 
						|
+			freeze_task(task);
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
diff --git a/kernel/events/core.c b/kernel/events/core.c
 | 
						|
index 563f39518f7fe6..873b17545717cb 100644
 | 
						|
--- a/kernel/events/core.c
 | 
						|
+++ b/kernel/events/core.c
 | 
						|
@@ -171,6 +171,19 @@ static void perf_ctx_unlock(struct perf_cpu_context *cpuctx,
 | 
						|
 	raw_spin_unlock(&cpuctx->ctx.lock);
 | 
						|
 }
 | 
						|
 
 | 
						|
+typedef struct {
 | 
						|
+	struct perf_cpu_context *cpuctx;
 | 
						|
+	struct perf_event_context *ctx;
 | 
						|
+} class_perf_ctx_lock_t;
 | 
						|
+
 | 
						|
+static inline void class_perf_ctx_lock_destructor(class_perf_ctx_lock_t *_T)
 | 
						|
+{ perf_ctx_unlock(_T->cpuctx, _T->ctx); }
 | 
						|
+
 | 
						|
+static inline class_perf_ctx_lock_t
 | 
						|
+class_perf_ctx_lock_constructor(struct perf_cpu_context *cpuctx,
 | 
						|
+				struct perf_event_context *ctx)
 | 
						|
+{ perf_ctx_lock(cpuctx, ctx); return (class_perf_ctx_lock_t){ cpuctx, ctx }; }
 | 
						|
+
 | 
						|
 #define TASK_TOMBSTONE ((void *)-1L)
 | 
						|
 
 | 
						|
 static bool is_kernel_event(struct perf_event *event)
 | 
						|
@@ -866,7 +879,13 @@ static void perf_cgroup_switch(struct task_struct *task)
 | 
						|
 	if (READ_ONCE(cpuctx->cgrp) == cgrp)
 | 
						|
 		return;
 | 
						|
 
 | 
						|
-	perf_ctx_lock(cpuctx, cpuctx->task_ctx);
 | 
						|
+	guard(perf_ctx_lock)(cpuctx, cpuctx->task_ctx);
 | 
						|
+	/*
 | 
						|
+	 * Re-check, could've raced vs perf_remove_from_context().
 | 
						|
+	 */
 | 
						|
+	if (READ_ONCE(cpuctx->cgrp) == NULL)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
 	perf_ctx_disable(&cpuctx->ctx, true);
 | 
						|
 
 | 
						|
 	ctx_sched_out(&cpuctx->ctx, EVENT_ALL|EVENT_CGROUP);
 | 
						|
@@ -884,7 +903,6 @@ static void perf_cgroup_switch(struct task_struct *task)
 | 
						|
 	ctx_sched_in(&cpuctx->ctx, EVENT_ALL|EVENT_CGROUP);
 | 
						|
 
 | 
						|
 	perf_ctx_enable(&cpuctx->ctx, true);
 | 
						|
-	perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int perf_cgroup_ensure_storage(struct perf_event *event,
 | 
						|
@@ -2067,8 +2085,9 @@ perf_aux_output_match(struct perf_event *event, struct perf_event *aux_event)
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void put_event(struct perf_event *event);
 | 
						|
-static void event_sched_out(struct perf_event *event,
 | 
						|
-			    struct perf_event_context *ctx);
 | 
						|
+static void __event_disable(struct perf_event *event,
 | 
						|
+			    struct perf_event_context *ctx,
 | 
						|
+			    enum perf_event_state state);
 | 
						|
 
 | 
						|
 static void perf_put_aux_event(struct perf_event *event)
 | 
						|
 {
 | 
						|
@@ -2101,8 +2120,7 @@ static void perf_put_aux_event(struct perf_event *event)
 | 
						|
 		 * state so that we don't try to schedule it again. Note
 | 
						|
 		 * that perf_event_enable() will clear the ERROR status.
 | 
						|
 		 */
 | 
						|
-		event_sched_out(iter, ctx);
 | 
						|
-		perf_event_set_state(event, PERF_EVENT_STATE_ERROR);
 | 
						|
+		__event_disable(iter, ctx, PERF_EVENT_STATE_ERROR);
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -2156,18 +2174,6 @@ static inline struct list_head *get_event_list(struct perf_event *event)
 | 
						|
 				    &event->pmu_ctx->flexible_active;
 | 
						|
 }
 | 
						|
 
 | 
						|
-/*
 | 
						|
- * Events that have PERF_EV_CAP_SIBLING require being part of a group and
 | 
						|
- * cannot exist on their own, schedule them out and move them into the ERROR
 | 
						|
- * state. Also see _perf_event_enable(), it will not be able to recover
 | 
						|
- * this ERROR state.
 | 
						|
- */
 | 
						|
-static inline void perf_remove_sibling_event(struct perf_event *event)
 | 
						|
-{
 | 
						|
-	event_sched_out(event, event->ctx);
 | 
						|
-	perf_event_set_state(event, PERF_EVENT_STATE_ERROR);
 | 
						|
-}
 | 
						|
-
 | 
						|
 static void perf_group_detach(struct perf_event *event)
 | 
						|
 {
 | 
						|
 	struct perf_event *leader = event->group_leader;
 | 
						|
@@ -2203,8 +2209,15 @@ static void perf_group_detach(struct perf_event *event)
 | 
						|
 	 */
 | 
						|
 	list_for_each_entry_safe(sibling, tmp, &event->sibling_list, sibling_list) {
 | 
						|
 
 | 
						|
+		/*
 | 
						|
+		 * Events that have PERF_EV_CAP_SIBLING require being part of
 | 
						|
+		 * a group and cannot exist on their own, schedule them out
 | 
						|
+		 * and move them into the ERROR state. Also see
 | 
						|
+		 * _perf_event_enable(), it will not be able to recover this
 | 
						|
+		 * ERROR state.
 | 
						|
+		 */
 | 
						|
 		if (sibling->event_caps & PERF_EV_CAP_SIBLING)
 | 
						|
-			perf_remove_sibling_event(sibling);
 | 
						|
+			__event_disable(sibling, ctx, PERF_EVENT_STATE_ERROR);
 | 
						|
 
 | 
						|
 		sibling->group_leader = sibling;
 | 
						|
 		list_del_init(&sibling->sibling_list);
 | 
						|
@@ -2437,6 +2450,15 @@ static void perf_remove_from_context(struct perf_event *event, unsigned long fla
 | 
						|
 	event_function_call(event, __perf_remove_from_context, (void *)flags);
 | 
						|
 }
 | 
						|
 
 | 
						|
+static void __event_disable(struct perf_event *event,
 | 
						|
+			    struct perf_event_context *ctx,
 | 
						|
+			    enum perf_event_state state)
 | 
						|
+{
 | 
						|
+	event_sched_out(event, ctx);
 | 
						|
+	perf_cgroup_event_disable(event, ctx);
 | 
						|
+	perf_event_set_state(event, state);
 | 
						|
+}
 | 
						|
+
 | 
						|
 /*
 | 
						|
  * Cross CPU call to disable a performance event
 | 
						|
  */
 | 
						|
@@ -2455,13 +2477,18 @@ static void __perf_event_disable(struct perf_event *event,
 | 
						|
 
 | 
						|
 	perf_pmu_disable(event->pmu_ctx->pmu);
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * When disabling a group leader, the whole group becomes ineligible
 | 
						|
+	 * to run, so schedule out the full group.
 | 
						|
+	 */
 | 
						|
 	if (event == event->group_leader)
 | 
						|
 		group_sched_out(event, ctx);
 | 
						|
-	else
 | 
						|
-		event_sched_out(event, ctx);
 | 
						|
 
 | 
						|
-	perf_event_set_state(event, PERF_EVENT_STATE_OFF);
 | 
						|
-	perf_cgroup_event_disable(event, ctx);
 | 
						|
+	/*
 | 
						|
+	 * But only mark the leader OFF; the siblings will remain
 | 
						|
+	 * INACTIVE.
 | 
						|
+	 */
 | 
						|
+	__event_disable(event, ctx, PERF_EVENT_STATE_OFF);
 | 
						|
 
 | 
						|
 	perf_pmu_enable(event->pmu_ctx->pmu);
 | 
						|
 }
 | 
						|
@@ -6987,6 +7014,10 @@ perf_sample_ustack_size(u16 stack_size, u16 header_size,
 | 
						|
 	if (!regs)
 | 
						|
 		return 0;
 | 
						|
 
 | 
						|
+	/* No mm, no stack, no dump. */
 | 
						|
+	if (!current->mm)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
 	/*
 | 
						|
 	 * Check if we fit in with the requested stack size into the:
 | 
						|
 	 * - TASK_SIZE
 | 
						|
@@ -7685,6 +7716,9 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs)
 | 
						|
 	const u32 max_stack = event->attr.sample_max_stack;
 | 
						|
 	struct perf_callchain_entry *callchain;
 | 
						|
 
 | 
						|
+	if (!current->mm)
 | 
						|
+		user = false;
 | 
						|
+
 | 
						|
 	if (!kernel && !user)
 | 
						|
 		return &__empty_callchain;
 | 
						|
 
 | 
						|
diff --git a/kernel/exit.c b/kernel/exit.c
 | 
						|
index 3540b2c9b1b6a0..03a1dd32e6ff3c 100644
 | 
						|
--- a/kernel/exit.c
 | 
						|
+++ b/kernel/exit.c
 | 
						|
@@ -858,6 +858,15 @@ void __noreturn do_exit(long code)
 | 
						|
 	tsk->exit_code = code;
 | 
						|
 	taskstats_exit(tsk, group_dead);
 | 
						|
 
 | 
						|
+	/*
 | 
						|
+	 * Since sampling can touch ->mm, make sure to stop everything before we
 | 
						|
+	 * tear it down.
 | 
						|
+	 *
 | 
						|
+	 * Also flushes inherited counters to the parent - before the parent
 | 
						|
+	 * gets woken up by child-exit notifications.
 | 
						|
+	 */
 | 
						|
+	perf_event_exit_task(tsk);
 | 
						|
+
 | 
						|
 	exit_mm();
 | 
						|
 
 | 
						|
 	if (group_dead)
 | 
						|
@@ -874,14 +883,6 @@ void __noreturn do_exit(long code)
 | 
						|
 	exit_task_work(tsk);
 | 
						|
 	exit_thread(tsk);
 | 
						|
 
 | 
						|
-	/*
 | 
						|
-	 * Flush inherited counters to the parent - before the parent
 | 
						|
-	 * gets woken up by child-exit notifications.
 | 
						|
-	 *
 | 
						|
-	 * because of cgroup mode, must be called before cgroup_exit()
 | 
						|
-	 */
 | 
						|
-	perf_event_exit_task(tsk);
 | 
						|
-
 | 
						|
 	sched_autogroup_exit_task(tsk);
 | 
						|
 	cgroup_exit(tsk);
 | 
						|
 
 | 
						|
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
 | 
						|
index 3130f24daf5979..353829883e66de 100644
 | 
						|
--- a/kernel/time/clocksource.c
 | 
						|
+++ b/kernel/time/clocksource.c
 | 
						|
@@ -288,7 +288,7 @@ static void clocksource_verify_choose_cpus(void)
 | 
						|
 {
 | 
						|
 	int cpu, i, n = verify_n_cpus;
 | 
						|
 
 | 
						|
-	if (n < 0) {
 | 
						|
+	if (n < 0 || n >= num_online_cpus()) {
 | 
						|
 		/* Check all of the CPUs. */
 | 
						|
 		cpumask_copy(&cpus_chosen, cpu_online_mask);
 | 
						|
 		cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);
 | 
						|
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
 | 
						|
index 650493ed76cd40..4351b9069a919d 100644
 | 
						|
--- a/kernel/trace/ftrace.c
 | 
						|
+++ b/kernel/trace/ftrace.c
 | 
						|
@@ -6772,9 +6772,10 @@ void ftrace_release_mod(struct module *mod)
 | 
						|
 
 | 
						|
 	mutex_lock(&ftrace_lock);
 | 
						|
 
 | 
						|
-	if (ftrace_disabled)
 | 
						|
-		goto out_unlock;
 | 
						|
-
 | 
						|
+	/*
 | 
						|
+	 * To avoid the UAF problem after the module is unloaded, the
 | 
						|
+	 * 'mod_map' resource needs to be released unconditionally.
 | 
						|
+	 */
 | 
						|
 	list_for_each_entry_safe(mod_map, n, &ftrace_mod_maps, list) {
 | 
						|
 		if (mod_map->mod == mod) {
 | 
						|
 			list_del_rcu(&mod_map->list);
 | 
						|
@@ -6783,6 +6784,9 @@ void ftrace_release_mod(struct module *mod)
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	if (ftrace_disabled)
 | 
						|
+		goto out_unlock;
 | 
						|
+
 | 
						|
 	/*
 | 
						|
 	 * Each module has its own ftrace_pages, remove
 | 
						|
 	 * them from the list.
 | 
						|
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
 | 
						|
index 5cd6d4e2691579..7abd69a776b20a 100644
 | 
						|
--- a/kernel/watchdog.c
 | 
						|
+++ b/kernel/watchdog.c
 | 
						|
@@ -40,6 +40,7 @@ int __read_mostly watchdog_user_enabled = 1;
 | 
						|
 static int __read_mostly watchdog_hardlockup_user_enabled = WATCHDOG_HARDLOCKUP_DEFAULT;
 | 
						|
 static int __read_mostly watchdog_softlockup_user_enabled = 1;
 | 
						|
 int __read_mostly watchdog_thresh = 10;
 | 
						|
+static int __read_mostly watchdog_thresh_next;
 | 
						|
 static int __read_mostly watchdog_hardlockup_available;
 | 
						|
 
 | 
						|
 struct cpumask watchdog_cpumask __read_mostly;
 | 
						|
@@ -627,12 +628,20 @@ int lockup_detector_offline_cpu(unsigned int cpu)
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static void __lockup_detector_reconfigure(void)
 | 
						|
+static void __lockup_detector_reconfigure(bool thresh_changed)
 | 
						|
 {
 | 
						|
 	cpus_read_lock();
 | 
						|
 	watchdog_hardlockup_stop();
 | 
						|
 
 | 
						|
 	softlockup_stop_all();
 | 
						|
+	/*
 | 
						|
+	 * To prevent watchdog_timer_fn from using the old interval and
 | 
						|
+	 * the new watchdog_thresh at the same time, which could lead to
 | 
						|
+	 * false softlockup reports, it is necessary to update the
 | 
						|
+	 * watchdog_thresh after the softlockup is completed.
 | 
						|
+	 */
 | 
						|
+	if (thresh_changed)
 | 
						|
+		watchdog_thresh = READ_ONCE(watchdog_thresh_next);
 | 
						|
 	set_sample_period();
 | 
						|
 	lockup_detector_update_enable();
 | 
						|
 	if (watchdog_enabled && watchdog_thresh)
 | 
						|
@@ -650,7 +659,7 @@ static void __lockup_detector_reconfigure(void)
 | 
						|
 void lockup_detector_reconfigure(void)
 | 
						|
 {
 | 
						|
 	mutex_lock(&watchdog_mutex);
 | 
						|
-	__lockup_detector_reconfigure();
 | 
						|
+	__lockup_detector_reconfigure(false);
 | 
						|
 	mutex_unlock(&watchdog_mutex);
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -670,27 +679,29 @@ static __init void lockup_detector_setup(void)
 | 
						|
 		return;
 | 
						|
 
 | 
						|
 	mutex_lock(&watchdog_mutex);
 | 
						|
-	__lockup_detector_reconfigure();
 | 
						|
+	__lockup_detector_reconfigure(false);
 | 
						|
 	softlockup_initialized = true;
 | 
						|
 	mutex_unlock(&watchdog_mutex);
 | 
						|
 }
 | 
						|
 
 | 
						|
 #else /* CONFIG_SOFTLOCKUP_DETECTOR */
 | 
						|
-static void __lockup_detector_reconfigure(void)
 | 
						|
+static void __lockup_detector_reconfigure(bool thresh_changed)
 | 
						|
 {
 | 
						|
 	cpus_read_lock();
 | 
						|
 	watchdog_hardlockup_stop();
 | 
						|
+	if (thresh_changed)
 | 
						|
+		watchdog_thresh = READ_ONCE(watchdog_thresh_next);
 | 
						|
 	lockup_detector_update_enable();
 | 
						|
 	watchdog_hardlockup_start();
 | 
						|
 	cpus_read_unlock();
 | 
						|
 }
 | 
						|
 void lockup_detector_reconfigure(void)
 | 
						|
 {
 | 
						|
-	__lockup_detector_reconfigure();
 | 
						|
+	__lockup_detector_reconfigure(false);
 | 
						|
 }
 | 
						|
 static inline void lockup_detector_setup(void)
 | 
						|
 {
 | 
						|
-	__lockup_detector_reconfigure();
 | 
						|
+	__lockup_detector_reconfigure(false);
 | 
						|
 }
 | 
						|
 #endif /* !CONFIG_SOFTLOCKUP_DETECTOR */
 | 
						|
 
 | 
						|
@@ -726,11 +737,11 @@ void lockup_detector_soft_poweroff(void)
 | 
						|
 #ifdef CONFIG_SYSCTL
 | 
						|
 
 | 
						|
 /* Propagate any changes to the watchdog infrastructure */
 | 
						|
-static void proc_watchdog_update(void)
 | 
						|
+static void proc_watchdog_update(bool thresh_changed)
 | 
						|
 {
 | 
						|
 	/* Remove impossible cpus to keep sysctl output clean. */
 | 
						|
 	cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask);
 | 
						|
-	__lockup_detector_reconfigure();
 | 
						|
+	__lockup_detector_reconfigure(thresh_changed);
 | 
						|
 }
 | 
						|
 
 | 
						|
 /*
 | 
						|
@@ -763,7 +774,7 @@ static int proc_watchdog_common(int which, struct ctl_table *table, int write,
 | 
						|
 		old = READ_ONCE(*param);
 | 
						|
 		err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 | 
						|
 		if (!err && old != READ_ONCE(*param))
 | 
						|
-			proc_watchdog_update();
 | 
						|
+			proc_watchdog_update(false);
 | 
						|
 	}
 | 
						|
 	mutex_unlock(&watchdog_mutex);
 | 
						|
 	return err;
 | 
						|
@@ -812,11 +823,13 @@ int proc_watchdog_thresh(struct ctl_table *table, int write,
 | 
						|
 
 | 
						|
 	mutex_lock(&watchdog_mutex);
 | 
						|
 
 | 
						|
-	old = READ_ONCE(watchdog_thresh);
 | 
						|
+	watchdog_thresh_next = READ_ONCE(watchdog_thresh);
 | 
						|
+
 | 
						|
+	old = watchdog_thresh_next;
 | 
						|
 	err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 | 
						|
 
 | 
						|
-	if (!err && write && old != READ_ONCE(watchdog_thresh))
 | 
						|
-		proc_watchdog_update();
 | 
						|
+	if (!err && write && old != READ_ONCE(watchdog_thresh_next))
 | 
						|
+		proc_watchdog_update(true);
 | 
						|
 
 | 
						|
 	mutex_unlock(&watchdog_mutex);
 | 
						|
 	return err;
 | 
						|
@@ -837,7 +850,7 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,
 | 
						|
 
 | 
						|
 	err = proc_do_large_bitmap(table, write, buffer, lenp, ppos);
 | 
						|
 	if (!err && write)
 | 
						|
-		proc_watchdog_update();
 | 
						|
+		proc_watchdog_update(false);
 | 
						|
 
 | 
						|
 	mutex_unlock(&watchdog_mutex);
 | 
						|
 	return err;
 | 
						|
@@ -857,7 +870,7 @@ static struct ctl_table watchdog_sysctls[] = {
 | 
						|
 	},
 | 
						|
 	{
 | 
						|
 		.procname	= "watchdog_thresh",
 | 
						|
-		.data		= &watchdog_thresh,
 | 
						|
+		.data		= &watchdog_thresh_next,
 | 
						|
 		.maxlen		= sizeof(int),
 | 
						|
 		.mode		= 0644,
 | 
						|
 		.proc_handler	= proc_watchdog_thresh,
 | 
						|
diff --git a/lib/Kconfig b/lib/Kconfig
 | 
						|
index ee365b7402f193..43d69669465aff 100644
 | 
						|
--- a/lib/Kconfig
 | 
						|
+++ b/lib/Kconfig
 | 
						|
@@ -751,6 +751,7 @@ config GENERIC_LIB_DEVMEM_IS_ALLOWED
 | 
						|
 
 | 
						|
 config PLDMFW
 | 
						|
 	bool
 | 
						|
+	select CRC32
 | 
						|
 	default n
 | 
						|
 
 | 
						|
 config ASN1_ENCODER
 | 
						|
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
 | 
						|
index 635f0f0f6860e8..78f5df12b8eb37 100644
 | 
						|
--- a/mm/huge_memory.c
 | 
						|
+++ b/mm/huge_memory.c
 | 
						|
@@ -2260,12 +2260,14 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 | 
						|
 {
 | 
						|
 	spinlock_t *ptl;
 | 
						|
 	struct mmu_notifier_range range;
 | 
						|
+	bool pmd_migration;
 | 
						|
 
 | 
						|
 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
 | 
						|
 				address & HPAGE_PMD_MASK,
 | 
						|
 				(address & HPAGE_PMD_MASK) + HPAGE_PMD_SIZE);
 | 
						|
 	mmu_notifier_invalidate_range_start(&range);
 | 
						|
 	ptl = pmd_lock(vma->vm_mm, pmd);
 | 
						|
+	pmd_migration = is_pmd_migration_entry(*pmd);
 | 
						|
 
 | 
						|
 	/*
 | 
						|
 	 * If caller asks to setup a migration entry, we need a folio to check
 | 
						|
@@ -2274,13 +2276,12 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 | 
						|
 	VM_BUG_ON(freeze && !folio);
 | 
						|
 	VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));
 | 
						|
 
 | 
						|
-	if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
 | 
						|
-	    is_pmd_migration_entry(*pmd)) {
 | 
						|
+	if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) || pmd_migration) {
 | 
						|
 		/*
 | 
						|
-		 * It's safe to call pmd_page when folio is set because it's
 | 
						|
-		 * guaranteed that pmd is present.
 | 
						|
+		 * Do not apply pmd_folio() to a migration entry; and folio lock
 | 
						|
+		 * guarantees that it must be of the wrong folio anyway.
 | 
						|
 		 */
 | 
						|
-		if (folio && folio != page_folio(pmd_page(*pmd)))
 | 
						|
+		if (folio && (pmd_migration || folio != page_folio(pmd_page(*pmd))))
 | 
						|
 			goto out;
 | 
						|
 		__split_huge_pmd_locked(vma, pmd, range.start, freeze);
 | 
						|
 	}
 | 
						|
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
 | 
						|
index 7c196b754071bd..d57d8f1c2dfea4 100644
 | 
						|
--- a/mm/hugetlb.c
 | 
						|
+++ b/mm/hugetlb.c
 | 
						|
@@ -96,7 +96,7 @@ static void hugetlb_vma_lock_free(struct vm_area_struct *vma);
 | 
						|
 static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma);
 | 
						|
 static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma);
 | 
						|
 static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
 | 
						|
-		unsigned long start, unsigned long end);
 | 
						|
+		unsigned long start, unsigned long end, bool take_locks);
 | 
						|
 static struct resv_map *vma_resv_map(struct vm_area_struct *vma);
 | 
						|
 
 | 
						|
 static inline bool subpool_is_free(struct hugepage_subpool *spool)
 | 
						|
@@ -4903,26 +4903,40 @@ static int hugetlb_vm_op_split(struct vm_area_struct *vma, unsigned long addr)
 | 
						|
 {
 | 
						|
 	if (addr & ~(huge_page_mask(hstate_vma(vma))))
 | 
						|
 		return -EINVAL;
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
 
 | 
						|
+void hugetlb_split(struct vm_area_struct *vma, unsigned long addr)
 | 
						|
+{
 | 
						|
 	/*
 | 
						|
 	 * PMD sharing is only possible for PUD_SIZE-aligned address ranges
 | 
						|
 	 * in HugeTLB VMAs. If we will lose PUD_SIZE alignment due to this
 | 
						|
 	 * split, unshare PMDs in the PUD_SIZE interval surrounding addr now.
 | 
						|
+	 * This function is called in the middle of a VMA split operation, with
 | 
						|
+	 * MM, VMA and rmap all write-locked to prevent concurrent page table
 | 
						|
+	 * walks (except hardware and gup_fast()).
 | 
						|
 	 */
 | 
						|
+	vma_assert_write_locked(vma);
 | 
						|
+	i_mmap_assert_write_locked(vma->vm_file->f_mapping);
 | 
						|
+
 | 
						|
 	if (addr & ~PUD_MASK) {
 | 
						|
-		/*
 | 
						|
-		 * hugetlb_vm_op_split is called right before we attempt to
 | 
						|
-		 * split the VMA. We will need to unshare PMDs in the old and
 | 
						|
-		 * new VMAs, so let's unshare before we split.
 | 
						|
-		 */
 | 
						|
 		unsigned long floor = addr & PUD_MASK;
 | 
						|
 		unsigned long ceil = floor + PUD_SIZE;
 | 
						|
 
 | 
						|
-		if (floor >= vma->vm_start && ceil <= vma->vm_end)
 | 
						|
-			hugetlb_unshare_pmds(vma, floor, ceil);
 | 
						|
+		if (floor >= vma->vm_start && ceil <= vma->vm_end) {
 | 
						|
+			/*
 | 
						|
+			 * Locking:
 | 
						|
+			 * Use take_locks=false here.
 | 
						|
+			 * The file rmap lock is already held.
 | 
						|
+			 * The hugetlb VMA lock can't be taken when we already
 | 
						|
+			 * hold the file rmap lock, and we don't need it because
 | 
						|
+			 * its purpose is to synchronize against concurrent page
 | 
						|
+			 * table walks, which are not possible thanks to the
 | 
						|
+			 * locks held by our caller.
 | 
						|
+			 */
 | 
						|
+			hugetlb_unshare_pmds(vma, floor, ceil, /* take_locks = */ false);
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
 static unsigned long hugetlb_vm_op_pagesize(struct vm_area_struct *vma)
 | 
						|
@@ -7062,6 +7076,13 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
 | 
						|
 		return 0;
 | 
						|
 
 | 
						|
 	pud_clear(pud);
 | 
						|
+	/*
 | 
						|
+	 * Once our caller drops the rmap lock, some other process might be
 | 
						|
+	 * using this page table as a normal, non-hugetlb page table.
 | 
						|
+	 * Wait for pending gup_fast() in other threads to finish before letting
 | 
						|
+	 * that happen.
 | 
						|
+	 */
 | 
						|
+	tlb_remove_table_sync_one();
 | 
						|
 	ptdesc_pmd_pts_dec(virt_to_ptdesc(ptep));
 | 
						|
 	mm_dec_nr_pmds(mm);
 | 
						|
 	return 1;
 | 
						|
@@ -7298,9 +7319,16 @@ void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int re
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
+/*
 | 
						|
+ * If @take_locks is false, the caller must ensure that no concurrent page table
 | 
						|
+ * access can happen (except for gup_fast() and hardware page walks).
 | 
						|
+ * If @take_locks is true, we take the hugetlb VMA lock (to lock out things like
 | 
						|
+ * concurrent page fault handling) and the file rmap lock.
 | 
						|
+ */
 | 
						|
 static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
 | 
						|
 				   unsigned long start,
 | 
						|
-				   unsigned long end)
 | 
						|
+				   unsigned long end,
 | 
						|
+				   bool take_locks)
 | 
						|
 {
 | 
						|
 	struct hstate *h = hstate_vma(vma);
 | 
						|
 	unsigned long sz = huge_page_size(h);
 | 
						|
@@ -7324,8 +7352,12 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
 | 
						|
 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm,
 | 
						|
 				start, end);
 | 
						|
 	mmu_notifier_invalidate_range_start(&range);
 | 
						|
-	hugetlb_vma_lock_write(vma);
 | 
						|
-	i_mmap_lock_write(vma->vm_file->f_mapping);
 | 
						|
+	if (take_locks) {
 | 
						|
+		hugetlb_vma_lock_write(vma);
 | 
						|
+		i_mmap_lock_write(vma->vm_file->f_mapping);
 | 
						|
+	} else {
 | 
						|
+		i_mmap_assert_write_locked(vma->vm_file->f_mapping);
 | 
						|
+	}
 | 
						|
 	for (address = start; address < end; address += PUD_SIZE) {
 | 
						|
 		ptep = hugetlb_walk(vma, address, sz);
 | 
						|
 		if (!ptep)
 | 
						|
@@ -7335,8 +7367,10 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
 | 
						|
 		spin_unlock(ptl);
 | 
						|
 	}
 | 
						|
 	flush_hugetlb_tlb_range(vma, start, end);
 | 
						|
-	i_mmap_unlock_write(vma->vm_file->f_mapping);
 | 
						|
-	hugetlb_vma_unlock_write(vma);
 | 
						|
+	if (take_locks) {
 | 
						|
+		i_mmap_unlock_write(vma->vm_file->f_mapping);
 | 
						|
+		hugetlb_vma_unlock_write(vma);
 | 
						|
+	}
 | 
						|
 	/*
 | 
						|
 	 * No need to call mmu_notifier_arch_invalidate_secondary_tlbs(), see
 | 
						|
 	 * Documentation/mm/mmu_notifier.rst.
 | 
						|
@@ -7351,7 +7385,8 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
 | 
						|
 void hugetlb_unshare_all_pmds(struct vm_area_struct *vma)
 | 
						|
 {
 | 
						|
 	hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE),
 | 
						|
-			ALIGN_DOWN(vma->vm_end, PUD_SIZE));
 | 
						|
+			ALIGN_DOWN(vma->vm_end, PUD_SIZE),
 | 
						|
+			/* take_locks = */ true);
 | 
						|
 }
 | 
						|
 
 | 
						|
 #ifdef CONFIG_CMA
 | 
						|
diff --git a/mm/mmap.c b/mm/mmap.c
 | 
						|
index 03a24cb3951d47..a9c70001e45601 100644
 | 
						|
--- a/mm/mmap.c
 | 
						|
+++ b/mm/mmap.c
 | 
						|
@@ -2402,7 +2402,13 @@ int __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
 | 
						|
 	init_vma_prep(&vp, vma);
 | 
						|
 	vp.insert = new;
 | 
						|
 	vma_prepare(&vp);
 | 
						|
+	/*
 | 
						|
+	 * Get rid of huge pages and shared page tables straddling the split
 | 
						|
+	 * boundary.
 | 
						|
+	 */
 | 
						|
 	vma_adjust_trans_huge(vma, vma->vm_start, addr, 0);
 | 
						|
+	if (is_vm_hugetlb_page(vma))
 | 
						|
+		hugetlb_split(vma, addr);
 | 
						|
 
 | 
						|
 	if (new_below) {
 | 
						|
 		vma->vm_start = addr;
 | 
						|
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
 | 
						|
index e632ec9b642109..9ceb841af819e4 100644
 | 
						|
--- a/mm/page-writeback.c
 | 
						|
+++ b/mm/page-writeback.c
 | 
						|
@@ -541,8 +541,8 @@ static int dirty_ratio_handler(struct ctl_table *table, int write, void *buffer,
 | 
						|
 
 | 
						|
 	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 | 
						|
 	if (ret == 0 && write && vm_dirty_ratio != old_ratio) {
 | 
						|
-		writeback_set_ratelimit();
 | 
						|
 		vm_dirty_bytes = 0;
 | 
						|
+		writeback_set_ratelimit();
 | 
						|
 	}
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
diff --git a/net/atm/common.c b/net/atm/common.c
 | 
						|
index f7019df41c3e59..9cc82acbc73588 100644
 | 
						|
--- a/net/atm/common.c
 | 
						|
+++ b/net/atm/common.c
 | 
						|
@@ -635,6 +635,7 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
 | 
						|
 
 | 
						|
 	skb->dev = NULL; /* for paths shared with net_device interfaces */
 | 
						|
 	if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
 | 
						|
+		atm_return_tx(vcc, skb);
 | 
						|
 		kfree_skb(skb);
 | 
						|
 		error = -EFAULT;
 | 
						|
 		goto out;
 | 
						|
diff --git a/net/atm/lec.c b/net/atm/lec.c
 | 
						|
index ac3cfc1ae51024..b7fa48a9b72059 100644
 | 
						|
--- a/net/atm/lec.c
 | 
						|
+++ b/net/atm/lec.c
 | 
						|
@@ -124,6 +124,7 @@ static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 | 
						|
 
 | 
						|
 /* Device structures */
 | 
						|
 static struct net_device *dev_lec[MAX_LEC_ITF];
 | 
						|
+static DEFINE_MUTEX(lec_mutex);
 | 
						|
 
 | 
						|
 #if IS_ENABLED(CONFIG_BRIDGE)
 | 
						|
 static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
 | 
						|
@@ -685,6 +686,7 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
 | 
						|
 	int bytes_left;
 | 
						|
 	struct atmlec_ioc ioc_data;
 | 
						|
 
 | 
						|
+	lockdep_assert_held(&lec_mutex);
 | 
						|
 	/* Lecd must be up in this case */
 | 
						|
 	bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
 | 
						|
 	if (bytes_left != 0)
 | 
						|
@@ -710,6 +712,7 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
 | 
						|
 
 | 
						|
 static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
 | 
						|
 {
 | 
						|
+	lockdep_assert_held(&lec_mutex);
 | 
						|
 	if (arg < 0 || arg >= MAX_LEC_ITF)
 | 
						|
 		return -EINVAL;
 | 
						|
 	arg = array_index_nospec(arg, MAX_LEC_ITF);
 | 
						|
@@ -725,6 +728,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg)
 | 
						|
 	int i;
 | 
						|
 	struct lec_priv *priv;
 | 
						|
 
 | 
						|
+	lockdep_assert_held(&lec_mutex);
 | 
						|
 	if (arg < 0)
 | 
						|
 		arg = 0;
 | 
						|
 	if (arg >= MAX_LEC_ITF)
 | 
						|
@@ -742,6 +746,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg)
 | 
						|
 		snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
 | 
						|
 		if (register_netdev(dev_lec[i])) {
 | 
						|
 			free_netdev(dev_lec[i]);
 | 
						|
+			dev_lec[i] = NULL;
 | 
						|
 			return -EINVAL;
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -904,7 +909,6 @@ static void *lec_itf_walk(struct lec_state *state, loff_t *l)
 | 
						|
 	v = (dev && netdev_priv(dev)) ?
 | 
						|
 		lec_priv_walk(state, l, netdev_priv(dev)) : NULL;
 | 
						|
 	if (!v && dev) {
 | 
						|
-		dev_put(dev);
 | 
						|
 		/* Partial state reset for the next time we get called */
 | 
						|
 		dev = NULL;
 | 
						|
 	}
 | 
						|
@@ -928,6 +932,7 @@ static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
 | 
						|
 {
 | 
						|
 	struct lec_state *state = seq->private;
 | 
						|
 
 | 
						|
+	mutex_lock(&lec_mutex);
 | 
						|
 	state->itf = 0;
 | 
						|
 	state->dev = NULL;
 | 
						|
 	state->locked = NULL;
 | 
						|
@@ -945,8 +950,9 @@ static void lec_seq_stop(struct seq_file *seq, void *v)
 | 
						|
 	if (state->dev) {
 | 
						|
 		spin_unlock_irqrestore(&state->locked->lec_arp_lock,
 | 
						|
 				       state->flags);
 | 
						|
-		dev_put(state->dev);
 | 
						|
+		state->dev = NULL;
 | 
						|
 	}
 | 
						|
+	mutex_unlock(&lec_mutex);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 | 
						|
@@ -1003,6 +1009,7 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 | 
						|
 		return -ENOIOCTLCMD;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	mutex_lock(&lec_mutex);
 | 
						|
 	switch (cmd) {
 | 
						|
 	case ATMLEC_CTRL:
 | 
						|
 		err = lecd_attach(vcc, (int)arg);
 | 
						|
@@ -1017,6 +1024,7 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 | 
						|
 		break;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	mutex_unlock(&lec_mutex);
 | 
						|
 	return err;
 | 
						|
 }
 | 
						|
 
 | 
						|
diff --git a/net/atm/raw.c b/net/atm/raw.c
 | 
						|
index 2b5f78a7ec3e4a..1e6511ec842cbc 100644
 | 
						|
--- a/net/atm/raw.c
 | 
						|
+++ b/net/atm/raw.c
 | 
						|
@@ -36,7 +36,7 @@ static void atm_pop_raw(struct atm_vcc *vcc, struct sk_buff *skb)
 | 
						|
 
 | 
						|
 	pr_debug("(%d) %d -= %d\n",
 | 
						|
 		 vcc->vci, sk_wmem_alloc_get(sk), ATM_SKB(skb)->acct_truesize);
 | 
						|
-	WARN_ON(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize, &sk->sk_wmem_alloc));
 | 
						|
+	atm_return_tx(vcc, skb);
 | 
						|
 	dev_kfree_skb_any(skb);
 | 
						|
 	sk->sk_write_space(sk);
 | 
						|
 }
 | 
						|
diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
 | 
						|
index 1820f09ff59ceb..3f24b4ee49c274 100644
 | 
						|
--- a/net/bridge/br_mst.c
 | 
						|
+++ b/net/bridge/br_mst.c
 | 
						|
@@ -80,10 +80,10 @@ static void br_mst_vlan_set_state(struct net_bridge_vlan_group *vg,
 | 
						|
 	if (br_vlan_get_state(v) == state)
 | 
						|
 		return;
 | 
						|
 
 | 
						|
-	br_vlan_set_state(v, state);
 | 
						|
-
 | 
						|
 	if (v->vid == vg->pvid)
 | 
						|
 		br_vlan_set_pvid_state(vg, state);
 | 
						|
+
 | 
						|
+	br_vlan_set_state(v, state);
 | 
						|
 }
 | 
						|
 
 | 
						|
 int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
 | 
						|
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
 | 
						|
index c38244d60ff86e..fa16ee88ec396a 100644
 | 
						|
--- a/net/bridge/br_multicast.c
 | 
						|
+++ b/net/bridge/br_multicast.c
 | 
						|
@@ -2104,12 +2104,17 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
 | 
						|
 	}
 | 
						|
 }
 | 
						|
 
 | 
						|
-void br_multicast_enable_port(struct net_bridge_port *port)
 | 
						|
+static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
 | 
						|
 {
 | 
						|
-	struct net_bridge *br = port->br;
 | 
						|
+	struct net_bridge *br = pmctx->port->br;
 | 
						|
 
 | 
						|
 	spin_lock_bh(&br->multicast_lock);
 | 
						|
-	__br_multicast_enable_port_ctx(&port->multicast_ctx);
 | 
						|
+	if (br_multicast_port_ctx_is_vlan(pmctx) &&
 | 
						|
+	    !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) {
 | 
						|
+		spin_unlock_bh(&br->multicast_lock);
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+	__br_multicast_enable_port_ctx(pmctx);
 | 
						|
 	spin_unlock_bh(&br->multicast_lock);
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -2136,11 +2141,67 @@ static void __br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx)
 | 
						|
 	br_multicast_rport_del_notify(pmctx, del);
 | 
						|
 }
 | 
						|
 
 | 
						|
+static void br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx)
 | 
						|
+{
 | 
						|
+	struct net_bridge *br = pmctx->port->br;
 | 
						|
+
 | 
						|
+	spin_lock_bh(&br->multicast_lock);
 | 
						|
+	if (br_multicast_port_ctx_is_vlan(pmctx) &&
 | 
						|
+	    !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) {
 | 
						|
+		spin_unlock_bh(&br->multicast_lock);
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	__br_multicast_disable_port_ctx(pmctx);
 | 
						|
+	spin_unlock_bh(&br->multicast_lock);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void br_multicast_toggle_port(struct net_bridge_port *port, bool on)
 | 
						|
+{
 | 
						|
+#if IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING)
 | 
						|
+	if (br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) {
 | 
						|
+		struct net_bridge_vlan_group *vg;
 | 
						|
+		struct net_bridge_vlan *vlan;
 | 
						|
+
 | 
						|
+		rcu_read_lock();
 | 
						|
+		vg = nbp_vlan_group_rcu(port);
 | 
						|
+		if (!vg) {
 | 
						|
+			rcu_read_unlock();
 | 
						|
+			return;
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		/* iterate each vlan, toggle vlan multicast context */
 | 
						|
+		list_for_each_entry_rcu(vlan, &vg->vlan_list, vlist) {
 | 
						|
+			struct net_bridge_mcast_port *pmctx =
 | 
						|
+						&vlan->port_mcast_ctx;
 | 
						|
+			u8 state = br_vlan_get_state(vlan);
 | 
						|
+			/* enable vlan multicast context when state is
 | 
						|
+			 * LEARNING or FORWARDING
 | 
						|
+			 */
 | 
						|
+			if (on && br_vlan_state_allowed(state, true))
 | 
						|
+				br_multicast_enable_port_ctx(pmctx);
 | 
						|
+			else
 | 
						|
+				br_multicast_disable_port_ctx(pmctx);
 | 
						|
+		}
 | 
						|
+		rcu_read_unlock();
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+#endif
 | 
						|
+	/* toggle port multicast context when vlan snooping is disabled */
 | 
						|
+	if (on)
 | 
						|
+		br_multicast_enable_port_ctx(&port->multicast_ctx);
 | 
						|
+	else
 | 
						|
+		br_multicast_disable_port_ctx(&port->multicast_ctx);
 | 
						|
+}
 | 
						|
+
 | 
						|
+void br_multicast_enable_port(struct net_bridge_port *port)
 | 
						|
+{
 | 
						|
+	br_multicast_toggle_port(port, true);
 | 
						|
+}
 | 
						|
+
 | 
						|
 void br_multicast_disable_port(struct net_bridge_port *port)
 | 
						|
 {
 | 
						|
-	spin_lock_bh(&port->br->multicast_lock);
 | 
						|
-	__br_multicast_disable_port_ctx(&port->multicast_ctx);
 | 
						|
-	spin_unlock_bh(&port->br->multicast_lock);
 | 
						|
+	br_multicast_toggle_port(port, false);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int __grp_src_delete_marked(struct net_bridge_port_group *pg)
 | 
						|
@@ -4210,6 +4271,32 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx)
 | 
						|
 #endif
 | 
						|
 }
 | 
						|
 
 | 
						|
+void br_multicast_update_vlan_mcast_ctx(struct net_bridge_vlan *v, u8 state)
 | 
						|
+{
 | 
						|
+#if IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING)
 | 
						|
+	struct net_bridge *br;
 | 
						|
+
 | 
						|
+	if (!br_vlan_should_use(v))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (br_vlan_is_master(v))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	br = v->port->br;
 | 
						|
+
 | 
						|
+	if (!br_opt_get(br, BROPT_MCAST_VLAN_SNOOPING_ENABLED))
 | 
						|
+		return;
 | 
						|
+
 | 
						|
+	if (br_vlan_state_allowed(state, true))
 | 
						|
+		br_multicast_enable_port_ctx(&v->port_mcast_ctx);
 | 
						|
+
 | 
						|
+	/* Multicast is not disabled for the vlan when it goes in
 | 
						|
+	 * blocking state because the timers will expire and stop by
 | 
						|
+	 * themselves without sending more queries.
 | 
						|
+	 */
 | 
						|
+#endif
 | 
						|
+}
 | 
						|
+
 | 
						|
 void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on)
 | 
						|
 {
 | 
						|
 	struct net_bridge *br;
 | 
						|
@@ -4303,9 +4390,9 @@ int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
 | 
						|
 		__br_multicast_open(&br->multicast_ctx);
 | 
						|
 	list_for_each_entry(p, &br->port_list, list) {
 | 
						|
 		if (on)
 | 
						|
-			br_multicast_disable_port(p);
 | 
						|
+			br_multicast_disable_port_ctx(&p->multicast_ctx);
 | 
						|
 		else
 | 
						|
-			br_multicast_enable_port(p);
 | 
						|
+			br_multicast_enable_port_ctx(&p->multicast_ctx);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	list_for_each_entry(vlan, &vg->vlan_list, vlist)
 | 
						|
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
 | 
						|
index 9197b511e45972..067d47b8eb8ffb 100644
 | 
						|
--- a/net/bridge/br_private.h
 | 
						|
+++ b/net/bridge/br_private.h
 | 
						|
@@ -1043,6 +1043,7 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
 | 
						|
 				struct net_bridge_vlan *vlan,
 | 
						|
 				struct net_bridge_mcast_port *pmctx);
 | 
						|
 void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx);
 | 
						|
+void br_multicast_update_vlan_mcast_ctx(struct net_bridge_vlan *v, u8 state);
 | 
						|
 void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on);
 | 
						|
 int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
 | 
						|
 				      struct netlink_ext_ack *extack);
 | 
						|
@@ -1479,6 +1480,11 @@ static inline void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pm
 | 
						|
 {
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline void br_multicast_update_vlan_mcast_ctx(struct net_bridge_vlan *v,
 | 
						|
+						      u8 state)
 | 
						|
+{
 | 
						|
+}
 | 
						|
+
 | 
						|
 static inline void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan,
 | 
						|
 						bool on)
 | 
						|
 {
 | 
						|
@@ -1830,7 +1836,9 @@ bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
 | 
						|
 bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
 | 
						|
 			      const struct net_bridge_vlan *v_opts);
 | 
						|
 
 | 
						|
-/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */
 | 
						|
+/* vlan state manipulation helpers using *_ONCE to annotate lock-free access,
 | 
						|
+ * while br_vlan_set_state() may access data protected by multicast_lock.
 | 
						|
+ */
 | 
						|
 static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v)
 | 
						|
 {
 | 
						|
 	return READ_ONCE(v->state);
 | 
						|
@@ -1839,6 +1847,7 @@ static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v)
 | 
						|
 static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state)
 | 
						|
 {
 | 
						|
 	WRITE_ONCE(v->state, state);
 | 
						|
+	br_multicast_update_vlan_mcast_ctx(v, state);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg)
 | 
						|
diff --git a/net/core/filter.c b/net/core/filter.c
 | 
						|
index 5143c8a9e52cab..3e10b4c8338f92 100644
 | 
						|
--- a/net/core/filter.c
 | 
						|
+++ b/net/core/filter.c
 | 
						|
@@ -1968,10 +1968,11 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset,
 | 
						|
 	bool is_pseudo = flags & BPF_F_PSEUDO_HDR;
 | 
						|
 	bool is_mmzero = flags & BPF_F_MARK_MANGLED_0;
 | 
						|
 	bool do_mforce = flags & BPF_F_MARK_ENFORCE;
 | 
						|
+	bool is_ipv6   = flags & BPF_F_IPV6;
 | 
						|
 	__sum16 *ptr;
 | 
						|
 
 | 
						|
 	if (unlikely(flags & ~(BPF_F_MARK_MANGLED_0 | BPF_F_MARK_ENFORCE |
 | 
						|
-			       BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK)))
 | 
						|
+			       BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK | BPF_F_IPV6)))
 | 
						|
 		return -EINVAL;
 | 
						|
 	if (unlikely(offset > 0xffff || offset & 1))
 | 
						|
 		return -EFAULT;
 | 
						|
@@ -1987,7 +1988,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset,
 | 
						|
 		if (unlikely(from != 0))
 | 
						|
 			return -EINVAL;
 | 
						|
 
 | 
						|
-		inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo);
 | 
						|
+		inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, is_ipv6);
 | 
						|
 		break;
 | 
						|
 	case 2:
 | 
						|
 		inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo);
 | 
						|
@@ -3229,6 +3230,13 @@ static const struct bpf_func_proto bpf_skb_vlan_pop_proto = {
 | 
						|
 	.arg1_type      = ARG_PTR_TO_CTX,
 | 
						|
 };
 | 
						|
 
 | 
						|
+static void bpf_skb_change_protocol(struct sk_buff *skb, u16 proto)
 | 
						|
+{
 | 
						|
+	skb->protocol = htons(proto);
 | 
						|
+	if (skb_valid_dst(skb))
 | 
						|
+		skb_dst_drop(skb);
 | 
						|
+}
 | 
						|
+
 | 
						|
 static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
 | 
						|
 {
 | 
						|
 	/* Caller already did skb_cow() with len as headroom,
 | 
						|
@@ -3325,7 +3333,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	skb->protocol = htons(ETH_P_IPV6);
 | 
						|
+	bpf_skb_change_protocol(skb, ETH_P_IPV6);
 | 
						|
 	skb_clear_hash(skb);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
@@ -3355,7 +3363,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	skb->protocol = htons(ETH_P_IP);
 | 
						|
+	bpf_skb_change_protocol(skb, ETH_P_IP);
 | 
						|
 	skb_clear_hash(skb);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
@@ -3546,10 +3554,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
 | 
						|
 		/* Match skb->protocol to new outer l3 protocol */
 | 
						|
 		if (skb->protocol == htons(ETH_P_IP) &&
 | 
						|
 		    flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6)
 | 
						|
-			skb->protocol = htons(ETH_P_IPV6);
 | 
						|
+			bpf_skb_change_protocol(skb, ETH_P_IPV6);
 | 
						|
 		else if (skb->protocol == htons(ETH_P_IPV6) &&
 | 
						|
 			 flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4)
 | 
						|
-			skb->protocol = htons(ETH_P_IP);
 | 
						|
+			bpf_skb_change_protocol(skb, ETH_P_IP);
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (skb_is_gso(skb)) {
 | 
						|
@@ -3602,10 +3610,10 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
 | 
						|
 	/* Match skb->protocol to new outer l3 protocol */
 | 
						|
 	if (skb->protocol == htons(ETH_P_IP) &&
 | 
						|
 	    flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6)
 | 
						|
-		skb->protocol = htons(ETH_P_IPV6);
 | 
						|
+		bpf_skb_change_protocol(skb, ETH_P_IPV6);
 | 
						|
 	else if (skb->protocol == htons(ETH_P_IPV6) &&
 | 
						|
 		 flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4)
 | 
						|
-		skb->protocol = htons(ETH_P_IP);
 | 
						|
+		bpf_skb_change_protocol(skb, ETH_P_IP);
 | 
						|
 
 | 
						|
 	if (skb_is_gso(skb)) {
 | 
						|
 		struct skb_shared_info *shinfo = skb_shinfo(skb);
 | 
						|
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
 | 
						|
index 2076db464e9360..c3169e1e635248 100644
 | 
						|
--- a/net/core/skmsg.c
 | 
						|
+++ b/net/core/skmsg.c
 | 
						|
@@ -689,7 +689,8 @@ static void sk_psock_backlog(struct work_struct *work)
 | 
						|
 			if (ret <= 0) {
 | 
						|
 				if (ret == -EAGAIN) {
 | 
						|
 					sk_psock_skb_state(psock, state, len, off);
 | 
						|
-
 | 
						|
+					/* Restore redir info we cleared before */
 | 
						|
+					skb_bpf_set_redir(skb, psock->sk, ingress);
 | 
						|
 					/* Delay slightly to prioritize any
 | 
						|
 					 * other work that might be here.
 | 
						|
 					 */
 | 
						|
diff --git a/net/core/sock.c b/net/core/sock.c
 | 
						|
index 84ba3f67bca97b..ec48690b5174eb 100644
 | 
						|
--- a/net/core/sock.c
 | 
						|
+++ b/net/core/sock.c
 | 
						|
@@ -3817,7 +3817,7 @@ static int assign_proto_idx(struct proto *prot)
 | 
						|
 {
 | 
						|
 	prot->inuse_idx = find_first_zero_bit(proto_inuse_idx, PROTO_INUSE_NR);
 | 
						|
 
 | 
						|
-	if (unlikely(prot->inuse_idx == PROTO_INUSE_NR - 1)) {
 | 
						|
+	if (unlikely(prot->inuse_idx == PROTO_INUSE_NR)) {
 | 
						|
 		pr_err("PROTO_INUSE_NR exhausted\n");
 | 
						|
 		return -ENOSPC;
 | 
						|
 	}
 | 
						|
@@ -3828,7 +3828,7 @@ static int assign_proto_idx(struct proto *prot)
 | 
						|
 
 | 
						|
 static void release_proto_idx(struct proto *prot)
 | 
						|
 {
 | 
						|
-	if (prot->inuse_idx != PROTO_INUSE_NR - 1)
 | 
						|
+	if (prot->inuse_idx != PROTO_INUSE_NR)
 | 
						|
 		clear_bit(prot->inuse_idx, proto_inuse_idx);
 | 
						|
 }
 | 
						|
 #else
 | 
						|
diff --git a/net/core/utils.c b/net/core/utils.c
 | 
						|
index c994e95172acf5..5895d034bf279d 100644
 | 
						|
--- a/net/core/utils.c
 | 
						|
+++ b/net/core/utils.c
 | 
						|
@@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
 | 
						|
 EXPORT_SYMBOL(inet_proto_csum_replace16);
 | 
						|
 
 | 
						|
 void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
 | 
						|
-				     __wsum diff, bool pseudohdr)
 | 
						|
+				     __wsum diff, bool pseudohdr, bool ipv6)
 | 
						|
 {
 | 
						|
 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
 | 
						|
 		csum_replace_by_diff(sum, diff);
 | 
						|
-		if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
 | 
						|
+		if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6)
 | 
						|
 			skb->csum = ~csum_sub(diff, skb->csum);
 | 
						|
 	} else if (pseudohdr) {
 | 
						|
 		*sum = ~csum_fold(csum_add(diff, csum_unfold(*sum)));
 | 
						|
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
 | 
						|
index 97dc30a03dbf26..8ee1ad2d8c13f6 100644
 | 
						|
--- a/net/ipv4/route.c
 | 
						|
+++ b/net/ipv4/route.c
 | 
						|
@@ -192,7 +192,11 @@ const __u8 ip_tos2prio[16] = {
 | 
						|
 EXPORT_SYMBOL(ip_tos2prio);
 | 
						|
 
 | 
						|
 static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
 | 
						|
+#ifndef CONFIG_PREEMPT_RT
 | 
						|
 #define RT_CACHE_STAT_INC(field) raw_cpu_inc(rt_cache_stat.field)
 | 
						|
+#else
 | 
						|
+#define RT_CACHE_STAT_INC(field) this_cpu_inc(rt_cache_stat.field)
 | 
						|
+#endif
 | 
						|
 
 | 
						|
 #ifdef CONFIG_PROC_FS
 | 
						|
 static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
 | 
						|
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
 | 
						|
index 32b28fc21b63c0..408985eb74eefa 100644
 | 
						|
--- a/net/ipv4/tcp_fastopen.c
 | 
						|
+++ b/net/ipv4/tcp_fastopen.c
 | 
						|
@@ -3,6 +3,7 @@
 | 
						|
 #include <linux/tcp.h>
 | 
						|
 #include <linux/rcupdate.h>
 | 
						|
 #include <net/tcp.h>
 | 
						|
+#include <net/busy_poll.h>
 | 
						|
 
 | 
						|
 void tcp_fastopen_init_key_once(struct net *net)
 | 
						|
 {
 | 
						|
@@ -279,6 +280,8 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
 | 
						|
 
 | 
						|
 	refcount_set(&req->rsk_refcnt, 2);
 | 
						|
 
 | 
						|
+	sk_mark_napi_id_set(child, skb);
 | 
						|
+
 | 
						|
 	/* Now finish processing the fastopen child socket. */
 | 
						|
 	tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB, skb);
 | 
						|
 
 | 
						|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 | 
						|
index a172248b667837..f7b95bc8ad60bb 100644
 | 
						|
--- a/net/ipv4/tcp_input.c
 | 
						|
+++ b/net/ipv4/tcp_input.c
 | 
						|
@@ -671,10 +671,12 @@ EXPORT_SYMBOL(tcp_initialize_rcv_mss);
 | 
						|
  */
 | 
						|
 static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
 | 
						|
 {
 | 
						|
-	u32 new_sample = tp->rcv_rtt_est.rtt_us;
 | 
						|
-	long m = sample;
 | 
						|
+	u32 new_sample, old_sample = tp->rcv_rtt_est.rtt_us;
 | 
						|
+	long m = sample << 3;
 | 
						|
 
 | 
						|
-	if (new_sample != 0) {
 | 
						|
+	if (old_sample == 0 || m < old_sample) {
 | 
						|
+		new_sample = m;
 | 
						|
+	} else {
 | 
						|
 		/* If we sample in larger samples in the non-timestamp
 | 
						|
 		 * case, we could grossly overestimate the RTT especially
 | 
						|
 		 * with chatty applications or bulk transfer apps which
 | 
						|
@@ -685,17 +687,9 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
 | 
						|
 		 * else with timestamps disabled convergence takes too
 | 
						|
 		 * long.
 | 
						|
 		 */
 | 
						|
-		if (!win_dep) {
 | 
						|
-			m -= (new_sample >> 3);
 | 
						|
-			new_sample += m;
 | 
						|
-		} else {
 | 
						|
-			m <<= 3;
 | 
						|
-			if (m < new_sample)
 | 
						|
-				new_sample = m;
 | 
						|
-		}
 | 
						|
-	} else {
 | 
						|
-		/* No previous measure. */
 | 
						|
-		new_sample = m << 3;
 | 
						|
+		if (win_dep)
 | 
						|
+			return;
 | 
						|
+		new_sample = old_sample - (old_sample >> 3) + sample;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	tp->rcv_rtt_est.rtt_us = new_sample;
 | 
						|
@@ -2469,20 +2463,33 @@ static inline bool tcp_packet_delayed(const struct tcp_sock *tp)
 | 
						|
 {
 | 
						|
 	const struct sock *sk = (const struct sock *)tp;
 | 
						|
 
 | 
						|
-	if (tp->retrans_stamp &&
 | 
						|
-	    tcp_tsopt_ecr_before(tp, tp->retrans_stamp))
 | 
						|
-		return true;  /* got echoed TS before first retransmission */
 | 
						|
+	/* Received an echoed timestamp before the first retransmission? */
 | 
						|
+	if (tp->retrans_stamp)
 | 
						|
+		return tcp_tsopt_ecr_before(tp, tp->retrans_stamp);
 | 
						|
+
 | 
						|
+	/* We set tp->retrans_stamp upon the first retransmission of a loss
 | 
						|
+	 * recovery episode, so normally if tp->retrans_stamp is 0 then no
 | 
						|
+	 * retransmission has happened yet (likely due to TSQ, which can cause
 | 
						|
+	 * fast retransmits to be delayed). So if snd_una advanced while
 | 
						|
+	 * (tp->retrans_stamp is 0 then apparently a packet was merely delayed,
 | 
						|
+	 * not lost. But there are exceptions where we retransmit but then
 | 
						|
+	 * clear tp->retrans_stamp, so we check for those exceptions.
 | 
						|
+	 */
 | 
						|
 
 | 
						|
-	/* Check if nothing was retransmitted (retrans_stamp==0), which may
 | 
						|
-	 * happen in fast recovery due to TSQ. But we ignore zero retrans_stamp
 | 
						|
-	 * in TCP_SYN_SENT, since when we set FLAG_SYN_ACKED we also clear
 | 
						|
-	 * retrans_stamp even if we had retransmitted the SYN.
 | 
						|
+	/* (1) For non-SACK connections, tcp_is_non_sack_preventing_reopen()
 | 
						|
+	 * clears tp->retrans_stamp when snd_una == high_seq.
 | 
						|
 	 */
 | 
						|
-	if (!tp->retrans_stamp &&	   /* no record of a retransmit/SYN? */
 | 
						|
-	    sk->sk_state != TCP_SYN_SENT)  /* not the FLAG_SYN_ACKED case? */
 | 
						|
-		return true;  /* nothing was retransmitted */
 | 
						|
+	if (!tcp_is_sack(tp) && !before(tp->snd_una, tp->high_seq))
 | 
						|
+		return false;
 | 
						|
 
 | 
						|
-	return false;
 | 
						|
+	/* (2) In TCP_SYN_SENT tcp_clean_rtx_queue() clears tp->retrans_stamp
 | 
						|
+	 * when setting FLAG_SYN_ACKED is set, even if the SYN was
 | 
						|
+	 * retransmitted.
 | 
						|
+	 */
 | 
						|
+	if (sk->sk_state == TCP_SYN_SENT)
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	return true;	/* tp->retrans_stamp is zero; no retransmit yet */
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* Undo procedures. */
 | 
						|
@@ -6705,6 +6712,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
 | 
						|
 		if (!tp->srtt_us)
 | 
						|
 			tcp_synack_rtt_meas(sk, req);
 | 
						|
 
 | 
						|
+		if (tp->rx_opt.tstamp_ok)
 | 
						|
+			tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
 | 
						|
+
 | 
						|
 		if (req) {
 | 
						|
 			tcp_rcv_synrecv_state_fastopen(sk);
 | 
						|
 		} else {
 | 
						|
@@ -6729,9 +6739,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
 | 
						|
 		tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale;
 | 
						|
 		tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
 | 
						|
 
 | 
						|
-		if (tp->rx_opt.tstamp_ok)
 | 
						|
-			tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
 | 
						|
-
 | 
						|
 		if (!inet_csk(sk)->icsk_ca_ops->cong_control)
 | 
						|
 			tcp_update_pacing_rate(sk);
 | 
						|
 
 | 
						|
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
 | 
						|
index c07e3da08d2a8b..24666291c54a87 100644
 | 
						|
--- a/net/ipv6/calipso.c
 | 
						|
+++ b/net/ipv6/calipso.c
 | 
						|
@@ -1210,6 +1210,10 @@ static int calipso_req_setattr(struct request_sock *req,
 | 
						|
 	struct ipv6_opt_hdr *old, *new;
 | 
						|
 	struct sock *sk = sk_to_full_sk(req_to_sk(req));
 | 
						|
 
 | 
						|
+	/* sk is NULL for SYN+ACK w/ SYN Cookie */
 | 
						|
+	if (!sk)
 | 
						|
+		return -ENOMEM;
 | 
						|
+
 | 
						|
 	if (req_inet->ipv6_opt && req_inet->ipv6_opt->hopopt)
 | 
						|
 		old = req_inet->ipv6_opt->hopopt;
 | 
						|
 	else
 | 
						|
@@ -1250,6 +1254,10 @@ static void calipso_req_delattr(struct request_sock *req)
 | 
						|
 	struct ipv6_txoptions *txopts;
 | 
						|
 	struct sock *sk = sk_to_full_sk(req_to_sk(req));
 | 
						|
 
 | 
						|
+	/* sk is NULL for SYN+ACK w/ SYN Cookie */
 | 
						|
+	if (!sk)
 | 
						|
+		return;
 | 
						|
+
 | 
						|
 	if (!req_inet->ipv6_opt || !req_inet->ipv6_opt->hopopt)
 | 
						|
 		return;
 | 
						|
 
 | 
						|
diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c
 | 
						|
index 95e9146918cc6f..b8d43ed4689db9 100644
 | 
						|
--- a/net/ipv6/ila/ila_common.c
 | 
						|
+++ b/net/ipv6/ila/ila_common.c
 | 
						|
@@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb,
 | 
						|
 
 | 
						|
 			diff = get_csum_diff(ip6h, p);
 | 
						|
 			inet_proto_csum_replace_by_diff(&th->check, skb,
 | 
						|
-							diff, true);
 | 
						|
+							diff, true, true);
 | 
						|
 		}
 | 
						|
 		break;
 | 
						|
 	case NEXTHDR_UDP:
 | 
						|
@@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb,
 | 
						|
 			if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
 | 
						|
 				diff = get_csum_diff(ip6h, p);
 | 
						|
 				inet_proto_csum_replace_by_diff(&uh->check, skb,
 | 
						|
-								diff, true);
 | 
						|
+								diff, true, true);
 | 
						|
 				if (!uh->check)
 | 
						|
 					uh->check = CSUM_MANGLED_0;
 | 
						|
 			}
 | 
						|
@@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb,
 | 
						|
 
 | 
						|
 			diff = get_csum_diff(ip6h, p);
 | 
						|
 			inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb,
 | 
						|
-							diff, true);
 | 
						|
+							diff, true, true);
 | 
						|
 		}
 | 
						|
 		break;
 | 
						|
 	}
 | 
						|
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
 | 
						|
index c6395551f5df08..54930b06c3a4a5 100644
 | 
						|
--- a/net/mac80211/mesh_hwmp.c
 | 
						|
+++ b/net/mac80211/mesh_hwmp.c
 | 
						|
@@ -634,7 +634,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 | 
						|
 				mesh_path_add_gate(mpath);
 | 
						|
 		}
 | 
						|
 		rcu_read_unlock();
 | 
						|
-	} else {
 | 
						|
+	} else if (ifmsh->mshcfg.dot11MeshForwarding) {
 | 
						|
 		rcu_read_lock();
 | 
						|
 		mpath = mesh_path_lookup(sdata, target_addr);
 | 
						|
 		if (mpath) {
 | 
						|
@@ -652,6 +652,8 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 | 
						|
 			}
 | 
						|
 		}
 | 
						|
 		rcu_read_unlock();
 | 
						|
+	} else {
 | 
						|
+		forward = false;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	if (reply) {
 | 
						|
@@ -669,7 +671,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
 | 
						|
+	if (forward) {
 | 
						|
 		u32 preq_id;
 | 
						|
 		u8 hopcount;
 | 
						|
 
 | 
						|
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
 | 
						|
index 45a093d3f1fa7f..ec5469add68a27 100644
 | 
						|
--- a/net/mac80211/tx.c
 | 
						|
+++ b/net/mac80211/tx.c
 | 
						|
@@ -4507,8 +4507,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 | 
						|
 						     IEEE80211_TX_CTRL_MLO_LINK_UNSPEC,
 | 
						|
 						     NULL);
 | 
						|
 	} else if (ieee80211_vif_is_mld(&sdata->vif) &&
 | 
						|
-		   sdata->vif.type == NL80211_IFTYPE_AP &&
 | 
						|
-		   !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) {
 | 
						|
+		   ((sdata->vif.type == NL80211_IFTYPE_AP &&
 | 
						|
+		     !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) ||
 | 
						|
+		    (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
 | 
						|
+		     !sdata->wdev.use_4addr))) {
 | 
						|
 		ieee80211_mlo_multicast_tx(dev, skb);
 | 
						|
 	} else {
 | 
						|
 normal:
 | 
						|
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
 | 
						|
index 43e8343df0db71..5a4b175b78c8c9 100644
 | 
						|
--- a/net/mpls/af_mpls.c
 | 
						|
+++ b/net/mpls/af_mpls.c
 | 
						|
@@ -81,8 +81,8 @@ static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index)
 | 
						|
 
 | 
						|
 	if (index < net->mpls.platform_labels) {
 | 
						|
 		struct mpls_route __rcu **platform_label =
 | 
						|
-			rcu_dereference(net->mpls.platform_label);
 | 
						|
-		rt = rcu_dereference(platform_label[index]);
 | 
						|
+			rcu_dereference_rtnl(net->mpls.platform_label);
 | 
						|
+		rt = rcu_dereference_rtnl(platform_label[index]);
 | 
						|
 	}
 | 
						|
 	return rt;
 | 
						|
 }
 | 
						|
diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c
 | 
						|
index ed1508a9e093ed..aab107727f186e 100644
 | 
						|
--- a/net/nfc/nci/uart.c
 | 
						|
+++ b/net/nfc/nci/uart.c
 | 
						|
@@ -119,22 +119,22 @@ static int nci_uart_set_driver(struct tty_struct *tty, unsigned int driver)
 | 
						|
 
 | 
						|
 	memcpy(nu, nci_uart_drivers[driver], sizeof(struct nci_uart));
 | 
						|
 	nu->tty = tty;
 | 
						|
-	tty->disc_data = nu;
 | 
						|
 	skb_queue_head_init(&nu->tx_q);
 | 
						|
 	INIT_WORK(&nu->write_work, nci_uart_write_work);
 | 
						|
 	spin_lock_init(&nu->rx_lock);
 | 
						|
 
 | 
						|
 	ret = nu->ops.open(nu);
 | 
						|
 	if (ret) {
 | 
						|
-		tty->disc_data = NULL;
 | 
						|
 		kfree(nu);
 | 
						|
+		return ret;
 | 
						|
 	} else if (!try_module_get(nu->owner)) {
 | 
						|
 		nu->ops.close(nu);
 | 
						|
-		tty->disc_data = NULL;
 | 
						|
 		kfree(nu);
 | 
						|
 		return -ENOENT;
 | 
						|
 	}
 | 
						|
-	return ret;
 | 
						|
+	tty->disc_data = nu;
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
 /* ------ LDISC part ------ */
 | 
						|
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
 | 
						|
index d564675a8be4d7..e871cb53946a3e 100644
 | 
						|
--- a/net/sched/sch_sfq.c
 | 
						|
+++ b/net/sched/sch_sfq.c
 | 
						|
@@ -656,6 +656,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
 | 
						|
 		NL_SET_ERR_MSG_MOD(extack, "invalid quantum");
 | 
						|
 		return -EINVAL;
 | 
						|
 	}
 | 
						|
+
 | 
						|
+	if (ctl->perturb_period < 0 ||
 | 
						|
+	    ctl->perturb_period > INT_MAX / HZ) {
 | 
						|
+		NL_SET_ERR_MSG_MOD(extack, "invalid perturb period");
 | 
						|
+		return -EINVAL;
 | 
						|
+	}
 | 
						|
+	perturb_period = ctl->perturb_period * HZ;
 | 
						|
+
 | 
						|
 	if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
 | 
						|
 					ctl_v1->Wlog, ctl_v1->Scell_log, NULL))
 | 
						|
 		return -EINVAL;
 | 
						|
@@ -672,14 +680,12 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
 | 
						|
 	headdrop = q->headdrop;
 | 
						|
 	maxdepth = q->maxdepth;
 | 
						|
 	maxflows = q->maxflows;
 | 
						|
-	perturb_period = q->perturb_period;
 | 
						|
 	quantum = q->quantum;
 | 
						|
 	flags = q->flags;
 | 
						|
 
 | 
						|
 	/* update and validate configuration */
 | 
						|
 	if (ctl->quantum)
 | 
						|
 		quantum = ctl->quantum;
 | 
						|
-	perturb_period = ctl->perturb_period * HZ;
 | 
						|
 	if (ctl->flows)
 | 
						|
 		maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
 | 
						|
 	if (ctl->divisor) {
 | 
						|
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
 | 
						|
index 951a87909c2974..d162e2dd860255 100644
 | 
						|
--- a/net/sched/sch_taprio.c
 | 
						|
+++ b/net/sched/sch_taprio.c
 | 
						|
@@ -1338,13 +1338,15 @@ static int taprio_dev_notifier(struct notifier_block *nb, unsigned long event,
 | 
						|
 
 | 
						|
 		stab = rtnl_dereference(q->root->stab);
 | 
						|
 
 | 
						|
-		oper = rtnl_dereference(q->oper_sched);
 | 
						|
+		rcu_read_lock();
 | 
						|
+		oper = rcu_dereference(q->oper_sched);
 | 
						|
 		if (oper)
 | 
						|
 			taprio_update_queue_max_sdu(q, oper, stab);
 | 
						|
 
 | 
						|
-		admin = rtnl_dereference(q->admin_sched);
 | 
						|
+		admin = rcu_dereference(q->admin_sched);
 | 
						|
 		if (admin)
 | 
						|
 			taprio_update_queue_max_sdu(q, admin, stab);
 | 
						|
+		rcu_read_unlock();
 | 
						|
 
 | 
						|
 		break;
 | 
						|
 	}
 | 
						|
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
 | 
						|
index b84c5e0a76f52d..adc04e88f349f0 100644
 | 
						|
--- a/net/sctp/socket.c
 | 
						|
+++ b/net/sctp/socket.c
 | 
						|
@@ -9094,7 +9094,8 @@ static void __sctp_write_space(struct sctp_association *asoc)
 | 
						|
 		wq = rcu_dereference(sk->sk_wq);
 | 
						|
 		if (wq) {
 | 
						|
 			if (waitqueue_active(&wq->wait))
 | 
						|
-				wake_up_interruptible(&wq->wait);
 | 
						|
+				wake_up_interruptible_poll(&wq->wait, EPOLLOUT |
 | 
						|
+						EPOLLWRNORM | EPOLLWRBAND);
 | 
						|
 
 | 
						|
 			/* Note that we try to include the Async I/O support
 | 
						|
 			 * here by modeling from the current TCP/UDP code.
 | 
						|
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
 | 
						|
index b43dc8409b1fb0..4d8d460747164e 100644
 | 
						|
--- a/net/sunrpc/svc.c
 | 
						|
+++ b/net/sunrpc/svc.c
 | 
						|
@@ -1344,7 +1344,8 @@ svc_process_common(struct svc_rqst *rqstp)
 | 
						|
 	case SVC_OK:
 | 
						|
 		break;
 | 
						|
 	case SVC_GARBAGE:
 | 
						|
-		goto err_garbage_args;
 | 
						|
+		rqstp->rq_auth_stat = rpc_autherr_badcred;
 | 
						|
+		goto err_bad_auth;
 | 
						|
 	case SVC_SYSERR:
 | 
						|
 		goto err_system_err;
 | 
						|
 	case SVC_DENIED:
 | 
						|
@@ -1485,14 +1486,6 @@ svc_process_common(struct svc_rqst *rqstp)
 | 
						|
 	*rqstp->rq_accept_statp = rpc_proc_unavail;
 | 
						|
 	goto sendit;
 | 
						|
 
 | 
						|
-err_garbage_args:
 | 
						|
-	svc_printk(rqstp, "failed to decode RPC header\n");
 | 
						|
-
 | 
						|
-	if (serv->sv_stats)
 | 
						|
-		serv->sv_stats->rpcbadfmt++;
 | 
						|
-	*rqstp->rq_accept_statp = rpc_garbage_args;
 | 
						|
-	goto sendit;
 | 
						|
-
 | 
						|
 err_system_err:
 | 
						|
 	if (serv->sv_stats)
 | 
						|
 		serv->sv_stats->rpcbadfmt++;
 | 
						|
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
 | 
						|
index 29df05879c8e95..f90d84492bbedc 100644
 | 
						|
--- a/net/sunrpc/xprtsock.c
 | 
						|
+++ b/net/sunrpc/xprtsock.c
 | 
						|
@@ -2724,6 +2724,11 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work)
 | 
						|
 	}
 | 
						|
 	rpc_shutdown_client(lower_clnt);
 | 
						|
 
 | 
						|
+	/* Check for ingress data that arrived before the socket's
 | 
						|
+	 * ->data_ready callback was set up.
 | 
						|
+	 */
 | 
						|
+	xs_poll_check_readable(upper_transport);
 | 
						|
+
 | 
						|
 out_unlock:
 | 
						|
 	current_restore_flags(pflags, PF_MEMALLOC);
 | 
						|
 	upper_transport->clnt = NULL;
 | 
						|
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
 | 
						|
index 79f91b6ca8c847..ea5bb131ebd060 100644
 | 
						|
--- a/net/tipc/crypto.c
 | 
						|
+++ b/net/tipc/crypto.c
 | 
						|
@@ -425,7 +425,7 @@ static void tipc_aead_free(struct rcu_head *rp)
 | 
						|
 	}
 | 
						|
 	free_percpu(aead->tfm_entry);
 | 
						|
 	kfree_sensitive(aead->key);
 | 
						|
-	kfree(aead);
 | 
						|
+	kfree_sensitive(aead);
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int tipc_aead_users(struct tipc_aead __rcu *aead)
 | 
						|
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
 | 
						|
index b16ca400ff559c..e993bd6ed7c26f 100644
 | 
						|
--- a/net/tipc/udp_media.c
 | 
						|
+++ b/net/tipc/udp_media.c
 | 
						|
@@ -489,7 +489,7 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
 | 
						|
 
 | 
						|
 		rtnl_lock();
 | 
						|
 		b = tipc_bearer_find(net, bname);
 | 
						|
-		if (!b) {
 | 
						|
+		if (!b || b->bcast_addr.media_id != TIPC_MEDIA_TYPE_UDP) {
 | 
						|
 			rtnl_unlock();
 | 
						|
 			return -EINVAL;
 | 
						|
 		}
 | 
						|
@@ -500,7 +500,7 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
 | 
						|
 
 | 
						|
 		rtnl_lock();
 | 
						|
 		b = rtnl_dereference(tn->bearer_list[bid]);
 | 
						|
-		if (!b) {
 | 
						|
+		if (!b || b->bcast_addr.media_id != TIPC_MEDIA_TYPE_UDP) {
 | 
						|
 			rtnl_unlock();
 | 
						|
 			return -EINVAL;
 | 
						|
 		}
 | 
						|
diff --git a/net/wireless/core.c b/net/wireless/core.c
 | 
						|
index a2b15349324b6e..f6693983b5e986 100644
 | 
						|
--- a/net/wireless/core.c
 | 
						|
+++ b/net/wireless/core.c
 | 
						|
@@ -550,6 +550,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
 | 
						|
 	INIT_WORK(&rdev->mgmt_registrations_update_wk,
 | 
						|
 		  cfg80211_mgmt_registrations_update_wk);
 | 
						|
 	spin_lock_init(&rdev->mgmt_registrations_lock);
 | 
						|
+	INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work);
 | 
						|
+	INIT_LIST_HEAD(&rdev->wiphy_work_list);
 | 
						|
+	spin_lock_init(&rdev->wiphy_work_lock);
 | 
						|
 
 | 
						|
 #ifdef CONFIG_CFG80211_DEFAULT_PS
 | 
						|
 	rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
 | 
						|
@@ -567,9 +570,6 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
 | 
						|
 		return NULL;
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work);
 | 
						|
-	INIT_LIST_HEAD(&rdev->wiphy_work_list);
 | 
						|
-	spin_lock_init(&rdev->wiphy_work_lock);
 | 
						|
 	INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work);
 | 
						|
 	INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
 | 
						|
 	INIT_WORK(&rdev->event_work, cfg80211_event_work);
 | 
						|
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
 | 
						|
index 95fcd2d3433e4b..0fbbc62ed3edec 100644
 | 
						|
--- a/security/selinux/xfrm.c
 | 
						|
+++ b/security/selinux/xfrm.c
 | 
						|
@@ -95,7 +95,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
 | 
						|
 
 | 
						|
 	ctx->ctx_doi = XFRM_SC_DOI_LSM;
 | 
						|
 	ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
 | 
						|
-	ctx->ctx_len = str_len;
 | 
						|
+	ctx->ctx_len = str_len + 1;
 | 
						|
 	memcpy(ctx->ctx_str, &uctx[1], str_len);
 | 
						|
 	ctx->ctx_str[str_len] = '\0';
 | 
						|
 	rc = security_context_to_sid(ctx->ctx_str, str_len,
 | 
						|
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
 | 
						|
index 3a0df631d25d91..3cd5b7da8e1528 100644
 | 
						|
--- a/sound/pci/hda/hda_intel.c
 | 
						|
+++ b/sound/pci/hda/hda_intel.c
 | 
						|
@@ -2266,6 +2266,8 @@ static const struct snd_pci_quirk power_save_denylist[] = {
 | 
						|
 	SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0),
 | 
						|
 	/* Dell ALC3271 */
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x0962, "Dell ALC3271", 0),
 | 
						|
+	/* https://bugzilla.kernel.org/show_bug.cgi?id=220210 */
 | 
						|
+	SND_PCI_QUIRK(0x17aa, 0x5079, "Lenovo Thinkpad E15", 0),
 | 
						|
 	{}
 | 
						|
 };
 | 
						|
 #endif /* CONFIG_PM */
 | 
						|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
 | 
						|
index 440b934cdc284a..82210b1e3b9782 100644
 | 
						|
--- a/sound/pci/hda/patch_realtek.c
 | 
						|
+++ b/sound/pci/hda/patch_realtek.c
 | 
						|
@@ -9952,6 +9952,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
 | 
						|
+	SND_PCI_QUIRK(0x1028, 0x0879, "Dell Latitude 5420 Rugged", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						|
 	SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
 | 
						|
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
 | 
						|
index 622df58a969421..9fdee74c28df27 100644
 | 
						|
--- a/sound/soc/amd/yc/acp6x-mach.c
 | 
						|
+++ b/sound/soc/amd/yc/acp6x-mach.c
 | 
						|
@@ -311,6 +311,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
 | 
						|
 			DMI_MATCH(DMI_PRODUCT_NAME, "83AS"),
 | 
						|
 		}
 | 
						|
 	},
 | 
						|
+	{
 | 
						|
+		.driver_data = &acp6x_card,
 | 
						|
+		.matches = {
 | 
						|
+			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 | 
						|
+			DMI_MATCH(DMI_PRODUCT_NAME, "83HN"),
 | 
						|
+		}
 | 
						|
+	},
 | 
						|
 	{
 | 
						|
 		.driver_data = &acp6x_card,
 | 
						|
 		.matches = {
 | 
						|
@@ -360,7 +367,7 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
 | 
						|
 			DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"),
 | 
						|
 		}
 | 
						|
 	},
 | 
						|
-        {
 | 
						|
+	{
 | 
						|
 		.driver_data = &acp6x_card,
 | 
						|
 		.matches = {
 | 
						|
 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
 | 
						|
diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
 | 
						|
index 5c6b825c757b33..181b16530e5bc9 100644
 | 
						|
--- a/sound/soc/codecs/tas2770.c
 | 
						|
+++ b/sound/soc/codecs/tas2770.c
 | 
						|
@@ -158,11 +158,37 @@ static const struct snd_kcontrol_new isense_switch =
 | 
						|
 static const struct snd_kcontrol_new vsense_switch =
 | 
						|
 	SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 2, 1, 1);
 | 
						|
 
 | 
						|
+static int sense_event(struct snd_soc_dapm_widget *w,
 | 
						|
+			struct snd_kcontrol *kcontrol, int event)
 | 
						|
+{
 | 
						|
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 | 
						|
+	struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Powering up ISENSE/VSENSE requires a trip through the shutdown state.
 | 
						|
+	 * Do that here to ensure that our changes are applied properly, otherwise
 | 
						|
+	 * we might end up with non-functional IVSENSE if playback started earlier,
 | 
						|
+	 * which would break software speaker protection.
 | 
						|
+	 */
 | 
						|
+	switch (event) {
 | 
						|
+	case SND_SOC_DAPM_PRE_REG:
 | 
						|
+		return snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
 | 
						|
+						    TAS2770_PWR_CTRL_MASK,
 | 
						|
+						    TAS2770_PWR_CTRL_SHUTDOWN);
 | 
						|
+	case SND_SOC_DAPM_POST_REG:
 | 
						|
+		return tas2770_update_pwr_ctrl(tas2770);
 | 
						|
+	default:
 | 
						|
+		return 0;
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+
 | 
						|
 static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = {
 | 
						|
 	SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
 | 
						|
 	SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2770_asi1_mux),
 | 
						|
-	SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch),
 | 
						|
-	SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch),
 | 
						|
+	SND_SOC_DAPM_SWITCH_E("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch,
 | 
						|
+		sense_event, SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
 | 
						|
+	SND_SOC_DAPM_SWITCH_E("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch,
 | 
						|
+		sense_event, SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
 | 
						|
 	SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2770_dac_event,
 | 
						|
 			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 | 
						|
 	SND_SOC_DAPM_OUTPUT("OUT"),
 | 
						|
diff --git a/sound/soc/meson/meson-card-utils.c b/sound/soc/meson/meson-card-utils.c
 | 
						|
index f7fd9c013e19f7..1adaf0041a4804 100644
 | 
						|
--- a/sound/soc/meson/meson-card-utils.c
 | 
						|
+++ b/sound/soc/meson/meson-card-utils.c
 | 
						|
@@ -231,7 +231,7 @@ static int meson_card_parse_of_optional(struct snd_soc_card *card,
 | 
						|
 						    const char *p))
 | 
						|
 {
 | 
						|
 	/* If property is not provided, don't fail ... */
 | 
						|
-	if (!of_property_read_bool(card->dev->of_node, propname))
 | 
						|
+	if (!of_property_present(card->dev->of_node, propname))
 | 
						|
 		return 0;
 | 
						|
 
 | 
						|
 	/* ... but do fail if it is provided and the parsing fails */
 | 
						|
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
 | 
						|
index 3eb29645a6377c..39d22304ce43ff 100644
 | 
						|
--- a/sound/soc/qcom/sdm845.c
 | 
						|
+++ b/sound/soc/qcom/sdm845.c
 | 
						|
@@ -90,6 +90,10 @@ static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
 | 
						|
 		else
 | 
						|
 			ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt,
 | 
						|
 							  tx_ch, 0, NULL);
 | 
						|
+		if (ret != 0 && ret != -ENOTSUPP) {
 | 
						|
+			dev_err(rtd->dev, "failed to set cpu chan map, err:%d\n", ret);
 | 
						|
+			return ret;
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
 | 
						|
index ab3c6b2544d205..140cb27f73287e 100644
 | 
						|
--- a/sound/soc/tegra/tegra210_ahub.c
 | 
						|
+++ b/sound/soc/tegra/tegra210_ahub.c
 | 
						|
@@ -1359,6 +1359,8 @@ static int tegra_ahub_probe(struct platform_device *pdev)
 | 
						|
 		return -ENOMEM;
 | 
						|
 
 | 
						|
 	ahub->soc_data = of_device_get_match_data(&pdev->dev);
 | 
						|
+	if (!ahub->soc_data)
 | 
						|
+		return -ENODEV;
 | 
						|
 
 | 
						|
 	platform_set_drvdata(pdev, ahub);
 | 
						|
 
 | 
						|
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
 | 
						|
index 0e9b5431a47f20..faac7df1fbcf02 100644
 | 
						|
--- a/sound/usb/mixer_maps.c
 | 
						|
+++ b/sound/usb/mixer_maps.c
 | 
						|
@@ -383,6 +383,13 @@ static const struct usbmix_name_map ms_usb_link_map[] = {
 | 
						|
 	{ 0 }   /* terminator */
 | 
						|
 };
 | 
						|
 
 | 
						|
+/* KTMicro USB */
 | 
						|
+static struct usbmix_name_map s31b2_0022_map[] = {
 | 
						|
+	{ 23, "Speaker Playback" },
 | 
						|
+	{ 18, "Headphone Playback" },
 | 
						|
+	{ 0 }
 | 
						|
+};
 | 
						|
+
 | 
						|
 /* ASUS ROG Zenith II with Realtek ALC1220-VB */
 | 
						|
 static const struct usbmix_name_map asus_zenith_ii_map[] = {
 | 
						|
 	{ 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */
 | 
						|
@@ -692,6 +699,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
 | 
						|
 		.id = USB_ID(0x045e, 0x083c),
 | 
						|
 		.map = ms_usb_link_map,
 | 
						|
 	},
 | 
						|
+	{
 | 
						|
+		/* KTMicro USB */
 | 
						|
+		.id = USB_ID(0X31b2, 0x0022),
 | 
						|
+		.map = s31b2_0022_map,
 | 
						|
+	},
 | 
						|
 	{ 0 } /* terminator */
 | 
						|
 };
 | 
						|
 
 | 
						|
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
 | 
						|
index 2a90f04a4160db..2e064a1032a050 100644
 | 
						|
--- a/tools/include/uapi/linux/bpf.h
 | 
						|
+++ b/tools/include/uapi/linux/bpf.h
 | 
						|
@@ -1913,6 +1913,7 @@ union bpf_attr {
 | 
						|
  * 		for updates resulting in a null checksum the value is set to
 | 
						|
  * 		**CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
 | 
						|
  * 		the checksum is to be computed against a pseudo-header.
 | 
						|
+ * 		Flag **BPF_F_IPV6** should be set for IPv6 packets.
 | 
						|
  *
 | 
						|
  * 		This helper works in combination with **bpf_csum_diff**\ (),
 | 
						|
  * 		which does not update the checksum in-place, but offers more
 | 
						|
@@ -5920,6 +5921,7 @@ enum {
 | 
						|
 	BPF_F_PSEUDO_HDR		= (1ULL << 4),
 | 
						|
 	BPF_F_MARK_MANGLED_0		= (1ULL << 5),
 | 
						|
 	BPF_F_MARK_ENFORCE		= (1ULL << 6),
 | 
						|
+	BPF_F_IPV6			= (1ULL << 7),
 | 
						|
 };
 | 
						|
 
 | 
						|
 /* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
 | 
						|
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
 | 
						|
index 8484b563b53d0a..2e9f28cece3ffe 100644
 | 
						|
--- a/tools/lib/bpf/btf.c
 | 
						|
+++ b/tools/lib/bpf/btf.c
 | 
						|
@@ -3922,6 +3922,19 @@ static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id
 | 
						|
 	return true;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static bool btf_dedup_identical_ptrs(struct btf_dedup *d, __u32 id1, __u32 id2)
 | 
						|
+{
 | 
						|
+	struct btf_type *t1, *t2;
 | 
						|
+
 | 
						|
+	t1 = btf_type_by_id(d->btf, id1);
 | 
						|
+	t2 = btf_type_by_id(d->btf, id2);
 | 
						|
+
 | 
						|
+	if (!btf_is_ptr(t1) || !btf_is_ptr(t2))
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	return t1->type == t2->type;
 | 
						|
+}
 | 
						|
+
 | 
						|
 /*
 | 
						|
  * Check equivalence of BTF type graph formed by candidate struct/union (we'll
 | 
						|
  * call it "candidate graph" in this description for brevity) to a type graph
 | 
						|
@@ -4054,6 +4067,9 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
 | 
						|
 		 */
 | 
						|
 		if (btf_dedup_identical_structs(d, hypot_type_id, cand_id))
 | 
						|
 			return 1;
 | 
						|
+		/* A similar case is again observed for PTRs. */
 | 
						|
+		if (btf_dedup_identical_ptrs(d, hypot_type_id, cand_id))
 | 
						|
+			return 1;
 | 
						|
 		return 0;
 | 
						|
 	}
 | 
						|
 
 | 
						|
diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
 | 
						|
index 9bee082194d5ea..fb11a967c450dc 100644
 | 
						|
--- a/tools/perf/util/print-events.c
 | 
						|
+++ b/tools/perf/util/print-events.c
 | 
						|
@@ -271,6 +271,7 @@ bool is_event_supported(u8 type, u64 config)
 | 
						|
 			ret = evsel__open(evsel, NULL, tmap) >= 0;
 | 
						|
 		}
 | 
						|
 
 | 
						|
+		evsel__close(evsel);
 | 
						|
 		evsel__delete(evsel);
 | 
						|
 	}
 | 
						|
 
 | 
						|
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
 | 
						|
index 7e8c937627dd94..13ce9a53d5dec5 100644
 | 
						|
--- a/tools/testing/selftests/x86/Makefile
 | 
						|
+++ b/tools/testing/selftests/x86/Makefile
 | 
						|
@@ -12,7 +12,7 @@ CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh "$(CC)" trivial_program.c -no-pie)
 | 
						|
 
 | 
						|
 TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
 | 
						|
 			check_initial_reg_state sigreturn iopl ioperm \
 | 
						|
-			test_vsyscall mov_ss_trap \
 | 
						|
+			test_vsyscall mov_ss_trap sigtrap_loop \
 | 
						|
 			syscall_arg_fault fsgsbase_restore sigaltstack
 | 
						|
 TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
 | 
						|
 			test_FCMOV test_FCOMI test_FISTTP \
 | 
						|
diff --git a/tools/testing/selftests/x86/sigtrap_loop.c b/tools/testing/selftests/x86/sigtrap_loop.c
 | 
						|
new file mode 100644
 | 
						|
index 00000000000000..9d065479e89f94
 | 
						|
--- /dev/null
 | 
						|
+++ b/tools/testing/selftests/x86/sigtrap_loop.c
 | 
						|
@@ -0,0 +1,101 @@
 | 
						|
+// SPDX-License-Identifier: GPL-2.0-only
 | 
						|
+/*
 | 
						|
+ * Copyright (C) 2025 Intel Corporation
 | 
						|
+ */
 | 
						|
+#define _GNU_SOURCE
 | 
						|
+
 | 
						|
+#include <err.h>
 | 
						|
+#include <signal.h>
 | 
						|
+#include <stdio.h>
 | 
						|
+#include <stdlib.h>
 | 
						|
+#include <string.h>
 | 
						|
+#include <sys/ucontext.h>
 | 
						|
+
 | 
						|
+#ifdef __x86_64__
 | 
						|
+# define REG_IP REG_RIP
 | 
						|
+#else
 | 
						|
+# define REG_IP REG_EIP
 | 
						|
+#endif
 | 
						|
+
 | 
						|
+static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags)
 | 
						|
+{
 | 
						|
+	struct sigaction sa;
 | 
						|
+
 | 
						|
+	memset(&sa, 0, sizeof(sa));
 | 
						|
+	sa.sa_sigaction = handler;
 | 
						|
+	sa.sa_flags = SA_SIGINFO | flags;
 | 
						|
+	sigemptyset(&sa.sa_mask);
 | 
						|
+
 | 
						|
+	if (sigaction(sig, &sa, 0))
 | 
						|
+		err(1, "sigaction");
 | 
						|
+
 | 
						|
+	return;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
 | 
						|
+{
 | 
						|
+	ucontext_t *ctx = (ucontext_t *)ctx_void;
 | 
						|
+	static unsigned int loop_count_on_same_ip;
 | 
						|
+	static unsigned long last_trap_ip;
 | 
						|
+
 | 
						|
+	if (last_trap_ip == ctx->uc_mcontext.gregs[REG_IP]) {
 | 
						|
+		printf("\tTrapped at %016lx\n", last_trap_ip);
 | 
						|
+
 | 
						|
+		/*
 | 
						|
+		 * If the same IP is hit more than 10 times in a row, it is
 | 
						|
+		 * _considered_ an infinite loop.
 | 
						|
+		 */
 | 
						|
+		if (++loop_count_on_same_ip > 10) {
 | 
						|
+			printf("[FAIL]\tDetected SIGTRAP infinite loop\n");
 | 
						|
+			exit(1);
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	loop_count_on_same_ip = 0;
 | 
						|
+	last_trap_ip = ctx->uc_mcontext.gregs[REG_IP];
 | 
						|
+	printf("\tTrapped at %016lx\n", last_trap_ip);
 | 
						|
+}
 | 
						|
+
 | 
						|
+int main(int argc, char *argv[])
 | 
						|
+{
 | 
						|
+	sethandler(SIGTRAP, sigtrap, 0);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Set the Trap Flag (TF) to single-step the test code, therefore to
 | 
						|
+	 * trigger a SIGTRAP signal after each instruction until the TF is
 | 
						|
+	 * cleared.
 | 
						|
+	 *
 | 
						|
+	 * Because the arithmetic flags are not significant here, the TF is
 | 
						|
+	 * set by pushing 0x302 onto the stack and then popping it into the
 | 
						|
+	 * flags register.
 | 
						|
+	 *
 | 
						|
+	 * Four instructions in the following asm code are executed with the
 | 
						|
+	 * TF set, thus the SIGTRAP handler is expected to run four times.
 | 
						|
+	 */
 | 
						|
+	printf("[RUN]\tSIGTRAP infinite loop detection\n");
 | 
						|
+	asm volatile(
 | 
						|
+#ifdef __x86_64__
 | 
						|
+		/*
 | 
						|
+		 * Avoid clobbering the redzone
 | 
						|
+		 *
 | 
						|
+		 * Equivalent to "sub $128, %rsp", however -128 can be encoded
 | 
						|
+		 * in a single byte immediate while 128 uses 4 bytes.
 | 
						|
+		 */
 | 
						|
+		"add $-128, %rsp\n\t"
 | 
						|
+#endif
 | 
						|
+		"push $0x302\n\t"
 | 
						|
+		"popf\n\t"
 | 
						|
+		"nop\n\t"
 | 
						|
+		"nop\n\t"
 | 
						|
+		"push $0x202\n\t"
 | 
						|
+		"popf\n\t"
 | 
						|
+#ifdef __x86_64__
 | 
						|
+		"sub $-128, %rsp\n\t"
 | 
						|
+#endif
 | 
						|
+	);
 | 
						|
+
 | 
						|
+	printf("[OK]\tNo SIGTRAP infinite loop detected\n");
 | 
						|
+	return 0;
 | 
						|
+}
 |