commit:     40650180ce0013e49466af83960fd7bd8884963e
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 17 11:38:20 2021 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Wed Feb 17 11:38:28 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=40650180

Linux patch 5.4.99

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README             |    4 +
 1098_linux-5.4.99.patch | 2513 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2517 insertions(+)

diff --git a/0000_README b/0000_README
index 0c2bf6f..3e20dc5 100644
--- a/0000_README
+++ b/0000_README
@@ -435,6 +435,10 @@ Patch:  1097_linux-5.4.98.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.4.98
 
+Patch:  1098_linux-5.4.99.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.4.99
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1098_linux-5.4.99.patch b/1098_linux-5.4.99.patch
new file mode 100644
index 0000000..e3c707b
--- /dev/null
+++ b/1098_linux-5.4.99.patch
@@ -0,0 +1,2513 @@
+diff --git a/Makefile b/Makefile
+index 4f6bfcf434e80..a0491ba1d7593 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 4
+-SUBLEVEL = 98
++SUBLEVEL = 99
+ EXTRAVERSION =
+ NAME = Kleptomaniac Octopus
+ 
+diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
+index 7b7ec7b1217b8..824393e1bcfb7 100644
+--- a/arch/arm/boot/dts/lpc32xx.dtsi
++++ b/arch/arm/boot/dts/lpc32xx.dtsi
+@@ -329,9 +329,6 @@
+ 
+                                       clocks = <&xtal_32k>, <&xtal>;
+                                       clock-names = "xtal_32k", "xtal";
+-
+-                                      assigned-clocks = <&clk 
LPC32XX_CLK_HCLK_PLL>;
+-                                      assigned-clock-rates = <208000000>;
+                               };
+                       };
+ 
+diff --git a/arch/arm/include/asm/kexec-internal.h 
b/arch/arm/include/asm/kexec-internal.h
+new file mode 100644
+index 0000000000000..ecc2322db7aa1
+--- /dev/null
++++ b/arch/arm/include/asm/kexec-internal.h
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ARM_KEXEC_INTERNAL_H
++#define _ARM_KEXEC_INTERNAL_H
++
++struct kexec_relocate_data {
++      unsigned long kexec_start_address;
++      unsigned long kexec_indirection_page;
++      unsigned long kexec_mach_type;
++      unsigned long kexec_r2;
++};
++
++#endif
+diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
+index c773b829ee8ee..bfb05c93494db 100644
+--- a/arch/arm/kernel/asm-offsets.c
++++ b/arch/arm/kernel/asm-offsets.c
+@@ -15,6 +15,7 @@
+ #include <linux/kvm_host.h>
+ #endif
+ #include <asm/cacheflush.h>
++#include <asm/kexec-internal.h>
+ #include <asm/glue-df.h>
+ #include <asm/glue-pf.h>
+ #include <asm/mach/arch.h>
+@@ -190,5 +191,9 @@ int main(void)
+   DEFINE(MPU_RGN_PRBAR,       offsetof(struct mpu_rgn, prbar));
+   DEFINE(MPU_RGN_PRLAR,       offsetof(struct mpu_rgn, prlar));
+ #endif
++  DEFINE(KEXEC_START_ADDR,    offsetof(struct kexec_relocate_data, 
kexec_start_address));
++  DEFINE(KEXEC_INDIR_PAGE,    offsetof(struct kexec_relocate_data, 
kexec_indirection_page));
++  DEFINE(KEXEC_MACH_TYPE,     offsetof(struct kexec_relocate_data, 
kexec_mach_type));
++  DEFINE(KEXEC_R2,            offsetof(struct kexec_relocate_data, kexec_r2));
+   return 0; 
+ }
+diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
+index 76300f3813e89..734adeb42df87 100644
+--- a/arch/arm/kernel/machine_kexec.c
++++ b/arch/arm/kernel/machine_kexec.c
+@@ -15,6 +15,7 @@
+ #include <asm/pgalloc.h>
+ #include <asm/mmu_context.h>
+ #include <asm/cacheflush.h>
++#include <asm/kexec-internal.h>
+ #include <asm/fncpy.h>
+ #include <asm/mach-types.h>
+ #include <asm/smp_plat.h>
+@@ -24,11 +25,6 @@
+ extern void relocate_new_kernel(void);
+ extern const unsigned int relocate_new_kernel_size;
+ 
+-extern unsigned long kexec_start_address;
+-extern unsigned long kexec_indirection_page;
+-extern unsigned long kexec_mach_type;
+-extern unsigned long kexec_boot_atags;
+-
+ static atomic_t waiting_for_crash_ipi;
+ 
+ /*
+@@ -161,6 +157,7 @@ void (*kexec_reinit)(void);
+ void machine_kexec(struct kimage *image)
+ {
+       unsigned long page_list, reboot_entry_phys;
++      struct kexec_relocate_data *data;
+       void (*reboot_entry)(void);
+       void *reboot_code_buffer;
+ 
+@@ -176,18 +173,17 @@ void machine_kexec(struct kimage *image)
+ 
+       reboot_code_buffer = page_address(image->control_code_page);
+ 
+-      /* Prepare parameters for reboot_code_buffer*/
+-      set_kernel_text_rw();
+-      kexec_start_address = image->start;
+-      kexec_indirection_page = page_list;
+-      kexec_mach_type = machine_arch_type;
+-      kexec_boot_atags = image->arch.kernel_r2;
+-
+       /* copy our kernel relocation code to the control code page */
+       reboot_entry = fncpy(reboot_code_buffer,
+                            &relocate_new_kernel,
+                            relocate_new_kernel_size);
+ 
++      data = reboot_code_buffer + relocate_new_kernel_size;
++      data->kexec_start_address = image->start;
++      data->kexec_indirection_page = page_list;
++      data->kexec_mach_type = machine_arch_type;
++      data->kexec_r2 = image->arch.kernel_r2;
++
+       /* get the identity mapping physical address for the reboot code */
+       reboot_entry_phys = virt_to_idmap(reboot_entry);
+ 
+diff --git a/arch/arm/kernel/relocate_kernel.S 
b/arch/arm/kernel/relocate_kernel.S
+index 7eaa2ae7aff58..5e15b5912cb05 100644
+--- a/arch/arm/kernel/relocate_kernel.S
++++ b/arch/arm/kernel/relocate_kernel.S
+@@ -5,14 +5,16 @@
+ 
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
++#include <asm/asm-offsets.h>
+ #include <asm/kexec.h>
+ 
+       .align  3       /* not needed for this code, but keeps fncpy() happy */
+ 
+ ENTRY(relocate_new_kernel)
+ 
+-      ldr     r0,kexec_indirection_page
+-      ldr     r1,kexec_start_address
++      adr     r7, relocate_new_kernel_end
++      ldr     r0, [r7, #KEXEC_INDIR_PAGE]
++      ldr     r1, [r7, #KEXEC_START_ADDR]
+ 
+       /*
+        * If there is no indirection page (we are doing crashdumps)
+@@ -57,34 +59,16 @@ ENTRY(relocate_new_kernel)
+ 
+ 2:
+       /* Jump to relocated kernel */
+-      mov lr,r1
+-      mov r0,#0
+-      ldr r1,kexec_mach_type
+-      ldr r2,kexec_boot_atags
+- ARM( ret lr  )
+- THUMB(       bx lr           )
+-
+-      .align
+-
+-      .globl kexec_start_address
+-kexec_start_address:
+-      .long   0x0
+-
+-      .globl kexec_indirection_page
+-kexec_indirection_page:
+-      .long   0x0
+-
+-      .globl kexec_mach_type
+-kexec_mach_type:
+-      .long   0x0
+-
+-      /* phy addr of the atags for the new kernel */
+-      .globl kexec_boot_atags
+-kexec_boot_atags:
+-      .long   0x0
++      mov     lr, r1
++      mov     r0, #0
++      ldr     r1, [r7, #KEXEC_MACH_TYPE]
++      ldr     r2, [r7, #KEXEC_R2]
++ ARM( ret     lr      )
++ THUMB(       bx      lr      )
+ 
+ ENDPROC(relocate_new_kernel)
+ 
++      .align  3
+ relocate_new_kernel_end:
+ 
+       .globl relocate_new_kernel_size
+diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
+index ab2568996ddb0..c01f76cd02422 100644
+--- a/arch/arm/kernel/signal.c
++++ b/arch/arm/kernel/signal.c
+@@ -694,18 +694,20 @@ struct page *get_signal_page(void)
+ 
+       addr = page_address(page);
+ 
++      /* Poison the entire page */
++      memset32(addr, __opcode_to_mem_arm(0xe7fddef1),
++               PAGE_SIZE / sizeof(u32));
++
+       /* Give the signal return code some randomness */
+       offset = 0x200 + (get_random_int() & 0x7fc);
+       signal_return_offset = offset;
+ 
+-      /*
+-       * Copy signal return handlers into the vector page, and
+-       * set sigreturn to be a pointer to these.
+-       */
++      /* Copy signal return handlers into the page */
+       memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
+ 
+-      ptr = (unsigned long)addr + offset;
+-      flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
++      /* Flush out all instructions in this page */
++      ptr = (unsigned long)addr;
++      flush_icache_range(ptr, ptr + PAGE_SIZE);
+ 
+       return page;
+ }
+diff --git a/arch/arm/mach-omap2/cpuidle44xx.c 
b/arch/arm/mach-omap2/cpuidle44xx.c
+index c8d317fafe2ea..de37027ad7587 100644
+--- a/arch/arm/mach-omap2/cpuidle44xx.c
++++ b/arch/arm/mach-omap2/cpuidle44xx.c
+@@ -151,10 +151,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device 
*dev,
+                                (cx->mpu_logic_state == PWRDM_POWER_OFF);
+ 
+       /* Enter broadcast mode for periodic timers */
+-      tick_broadcast_enable();
++      RCU_NONIDLE(tick_broadcast_enable());
+ 
+       /* Enter broadcast mode for one-shot timers */
+-      tick_broadcast_enter();
++      RCU_NONIDLE(tick_broadcast_enter());
+ 
+       /*
+        * Call idle CPU PM enter notifier chain so that
+@@ -166,7 +166,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device 
*dev,
+ 
+       if (dev->cpu == 0) {
+               pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+-              omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
++              RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
+ 
+               /*
+                * Call idle CPU cluster PM enter notifier chain
+@@ -178,7 +178,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device 
*dev,
+                               index = 0;
+                               cx = state_ptr + index;
+                               pwrdm_set_logic_retst(mpu_pd, 
cx->mpu_logic_state);
+-                              omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
++                              RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, 
cx->mpu_state));
+                               mpuss_can_lose_context = 0;
+                       }
+               }
+@@ -194,9 +194,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device 
*dev,
+                   mpuss_can_lose_context)
+                       gic_dist_disable();
+ 
+-              clkdm_deny_idle(cpu_clkdm[1]);
+-              omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
+-              clkdm_allow_idle(cpu_clkdm[1]);
++              RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1]));
++              RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON));
++              RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1]));
+ 
+               if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
+                   mpuss_can_lose_context) {
+@@ -222,7 +222,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device 
*dev,
+       cpu_pm_exit();
+ 
+ cpu_pm_out:
+-      tick_broadcast_exit();
++      RCU_NONIDLE(tick_broadcast_exit());
+ 
+ fail:
+       cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
+index f45bff158fc20..57dfc13b27529 100644
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -370,8 +370,6 @@ static int __init xen_guest_init(void)
+               return -ENOMEM;
+       }
+       gnttab_init();
+-      if (!xen_initial_domain())
+-              xenbus_probe();
+ 
+       /*
+        * Making sure board specific code will not set up ops for
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts 
b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index 751651a6cd819..bf4fde88011c8 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -337,7 +337,9 @@
+ &gcc {
+       protected-clocks = <GCC_QSPI_CORE_CLK>,
+                          <GCC_QSPI_CORE_CLK_SRC>,
+-                         <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
++                         <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
++                         <GCC_LPASS_Q6_AXI_CLK>,
++                         <GCC_LPASS_SWAY_CLK>;
+ };
+ 
+ &pm8998_gpio {
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts 
b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+index e638f216dbfb3..840d6b9bbb598 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+@@ -232,7 +232,9 @@
+ &gcc {
+       protected-clocks = <GCC_QSPI_CORE_CLK>,
+                          <GCC_QSPI_CORE_CLK_SRC>,
+-                         <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
++                         <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
++                         <GCC_LPASS_Q6_AXI_CLK>,
++                         <GCC_LPASS_SWAY_CLK>;
+ };
+ 
+ &i2c1 {
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+index bb7d0aac6b9db..9d6ed8cda2c86 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+@@ -232,6 +232,7 @@
+               reg = <0x0 0xf8000000 0x0 0x2000000>,
+                     <0x0 0xfd000000 0x0 0x1000000>;
+               reg-names = "axi-base", "apb-base";
++              device_type = "pci";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+@@ -250,7 +251,6 @@
+                               <0 0 0 2 &pcie0_intc 1>,
+                               <0 0 0 3 &pcie0_intc 2>,
+                               <0 0 0 4 &pcie0_intc 3>;
+-              linux,pci-domain = <0>;
+               max-link-speed = <1>;
+               msi-map = <0x0 &its 0x0 0x1000>;
+               phys = <&pcie_phy 0>, <&pcie_phy 1>,
+diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c
+index 85e60509f0a83..d4b53af657c84 100644
+--- a/arch/h8300/kernel/asm-offsets.c
++++ b/arch/h8300/kernel/asm-offsets.c
+@@ -63,6 +63,9 @@ int main(void)
+       OFFSET(TI_FLAGS, thread_info, flags);
+       OFFSET(TI_CPU, thread_info, cpu);
+       OFFSET(TI_PRE, thread_info, preempt_count);
++#ifdef CONFIG_PREEMPTION
++      DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
++#endif
+ 
+       return 0;
+ }
+diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
+index a4e576019d79c..3ea360cad337b 100644
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -102,6 +102,7 @@ SECTIONS
+ #ifdef CONFIG_PPC64
+               *(.tramp.ftrace.text);
+ #endif
++              NOINSTR_TEXT
+               SCHED_TEXT
+               CPUIDLE_TEXT
+               LOCK_TEXT
+diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
+index 3db261c4810fc..6a30794aa1eea 100644
+--- a/arch/riscv/include/asm/page.h
++++ b/arch/riscv/include/asm/page.h
+@@ -119,7 +119,10 @@ extern unsigned long min_low_pfn;
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+-#define virt_addr_valid(vaddr)        (pfn_valid(virt_to_pfn(vaddr)))
++#define virt_addr_valid(vaddr)        ({                                      
        \
++      unsigned long _addr = (unsigned long)vaddr;                             
\
++      (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); 
\
++})
+ 
+ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index b5e3bfd4facea..8ca3cf7c5ec97 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -61,6 +61,9 @@ endif
+ KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow
+ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
+ 
++# Intel CET isn't enabled in the kernel
++KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
++
+ ifeq ($(CONFIG_X86_32),y)
+         BITS := 32
+         UTS_MACHINE := i386
+@@ -131,9 +134,6 @@ else
+ 
+         KBUILD_CFLAGS += -mno-red-zone
+         KBUILD_CFLAGS += -mcmodel=kernel
+-
+-      # Intel CET isn't enabled in the kernel
+-      KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
+ endif
+ 
+ ifdef CONFIG_X86_X32
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 7d19aae015aeb..ba32adaeefdd0 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -6320,13 +6320,13 @@ static unsigned int bfq_update_depths(struct bfq_data 
*bfqd,
+        * limit 'something'.
+        */
+       /* no more than 50% of tags for async I/O */
+-      bfqd->word_depths[0][0] = max(bt->sb.depth >> 1, 1U);
++      bfqd->word_depths[0][0] = max((1U << bt->sb.shift) >> 1, 1U);
+       /*
+        * no more than 75% of tags for sync writes (25% extra tags
+        * w.r.t. async I/O, to prevent async I/O from starving sync
+        * writes)
+        */
+-      bfqd->word_depths[0][1] = max((bt->sb.depth * 3) >> 2, 1U);
++      bfqd->word_depths[0][1] = max(((1U << bt->sb.shift) * 3) >> 2, 1U);
+ 
+       /*
+        * In-word depths in case some bfq_queue is being weight-
+@@ -6336,9 +6336,9 @@ static unsigned int bfq_update_depths(struct bfq_data 
*bfqd,
+        * shortage.
+        */
+       /* no more than ~18% of tags for async I/O */
+-      bfqd->word_depths[1][0] = max((bt->sb.depth * 3) >> 4, 1U);
++      bfqd->word_depths[1][0] = max(((1U << bt->sb.shift) * 3) >> 4, 1U);
+       /* no more than ~37% of tags for sync writes (~20% extra tags) */
+-      bfqd->word_depths[1][1] = max((bt->sb.depth * 6) >> 4, 1U);
++      bfqd->word_depths[1][1] = max(((1U << bt->sb.shift) * 6) >> 4, 1U);
+ 
+       for (i = 0; i < 2; i++)
+               for (j = 0; j < 2; j++)
+diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
+index fa4ecb9155909..9d3a76604d94c 100644
+--- a/drivers/clk/sunxi-ng/ccu_mp.c
++++ b/drivers/clk/sunxi-ng/ccu_mp.c
+@@ -108,7 +108,7 @@ static unsigned long ccu_mp_round_rate(struct 
ccu_mux_internal *mux,
+       max_m = cmp->m.max ?: 1 << cmp->m.width;
+       max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
+ 
+-      if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
++      if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) {
+               ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
+               rate = *parent_rate / p / m;
+       } else {
+diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
+index 226da8df6f100..94d9fa0d6aa70 100644
+--- a/drivers/gpio/gpio-ep93xx.c
++++ b/drivers/gpio/gpio-ep93xx.c
+@@ -25,6 +25,9 @@
+ /* Maximum value for gpio line identifiers */
+ #define EP93XX_GPIO_LINE_MAX 63
+ 
++/* Number of GPIO chips in EP93XX */
++#define EP93XX_GPIO_CHIP_NUM 8
++
+ /* Maximum value for irq capable line identifiers */
+ #define EP93XX_GPIO_LINE_MAX_IRQ 23
+ 
+@@ -34,74 +37,75 @@
+  */
+ #define EP93XX_GPIO_F_IRQ_BASE 80
+ 
+-struct ep93xx_gpio {
+-      void __iomem            *base;
+-      struct gpio_chip        gc[8];
++struct ep93xx_gpio_irq_chip {
++      struct irq_chip ic;
++      u8 irq_offset;
++      u8 int_unmasked;
++      u8 int_enabled;
++      u8 int_type1;
++      u8 int_type2;
++      u8 int_debounce;
+ };
+ 
+-/*************************************************************************
+- * Interrupt handling for EP93xx on-chip GPIOs
+- *************************************************************************/
+-static unsigned char gpio_int_unmasked[3];
+-static unsigned char gpio_int_enabled[3];
+-static unsigned char gpio_int_type1[3];
+-static unsigned char gpio_int_type2[3];
+-static unsigned char gpio_int_debounce[3];
+-
+-/* Port ordering is: A B F */
+-static const u8 int_type1_register_offset[3]  = { 0x90, 0xac, 0x4c };
+-static const u8 int_type2_register_offset[3]  = { 0x94, 0xb0, 0x50 };
+-static const u8 eoi_register_offset[3]                = { 0x98, 0xb4, 0x54 };
+-static const u8 int_en_register_offset[3]     = { 0x9c, 0xb8, 0x58 };
+-static const u8 int_debounce_register_offset[3]       = { 0xa8, 0xc4, 0x64 };
+-
+-static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned 
port)
+-{
+-      BUG_ON(port > 2);
++struct ep93xx_gpio_chip {
++      struct gpio_chip                gc;
++      struct ep93xx_gpio_irq_chip     *eic;
++};
+ 
+-      writeb_relaxed(0, epg->base + int_en_register_offset[port]);
++struct ep93xx_gpio {
++      void __iomem            *base;
++      struct ep93xx_gpio_chip gc[EP93XX_GPIO_CHIP_NUM];
++};
+ 
+-      writeb_relaxed(gpio_int_type2[port],
+-                     epg->base + int_type2_register_offset[port]);
++#define to_ep93xx_gpio_chip(x) container_of(x, struct ep93xx_gpio_chip, gc)
+ 
+-      writeb_relaxed(gpio_int_type1[port],
+-                     epg->base + int_type1_register_offset[port]);
++static struct ep93xx_gpio_irq_chip *to_ep93xx_gpio_irq_chip(struct gpio_chip 
*gc)
++{
++      struct ep93xx_gpio_chip *egc = to_ep93xx_gpio_chip(gc);
+ 
+-      writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
+-             epg->base + int_en_register_offset[port]);
++      return egc->eic;
+ }
+ 
+-static int ep93xx_gpio_port(struct gpio_chip *gc)
++/*************************************************************************
++ * Interrupt handling for EP93xx on-chip GPIOs
++ *************************************************************************/
++#define EP93XX_INT_TYPE1_OFFSET               0x00
++#define EP93XX_INT_TYPE2_OFFSET               0x04
++#define EP93XX_INT_EOI_OFFSET         0x08
++#define EP93XX_INT_EN_OFFSET          0x0c
++#define EP93XX_INT_STATUS_OFFSET      0x10
++#define EP93XX_INT_RAW_STATUS_OFFSET  0x14
++#define EP93XX_INT_DEBOUNCE_OFFSET    0x18
++
++static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg,
++                                        struct ep93xx_gpio_irq_chip *eic)
+ {
+-      struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = 0;
++      writeb_relaxed(0, epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET);
+ 
+-      while (port < ARRAY_SIZE(epg->gc) && gc != &epg->gc[port])
+-              port++;
++      writeb_relaxed(eic->int_type2,
++                     epg->base + eic->irq_offset + EP93XX_INT_TYPE2_OFFSET);
+ 
+-      /* This should not happen but is there as a last safeguard */
+-      if (port == ARRAY_SIZE(epg->gc)) {
+-              pr_crit("can't find the GPIO port\n");
+-              return 0;
+-      }
++      writeb_relaxed(eic->int_type1,
++                     epg->base + eic->irq_offset + EP93XX_INT_TYPE1_OFFSET);
+ 
+-      return port;
++      writeb_relaxed(eic->int_unmasked & eic->int_enabled,
++                     epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET);
+ }
+ 
+ static void ep93xx_gpio_int_debounce(struct gpio_chip *gc,
+                                    unsigned int offset, bool enable)
+ {
+       struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = ep93xx_gpio_port(gc);
++      struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
+       int port_mask = BIT(offset);
+ 
+       if (enable)
+-              gpio_int_debounce[port] |= port_mask;
++              eic->int_debounce |= port_mask;
+       else
+-              gpio_int_debounce[port] &= ~port_mask;
++              eic->int_debounce &= ~port_mask;
+ 
+-      writeb(gpio_int_debounce[port],
+-             epg->base + int_debounce_register_offset[port]);
++      writeb(eic->int_debounce,
++             epg->base + eic->irq_offset + EP93XX_INT_DEBOUNCE_OFFSET);
+ }
+ 
+ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
+@@ -122,12 +126,12 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc 
*desc)
+        */
+       stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
+       for_each_set_bit(offset, &stat, 8)
+-              generic_handle_irq(irq_find_mapping(epg->gc[0].irq.domain,
++              generic_handle_irq(irq_find_mapping(epg->gc[0].gc.irq.domain,
+                                                   offset));
+ 
+       stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
+       for_each_set_bit(offset, &stat, 8)
+-              generic_handle_irq(irq_find_mapping(epg->gc[1].irq.domain,
++              generic_handle_irq(irq_find_mapping(epg->gc[1].gc.irq.domain,
+                                                   offset));
+ 
+       chained_irq_exit(irqchip, desc);
+@@ -153,52 +157,52 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc 
*desc)
+ static void ep93xx_gpio_irq_ack(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
+       struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = ep93xx_gpio_port(gc);
+       int port_mask = BIT(d->irq & 7);
+ 
+       if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
+-              gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+-              ep93xx_gpio_update_int_params(epg, port);
++              eic->int_type2 ^= port_mask; /* switch edge direction */
++              ep93xx_gpio_update_int_params(epg, eic);
+       }
+ 
+-      writeb(port_mask, epg->base + eoi_register_offset[port]);
++      writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET);
+ }
+ 
+ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
+       struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = ep93xx_gpio_port(gc);
+       int port_mask = BIT(d->irq & 7);
+ 
+       if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
+-              gpio_int_type2[port] ^= port_mask; /* switch edge direction */
++              eic->int_type2 ^= port_mask; /* switch edge direction */
+ 
+-      gpio_int_unmasked[port] &= ~port_mask;
+-      ep93xx_gpio_update_int_params(epg, port);
++      eic->int_unmasked &= ~port_mask;
++      ep93xx_gpio_update_int_params(epg, eic);
+ 
+-      writeb(port_mask, epg->base + eoi_register_offset[port]);
++      writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET);
+ }
+ 
+ static void ep93xx_gpio_irq_mask(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
+       struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = ep93xx_gpio_port(gc);
+ 
+-      gpio_int_unmasked[port] &= ~BIT(d->irq & 7);
+-      ep93xx_gpio_update_int_params(epg, port);
++      eic->int_unmasked &= ~BIT(d->irq & 7);
++      ep93xx_gpio_update_int_params(epg, eic);
+ }
+ 
+ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
+       struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = ep93xx_gpio_port(gc);
+ 
+-      gpio_int_unmasked[port] |= BIT(d->irq & 7);
+-      ep93xx_gpio_update_int_params(epg, port);
++      eic->int_unmasked |= BIT(d->irq & 7);
++      ep93xx_gpio_update_int_params(epg, eic);
+ }
+ 
+ /*
+@@ -209,8 +213,8 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
+ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
+       struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+-      int port = ep93xx_gpio_port(gc);
+       int offset = d->irq & 7;
+       int port_mask = BIT(offset);
+       irq_flow_handler_t handler;
+@@ -219,32 +223,32 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, 
unsigned int type)
+ 
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+-              gpio_int_type1[port] |= port_mask;
+-              gpio_int_type2[port] |= port_mask;
++              eic->int_type1 |= port_mask;
++              eic->int_type2 |= port_mask;
+               handler = handle_edge_irq;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+-              gpio_int_type1[port] |= port_mask;
+-              gpio_int_type2[port] &= ~port_mask;
++              eic->int_type1 |= port_mask;
++              eic->int_type2 &= ~port_mask;
+               handler = handle_edge_irq;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+-              gpio_int_type1[port] &= ~port_mask;
+-              gpio_int_type2[port] |= port_mask;
++              eic->int_type1 &= ~port_mask;
++              eic->int_type2 |= port_mask;
+               handler = handle_level_irq;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+-              gpio_int_type1[port] &= ~port_mask;
+-              gpio_int_type2[port] &= ~port_mask;
++              eic->int_type1 &= ~port_mask;
++              eic->int_type2 &= ~port_mask;
+               handler = handle_level_irq;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+-              gpio_int_type1[port] |= port_mask;
++              eic->int_type1 |= port_mask;
+               /* set initial polarity based on current input level */
+               if (gc->get(gc, offset))
+-                      gpio_int_type2[port] &= ~port_mask; /* falling */
++                      eic->int_type2 &= ~port_mask; /* falling */
+               else
+-                      gpio_int_type2[port] |= port_mask; /* rising */
++                      eic->int_type2 |= port_mask; /* rising */
+               handler = handle_edge_irq;
+               break;
+       default:
+@@ -253,22 +257,13 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, 
unsigned int type)
+ 
+       irq_set_handler_locked(d, handler);
+ 
+-      gpio_int_enabled[port] |= port_mask;
++      eic->int_enabled |= port_mask;
+ 
+-      ep93xx_gpio_update_int_params(epg, port);
++      ep93xx_gpio_update_int_params(epg, eic);
+ 
+       return 0;
+ }
+ 
+-static struct irq_chip ep93xx_gpio_irq_chip = {
+-      .name           = "GPIO",
+-      .irq_ack        = ep93xx_gpio_irq_ack,
+-      .irq_mask_ack   = ep93xx_gpio_irq_mask_ack,
+-      .irq_mask       = ep93xx_gpio_irq_mask,
+-      .irq_unmask     = ep93xx_gpio_irq_unmask,
+-      .irq_set_type   = ep93xx_gpio_irq_type,
+-};
+-
+ /*************************************************************************
+  * gpiolib interface for EP93xx on-chip GPIOs
+  *************************************************************************/
+@@ -276,17 +271,19 @@ struct ep93xx_gpio_bank {
+       const char      *label;
+       int             data;
+       int             dir;
++      int             irq;
+       int             base;
+       bool            has_irq;
+       bool            has_hierarchical_irq;
+       unsigned int    irq_base;
+ };
+ 
+-#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq, _has_hier, 
_irq_base) \
++#define EP93XX_GPIO_BANK(_label, _data, _dir, _irq, _base, _has_irq, 
_has_hier, _irq_base) \
+       {                                                       \
+               .label          = _label,                       \
+               .data           = _data,                        \
+               .dir            = _dir,                         \
++              .irq            = _irq,                         \
+               .base           = _base,                        \
+               .has_irq        = _has_irq,                     \
+               .has_hierarchical_irq = _has_hier,              \
+@@ -295,16 +292,16 @@ struct ep93xx_gpio_bank {
+ 
+ static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
+       /* Bank A has 8 IRQs */
+-      EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true, false, 64),
++      EP93XX_GPIO_BANK("A", 0x00, 0x10, 0x90, 0, true, false, 64),
+       /* Bank B has 8 IRQs */
+-      EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true, false, 72),
+-      EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false, false, 0),
+-      EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false, false, 0),
+-      EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false, false, 0),
++      EP93XX_GPIO_BANK("B", 0x04, 0x14, 0xac, 8, true, false, 72),
++      EP93XX_GPIO_BANK("C", 0x08, 0x18, 0x00, 40, false, false, 0),
++      EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 0x00, 24, false, false, 0),
++      EP93XX_GPIO_BANK("E", 0x20, 0x24, 0x00, 32, false, false, 0),
+       /* Bank F has 8 IRQs */
+-      EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, false, true, 0),
+-      EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false, false, 0),
+-      EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false, false, 0),
++      EP93XX_GPIO_BANK("F", 0x30, 0x34, 0x4c, 16, false, true, 0),
++      EP93XX_GPIO_BANK("G", 0x38, 0x3c, 0x00, 48, false, false, 0),
++      EP93XX_GPIO_BANK("H", 0x40, 0x44, 0x00, 56, false, false, 0),
+ };
+ 
+ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
+@@ -326,13 +323,23 @@ static int ep93xx_gpio_f_to_irq(struct gpio_chip *gc, 
unsigned offset)
+       return EP93XX_GPIO_F_IRQ_BASE + offset;
+ }
+ 
+-static int ep93xx_gpio_add_bank(struct gpio_chip *gc,
++static void ep93xx_init_irq_chip(struct device *dev, struct irq_chip *ic)
++{
++      ic->irq_ack = ep93xx_gpio_irq_ack;
++      ic->irq_mask_ack = ep93xx_gpio_irq_mask_ack;
++      ic->irq_mask = ep93xx_gpio_irq_mask;
++      ic->irq_unmask = ep93xx_gpio_irq_unmask;
++      ic->irq_set_type = ep93xx_gpio_irq_type;
++}
++
++static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc,
+                               struct platform_device *pdev,
+                               struct ep93xx_gpio *epg,
+                               struct ep93xx_gpio_bank *bank)
+ {
+       void __iomem *data = epg->base + bank->data;
+       void __iomem *dir = epg->base + bank->dir;
++      struct gpio_chip *gc = &egc->gc;
+       struct device *dev = &pdev->dev;
+       struct gpio_irq_chip *girq;
+       int err;
+@@ -346,8 +353,21 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc,
+ 
+       girq = &gc->irq;
+       if (bank->has_irq || bank->has_hierarchical_irq) {
++              struct irq_chip *ic;
++
+               gc->set_config = ep93xx_gpio_set_config;
+-              girq->chip = &ep93xx_gpio_irq_chip;
++              egc->eic = devm_kcalloc(dev, 1,
++                                      sizeof(*egc->eic),
++                                      GFP_KERNEL);
++              if (!egc->eic)
++                      return -ENOMEM;
++              egc->eic->irq_offset = bank->irq;
++              ic = &egc->eic->ic;
++              ic->name = devm_kasprintf(dev, GFP_KERNEL, "gpio-irq-%s", 
bank->label);
++              if (!ic->name)
++                      return -ENOMEM;
++              ep93xx_init_irq_chip(dev, ic);
++              girq->chip = ic;
+       }
+ 
+       if (bank->has_irq) {
+@@ -389,7 +409,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc,
+                       gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i;
+                       irq_set_chip_data(gpio_irq, &epg->gc[5]);
+                       irq_set_chip_and_handler(gpio_irq,
+-                                               &ep93xx_gpio_irq_chip,
++                                               girq->chip,
+                                                handle_level_irq);
+                       irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+               }
+@@ -415,7 +435,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
+               return PTR_ERR(epg->base);
+ 
+       for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
+-              struct gpio_chip *gc = &epg->gc[i];
++              struct ep93xx_gpio_chip *gc = &epg->gc[i];
+               struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
+ 
+               if (ep93xx_gpio_add_bank(gc, pdev, epg, bank))
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index de06ee7d2ad46..fbbe611d4873f 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1093,8 +1093,8 @@ static void emulated_link_detect(struct dc_link *link)
+       link->type = dc_connection_none;
+       prev_sink = link->local_sink;
+ 
+-      if (prev_sink != NULL)
+-              dc_sink_retain(prev_sink);
++      if (prev_sink)
++              dc_sink_release(prev_sink);
+ 
+       switch (link->connector_signal) {
+       case SIGNAL_TYPE_HDMI_TYPE_A: {
+@@ -1417,8 +1417,10 @@ amdgpu_dm_update_connector_after_detect(struct 
amdgpu_dm_connector *aconnector)
+                * TODO: check if we still need the S3 mode update workaround.
+                * If yes, put it here.
+                */
+-              if (aconnector->dc_sink)
++              if (aconnector->dc_sink) {
+                       amdgpu_dm_update_freesync_caps(connector, NULL);
++                      dc_sink_release(aconnector->dc_sink);
++              }
+ 
+               aconnector->dc_sink = sink;
+               dc_sink_retain(aconnector->dc_sink);
+@@ -6463,14 +6465,14 @@ static int dm_force_atomic_commit(struct drm_connector 
*connector)
+ 
+       ret = PTR_ERR_OR_ZERO(conn_state);
+       if (ret)
+-              goto err;
++              goto out;
+ 
+       /* Attach crtc to drm_atomic_state*/
+       crtc_state = drm_atomic_get_crtc_state(state, 
&disconnected_acrtc->base);
+ 
+       ret = PTR_ERR_OR_ZERO(crtc_state);
+       if (ret)
+-              goto err;
++              goto out;
+ 
+       /* force a restore */
+       crtc_state->mode_changed = true;
+@@ -6480,17 +6482,15 @@ static int dm_force_atomic_commit(struct drm_connector 
*connector)
+ 
+       ret = PTR_ERR_OR_ZERO(plane_state);
+       if (ret)
+-              goto err;
+-
++              goto out;
+ 
+       /* Call commit internally with the state we just constructed */
+       ret = drm_atomic_commit(state);
+-      if (!ret)
+-              return 0;
+ 
+-err:
+-      DRM_ERROR("Restoring old state failed with %i\n", ret);
++out:
+       drm_atomic_state_put(state);
++      if (ret)
++              DRM_ERROR("Restoring old state failed with %i\n", ret);
+ 
+       return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+index a6d5beada6634..f63cbbee7b337 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+@@ -826,6 +826,8 @@ enum dcn20_clk_src_array_id {
+       DCN20_CLK_SRC_PLL0,
+       DCN20_CLK_SRC_PLL1,
+       DCN20_CLK_SRC_PLL2,
++      DCN20_CLK_SRC_PLL3,
++      DCN20_CLK_SRC_PLL4,
+       DCN20_CLK_SRC_TOTAL_DCN21
+ };
+ 
+@@ -1498,6 +1500,14 @@ static bool construct(
+                       dcn21_clock_source_create(ctx, ctx->dc_bios,
+                               CLOCK_SOURCE_COMBO_PHY_PLL2,
+                               &clk_src_regs[2], false);
++      pool->base.clock_sources[DCN20_CLK_SRC_PLL3] =
++                      dcn21_clock_source_create(ctx, ctx->dc_bios,
++                              CLOCK_SOURCE_COMBO_PHY_PLL3,
++                              &clk_src_regs[3], false);
++      pool->base.clock_sources[DCN20_CLK_SRC_PLL4] =
++                      dcn21_clock_source_create(ctx, ctx->dc_bios,
++                              CLOCK_SOURCE_COMBO_PHY_PLL4,
++                              &clk_src_regs[4], false);
+ 
+       pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21;
+ 
+diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
+index ae7ae432aa4ab..6bf1425e8b0ca 100644
+--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
+@@ -665,6 +665,30 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
+                    SUN4I_TCON1_BASIC5_V_SYNC(vsync) |
+                    SUN4I_TCON1_BASIC5_H_SYNC(hsync));
+ 
++      /* Setup the polarity of multiple signals */
++      if (tcon->quirks->polarity_in_ch0) {
++              val = 0;
++
++              if (mode->flags & DRM_MODE_FLAG_PHSYNC)
++                      val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
++
++              if (mode->flags & DRM_MODE_FLAG_PVSYNC)
++                      val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
++
++              regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
++      } else {
++              /* according to vendor driver, this bit must be always set */
++              val = SUN4I_TCON1_IO_POL_UNKNOWN;
++
++              if (mode->flags & DRM_MODE_FLAG_PHSYNC)
++                      val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE;
++
++              if (mode->flags & DRM_MODE_FLAG_PVSYNC)
++                      val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE;
++
++              regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val);
++      }
++
+       /* Map output pins to channel 1 */
+       regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
+                          SUN4I_TCON_GCTL_IOMAP_MASK,
+@@ -1482,6 +1506,7 @@ static const struct sun4i_tcon_quirks 
sun8i_a83t_tv_quirks = {
+ 
+ static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = {
+       .has_channel_1          = true,
++      .polarity_in_ch0        = true,
+       .set_mux                = sun8i_r40_tcon_tv_set_mux,
+ };
+ 
+diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon.h
+index a62ec826ae71e..5bdbaf0847824 100644
+--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
+@@ -153,6 +153,11 @@
+ #define SUN4I_TCON1_BASIC5_V_SYNC(height)             (((height) - 1) & 0x3ff)
+ 
+ #define SUN4I_TCON1_IO_POL_REG                        0xf0
++/* there is no documentation about this bit */
++#define SUN4I_TCON1_IO_POL_UNKNOWN                    BIT(26)
++#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE             BIT(25)
++#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE             BIT(24)
++
+ #define SUN4I_TCON1_IO_TRI_REG                        0xf4
+ 
+ #define SUN4I_TCON_ECC_FIFO_REG                       0xf8
+@@ -224,6 +229,7 @@ struct sun4i_tcon_quirks {
+       bool    needs_de_be_mux; /* sun6i needs mux to select backend */
+       bool    needs_edp_reset; /* a80 edp reset needed for tcon0 access */
+       bool    supports_lvds;   /* Does the TCON support an LVDS output? */
++      bool    polarity_in_ch0; /* some tcon1 channels have polarity bits in 
tcon0 pol register */
+       u8      dclk_min_div;   /* minimum divider for TCON0 DCLK */
+ 
+       /* callback to handle tcon muxing options */
+diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c 
b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+index 12fe241956213..8f721be26477b 100644
+--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+@@ -49,11 +49,9 @@ sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
+ {
+       /*
+        * Controller support maximum of 594 MHz, which correlates to
+-       * 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than
+-       * 340 MHz scrambling has to be enabled. Because scrambling is
+-       * not yet implemented, just limit to 340 MHz for now.
++       * 4K@60Hz 4:4:4 or RGB.
+        */
+-      if (mode->clock > 340000)
++      if (mode->clock > 594000)
+               return MODE_CLOCK_HIGH;
+ 
+       return MODE_OK;
+diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c 
b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+index 43643ad317306..a4012ec13d4b3 100644
+--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
++++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+@@ -104,29 +104,21 @@ static const struct dw_hdmi_mpll_config 
sun50i_h6_mpll_cfg[] = {
+ 
+ static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
+       /* pixelclk    bpp8    bpp10   bpp12 */
+-      { 25175000,  { 0x0000, 0x0000, 0x0000 }, },
+       { 27000000,  { 0x0012, 0x0000, 0x0000 }, },
+-      { 59400000,  { 0x0008, 0x0008, 0x0008 }, },
+-      { 72000000,  { 0x0008, 0x0008, 0x001b }, },
+-      { 74250000,  { 0x0013, 0x0013, 0x0013 }, },
+-      { 90000000,  { 0x0008, 0x001a, 0x001b }, },
+-      { 118800000, { 0x001b, 0x001a, 0x001b }, },
+-      { 144000000, { 0x001b, 0x001a, 0x0034 }, },
+-      { 180000000, { 0x001b, 0x0033, 0x0034 }, },
+-      { 216000000, { 0x0036, 0x0033, 0x0034 }, },
+-      { 237600000, { 0x0036, 0x0033, 0x001b }, },
+-      { 288000000, { 0x0036, 0x001b, 0x001b }, },
+-      { 297000000, { 0x0019, 0x001b, 0x0019 }, },
+-      { 330000000, { 0x0036, 0x001b, 0x001b }, },
+-      { 594000000, { 0x003f, 0x001b, 0x001b }, },
++      { 74250000,  { 0x0013, 0x001a, 0x001b }, },
++      { 148500000, { 0x0019, 0x0033, 0x0034 }, },
++      { 297000000, { 0x0019, 0x001b, 0x001b }, },
++      { 594000000, { 0x0010, 0x001b, 0x001b }, },
+       { ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
+ };
+ 
+ static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
+       /*pixelclk   symbol   term   vlev*/
+-      { 74250000,  0x8009, 0x0004, 0x0232},
+-      { 148500000, 0x8029, 0x0004, 0x0273},
+-      { 594000000, 0x8039, 0x0004, 0x014a},
++      { 27000000,  0x8009, 0x0007, 0x02b0 },
++      { 74250000,  0x8009, 0x0006, 0x022d },
++      { 148500000, 0x8029, 0x0006, 0x0270 },
++      { 297000000, 0x8039, 0x0005, 0x01ab },
++      { 594000000, 0x8029, 0x0000, 0x008a },
+       { ~0UL,      0x0000, 0x0000, 0x0000}
+ };
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
+index 5e5f90810acaf..363f456ea7134 100644
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -205,7 +205,7 @@ static void vc4_plane_reset(struct drm_plane *plane)
+       __drm_atomic_helper_plane_reset(plane, &vc4_state->base);
+ }
+ 
+-static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
++static void vc4_dlist_counter_increment(struct vc4_plane_state *vc4_state)
+ {
+       if (vc4_state->dlist_count == vc4_state->dlist_size) {
+               u32 new_size = max(4u, vc4_state->dlist_count * 2);
+@@ -220,7 +220,15 @@ static void vc4_dlist_write(struct vc4_plane_state 
*vc4_state, u32 val)
+               vc4_state->dlist_size = new_size;
+       }
+ 
+-      vc4_state->dlist[vc4_state->dlist_count++] = val;
++      vc4_state->dlist_count++;
++}
++
++static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
++{
++      unsigned int idx = vc4_state->dlist_count;
++
++      vc4_dlist_counter_increment(vc4_state);
++      vc4_state->dlist[idx] = val;
+ }
+ 
+ /* Returns the scl0/scl1 field based on whether the dimensions need to
+@@ -871,8 +879,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
+                * be set when calling vc4_plane_allocate_lbm().
+                */
+               if (vc4_state->y_scaling[0] != VC4_SCALING_NONE ||
+-                  vc4_state->y_scaling[1] != VC4_SCALING_NONE)
+-                      vc4_state->lbm_offset = vc4_state->dlist_count++;
++                  vc4_state->y_scaling[1] != VC4_SCALING_NONE) {
++                      vc4_state->lbm_offset = vc4_state->dlist_count;
++                      vc4_dlist_counter_increment(vc4_state);
++              }
+ 
+               if (num_planes > 1) {
+                       /* Emit Cb/Cr as channel 0 and Y as channel
+diff --git a/drivers/i2c/busses/i2c-stm32f7.c 
b/drivers/i2c/busses/i2c-stm32f7.c
+index b2634afe066d3..a7977eef2ead5 100644
+--- a/drivers/i2c/busses/i2c-stm32f7.c
++++ b/drivers/i2c/busses/i2c-stm32f7.c
+@@ -53,6 +53,8 @@
+ #define STM32F7_I2C_CR1_RXDMAEN                       BIT(15)
+ #define STM32F7_I2C_CR1_TXDMAEN                       BIT(14)
+ #define STM32F7_I2C_CR1_ANFOFF                        BIT(12)
++#define STM32F7_I2C_CR1_DNF_MASK              GENMASK(11, 8)
++#define STM32F7_I2C_CR1_DNF(n)                        (((n) & 0xf) << 8)
+ #define STM32F7_I2C_CR1_ERRIE                 BIT(7)
+ #define STM32F7_I2C_CR1_TCIE                  BIT(6)
+ #define STM32F7_I2C_CR1_STOPIE                        BIT(5)
+@@ -151,7 +153,7 @@
+ #define STM32F7_I2C_MAX_SLAVE                 0x2
+ 
+ #define STM32F7_I2C_DNF_DEFAULT                       0
+-#define STM32F7_I2C_DNF_MAX                   16
++#define STM32F7_I2C_DNF_MAX                   15
+ 
+ #define STM32F7_I2C_ANALOG_FILTER_ENABLE      1
+ #define STM32F7_I2C_ANALOG_FILTER_DELAY_MIN   50      /* ns */
+@@ -657,6 +659,13 @@ static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev 
*i2c_dev)
+       else
+               stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
+                                    STM32F7_I2C_CR1_ANFOFF);
++
++      /* Program the Digital Filter */
++      stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
++                           STM32F7_I2C_CR1_DNF_MASK);
++      stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
++                           STM32F7_I2C_CR1_DNF(i2c_dev->setup.dnf));
++
+       stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
+                            STM32F7_I2C_CR1_PE);
+ }
+diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile
+index c70b3822013f4..30c8ac24635d4 100644
+--- a/drivers/misc/lkdtm/Makefile
++++ b/drivers/misc/lkdtm/Makefile
+@@ -16,7 +16,7 @@ KCOV_INSTRUMENT_rodata.o     := n
+ 
+ OBJCOPYFLAGS :=
+ OBJCOPYFLAGS_rodata_objcopy.o := \
+-                      --rename-section .text=.rodata,alloc,readonly,load
++                      --rename-section 
.noinstr.text=.rodata,alloc,readonly,load
+ targets += rodata.o rodata_objcopy.o
+ $(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE
+       $(call if_changed,objcopy)
+diff --git a/drivers/misc/lkdtm/rodata.c b/drivers/misc/lkdtm/rodata.c
+index 58d180af72cf0..baacb876d1d94 100644
+--- a/drivers/misc/lkdtm/rodata.c
++++ b/drivers/misc/lkdtm/rodata.c
+@@ -5,7 +5,7 @@
+  */
+ #include "lkdtm.h"
+ 
+-void notrace lkdtm_rodata_do_nothing(void)
++void noinstr lkdtm_rodata_do_nothing(void)
+ {
+       /* Does nothing. We just want an architecture agnostic "return". */
+ }
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h 
b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+index 7428f62408a20..fac80831d5327 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+@@ -181,6 +181,8 @@ enum enetc_bdr_type {TX, RX};
+ #define ENETC_PTCCBSR0(n)     (0x1110 + (n) * 8) /* n = 0 to 7*/
+ #define ENETC_PTCCBSR1(n)     (0x1114 + (n) * 8) /* n = 0 to 7*/
+ #define ENETC_RSSHASH_KEY_SIZE        40
++#define ENETC_PRSSCAPR                0x1404
++#define ENETC_PRSSCAPR_GET_NUM_RSS(val)       (BIT((val) & 0xf) * 32)
+ #define ENETC_PRSSK(n)                (0x1410 + (n) * 4) /* n = [0..9] */
+ #define ENETC_PSIVLANFMR      0x1700
+ #define ENETC_PSIVLANFMR_VS   BIT(0)
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c 
b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+index 74847aa644f12..22f70638a4055 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+@@ -809,6 +809,51 @@ static void enetc_of_put_phy(struct enetc_ndev_priv *priv)
+               of_node_put(priv->phy_node);
+ }
+ 
++/* Initialize the entire shared memory for the flow steering entries
++ * of this port (PF + VFs)
++ */
++static int enetc_init_port_rfs_memory(struct enetc_si *si)
++{
++      struct enetc_cmd_rfse rfse = {0};
++      struct enetc_hw *hw = &si->hw;
++      int num_rfs, i, err = 0;
++      u32 val;
++
++      val = enetc_port_rd(hw, ENETC_PRFSCAPR);
++      num_rfs = ENETC_PRFSCAPR_GET_NUM_RFS(val);
++
++      for (i = 0; i < num_rfs; i++) {
++              err = enetc_set_fs_entry(si, &rfse, i);
++              if (err)
++                      break;
++      }
++
++      return err;
++}
++
++static int enetc_init_port_rss_memory(struct enetc_si *si)
++{
++      struct enetc_hw *hw = &si->hw;
++      int num_rss, err;
++      int *rss_table;
++      u32 val;
++
++      val = enetc_port_rd(hw, ENETC_PRSSCAPR);
++      num_rss = ENETC_PRSSCAPR_GET_NUM_RSS(val);
++      if (!num_rss)
++              return 0;
++
++      rss_table = kcalloc(num_rss, sizeof(*rss_table), GFP_KERNEL);
++      if (!rss_table)
++              return -ENOMEM;
++
++      err = enetc_set_rss_table(si, rss_table, num_rss);
++
++      kfree(rss_table);
++
++      return err;
++}
++
+ static int enetc_pf_probe(struct pci_dev *pdev,
+                         const struct pci_device_id *ent)
+ {
+@@ -863,6 +908,18 @@ static int enetc_pf_probe(struct pci_dev *pdev,
+               goto err_alloc_si_res;
+       }
+ 
++      err = enetc_init_port_rfs_memory(si);
++      if (err) {
++              dev_err(&pdev->dev, "Failed to initialize RFS memory\n");
++              goto err_init_port_rfs;
++      }
++
++      err = enetc_init_port_rss_memory(si);
++      if (err) {
++              dev_err(&pdev->dev, "Failed to initialize RSS memory\n");
++              goto err_init_port_rss;
++      }
++
+       err = enetc_alloc_msix(priv);
+       if (err) {
+               dev_err(&pdev->dev, "MSIX alloc failed\n");
+@@ -888,6 +945,8 @@ err_reg_netdev:
+       enetc_mdio_remove(pf);
+       enetc_of_put_phy(priv);
+       enetc_free_msix(priv);
++err_init_port_rss:
++err_init_port_rfs:
+ err_alloc_msix:
+       enetc_free_si_resources(priv);
+ err_alloc_si_res:
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 6887b7fda6e07..08040cafc06bc 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -8563,12 +8563,19 @@ int hclge_reset_tqp(struct hnae3_handle *handle, u16 
queue_id)
+ 
+ void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id)
+ {
++      struct hnae3_handle *handle = &vport->nic;
+       struct hclge_dev *hdev = vport->back;
+       int reset_try_times = 0;
+       int reset_status;
+       u16 queue_gid;
+       int ret;
+ 
++      if (queue_id >= handle->kinfo.num_tqps) {
++              dev_warn(&hdev->pdev->dev, "Invalid vf queue id(%u)\n",
++                       queue_id);
++              return;
++      }
++
+       queue_gid = hclge_covert_handle_qid_global(&vport->nic, queue_id);
+ 
+       ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, true);
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
+index c3079f436f6d7..0f35eec967ae8 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -4595,7 +4595,22 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
+                               complete(&adapter->init_done);
+                               adapter->init_done_rc = -EIO;
+                       }
+-                      ibmvnic_reset(adapter, VNIC_RESET_FAILOVER);
++                      rc = ibmvnic_reset(adapter, VNIC_RESET_FAILOVER);
++                      if (rc && rc != -EBUSY) {
++                              /* We were unable to schedule the failover
++                               * reset either because the adapter was still
++                               * probing (eg: during kexec) or we could not
++                               * allocate memory. Clear the failover_pending
++                               * flag since no one else will. We ignore
++                               * EBUSY because it means either FAILOVER reset
++                               * is already scheduled or the adapter is
++                               * being removed.
++                               */
++                              netdev_err(netdev,
++                                         "Error %ld scheduling failover 
reset\n",
++                                         rc);
++                              adapter->failover_pending = false;
++                      }
+                       break;
+               case IBMVNIC_CRQ_INIT_COMPLETE:
+                       dev_info(dev, "Partner initialization complete\n");
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+index 1d135b02ea021..52b453b605979 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+@@ -332,7 +332,12 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
+ 
+               priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
+       } else if (!qopt->enable) {
+-              return stmmac_dma_qmode(priv, priv->ioaddr, queue, 
MTL_QUEUE_DCB);
++              ret = stmmac_dma_qmode(priv, priv->ioaddr, queue,
++                                     MTL_QUEUE_DCB);
++              if (ret)
++                      return ret;
++
++              priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
+       }
+ 
+       /* Port Transmit Rate and Speed Divider */
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
+index 026d996612fbe..781952b686ed2 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -452,15 +452,17 @@ static void
+ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+                 int len, bool more)
+ {
+-      struct page *page = virt_to_head_page(data);
+-      int offset = data - page_address(page);
+       struct sk_buff *skb = q->rx_head;
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 
+       if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) {
+-              offset += q->buf_offset;
++              struct page *page = virt_to_head_page(data);
++              int offset = data - page_address(page) + q->buf_offset;
++
+               skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len,
+                               q->buf_size);
++      } else {
++              skb_free_frag(data);
+       }
+ 
+       if (more)
+diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
+index 9b62f65b630e4..48e2006f96ce6 100644
+--- a/drivers/net/xen-netback/rx.c
++++ b/drivers/net/xen-netback/rx.c
+@@ -38,10 +38,15 @@ static bool xenvif_rx_ring_slots_available(struct 
xenvif_queue *queue)
+       RING_IDX prod, cons;
+       struct sk_buff *skb;
+       int needed;
++      unsigned long flags;
++
++      spin_lock_irqsave(&queue->rx_queue.lock, flags);
+ 
+       skb = skb_peek(&queue->rx_queue);
+-      if (!skb)
++      if (!skb) {
++              spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
+               return false;
++      }
+ 
+       needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE);
+       if (skb_is_gso(skb))
+@@ -49,6 +54,8 @@ static bool xenvif_rx_ring_slots_available(struct 
xenvif_queue *queue)
+       if (skb->sw_hash)
+               needed++;
+ 
++      spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
++
+       do {
+               prod = queue->rx.sring->req_prod;
+               cons = queue->rx.req_cons;
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 434d3f21f0e13..19e375b59f407 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -3147,6 +3147,8 @@ static const struct pci_device_id nvme_id_table[] = {
+       { PCI_DEVICE(0x144d, 0xa822),   /* Samsung PM1725a */
+               .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY |
+                               NVME_QUIRK_IGNORE_DEV_SUBNQN, },
++      { PCI_DEVICE(0x1987, 0x5016),   /* Phison E16 */
++              .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+       { PCI_DEVICE(0x1d1d, 0x1f1f),   /* LighNVM qemu device */
+               .driver_data = NVME_QUIRK_LIGHTNVM, },
+       { PCI_DEVICE(0x1d1d, 0x2807),   /* CNEX WL */
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index a44a2ec332872..63a530a3d9feb 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -32,6 +32,10 @@ MODULE_LICENSE("GPL");
+ MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
+ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
+ 
++static int enable_tablet_mode_sw = -1;
++module_param(enable_tablet_mode_sw, int, 0444);
++MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting 
(-1=auto, 0=no, 1=yes)");
++
+ #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
+ #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
+ 
+@@ -654,10 +658,12 @@ static int __init hp_wmi_input_setup(void)
+       }
+ 
+       /* Tablet mode */
+-      val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
+-      if (!(val < 0)) {
+-              __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
+-              input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
++      if (enable_tablet_mode_sw > 0) {
++              val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
++              if (val >= 0) {
++                      __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
++                      input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 
val);
++              }
+       }
+ 
+       err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
+diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c
+index bb8271531da70..ffe3440abb74c 100644
+--- a/drivers/usb/dwc3/ulpi.c
++++ b/drivers/usb/dwc3/ulpi.c
+@@ -7,6 +7,8 @@
+  * Author: Heikki Krogerus <[email protected]>
+  */
+ 
++#include <linux/delay.h>
++#include <linux/time64.h>
+ #include <linux/ulpi/regs.h>
+ 
+ #include "core.h"
+@@ -17,12 +19,22 @@
+               DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \
+               DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a))
+ 
+-static int dwc3_ulpi_busyloop(struct dwc3 *dwc)
++#define DWC3_ULPI_BASE_DELAY  DIV_ROUND_UP(NSEC_PER_SEC, 60000000L)
++
++static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read)
+ {
+-      unsigned count = 1000;
++      unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY;
++      unsigned int count = 1000;
+       u32 reg;
+ 
++      if (addr >= ULPI_EXT_VENDOR_SPECIFIC)
++              ns += DWC3_ULPI_BASE_DELAY;
++
++      if (read)
++              ns += DWC3_ULPI_BASE_DELAY;
++
+       while (count--) {
++              ndelay(ns);
+               reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+               if (reg & DWC3_GUSB2PHYACC_DONE)
+                       return 0;
+@@ -47,7 +59,7 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr)
+       reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
+       dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+ 
+-      ret = dwc3_ulpi_busyloop(dwc);
++      ret = dwc3_ulpi_busyloop(dwc, addr, true);
+       if (ret)
+               return ret;
+ 
+@@ -71,7 +83,7 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 
val)
+       reg |= DWC3_GUSB2PHYACC_WRITE | val;
+       dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+ 
+-      return dwc3_ulpi_busyloop(dwc);
++      return dwc3_ulpi_busyloop(dwc, addr, false);
+ }
+ 
+ static const struct ulpi_ops dwc3_ulpi_ops = {
+diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h
+index a9bb5f91082d3..88516a8a9f932 100644
+--- a/drivers/xen/xenbus/xenbus.h
++++ b/drivers/xen/xenbus/xenbus.h
+@@ -115,7 +115,6 @@ int xenbus_probe_node(struct xen_bus_type *bus,
+                     const char *type,
+                     const char *nodename);
+ int xenbus_probe_devices(struct xen_bus_type *bus);
+-void xenbus_probe(void);
+ 
+ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus);
+ 
+diff --git a/drivers/xen/xenbus/xenbus_probe.c 
b/drivers/xen/xenbus/xenbus_probe.c
+index 786494bb7f20b..652894d619677 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -683,7 +683,7 @@ void unregister_xenstore_notifier(struct notifier_block 
*nb)
+ }
+ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
+ 
+-void xenbus_probe(void)
++static void xenbus_probe(void)
+ {
+       xenstored_ready = 1;
+ 
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index ec5eca5a96f41..7b758d623b5bd 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -76,6 +76,14 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
+ 
+               if (ovl_is_private_xattr(name))
+                       continue;
++
++              error = security_inode_copy_up_xattr(name);
++              if (error < 0 && error != -EOPNOTSUPP)
++                      break;
++              if (error == 1) {
++                      error = 0;
++                      continue; /* Discard */
++              }
+ retry:
+               size = vfs_getxattr(old, name, value, value_size);
+               if (size == -ERANGE)
+@@ -99,13 +107,6 @@ retry:
+                       goto retry;
+               }
+ 
+-              error = security_inode_copy_up_xattr(name);
+-              if (error < 0 && error != -EOPNOTSUPP)
+-                      break;
+-              if (error == 1) {
+-                      error = 0;
+-                      continue; /* Discard */
+-              }
+               error = vfs_setxattr(new, name, value, size, 0);
+               if (error)
+                       break;
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index bb980721502dd..56b55397a7a00 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -337,7 +337,9 @@ int ovl_xattr_set(struct dentry *dentry, struct inode 
*inode, const char *name,
+               goto out;
+ 
+       if (!value && !upperdentry) {
++              old_cred = ovl_override_creds(dentry->d_sb);
+               err = vfs_getxattr(realdentry, name, NULL, 0);
++              revert_creds(old_cred);
+               if (err < 0)
+                       goto out_drop_write;
+       }
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index d6b724beb304c..87cf9b1d2eca3 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -79,7 +79,7 @@ static void ovl_dentry_release(struct dentry *dentry)
+ static struct dentry *ovl_d_real(struct dentry *dentry,
+                                const struct inode *inode)
+ {
+-      struct dentry *real;
++      struct dentry *real = NULL, *lower;
+ 
+       /* It's an overlay file */
+       if (inode && d_inode(dentry) == inode)
+@@ -98,9 +98,10 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
+       if (real && !inode && ovl_has_upperdata(d_inode(dentry)))
+               return real;
+ 
+-      real = ovl_dentry_lowerdata(dentry);
+-      if (!real)
++      lower = ovl_dentry_lowerdata(dentry);
++      if (!lower)
+               goto bug;
++      real = lower;
+ 
+       /* Handle recursion */
+       real = d_real(real, inode);
+@@ -108,8 +109,10 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
+       if (!inode || inode == d_inode(real))
+               return real;
+ bug:
+-      WARN(1, "ovl_d_real(%pd4, %s:%lu): real dentry not found\n", dentry,
+-           inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
++      WARN(1, "%s(%pd4, %s:%lu): real dentry (%p/%lu) not found\n",
++           __func__, dentry, inode ? inode->i_sb->s_id : "NULL",
++           inode ? inode->i_ino : 0, real,
++           real && d_inode(real) ? d_inode(real)->i_ino : 0);
+       return dentry;
+ }
+ 
+diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
+index d1779d442aa51..66397ed10acb7 100644
+--- a/include/asm-generic/sections.h
++++ b/include/asm-generic/sections.h
+@@ -53,6 +53,9 @@ extern char __ctors_start[], __ctors_end[];
+ /* Start and end of .opd section - used for function descriptors. */
+ extern char __start_opd[], __end_opd[];
+ 
++/* Start and end of instrumentation protected text section */
++extern char __noinstr_text_start[], __noinstr_text_end[];
++
+ extern __visible const void __nosave_begin, __nosave_end;
+ 
+ /* Function descriptor handling (if any).  Override in asm/sections.h */
+diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
+index 130f16cc0b86d..2267b7c763c64 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -396,7 +396,7 @@
+       }                                                               \
+                                                                       \
+       /* Built-in firmware blobs */                                   \
+-      .builtin_fw        : AT(ADDR(.builtin_fw) - LOAD_OFFSET) {      \
++      .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) ALIGN(8) {    \
+               __start_builtin_fw = .;                                 \
+               KEEP(*(.builtin_fw))                                    \
+               __end_builtin_fw = .;                                   \
+@@ -510,6 +510,15 @@
+ #define RODATA          RO_DATA_SECTION(4096)
+ #define RO_DATA(align)  RO_DATA_SECTION(align)
+ 
++/*
++ * Non-instrumentable text section
++ */
++#define NOINSTR_TEXT                                                  \
++              ALIGN_FUNCTION();                                       \
++              __noinstr_text_start = .;                               \
++              *(.noinstr.text)                                        \
++              __noinstr_text_end = .;
++
+ /*
+  * .text section. Map to function alignment to avoid address changes
+  * during second ld run in second ld pass when generating System.map
+@@ -524,6 +533,7 @@
+               *(TEXT_MAIN .text.fixup)                                \
+               *(.text.unlikely .text.unlikely.*)                      \
+               *(.text.unknown .text.unknown.*)                        \
++              NOINSTR_TEXT                                            \
+               *(.text..refcount)                                      \
+               *(.ref.text)                                            \
+       MEM_KEEP(init.text*)                                            \
+diff --git a/include/linux/compiler.h b/include/linux/compiler.h
+index f164a9b12813f..9446e8fbe55c5 100644
+--- a/include/linux/compiler.h
++++ b/include/linux/compiler.h
+@@ -134,12 +134,65 @@ void ftrace_likely_update(struct ftrace_likely_data *f, 
int val,
+ /* Annotate a C jump table to allow objtool to follow the code flow */
+ #define __annotate_jump_table __section(.rodata..c_jump_table)
+ 
++#ifdef CONFIG_DEBUG_ENTRY
++/* Begin/end of an instrumentation safe region */
++#define instrumentation_begin() ({                                    \
++      asm volatile("%c0:\n\t"                                         \
++                   ".pushsection .discard.instr_begin\n\t"            \
++                   ".long %c0b - .\n\t"                               \
++                   ".popsection\n\t" : : "i" (__COUNTER__));          \
++})
++
++/*
++ * Because instrumentation_{begin,end}() can nest, objtool validation 
considers
++ * _begin() a +1 and _end() a -1 and computes a sum over the instructions.
++ * When the value is greater than 0, we consider instrumentation allowed.
++ *
++ * There is a problem with code like:
++ *
++ * noinstr void foo()
++ * {
++ *    instrumentation_begin();
++ *    ...
++ *    if (cond) {
++ *            instrumentation_begin();
++ *            ...
++ *            instrumentation_end();
++ *    }
++ *    bar();
++ *    instrumentation_end();
++ * }
++ *
++ * If instrumentation_end() would be an empty label, like all the other
++ * annotations, the inner _end(), which is at the end of a conditional block,
++ * would land on the instruction after the block.
++ *
++ * If we then consider the sum of the !cond path, we'll see that the call to
++ * bar() is with a 0-value, even though, we meant it to happen with a positive
++ * value.
++ *
++ * To avoid this, have _end() be a NOP instruction, this ensures it will be
++ * part of the condition block and does not escape.
++ */
++#define instrumentation_end() ({                                      \
++      asm volatile("%c0: nop\n\t"                                     \
++                   ".pushsection .discard.instr_end\n\t"              \
++                   ".long %c0b - .\n\t"                               \
++                   ".popsection\n\t" : : "i" (__COUNTER__));          \
++})
++#endif /* CONFIG_DEBUG_ENTRY */
++
+ #else
+ #define annotate_reachable()
+ #define annotate_unreachable()
+ #define __annotate_jump_table
+ #endif
+ 
++#ifndef instrumentation_begin
++#define instrumentation_begin()               do { } while(0)
++#define instrumentation_end()         do { } while(0)
++#endif
++
+ #ifndef ASM_UNREACHABLE
+ # define ASM_UNREACHABLE
+ #endif
+diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
+index 77433633572e4..b94d08d055ff5 100644
+--- a/include/linux/compiler_types.h
++++ b/include/linux/compiler_types.h
+@@ -118,6 +118,10 @@ struct ftrace_likely_data {
+ #define notrace                       
__attribute__((__no_instrument_function__))
+ #endif
+ 
++/* Section for code which can't be instrumented at all */
++#define noinstr                                                               
\
++      noinline notrace __attribute((__section__(".noinstr.text")))
++
+ /*
+  * it doesn't make sense on ARM (currently the only user of __naked)
+  * to trace naked functions because then mcount is called without
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index ec3081ab04c01..3e0692fd6282c 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -4044,6 +4044,7 @@ static inline void netif_tx_disable(struct net_device 
*dev)
+ 
+       local_bh_disable();
+       cpu = smp_processor_id();
++      spin_lock(&dev->tx_global_lock);
+       for (i = 0; i < dev->num_tx_queues; i++) {
+               struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
+ 
+@@ -4051,6 +4052,7 @@ static inline void netif_tx_disable(struct net_device 
*dev)
+               netif_tx_stop_queue(txq);
+               __netif_tx_unlock(txq);
+       }
++      spin_unlock(&dev->tx_global_lock);
+       local_bh_enable();
+ }
+ 
+diff --git a/include/linux/uio.h b/include/linux/uio.h
+index ab5f523bc0df9..b74d292b9960e 100644
+--- a/include/linux/uio.h
++++ b/include/linux/uio.h
+@@ -261,7 +261,13 @@ static inline void iov_iter_reexpand(struct iov_iter *i, 
size_t count)
+ {
+       i->count = count;
+ }
+-size_t csum_and_copy_to_iter(const void *addr, size_t bytes, void *csump, 
struct iov_iter *i);
++
++struct csum_state {
++      __wsum csum;
++      size_t off;
++};
++
++size_t csum_and_copy_to_iter(const void *addr, size_t bytes, void *csstate, 
struct iov_iter *i);
+ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct 
iov_iter *i);
+ bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, 
struct iov_iter *i);
+ size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp,
+diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
+index fe9a9fa2ebc45..14d47ed4114fd 100644
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -187,8 +187,6 @@ void xs_suspend_cancel(void);
+ 
+ struct work_struct;
+ 
+-void xenbus_probe(void);
+-
+ #define XENBUS_IS_ERR_READ(str) ({                    \
+       if (!IS_ERR(str) && strlen(str) == 0) {         \
+               kfree(str);                             \
+diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
+index 173e983619d77..fba2ade28fb3a 100644
+--- a/kernel/bpf/stackmap.c
++++ b/kernel/bpf/stackmap.c
+@@ -112,6 +112,8 @@ static struct bpf_map *stack_map_alloc(union bpf_attr 
*attr)
+ 
+       /* hash table size must be power of 2 */
+       n_buckets = roundup_pow_of_two(attr->max_entries);
++      if (!n_buckets)
++              return ERR_PTR(-E2BIG);
+ 
+       cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap);
+       cost += n_buckets * (value_size + sizeof(struct stack_map_bucket));
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index 35faf082a709c..37db8eba149ac 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -3627,6 +3627,7 @@ static ssize_t cgroup_pressure_write(struct 
kernfs_open_file *of, char *buf,
+ {
+       struct psi_trigger *new;
+       struct cgroup *cgrp;
++      struct psi_group *psi;
+ 
+       cgrp = cgroup_kn_lock_live(of->kn, false);
+       if (!cgrp)
+@@ -3635,7 +3636,8 @@ static ssize_t cgroup_pressure_write(struct 
kernfs_open_file *of, char *buf,
+       cgroup_get(cgrp);
+       cgroup_kn_unlock(of->kn);
+ 
+-      new = psi_trigger_create(&cgrp->psi, buf, nbytes, res);
++      psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
++      new = psi_trigger_create(psi, buf, nbytes, res);
+       if (IS_ERR(new)) {
+               cgroup_put(cgrp);
+               return PTR_ERR(new);
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 67af28f03cf41..1a75610f5f57b 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -2498,7 +2498,7 @@ trace_event_buffer_lock_reserve(struct ring_buffer 
**current_rb,
+           (entry = this_cpu_read(trace_buffered_event))) {
+               /* Try to use the per cpu buffer first */
+               val = this_cpu_inc_return(trace_buffered_event_cnt);
+-              if (val == 1) {
++              if ((len < (PAGE_SIZE - sizeof(*entry))) && val == 1) {
+                       trace_event_setup(entry, type, flags, pc);
+                       entry->array[0] = len;
+                       return entry;
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index 309b2b3c5349e..e31ee325dad16 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -1107,7 +1107,8 @@ system_enable_read(struct file *filp, char __user *ubuf, 
size_t cnt,
+       mutex_lock(&event_mutex);
+       list_for_each_entry(file, &tr->events, list) {
+               call = file->event_call;
+-              if (!trace_event_name(call) || !call->class || 
!call->class->reg)
++              if ((call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) ||
++                  !trace_event_name(call) || !call->class || 
!call->class->reg)
+                       continue;
+ 
+               if (system && strcmp(call->class->system, system->name) != 0)
+diff --git a/lib/iov_iter.c b/lib/iov_iter.c
+index 639d5e7014c1e..9ea6f7bb83095 100644
+--- a/lib/iov_iter.c
++++ b/lib/iov_iter.c
+@@ -570,12 +570,13 @@ static __wsum csum_and_memcpy(void *to, const void 
*from, size_t len,
+ }
+ 
+ static size_t csum_and_copy_to_pipe_iter(const void *addr, size_t bytes,
+-                              __wsum *csum, struct iov_iter *i)
++                                       struct csum_state *csstate,
++                                       struct iov_iter *i)
+ {
+       struct pipe_inode_info *pipe = i->pipe;
++      __wsum sum = csstate->csum;
++      size_t off = csstate->off;
+       size_t n, r;
+-      size_t off = 0;
+-      __wsum sum = *csum;
+       int idx;
+ 
+       if (!sanity(i))
+@@ -596,7 +597,8 @@ static size_t csum_and_copy_to_pipe_iter(const void *addr, 
size_t bytes,
+               addr += chunk;
+       }
+       i->count -= bytes;
+-      *csum = sum;
++      csstate->csum = sum;
++      csstate->off = off;
+       return bytes;
+ }
+ 
+@@ -1484,18 +1486,19 @@ bool csum_and_copy_from_iter_full(void *addr, size_t 
bytes, __wsum *csum,
+ }
+ EXPORT_SYMBOL(csum_and_copy_from_iter_full);
+ 
+-size_t csum_and_copy_to_iter(const void *addr, size_t bytes, void *csump,
++size_t csum_and_copy_to_iter(const void *addr, size_t bytes, void *_csstate,
+                            struct iov_iter *i)
+ {
++      struct csum_state *csstate = _csstate;
+       const char *from = addr;
+-      __wsum *csum = csump;
+       __wsum sum, next;
+-      size_t off = 0;
++      size_t off;
+ 
+       if (unlikely(iov_iter_is_pipe(i)))
+-              return csum_and_copy_to_pipe_iter(addr, bytes, csum, i);
++              return csum_and_copy_to_pipe_iter(addr, bytes, _csstate, i);
+ 
+-      sum = *csum;
++      sum = csstate->csum;
++      off = csstate->off;
+       if (unlikely(iov_iter_is_discard(i))) {
+               WARN_ON(1);     /* for now */
+               return 0;
+@@ -1524,7 +1527,8 @@ size_t csum_and_copy_to_iter(const void *addr, size_t 
bytes, void *csump,
+               off += v.iov_len;
+       })
+       )
+-      *csum = sum;
++      csstate->csum = sum;
++      csstate->off = off;
+       return bytes;
+ }
+ EXPORT_SYMBOL(csum_and_copy_to_iter);
+diff --git a/net/core/datagram.c b/net/core/datagram.c
+index 189ad4c73a3fe..b0488f30f2c4e 100644
+--- a/net/core/datagram.c
++++ b/net/core/datagram.c
+@@ -700,8 +700,16 @@ static int skb_copy_and_csum_datagram(const struct 
sk_buff *skb, int offset,
+                                     struct iov_iter *to, int len,
+                                     __wsum *csump)
+ {
+-      return __skb_datagram_iter(skb, offset, to, len, true,
+-                      csum_and_copy_to_iter, csump);
++      struct csum_state csdata = { .csum = *csump };
++      int ret;
++
++      ret = __skb_datagram_iter(skb, offset, to, len, true,
++                                csum_and_copy_to_iter, &csdata);
++      if (ret)
++              return ret;
++
++      *csump = csdata.csum;
++      return 0;
+ }
+ 
+ /**
+diff --git a/net/core/dev.c b/net/core/dev.c
+index ec66d13d2bdad..d90e8bd87df83 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -5275,10 +5275,11 @@ static void gro_normal_list(struct napi_struct *napi)
+ /* Queue one GRO_NORMAL SKB up for list processing. If batch size exceeded,
+  * pass the whole batch up to the stack.
+  */
+-static void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb)
++static void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb, int 
segs)
+ {
+       list_add_tail(&skb->list, &napi->rx_list);
+-      if (++napi->rx_count >= gro_normal_batch)
++      napi->rx_count += segs;
++      if (napi->rx_count >= gro_normal_batch)
+               gro_normal_list(napi);
+ }
+ 
+@@ -5317,7 +5318,7 @@ static int napi_gro_complete(struct napi_struct *napi, 
struct sk_buff *skb)
+       }
+ 
+ out:
+-      gro_normal_one(napi, skb);
++      gro_normal_one(napi, skb, NAPI_GRO_CB(skb)->count);
+       return NET_RX_SUCCESS;
+ }
+ 
+@@ -5608,7 +5609,7 @@ static gro_result_t napi_skb_finish(struct napi_struct 
*napi,
+ {
+       switch (ret) {
+       case GRO_NORMAL:
+-              gro_normal_one(napi, skb);
++              gro_normal_one(napi, skb, 1);
+               break;
+ 
+       case GRO_DROP:
+@@ -5696,7 +5697,7 @@ static gro_result_t napi_frags_finish(struct napi_struct 
*napi,
+               __skb_push(skb, ETH_HLEN);
+               skb->protocol = eth_type_trans(skb, skb->dev);
+               if (ret == GRO_NORMAL)
+-                      gro_normal_one(napi, skb);
++                      gro_normal_one(napi, skb, 1);
+               break;
+ 
+       case GRO_DROP:
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index 0f7f38c295799..70e6fc2edd304 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -399,18 +399,21 @@ static int dsa_switch_setup(struct dsa_switch *ds)
+               ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
+               if (!ds->slave_mii_bus) {
+                       err = -ENOMEM;
+-                      goto unregister_notifier;
++                      goto teardown;
+               }
+ 
+               dsa_slave_mii_bus_init(ds);
+ 
+               err = mdiobus_register(ds->slave_mii_bus);
+               if (err < 0)
+-                      goto unregister_notifier;
++                      goto teardown;
+       }
+ 
+       return 0;
+ 
++teardown:
++      if (ds->ops->teardown)
++              ds->ops->teardown(ds);
+ unregister_notifier:
+       dsa_switch_unregister_notifier(ds);
+ unregister_devlink:
+diff --git a/net/netfilter/nf_conntrack_core.c 
b/net/netfilter/nf_conntrack_core.c
+index 200cdad3ff3ab..9a40312b1f161 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1091,7 +1091,8 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple 
*tuple,
+                        * Let nf_ct_resolve_clash() deal with this later.
+                        */
+                       if 
(nf_ct_tuple_equal(&ignored_conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+-                                            
&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple))
++                                            
&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple) &&
++                                            nf_ct_zone_equal(ct, zone, 
IP_CT_DIR_ORIGINAL))
+                               continue;
+ 
+                       NF_CT_STAT_INC_ATOMIC(net, found);
+diff --git a/net/netfilter/nf_flow_table_core.c 
b/net/netfilter/nf_flow_table_core.c
+index 128245efe84ab..e05e5df803d68 100644
+--- a/net/netfilter/nf_flow_table_core.c
++++ b/net/netfilter/nf_flow_table_core.c
+@@ -354,7 +354,7 @@ static int nf_flow_nat_port_tcp(struct sk_buff *skb, 
unsigned int thoff,
+               return -1;
+ 
+       tcph = (void *)(skb_network_header(skb) + thoff);
+-      inet_proto_csum_replace2(&tcph->check, skb, port, new_port, true);
++      inet_proto_csum_replace2(&tcph->check, skb, port, new_port, false);
+ 
+       return 0;
+ }
+@@ -371,7 +371,7 @@ static int nf_flow_nat_port_udp(struct sk_buff *skb, 
unsigned int thoff,
+       udph = (void *)(skb_network_header(skb) + thoff);
+       if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) {
+               inet_proto_csum_replace2(&udph->check, skb, port,
+-                                       new_port, true);
++                                       new_port, false);
+               if (!udph->check)
+                       udph->check = CSUM_MANGLED_0;
+       }
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 40216c2a7dd72..373ea0e49f12d 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -7696,6 +7696,17 @@ int __nft_release_basechain(struct nft_ctx *ctx)
+ }
+ EXPORT_SYMBOL_GPL(__nft_release_basechain);
+ 
++static void __nft_release_hooks(struct net *net)
++{
++      struct nft_table *table;
++      struct nft_chain *chain;
++
++      list_for_each_entry(table, &net->nft.tables, list) {
++              list_for_each_entry(chain, &table->chains, list)
++                      nf_tables_unregister_hook(net, table, chain);
++      }
++}
++
+ static void __nft_release_tables(struct net *net)
+ {
+       struct nft_flowtable *flowtable, *nf;
+@@ -7711,10 +7722,6 @@ static void __nft_release_tables(struct net *net)
+ 
+       list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
+               ctx.family = table->family;
+-
+-              list_for_each_entry(chain, &table->chains, list)
+-                      nf_tables_unregister_hook(net, table, chain);
+-              /* No packets are walking on these chains anymore. */
+               ctx.table = table;
+               list_for_each_entry(chain, &table->chains, list) {
+                       ctx.chain = chain;
+@@ -7762,6 +7769,11 @@ static int __net_init nf_tables_init_net(struct net 
*net)
+       return 0;
+ }
+ 
++static void __net_exit nf_tables_pre_exit_net(struct net *net)
++{
++      __nft_release_hooks(net);
++}
++
+ static void __net_exit nf_tables_exit_net(struct net *net)
+ {
+       mutex_lock(&net->nft.commit_mutex);
+@@ -7774,8 +7786,9 @@ static void __net_exit nf_tables_exit_net(struct net 
*net)
+ }
+ 
+ static struct pernet_operations nf_tables_net_ops = {
+-      .init   = nf_tables_init_net,
+-      .exit   = nf_tables_exit_net,
++      .init           = nf_tables_init_net,
++      .pre_exit       = nf_tables_pre_exit_net,
++      .exit           = nf_tables_exit_net,
+ };
+ 
+ static int __init nf_tables_module_init(void)
+diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
+index 6c2582a197667..3469b60736103 100644
+--- a/net/netfilter/xt_recent.c
++++ b/net/netfilter/xt_recent.c
+@@ -152,7 +152,8 @@ static void recent_entry_remove(struct recent_table *t, 
struct recent_entry *e)
+ /*
+  * Drop entries with timestamps older then 'time'.
+  */
+-static void recent_entry_reap(struct recent_table *t, unsigned long time)
++static void recent_entry_reap(struct recent_table *t, unsigned long time,
++                            struct recent_entry *working, bool update)
+ {
+       struct recent_entry *e;
+ 
+@@ -161,6 +162,12 @@ static void recent_entry_reap(struct recent_table *t, 
unsigned long time)
+        */
+       e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
+ 
++      /*
++       * Do not reap the entry which are going to be updated.
++       */
++      if (e == working && update)
++              return;
++
+       /*
+        * The last time stamp is the most recent.
+        */
+@@ -303,7 +310,8 @@ recent_mt(const struct sk_buff *skb, struct 
xt_action_param *par)
+ 
+               /* info->seconds must be non-zero */
+               if (info->check_set & XT_RECENT_REAP)
+-                      recent_entry_reap(t, time);
++                      recent_entry_reap(t, time, e,
++                              info->check_set & XT_RECENT_UPDATE && ret);
+       }
+ 
+       if (info->check_set & XT_RECENT_SET ||
+diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c
+index e35869e81766e..997af345ce374 100644
+--- a/net/qrtr/tun.c
++++ b/net/qrtr/tun.c
+@@ -80,6 +80,12 @@ static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, 
struct iov_iter *from)
+       ssize_t ret;
+       void *kbuf;
+ 
++      if (!len)
++              return -EINVAL;
++
++      if (len > KMALLOC_MAX_SIZE)
++              return -ENOMEM;
++
+       kbuf = kzalloc(len, GFP_KERNEL);
+       if (!kbuf)
+               return -ENOMEM;
+diff --git a/net/rds/rdma.c b/net/rds/rdma.c
+index 8e10f954a22fe..1c42a600fe7fa 100644
+--- a/net/rds/rdma.c
++++ b/net/rds/rdma.c
+@@ -532,6 +532,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args,
+       if (args->nr_local == 0)
+               return -EINVAL;
+ 
++      if (args->nr_local > UIO_MAXIOV)
++              return -EMSGSIZE;
++
+       iov->iov = kcalloc(args->nr_local,
+                          sizeof(struct rds_iovec),
+                          GFP_KERNEL);
+diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
+index 38a46167523fa..f8233bc76c0ea 100644
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -507,8 +507,6 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct 
rxrpc_call *call)
+               rxrpc_disconnect_call(call);
+       if (call->security)
+               call->security->free_call_crypto(call);
+-
+-      rxrpc_cleanup_ring(call);
+       _leave("");
+ }
+ 
+diff --git a/net/sctp/proc.c b/net/sctp/proc.c
+index f7da88ae20a57..982a87b3e11f8 100644
+--- a/net/sctp/proc.c
++++ b/net/sctp/proc.c
+@@ -215,6 +215,12 @@ static void sctp_transport_seq_stop(struct seq_file *seq, 
void *v)
+ {
+       struct sctp_ht_iter *iter = seq->private;
+ 
++      if (v && v != SEQ_START_TOKEN) {
++              struct sctp_transport *transport = v;
++
++              sctp_transport_put(transport);
++      }
++
+       sctp_transport_walk_stop(&iter->hti);
+ }
+ 
+@@ -222,6 +228,12 @@ static void *sctp_transport_seq_next(struct seq_file 
*seq, void *v, loff_t *pos)
+ {
+       struct sctp_ht_iter *iter = seq->private;
+ 
++      if (v && v != SEQ_START_TOKEN) {
++              struct sctp_transport *transport = v;
++
++              sctp_transport_put(transport);
++      }
++
+       ++*pos;
+ 
+       return sctp_transport_get_next(seq_file_net(seq), &iter->hti);
+@@ -277,8 +289,6 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void 
*v)
+               sk->sk_rcvbuf);
+       seq_printf(seq, "\n");
+ 
+-      sctp_transport_put(transport);
+-
+       return 0;
+ }
+ 
+@@ -354,8 +364,6 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, 
void *v)
+               seq_printf(seq, "\n");
+       }
+ 
+-      sctp_transport_put(transport);
+-
+       return 0;
+ }
+ 
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 3a074a03d3820..5d323574d04fe 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -808,10 +808,12 @@ static int vsock_shutdown(struct socket *sock, int mode)
+        */
+ 
+       sk = sock->sk;
++
++      lock_sock(sk);
+       if (sock->state == SS_UNCONNECTED) {
+               err = -ENOTCONN;
+               if (sk->sk_type == SOCK_STREAM)
+-                      return err;
++                      goto out;
+       } else {
+               sock->state = SS_DISCONNECTING;
+               err = 0;
+@@ -820,10 +822,8 @@ static int vsock_shutdown(struct socket *sock, int mode)
+       /* Receive and send shutdowns are treated alike. */
+       mode = mode & (RCV_SHUTDOWN | SEND_SHUTDOWN);
+       if (mode) {
+-              lock_sock(sk);
+               sk->sk_shutdown |= mode;
+               sk->sk_state_change(sk);
+-              release_sock(sk);
+ 
+               if (sk->sk_type == SOCK_STREAM) {
+                       sock_reset_flag(sk, SOCK_DONE);
+@@ -831,6 +831,8 @@ static int vsock_shutdown(struct socket *sock, int mode)
+               }
+       }
+ 
++out:
++      release_sock(sk);
+       return err;
+ }
+ 
+@@ -1099,7 +1101,6 @@ static void vsock_connect_timeout(struct work_struct 
*work)
+ {
+       struct sock *sk;
+       struct vsock_sock *vsk;
+-      int cancel = 0;
+ 
+       vsk = container_of(work, struct vsock_sock, connect_work.work);
+       sk = sk_vsock(vsk);
+@@ -1110,11 +1111,9 @@ static void vsock_connect_timeout(struct work_struct 
*work)
+               sk->sk_state = TCP_CLOSE;
+               sk->sk_err = ETIMEDOUT;
+               sk->sk_error_report(sk);
+-              cancel = 1;
++              vsock_transport_cancel_pkt(vsk);
+       }
+       release_sock(sk);
+-      if (cancel)
+-              vsock_transport_cancel_pkt(vsk);
+ 
+       sock_put(sk);
+ }
+diff --git a/net/vmw_vsock/hyperv_transport.c 
b/net/vmw_vsock/hyperv_transport.c
+index 463cefc1e5ae2..a3c57c048cbd8 100644
+--- a/net/vmw_vsock/hyperv_transport.c
++++ b/net/vmw_vsock/hyperv_transport.c
+@@ -464,14 +464,10 @@ static void hvs_shutdown_lock_held(struct hvsock *hvs, 
int mode)
+ 
+ static int hvs_shutdown(struct vsock_sock *vsk, int mode)
+ {
+-      struct sock *sk = sk_vsock(vsk);
+-
+       if (!(mode & SEND_SHUTDOWN))
+               return 0;
+ 
+-      lock_sock(sk);
+       hvs_shutdown_lock_held(vsk->trans, mode);
+-      release_sock(sk);
+       return 0;
+ }
+ 
+diff --git a/net/vmw_vsock/virtio_transport_common.c 
b/net/vmw_vsock/virtio_transport_common.c
+index efbb521bff135..dde16a033a09d 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1100,10 +1100,10 @@ void virtio_transport_recv_pkt(struct virtio_transport 
*t,
+ 
+       vsk = vsock_sk(sk);
+ 
+-      space_available = virtio_transport_space_update(sk, pkt);
+-
+       lock_sock(sk);
+ 
++      space_available = virtio_transport_space_update(sk, pkt);
++
+       /* Update CID in case it has changed after a transport reset event */
+       vsk->local_addr.svm_cid = dst.svm_cid;
+ 
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 52f1152c98389..13cda6aa26880 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -960,7 +960,7 @@ static void check_section(const char *modname, struct 
elf_info *elf,
+ 
+ #define DATA_SECTIONS ".data", ".data.rel"
+ #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
+-              ".kprobes.text", ".cpuidle.text"
++              ".kprobes.text", ".cpuidle.text", ".noinstr.text"
+ #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
+               ".fixup", ".entry.text", ".exception.text", ".text.*", \
+               ".coldtext"
+diff --git a/security/commoncap.c b/security/commoncap.c
+index 0ca31c8bc0b13..28a6939bcc4e5 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -371,10 +371,11 @@ int cap_inode_getsecurity(struct inode *inode, const 
char *name, void **buffer,
+ {
+       int size, ret;
+       kuid_t kroot;
++      u32 nsmagic, magic;
+       uid_t root, mappedroot;
+       char *tmpbuf = NULL;
+       struct vfs_cap_data *cap;
+-      struct vfs_ns_cap_data *nscap;
++      struct vfs_ns_cap_data *nscap = NULL;
+       struct dentry *dentry;
+       struct user_namespace *fs_ns;
+ 
+@@ -396,46 +397,61 @@ int cap_inode_getsecurity(struct inode *inode, const 
char *name, void **buffer,
+       fs_ns = inode->i_sb->s_user_ns;
+       cap = (struct vfs_cap_data *) tmpbuf;
+       if (is_v2header((size_t) ret, cap)) {
+-              /* If this is sizeof(vfs_cap_data) then we're ok with the
+-               * on-disk value, so return that.  */
+-              if (alloc)
+-                      *buffer = tmpbuf;
+-              else
+-                      kfree(tmpbuf);
+-              return ret;
+-      } else if (!is_v3header((size_t) ret, cap)) {
+-              kfree(tmpbuf);
+-              return -EINVAL;
++              root = 0;
++      } else if (is_v3header((size_t) ret, cap)) {
++              nscap = (struct vfs_ns_cap_data *) tmpbuf;
++              root = le32_to_cpu(nscap->rootid);
++      } else {
++              size = -EINVAL;
++              goto out_free;
+       }
+ 
+-      nscap = (struct vfs_ns_cap_data *) tmpbuf;
+-      root = le32_to_cpu(nscap->rootid);
+       kroot = make_kuid(fs_ns, root);
+ 
+       /* If the root kuid maps to a valid uid in current ns, then return
+        * this as a nscap. */
+       mappedroot = from_kuid(current_user_ns(), kroot);
+       if (mappedroot != (uid_t)-1 && mappedroot != (uid_t)0) {
++              size = sizeof(struct vfs_ns_cap_data);
+               if (alloc) {
+-                      *buffer = tmpbuf;
++                      if (!nscap) {
++                              /* v2 -> v3 conversion */
++                              nscap = kzalloc(size, GFP_ATOMIC);
++                              if (!nscap) {
++                                      size = -ENOMEM;
++                                      goto out_free;
++                              }
++                              nsmagic = VFS_CAP_REVISION_3;
++                              magic = le32_to_cpu(cap->magic_etc);
++                              if (magic & VFS_CAP_FLAGS_EFFECTIVE)
++                                      nsmagic |= VFS_CAP_FLAGS_EFFECTIVE;
++                              memcpy(&nscap->data, &cap->data, sizeof(__le32) 
* 2 * VFS_CAP_U32);
++                              nscap->magic_etc = cpu_to_le32(nsmagic);
++                      } else {
++                              /* use allocated v3 buffer */
++                              tmpbuf = NULL;
++                      }
+                       nscap->rootid = cpu_to_le32(mappedroot);
+-              } else
+-                      kfree(tmpbuf);
+-              return size;
++                      *buffer = nscap;
++              }
++              goto out_free;
+       }
+ 
+       if (!rootid_owns_currentns(kroot)) {
+-              kfree(tmpbuf);
+-              return -EOPNOTSUPP;
++              size = -EOVERFLOW;
++              goto out_free;
+       }
+ 
+       /* This comes from a parent namespace.  Return as a v2 capability */
+       size = sizeof(struct vfs_cap_data);
+       if (alloc) {
+-              *buffer = kmalloc(size, GFP_ATOMIC);
+-              if (*buffer) {
+-                      struct vfs_cap_data *cap = *buffer;
+-                      __le32 nsmagic, magic;
++              if (nscap) {
++                      /* v3 -> v2 conversion */
++                      cap = kzalloc(size, GFP_ATOMIC);
++                      if (!cap) {
++                              size = -ENOMEM;
++                              goto out_free;
++                      }
+                       magic = VFS_CAP_REVISION_2;
+                       nsmagic = le32_to_cpu(nscap->magic_etc);
+                       if (nsmagic & VFS_CAP_FLAGS_EFFECTIVE)
+@@ -443,9 +459,12 @@ int cap_inode_getsecurity(struct inode *inode, const char 
*name, void **buffer,
+                       memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * 
VFS_CAP_U32);
+                       cap->magic_etc = cpu_to_le32(magic);
+               } else {
+-                      size = -ENOMEM;
++                      /* use unconverted v2 */
++                      tmpbuf = NULL;
+               }
++              *buffer = cap;
+       }
++out_free:
+       kfree(tmpbuf);
+       return size;
+ }
+diff --git a/tools/testing/selftests/networking/timestamping/txtimestamp.c 
b/tools/testing/selftests/networking/timestamping/txtimestamp.c
+index 7e386be471201..2fce2e8f47f55 100644
+--- a/tools/testing/selftests/networking/timestamping/txtimestamp.c
++++ b/tools/testing/selftests/networking/timestamping/txtimestamp.c
+@@ -26,6 +26,7 @@
+ #include <inttypes.h>
+ #include <linux/errqueue.h>
+ #include <linux/if_ether.h>
++#include <linux/if_packet.h>
+ #include <linux/ipv6.h>
+ #include <linux/net_tstamp.h>
+ #include <netdb.h>
+@@ -34,7 +35,6 @@
+ #include <netinet/ip.h>
+ #include <netinet/udp.h>
+ #include <netinet/tcp.h>
+-#include <netpacket/packet.h>
+ #include <poll.h>
+ #include <stdarg.h>
+ #include <stdbool.h>
+@@ -396,12 +396,12 @@ static void do_test(int family, unsigned int report_opt)
+       total_len = cfg_payload_len;
+       if (cfg_use_pf_packet || cfg_proto == SOCK_RAW) {
+               total_len += sizeof(struct udphdr);
+-              if (cfg_use_pf_packet || cfg_ipproto == IPPROTO_RAW)
++              if (cfg_use_pf_packet || cfg_ipproto == IPPROTO_RAW) {
+                       if (family == PF_INET)
+                               total_len += sizeof(struct iphdr);
+                       else
+                               total_len += sizeof(struct ipv6hdr);
+-
++              }
+               /* special case, only rawv6_sendmsg:
+                * pass proto in sin6_port if not connected
+                * also see ANK comment in net/ipv4/raw.c

Reply via email to