commit:     c51efacc235ba2b5e5d0d734e00813df447d6ae2
Author:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 21 01:17:23 2025 +0000
Commit:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Aug 21 01:17:23 2025 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c51efacc

Linux patch 5.4.276

Signed-off-by: Arisu Tachibana <alicef <AT> gentoo.org>

 0000_README              |    4 +
 1275_linux-5.4.276.patch | 2862 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2866 insertions(+)

diff --git a/0000_README b/0000_README
index 8472e5b7..45e0bd46 100644
--- a/0000_README
+++ b/0000_README
@@ -1143,6 +1143,10 @@ Patch:  1274_linux-5.4.275.patch
 From:   https://www.kernel.org
 Desc:   Linux 5.4.275
 
+Patch:  1275_linux-5.4.276.patch
+From:   https://www.kernel.org
+Desc:   Linux 5.4.276
+
 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/1275_linux-5.4.276.patch b/1275_linux-5.4.276.patch
new file mode 100644
index 00000000..f831e78b
--- /dev/null
+++ b/1275_linux-5.4.276.patch
@@ -0,0 +1,2862 @@
+diff --git a/Makefile b/Makefile
+index dfb0d0dcc20b6..b45c9b7543e51 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 4
+-SUBLEVEL = 275
++SUBLEVEL = 276
+ EXTRAVERSION =
+ NAME = Kleptomaniac Octopus
+ 
+diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
+index 2849a9b65a055..ae578860f7295 100644
+--- a/arch/mips/include/asm/ptrace.h
++++ b/arch/mips/include/asm/ptrace.h
+@@ -157,7 +157,7 @@ static inline long regs_return_value(struct pt_regs *regs)
+ #define instruction_pointer(regs) ((regs)->cp0_epc)
+ #define profile_pc(regs) instruction_pointer(regs)
+ 
+-extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long 
syscall);
++extern asmlinkage long syscall_trace_enter(struct pt_regs *regs);
+ extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
+ 
+ extern void die(const char *, struct pt_regs *) __noreturn;
+diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
+index aebfda81120a1..6c5269d3aacba 100644
+--- a/arch/mips/kernel/asm-offsets.c
++++ b/arch/mips/kernel/asm-offsets.c
+@@ -100,6 +100,7 @@ void output_thread_info_defines(void)
+       OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
+       OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
+       OFFSET(TI_REGS, thread_info, regs);
++      OFFSET(TI_SYSCALL, thread_info, syscall);
+       DEFINE(_THREAD_SIZE, THREAD_SIZE);
+       DEFINE(_THREAD_MASK, THREAD_MASK);
+       DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
+diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
+index 414b6e9c900b2..cfb548fd2712c 100644
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -1399,16 +1399,13 @@ long arch_ptrace(struct task_struct *child, long 
request,
+  * Notification of system call entry/exit
+  * - triggered by current->work.syscall_trace
+  */
+-asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
++asmlinkage long syscall_trace_enter(struct pt_regs *regs)
+ {
+       user_exit();
+ 
+-      current_thread_info()->syscall = syscall;
+-
+       if (test_thread_flag(TIF_SYSCALL_TRACE)) {
+               if (tracehook_report_syscall_entry(regs))
+                       return -1;
+-              syscall = current_thread_info()->syscall;
+       }
+ 
+ #ifdef CONFIG_SECCOMP
+@@ -1417,7 +1414,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs 
*regs, long syscall)
+               struct seccomp_data sd;
+               unsigned long args[6];
+ 
+-              sd.nr = syscall;
++              sd.nr = current_thread_info()->syscall;
+               sd.arch = syscall_get_arch(current);
+               syscall_get_arguments(current, regs, args);
+               for (i = 0; i < 6; i++)
+@@ -1427,23 +1424,23 @@ asmlinkage long syscall_trace_enter(struct pt_regs 
*regs, long syscall)
+               ret = __secure_computing(&sd);
+               if (ret == -1)
+                       return ret;
+-              syscall = current_thread_info()->syscall;
+       }
+ #endif
+ 
+       if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+               trace_sys_enter(regs, regs->regs[2]);
+ 
+-      audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
++      audit_syscall_entry(current_thread_info()->syscall,
++                          regs->regs[4], regs->regs[5],
+                           regs->regs[6], regs->regs[7]);
+ 
+       /*
+        * Negative syscall numbers are mistaken for rejected syscalls, but
+        * won't have had the return value set appropriately, so we do so now.
+        */
+-      if (syscall < 0)
++      if (current_thread_info()->syscall < 0)
+               syscall_set_return_value(current, regs, -ENOSYS, 0);
+-      return syscall;
++      return current_thread_info()->syscall;
+ }
+ 
+ /*
+diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
+index b449b68662a9a..80747719a35ca 100644
+--- a/arch/mips/kernel/scall32-o32.S
++++ b/arch/mips/kernel/scall32-o32.S
+@@ -80,6 +80,18 @@ loads_done:
+       PTR     load_a7, bad_stack_a7
+       .previous
+ 
++      /*
++       * syscall number is in v0 unless we called syscall(__NR_###)
++       * where the real syscall number is in a0
++       */
++      subu    t2, v0,  __NR_O32_Linux
++      bnez    t2, 1f /* __NR_syscall at offset 0 */
++      LONG_S  a0, TI_SYSCALL($28)     # Save a0 as syscall number
++      b       2f
++1:
++      LONG_S  v0, TI_SYSCALL($28)     # Save v0 as syscall number
++2:
++
+       lw      t0, TI_FLAGS($28)       # syscall tracing enabled?
+       li      t1, _TIF_WORK_SYSCALL_ENTRY
+       and     t0, t1
+@@ -117,16 +129,7 @@ syscall_trace_entry:
+       SAVE_STATIC
+       move    a0, sp
+ 
+-      /*
+-       * syscall number is in v0 unless we called syscall(__NR_###)
+-       * where the real syscall number is in a0
+-       */
+-      move    a1, v0
+-      subu    t2, v0,  __NR_O32_Linux
+-      bnez    t2, 1f /* __NR_syscall at offset 0 */
+-      lw      a1, PT_R4(sp)
+-
+-1:    jal     syscall_trace_enter
++      jal     syscall_trace_enter
+ 
+       bltz    v0, 1f                  # seccomp failed? Skip syscall
+ 
+diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
+index 35d8c86b160ea..a8679e34c95e3 100644
+--- a/arch/mips/kernel/scall64-n32.S
++++ b/arch/mips/kernel/scall64-n32.S
+@@ -44,6 +44,8 @@ NESTED(handle_sysn32, PT_SIZE, sp)
+ 
+       sd      a3, PT_R26(sp)          # save a3 for syscall restarting
+ 
++      LONG_S  v0, TI_SYSCALL($28)     # Store syscall number
++
+       li      t1, _TIF_WORK_SYSCALL_ENTRY
+       LONG_L  t0, TI_FLAGS($28)       # syscall tracing enabled?
+       and     t0, t1, t0
+@@ -72,7 +74,6 @@ syscall_common:
+ n32_syscall_trace_entry:
+       SAVE_STATIC
+       move    a0, sp
+-      move    a1, v0
+       jal     syscall_trace_enter
+ 
+       bltz    v0, 1f                  # seccomp failed? Skip syscall
+diff --git a/arch/mips/kernel/scall64-n64.S b/arch/mips/kernel/scall64-n64.S
+index 23b2e2b1609cf..a3b5ab509b412 100644
+--- a/arch/mips/kernel/scall64-n64.S
++++ b/arch/mips/kernel/scall64-n64.S
+@@ -47,6 +47,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
+ 
+       sd      a3, PT_R26(sp)          # save a3 for syscall restarting
+ 
++      LONG_S  v0, TI_SYSCALL($28)     # Store syscall number
++
+       li      t1, _TIF_WORK_SYSCALL_ENTRY
+       LONG_L  t0, TI_FLAGS($28)       # syscall tracing enabled?
+       and     t0, t1, t0
+@@ -83,7 +85,6 @@ n64_syscall_exit:
+ syscall_trace_entry:
+       SAVE_STATIC
+       move    a0, sp
+-      move    a1, v0
+       jal     syscall_trace_enter
+ 
+       bltz    v0, 1f                  # seccomp failed? Skip syscall
+diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
+index 41df8221bb8fd..d8f41e919c171 100644
+--- a/arch/mips/kernel/scall64-o32.S
++++ b/arch/mips/kernel/scall64-o32.S
+@@ -79,6 +79,22 @@ loads_done:
+       PTR     load_a7, bad_stack_a7
+       .previous
+ 
++      /*
++       * absolute syscall number is in v0 unless we called syscall(__NR_###)
++       * where the real syscall number is in a0
++       * note: NR_syscall is the first O32 syscall but the macro is
++       * only defined when compiling with -mabi=32 (CONFIG_32BIT)
++       * therefore __NR_O32_Linux is used (4000)
++       */
++
++      subu    t2, v0,  __NR_O32_Linux
++      bnez    t2, 1f /* __NR_syscall at offset 0 */
++      LONG_S  a0, TI_SYSCALL($28)     # Save a0 as syscall number
++      b       2f
++1:
++      LONG_S  v0, TI_SYSCALL($28)     # Save v0 as syscall number
++2:
++
+       li      t1, _TIF_WORK_SYSCALL_ENTRY
+       LONG_L  t0, TI_FLAGS($28)       # syscall tracing enabled?
+       and     t0, t1, t0
+@@ -113,22 +129,7 @@ trace_a_syscall:
+       sd      a7, PT_R11(sp)          # For indirect syscalls
+ 
+       move    a0, sp
+-      /*
+-       * absolute syscall number is in v0 unless we called syscall(__NR_###)
+-       * where the real syscall number is in a0
+-       * note: NR_syscall is the first O32 syscall but the macro is
+-       * only defined when compiling with -mabi=32 (CONFIG_32BIT)
+-       * therefore __NR_O32_Linux is used (4000)
+-       */
+-      .set    push
+-      .set    reorder
+-      subu    t1, v0,  __NR_O32_Linux
+-      move    a1, v0
+-      bnez    t1, 1f /* __NR_syscall at offset 0 */
+-      ld      a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
+-      .set    pop
+-
+-1:    jal     syscall_trace_enter
++      jal     syscall_trace_enter
+ 
+       bltz    v0, 1f                  # seccomp failed? Skip syscall
+ 
+diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
+index 19ee8355b2a7f..5c41d1ab2a622 100644
+--- a/arch/s390/mm/gmap.c
++++ b/arch/s390/mm/gmap.c
+@@ -2610,7 +2610,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, 
unsigned long addr,
+               return 0;
+ 
+       start = pmd_val(*pmd) & HPAGE_MASK;
+-      end = start + HPAGE_SIZE - 1;
++      end = start + HPAGE_SIZE;
+       __storage_key_init_range(start, end);
+       set_bit(PG_arch_1, &page->flags);
+       cond_resched();
+diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
+index ff8234bca56cd..6b688e3498c01 100644
+--- a/arch/s390/mm/hugetlbpage.c
++++ b/arch/s390/mm/hugetlbpage.c
+@@ -146,7 +146,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, 
unsigned long rste)
+       }
+ 
+       if (!test_and_set_bit(PG_arch_1, &page->flags))
+-              __storage_key_init_range(paddr, paddr + size - 1);
++              __storage_key_init_range(paddr, paddr + size);
+ }
+ 
+ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c
+index 6fd54e968d10a..1564472fd5d50 100644
+--- a/drivers/ata/sata_gemini.c
++++ b/drivers/ata/sata_gemini.c
+@@ -201,7 +201,10 @@ int gemini_sata_start_bridge(struct sata_gemini *sg, 
unsigned int bridge)
+               pclk = sg->sata0_pclk;
+       else
+               pclk = sg->sata1_pclk;
+-      clk_enable(pclk);
++      ret = clk_enable(pclk);
++      if (ret)
++              return ret;
++
+       msleep(10);
+ 
+       /* Do not keep clocking a bridge that is not online */
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 59a77587da47b..56be3f97c265a 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -4061,7 +4061,8 @@ void clk_unregister(struct clk *clk)
+       if (clk->core->ops == &clk_nodrv_ops) {
+               pr_err("%s: unregistered clock: %s\n", __func__,
+                      clk->core->name);
+-              goto unlock;
++              clk_prepare_unlock();
++              return;
+       }
+       /*
+        * Assign empty clock ops for consumers that might still hold
+@@ -4092,11 +4093,10 @@ void clk_unregister(struct clk *clk)
+       if (clk->core->protect_count)
+               pr_warn("%s: unregistering protected clock: %s\n",
+                                       __func__, clk->core->name);
++      clk_prepare_unlock();
+ 
+       kref_put(&clk->core->ref, __clk_release);
+       free_clk(clk);
+-unlock:
+-      clk_prepare_unlock();
+ }
+ EXPORT_SYMBOL_GPL(clk_unregister);
+ 
+@@ -4258,13 +4258,11 @@ void __clk_put(struct clk *clk)
+           clk->max_rate < clk->core->req_rate)
+               clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
+ 
+-      owner = clk->core->owner;
+-      kref_put(&clk->core->ref, __clk_release);
+-
+       clk_prepare_unlock();
+ 
++      owner = clk->core->owner;
++      kref_put(&clk->core->ref, __clk_release);
+       module_put(owner);
+-
+       free_clk(clk);
+ }
+ 
+diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c 
b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+index 2f00f1b7b9c00..c02f4e4a69e40 100644
+--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
++++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+@@ -1172,12 +1172,19 @@ static const u32 usb2_clk_regs[] = {
+       SUN50I_H6_USB3_CLK_REG,
+ };
+ 
++static struct ccu_mux_nb sun50i_h6_cpu_nb = {
++      .common         = &cpux_clk.common,
++      .cm             = &cpux_clk.mux,
++      .delay_us       = 1,
++      .bypass_index   = 0, /* index of 24 MHz oscillator */
++};
++
+ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
+ {
+       struct resource *res;
+       void __iomem *reg;
++      int i, ret;
+       u32 val;
+-      int i;
+ 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg = devm_ioremap_resource(&pdev->dev, res);
+@@ -1231,7 +1238,15 @@ static int sun50i_h6_ccu_probe(struct platform_device 
*pdev)
+       val |= BIT(24);
+       writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
+ 
+-      return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
++      ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
++      if (ret)
++              return ret;
++
++      /* Reparent CPU during PLL CPUX rate changes */
++      ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
++                                &sun50i_h6_cpu_nb);
++
++      return 0;
+ }
+ 
+ static const struct of_device_id sun50i_h6_ccu_ids[] = {
+diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c
+index 9ee747a85ee49..8bb609085911f 100644
+--- a/drivers/firewire/nosy.c
++++ b/drivers/firewire/nosy.c
+@@ -148,10 +148,12 @@ packet_buffer_get(struct client *client, char __user 
*data, size_t user_length)
+       if (atomic_read(&buffer->size) == 0)
+               return -ENODEV;
+ 
+-      /* FIXME: Check length <= user_length. */
++      length = buffer->head->length;
++
++      if (length > user_length)
++              return 0;
+ 
+       end = buffer->data + buffer->capacity;
+-      length = buffer->head->length;
+ 
+       if (&buffer->head->data[length] < end) {
+               if (copy_to_user(data, buffer->head->data, length))
+diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
+index 6603f13f5de9b..2db5448c4293a 100644
+--- a/drivers/firewire/ohci.c
++++ b/drivers/firewire/ohci.c
+@@ -2053,6 +2053,8 @@ static void bus_reset_work(struct work_struct *work)
+ 
+       ohci->generation = generation;
+       reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
++      if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
++              reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
+ 
+       if (ohci->quirks & QUIRK_RESET_PACKET)
+               ohci->request_generation = generation;
+@@ -2119,12 +2121,14 @@ static irqreturn_t irq_handler(int irq, void *data)
+               return IRQ_NONE;
+ 
+       /*
+-       * busReset and postedWriteErr must not be cleared yet
++       * busReset and postedWriteErr events must not be cleared yet
+        * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
+        */
+       reg_write(ohci, OHCI1394_IntEventClear,
+                 event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
+       log_irqs(ohci, event);
++      if (event & OHCI1394_busReset)
++              reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
+ 
+       if (event & OHCI1394_selfIDComplete)
+               queue_work(selfid_workqueue, &ohci->bus_reset_work);
+diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c
+index 14d1f4c933b69..8b9c1833bf7d4 100644
+--- a/drivers/gpio/gpio-crystalcove.c
++++ b/drivers/gpio/gpio-crystalcove.c
+@@ -91,7 +91,7 @@ static inline int to_reg(int gpio, enum ctrl_register 
reg_type)
+               case 0x5e:
+                       return GPIOPANELCTL;
+               default:
+-                      return -EOPNOTSUPP;
++                      return -ENOTSUPP;
+               }
+       }
+ 
+diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
+index 444fe9e7f04ac..79946c098271a 100644
+--- a/drivers/gpio/gpio-wcove.c
++++ b/drivers/gpio/gpio-wcove.c
+@@ -102,7 +102,7 @@ static inline int to_reg(int gpio, enum ctrl_register 
reg_type)
+       unsigned int reg;
+ 
+       if (gpio >= WCOVE_GPIO_NUM)
+-              return -EOPNOTSUPP;
++              return -ENOTSUPP;
+ 
+       if (reg_type == CTRL_IN)
+               reg = GPIO_IN_CTRL_BASE + gpio;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+index 874093a0b04f0..da052e3a187e0 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+@@ -1066,7 +1066,7 @@ static int vmw_event_fence_action_create(struct drm_file 
*file_priv,
+       }
+ 
+       event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
+-      event->event.base.length = sizeof(*event);
++      event->event.base.length = sizeof(event->event);
+       event->event.user_data = user_data;
+ 
+       ret = drm_event_reserve_init(dev, file_priv, &event->base, 
&event->event.base);
+diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
+index fcda8621ae6f9..5a1bf59be7341 100644
+--- a/drivers/gpu/host1x/bus.c
++++ b/drivers/gpu/host1x/bus.c
+@@ -335,11 +335,6 @@ static int host1x_device_uevent(struct device *dev,
+       return 0;
+ }
+ 
+-static int host1x_dma_configure(struct device *dev)
+-{
+-      return of_dma_configure(dev, dev->of_node, true);
+-}
+-
+ static const struct dev_pm_ops host1x_device_pm_ops = {
+       .suspend = pm_generic_suspend,
+       .resume = pm_generic_resume,
+@@ -353,7 +348,6 @@ struct bus_type host1x_bus_type = {
+       .name = "host1x",
+       .match = host1x_device_match,
+       .uevent = host1x_device_uevent,
+-      .dma_configure = host1x_dma_configure,
+       .pm = &host1x_device_pm_ops,
+ };
+ 
+@@ -442,8 +436,6 @@ static int host1x_device_add(struct host1x *host1x,
+       device->dev.bus = &host1x_bus_type;
+       device->dev.parent = host1x->dev;
+ 
+-      of_dma_configure(&device->dev, host1x->dev->of_node, true);
+-
+       device->dev.dma_parms = &device->dma_parms;
+       dma_set_max_seg_size(&device->dev, SZ_4M);
+ 
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c 
b/drivers/net/dsa/mv88e6xxx/chip.c
+index c1655e5952220..81e6227cc8758 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -4200,6 +4200,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6097,
+               .name = "Marvell 88E6085",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 10,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4222,6 +4223,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6095,
+               .name = "Marvell 88E6095/88E6095F",
+               .num_databases = 256,
++              .num_macs = 8192,
+               .num_ports = 11,
+               .num_internal_phys = 0,
+               .max_vid = 4095,
+@@ -4242,6 +4244,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6097,
+               .name = "Marvell 88E6097/88E6097F",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 11,
+               .num_internal_phys = 8,
+               .max_vid = 4095,
+@@ -4264,6 +4267,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6165,
+               .name = "Marvell 88E6123",
+               .num_databases = 4096,
++              .num_macs = 1024,
+               .num_ports = 3,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4286,6 +4290,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6185,
+               .name = "Marvell 88E6131",
+               .num_databases = 256,
++              .num_macs = 8192,
+               .num_ports = 8,
+               .num_internal_phys = 0,
+               .max_vid = 4095,
+@@ -4305,7 +4310,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
+               .family = MV88E6XXX_FAMILY_6341,
+               .name = "Marvell 88E6141",
+-              .num_databases = 4096,
++              .num_databases = 256,
++              .num_macs = 2048,
+               .num_ports = 6,
+               .num_internal_phys = 5,
+               .num_gpio = 11,
+@@ -4329,6 +4335,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6165,
+               .name = "Marvell 88E6161",
+               .num_databases = 4096,
++              .num_macs = 1024,
+               .num_ports = 6,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4352,6 +4359,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6165,
+               .name = "Marvell 88E6165",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 6,
+               .num_internal_phys = 0,
+               .max_vid = 4095,
+@@ -4375,6 +4383,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6171",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4397,6 +4406,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6172",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+@@ -4420,6 +4430,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6175",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4442,6 +4453,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6176",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+@@ -4465,6 +4477,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6185,
+               .name = "Marvell 88E6185",
+               .num_databases = 256,
++              .num_macs = 8192,
+               .num_ports = 10,
+               .num_internal_phys = 0,
+               .max_vid = 4095,
+@@ -4485,6 +4498,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6390,
+               .name = "Marvell 88E6190",
+               .num_databases = 4096,
++              .num_macs = 16384,
+               .num_ports = 11,        /* 10 + Z80 */
+               .num_internal_phys = 9,
+               .num_gpio = 16,
+@@ -4508,6 +4522,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6390,
+               .name = "Marvell 88E6190X",
+               .num_databases = 4096,
++              .num_macs = 16384,
+               .num_ports = 11,        /* 10 + Z80 */
+               .num_internal_phys = 9,
+               .num_gpio = 16,
+@@ -4531,6 +4546,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6390,
+               .name = "Marvell 88E6191",
+               .num_databases = 4096,
++              .num_macs = 16384,
+               .num_ports = 11,        /* 10 + Z80 */
+               .num_internal_phys = 9,
+               .max_vid = 8191,
+@@ -4581,6 +4597,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6240",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+@@ -4651,6 +4668,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6320,
+               .name = "Marvell 88E6320",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+@@ -4675,6 +4693,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6320,
+               .name = "Marvell 88E6321",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+@@ -4697,7 +4716,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
+               .family = MV88E6XXX_FAMILY_6341,
+               .name = "Marvell 88E6341",
+-              .num_databases = 4096,
++              .num_databases = 256,
++              .num_macs = 2048,
+               .num_internal_phys = 5,
+               .num_ports = 6,
+               .num_gpio = 11,
+@@ -4722,6 +4742,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6350",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4744,6 +4765,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6351",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .max_vid = 4095,
+@@ -4766,6 +4788,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6352",
+               .num_databases = 4096,
++              .num_macs = 8192,
+               .num_ports = 7,
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+@@ -4789,6 +4812,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6390,
+               .name = "Marvell 88E6390",
+               .num_databases = 4096,
++              .num_macs = 16384,
+               .num_ports = 11,        /* 10 + Z80 */
+               .num_internal_phys = 9,
+               .num_gpio = 16,
+@@ -4812,6 +4836,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .family = MV88E6XXX_FAMILY_6390,
+               .name = "Marvell 88E6390X",
+               .num_databases = 4096,
++              .num_macs = 16384,
+               .num_ports = 11,        /* 10 + Z80 */
+               .num_internal_phys = 9,
+               .num_gpio = 16,
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.h 
b/drivers/net/dsa/mv88e6xxx/chip.h
+index e9b1a1ac9a8e2..24dd73be37040 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.h
++++ b/drivers/net/dsa/mv88e6xxx/chip.h
+@@ -94,6 +94,7 @@ struct mv88e6xxx_info {
+       u16 prod_num;
+       const char *name;
+       unsigned int num_databases;
++      unsigned int num_macs;
+       unsigned int num_ports;
+       unsigned int num_internal_phys;
+       unsigned int num_gpio;
+@@ -609,6 +610,11 @@ static inline unsigned int mv88e6xxx_num_databases(struct 
mv88e6xxx_chip *chip)
+       return chip->info->num_databases;
+ }
+ 
++static inline unsigned int mv88e6xxx_num_macs(struct  mv88e6xxx_chip *chip)
++{
++      return chip->info->num_macs;
++}
++
+ static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
+ {
+       return chip->info->num_ports;
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c 
b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index 380bf7a328ba3..469cfc74617a6 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -2796,7 +2796,7 @@ static void bcmgenet_set_hw_addr(struct bcmgenet_priv 
*priv,
+ }
+ 
+ /* Returns a reusable dma control register value */
+-static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
++static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx)
+ {
+       unsigned int i;
+       u32 reg;
+@@ -2821,6 +2821,14 @@ static u32 bcmgenet_dma_disable(struct bcmgenet_priv 
*priv)
+       udelay(10);
+       bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH);
+ 
++      if (flush_rx) {
++              reg = bcmgenet_rbuf_ctrl_get(priv);
++              bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0));
++              udelay(10);
++              bcmgenet_rbuf_ctrl_set(priv, reg);
++              udelay(10);
++      }
++
+       return dma_ctrl;
+ }
+ 
+@@ -2916,8 +2924,8 @@ static int bcmgenet_open(struct net_device *dev)
+ 
+       bcmgenet_set_hw_addr(priv, dev->dev_addr);
+ 
+-      /* Disable RX/TX DMA and flush TX queues */
+-      dma_ctrl = bcmgenet_dma_disable(priv);
++      /* Disable RX/TX DMA and flush TX and RX queues */
++      dma_ctrl = bcmgenet_dma_disable(priv, true);
+ 
+       /* Reinitialize TDMA and RDMA and SW housekeeping */
+       ret = bcmgenet_init_dma(priv);
+@@ -3670,7 +3678,7 @@ static int bcmgenet_resume(struct device *d)
+               bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
+ 
+       /* Disable RX/TX DMA and flush TX queues */
+-      dma_ctrl = bcmgenet_dma_disable(priv);
++      dma_ctrl = bcmgenet_dma_disable(priv, false);
+ 
+       /* Reinitialize TDMA and RDMA and SW housekeeping */
+       ret = bcmgenet_init_dma(priv);
+diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c 
b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
+index 04ad0f2b9677e..777f0d7e48192 100644
+--- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
++++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
+@@ -312,7 +312,7 @@ bnad_debugfs_write_regrd(struct file *file, const char 
__user *buf,
+       void *kern_buf;
+ 
+       /* Copy the user space buf */
+-      kern_buf = memdup_user(buf, nbytes);
++      kern_buf = memdup_user_nul(buf, nbytes);
+       if (IS_ERR(kern_buf))
+               return PTR_ERR(kern_buf);
+ 
+@@ -372,7 +372,7 @@ bnad_debugfs_write_regwr(struct file *file, const char 
__user *buf,
+       void *kern_buf;
+ 
+       /* Copy the user space buf */
+-      kern_buf = memdup_user(buf, nbytes);
++      kern_buf = memdup_user_nul(buf, nbytes);
+       if (IS_ERR(kern_buf))
+               return PTR_ERR(kern_buf);
+ 
+diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c 
b/drivers/net/ethernet/qlogic/qede/qede_filter.c
+index 5041994bf03fb..3142d92a98f02 100644
+--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c
++++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c
+@@ -1949,8 +1949,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, 
__be16 proto,
+                           struct flow_cls_offload *f)
+ {
+       struct qede_arfs_fltr_node *n;
+-      int min_hlen, rc = -EINVAL;
+       struct qede_arfs_tuple t;
++      int min_hlen, rc;
+ 
+       __qede_lock(edev);
+ 
+@@ -1960,7 +1960,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, 
__be16 proto,
+       }
+ 
+       /* parse flower attribute and prepare filter */
+-      if (qede_parse_flow_attr(edev, proto, f->rule, &t))
++      rc = qede_parse_flow_attr(edev, proto, f->rule, &t);
++      if (rc)
+               goto unlock;
+ 
+       /* Validate profile mode and number of filters */
+@@ -1969,12 +1970,15 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, 
__be16 proto,
+               DP_NOTICE(edev,
+                         "Filter configuration invalidated, filter mode=0x%x, 
configured mode=0x%x, filter count=0x%x\n",
+                         t.mode, edev->arfs->mode, edev->arfs->filter_count);
++              rc = -EINVAL;
+               goto unlock;
+       }
+ 
+       /* parse tc actions and get the vf_id */
+-      if (qede_parse_actions(edev, &f->rule->action))
++      if (qede_parse_actions(edev, &f->rule->action)) {
++              rc = -EINVAL;
+               goto unlock;
++      }
+ 
+       if (qede_flow_find_fltr(edev, &t)) {
+               rc = -EEXIST;
+@@ -2079,10 +2083,9 @@ static int qede_flow_spec_to_rule(struct qede_dev *edev,
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+ 
+-      if (qede_parse_flow_attr(edev, proto, flow->rule, t)) {
+-              err = -EINVAL;
++      err = qede_parse_flow_attr(edev, proto, flow->rule, t);
++      if (err)
+               goto err_out;
+-      }
+ 
+       /* Make sure location is valid and filter isn't already set */
+       err = qede_flow_spec_validate(edev, &flow->rule->action, t,
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index c2bd4abce6de5..1c48d3d9522ba 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1380,6 +1380,7 @@ static const struct usb_device_id products[] = {
+       {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)},    /* Foxconn T77W968 LTE with 
eSIM support*/
+       {QMI_FIXED_INTF(0x2692, 0x9025, 4)},    /* Cellient MPL200 (rebranded 
Qualcomm 05c6:9025) */
+       {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
++      {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
+ 
+       /* 4. Gobi 1000 devices */
+       {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
+diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
+index a1c2dc304fb10..3947b7064bead 100644
+--- a/drivers/pinctrl/core.c
++++ b/drivers/pinctrl/core.c
+@@ -2053,13 +2053,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
+ 
+       error = pinctrl_claim_hogs(pctldev);
+       if (error) {
+-              dev_err(pctldev->dev, "could not claim hogs: %i\n",
+-                      error);
+-              pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
+-                                    pctldev->desc->npins);
+-              mutex_destroy(&pctldev->mutex);
+-              kfree(pctldev);
+-
++              dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
+               return error;
+       }
+ 
+diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
+index 362d84c2ead44..200357094e3be 100644
+--- a/drivers/pinctrl/devicetree.c
++++ b/drivers/pinctrl/devicetree.c
+@@ -223,14 +223,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct 
pinctrl_dev *pctldev)
+       for (state = 0; ; state++) {
+               /* Retrieve the pinctrl-* property */
+               propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
+-              if (!propname)
+-                      return -ENOMEM;
++              if (!propname) {
++                      ret = -ENOMEM;
++                      goto err;
++              }
+               prop = of_find_property(np, propname, &size);
+               kfree(propname);
+               if (!prop) {
+                       if (state == 0) {
+-                              of_node_put(np);
+-                              return -ENODEV;
++                              ret = -ENODEV;
++                              goto err;
+                       }
+                       break;
+               }
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+index 32451e8693be7..905dae8c3fd86 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+@@ -1070,15 +1070,12 @@ static const struct mtk_pin_soc mt6765_data = {
+       .ngrps = ARRAY_SIZE(mtk_pins_mt6765),
+       .eint_hw = &mt6765_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = true,
+       .base_names = mt6765_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
+-      .bias_disable_set = mtk_pinconf_bias_disable_set,
+-      .bias_disable_get = mtk_pinconf_bias_disable_get,
+-      .bias_set = mtk_pinconf_bias_set,
+-      .bias_get = mtk_pinconf_bias_get,
+-      .drive_set = mtk_pinconf_drive_set_rev1,
+-      .drive_get = mtk_pinconf_drive_get_rev1,
++      .bias_set_combo = mtk_pinconf_bias_set_combo,
++      .bias_get_combo = mtk_pinconf_bias_get_combo,
++      .drive_set = mtk_pinconf_drive_set_raw,
++      .drive_get = mtk_pinconf_drive_get_raw,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+       .adv_pull_set = mtk_pinconf_adv_pull_set,
+ };
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c 
b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+index 9a74d5025be64..60318339b6183 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+@@ -554,13 +554,10 @@ static const struct mtk_pin_soc mt8183_data = {
+       .ngrps = ARRAY_SIZE(mtk_pins_mt8183),
+       .eint_hw = &mt8183_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = true,
+       .base_names = mt8183_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
+-      .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
+-      .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
+-      .bias_set = mtk_pinconf_bias_set_rev1,
+-      .bias_get = mtk_pinconf_bias_get_rev1,
++      .bias_set_combo = mtk_pinconf_bias_set_combo,
++      .bias_get_combo = mtk_pinconf_bias_get_combo,
+       .drive_set = mtk_pinconf_drive_set_rev1,
+       .drive_get = mtk_pinconf_drive_get_rev1,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index c3e6f3c1b4743..7dea3fcda880d 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -6,6 +6,7 @@
+  *
+  */
+ 
++#include <dt-bindings/pinctrl/mt65xx.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
+ #include <linux/gpio/driver.h>
+@@ -66,34 +67,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
+                                  const struct mtk_pin_desc *desc,
+                                  int field, struct mtk_pin_field *pfd)
+ {
+-      const struct mtk_pin_field_calc *c, *e;
++      const struct mtk_pin_field_calc *c;
+       const struct mtk_pin_reg_calc *rc;
++      int start = 0, end, check;
++      bool found = false;
+       u32 bits;
+ 
+       if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
+               rc = &hw->soc->reg_cal[field];
+       } else {
+               dev_dbg(hw->dev,
+-                      "Not support field %d for pin %d (%s)\n",
+-                      field, desc->number, desc->name);
++                      "Not support field %d for this soc\n", field);
+               return -ENOTSUPP;
+       }
+ 
+-      c = rc->range;
+-      e = c + rc->nranges;
++      end = rc->nranges - 1;
+ 
+-      while (c < e) {
+-              if (desc->number >= c->s_pin && desc->number <= c->e_pin)
++      while (start <= end) {
++              check = (start + end) >> 1;
++              if (desc->number >= rc->range[check].s_pin
++               && desc->number <= rc->range[check].e_pin) {
++                      found = true;
++                      break;
++              } else if (start == end)
+                       break;
+-              c++;
++              else if (desc->number < rc->range[check].s_pin)
++                      end = check - 1;
++              else
++                      start = check + 1;
+       }
+ 
+-      if (c >= e) {
++      if (!found) {
+               dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
+                       field, desc->number, desc->name);
+               return -ENOTSUPP;
+       }
+ 
++      c = rc->range + check;
++
+       if (c->i_base > hw->nbase - 1) {
+               dev_err(hw->dev,
+                       "Invalid base for field %d for pin = %d (%s)\n",
+@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
+       if (err)
+               return err;
+ 
++      if (value < 0 || value > pf.mask)
++              return -EINVAL;
++
+       if (!pf.next)
+               mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
+                       (value & pf.mask) << pf.bitpos);
+@@ -506,6 +520,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
+       return 0;
+ }
+ 
++/* Combo for the following pull register type:
++ * 1. PU + PD
++ * 2. PULLSEL + PULLEN
++ * 3. PUPD + R0 + R1
++ */
++static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, pu, pd;
++
++      if (arg == MTK_DISABLE) {
++              pu = 0;
++              pd = 0;
++      } else if ((arg == MTK_ENABLE) && pullup) {
++              pu = 1;
++              pd = 0;
++      } else if ((arg == MTK_ENABLE) && !pullup) {
++              pu = 0;
++              pd = 1;
++      } else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, enable;
++
++      if (arg == MTK_DISABLE)
++              enable = 0;
++      else if (arg == MTK_ENABLE)
++              enable = 1;
++      else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, r0, r1;
++
++      if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
++              pullup = 0;
++              r0 = 0;
++              r1 = 0;
++      } else if (arg == MTK_PUPD_SET_R1R0_01) {
++              r0 = 1;
++              r1 = 0;
++      } else if (arg == MTK_PUPD_SET_R1R0_10) {
++              r0 = 0;
++              r1 = 1;
++      } else if (arg == MTK_PUPD_SET_R1R0_11) {
++              r0 = 1;
++              r1 = 1;
++      } else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err, pu, pd;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
++      if (err)
++              goto out;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
++      if (err)
++              goto out;
++
++      if (pu == 0 && pd == 0) {
++              *pullup = 0;
++              *enable = MTK_DISABLE;
++      } else if (pu == 1 && pd == 0) {
++              *pullup = 1;
++              *enable = MTK_ENABLE;
++      } else if (pu == 0 && pd == 1) {
++              *pullup = 0;
++              *enable = MTK_ENABLE;
++      } else
++              err = -EINVAL;
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
++      if (err)
++              goto out;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err, r0, r1;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
++      if (err)
++              goto out;
++      /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
++      *pullup = !(*pullup);
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
++      if (err)
++              goto out;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
++      if (err)
++              goto out;
++
++      if ((r1 == 0) && (r0 == 0))
++              *enable = MTK_PUPD_SET_R1R0_00;
++      else if ((r1 == 0) && (r0 == 1))
++              *enable = MTK_PUPD_SET_R1R0_01;
++      else if ((r1 == 1) && (r0 == 0))
++              *enable = MTK_PUPD_SET_R1R0_10;
++      else if ((r1 == 1) && (r0 == 1))
++              *enable = MTK_PUPD_SET_R1R0_11;
++      else
++              err = -EINVAL;
++
++out:
++      return err;
++}
++
++int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err;
++
++      err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
++
++out:
++      return err;
++}
++
++int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
++                            const struct mtk_pin_desc *desc,
++                            u32 *pullup, u32 *enable)
++{
++      int err;
++
++      err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
++
++out:
++      return err;
++}
++
+ /* Revision 0 */
+ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
+                         const struct mtk_pin_desc *desc, u32 arg)
+@@ -597,6 +831,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
+       return 0;
+ }
+ 
++int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, u32 arg)
++{
++      return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
++}
++
++int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, int *val)
++{
++      return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
++}
++
+ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
+                            const struct mtk_pin_desc *desc, bool pullup,
+                            u32 arg)
+@@ -630,7 +876,9 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
+                       if (err)
+                               return err;
+               } else {
+-                      return -ENOTSUPP;
++                      err = mtk_pinconf_bias_set_rev1(hw, desc, pullup);
++                      if (err)
++                              err = mtk_pinconf_bias_set(hw, desc, pullup);
+               }
+       }
+ 
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+index 1b7da42aa1d53..27df087363960 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+@@ -216,6 +216,11 @@ struct mtk_pin_soc {
+       int (*bias_get)(struct mtk_pinctrl *hw,
+                       const struct mtk_pin_desc *desc, bool pullup, int *res);
+ 
++      int (*bias_set_combo)(struct mtk_pinctrl *hw,
++                      const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
++      int (*bias_get_combo)(struct mtk_pinctrl *hw,
++                      const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
++
+       int (*drive_set)(struct mtk_pinctrl *hw,
+                        const struct mtk_pin_desc *desc, u32 arg);
+       int (*drive_get)(struct mtk_pinctrl *hw,
+@@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
+ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
+                             const struct mtk_pin_desc *desc, bool pullup,
+                             int *res);
++int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 enable);
++int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
++                            const struct mtk_pin_desc *desc,
++                            u32 *pullup, u32 *enable);
+ 
+ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
+                         const struct mtk_pin_desc *desc, u32 arg);
+@@ -288,6 +299,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
+ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
+                              const struct mtk_pin_desc *desc, int *val);
+ 
++int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, u32 arg);
++int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, int *val);
++
+ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
+                            const struct mtk_pin_desc *desc, bool pullup,
+                            u32 arg);
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 31449514a8c0c..126bf1a43b297 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -78,123 +78,101 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       u32 param = pinconf_to_config_param(*config);
+-      int val, val2, err, reg, ret = 1;
++      int pullup, reg, err = -ENOTSUPP, ret = 1;
+       const struct mtk_pin_desc *desc;
+ 
++      if (pin >= hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+ 
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_get) {
+-                      err = hw->soc->bias_disable_get(hw, desc, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
+-              break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_get) {
+-                      err = hw->soc->bias_get(hw, desc, 1, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
+-              break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_get) {
+-                      err = hw->soc->bias_get(hw, desc, 0, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
++              if (!hw->soc->bias_get_combo)
++                      break;
++              err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++              if (err)
++                      break;
++              if (ret == MTK_PUPD_SET_R1R0_00)
++                      ret = MTK_DISABLE;
++              if (param == PIN_CONFIG_BIAS_DISABLE) {
++                      if (ret != MTK_DISABLE)
++                              err = -EINVAL;
++              } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
++                      if (!pullup || ret == MTK_DISABLE)
++                              err = -EINVAL;
++              } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
++                      if (pullup || ret == MTK_DISABLE)
++                              err = -EINVAL;
+               }
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
+-              if (err)
+-                      return err;
+-
+-              if (!val)
+-                      return -EINVAL;
+-
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+-      case PIN_CONFIG_OUTPUT_ENABLE:
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret);
++              if (!ret)
++                      err = -EINVAL;
++              break;
++      case PIN_CONFIG_OUTPUT:
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+-                      return err;
++                      break;
+ 
+-              /* HW takes input mode as zero; output mode as non-zero */
+-              if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
+-                  (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
+-                      return -EINVAL;
++              if (!ret) {
++                      err = -EINVAL;
++                      break;
++              }
+ 
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret);
+               break;
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+-                      return err;
+-
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
+-              if (err)
+-                      return err;
+-
+-              if (val || !val2)
+-                      return -EINVAL;
++                      break;
++              /* return error when in output mode
++               * because schmitt trigger only work in input mode
++               */
++              if (ret) {
++                      err = -EINVAL;
++                      break;
++              }
+ 
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
++              if (!ret)
++                      err = -EINVAL;
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+-              if (hw->soc->drive_get) {
+-                      err = hw->soc->drive_get(hw, desc, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      err = -ENOTSUPP;
+-              }
++              if (!hw->soc->drive_get)
++                      break;
++              err = hw->soc->drive_get(hw, desc, &ret);
+               break;
+       case MTK_PIN_CONFIG_TDSEL:
+       case MTK_PIN_CONFIG_RDSEL:
+               reg = (param == MTK_PIN_CONFIG_TDSEL) ?
+                      PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
+-
+-              err = mtk_hw_get_value(hw, desc, reg, &val);
+-              if (err)
+-                      return err;
+-
+-              ret = val;
+-
++              err = mtk_hw_get_value(hw, desc, reg, &ret);
+               break;
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+-              if (hw->soc->adv_pull_get) {
+-                      bool pullup;
+-
+-                      pullup = param == MTK_PIN_CONFIG_PU_ADV;
+-                      err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->adv_pull_get)
++                      break;
++              pullup = param == MTK_PIN_CONFIG_PU_ADV;
++              err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
+               break;
+       case MTK_PIN_CONFIG_DRV_ADV:
+-              if (hw->soc->adv_drive_get) {
+-                      err = hw->soc->adv_drive_get(hw, desc, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->adv_drive_get)
++                      break;
++              err = hw->soc->adv_drive_get(hw, desc, &ret);
+               break;
+-      default:
+-              return -ENOTSUPP;
+       }
+ 
+-      *config = pinconf_to_config_packed(param, ret);
++      if (!err)
++              *config = pinconf_to_config_packed(param, ret);
+ 
+-      return 0;
++      return err;
+ }
+ 
+ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+@@ -202,140 +180,84 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, 
unsigned int pin,
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       const struct mtk_pin_desc *desc;
+-      int err = 0;
++      int err = -ENOTSUPP;
+       u32 reg;
+ 
++      if (pin >= hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+ 
+       switch ((u32)param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_set) {
+-                      err = hw->soc->bias_disable_set(hw, desc);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->bias_set_combo)
++                      break;
++              err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_set) {
+-                      err = hw->soc->bias_set(hw, desc, 1);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->bias_set_combo)
++                      break;
++              err = hw->soc->bias_set_combo(hw, desc, 1, arg);
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_set) {
+-                      err = hw->soc->bias_set(hw, desc, 0);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
+-              break;
+-      case PIN_CONFIG_OUTPUT_ENABLE:
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+-                                     MTK_DISABLE);
+-              if (err)
+-                      goto err;
+-
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+-                                     MTK_OUTPUT);
+-              if (err)
+-                      goto err;
++              if (!hw->soc->bias_set_combo)
++                      break;
++              err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+-              if (hw->soc->ies_present) {
+-                      mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
+-                                       MTK_ENABLE);
+-              }
+-
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+-                                     MTK_INPUT);
+-              if (err)
+-                      goto err;
++              /* regard all non-zero value as enable */
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
+-                                     arg);
+-              if (err)
+-                      goto err;
+-
++              /* regard all non-zero value as enable */
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
+               break;
+       case PIN_CONFIG_OUTPUT:
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+                                      MTK_OUTPUT);
+               if (err)
+-                      goto err;
++                      break;
+ 
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
+                                      arg);
+-              if (err)
+-                      goto err;
+               break;
++      case PIN_CONFIG_INPUT_SCHMITT:
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+               /* arg = 1: Input mode & SMT enable ;
+                * arg = 0: Output mode & SMT disable
+                */
+-              arg = arg ? 2 : 1;
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+-                                     arg & 1);
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
+               if (err)
+-                      goto err;
++                      break;
+ 
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+-                                     !!(arg & 2));
+-              if (err)
+-                      goto err;
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+-              if (hw->soc->drive_set) {
+-                      err = hw->soc->drive_set(hw, desc, arg);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->drive_set)
++                      break;
++              err = hw->soc->drive_set(hw, desc, arg);
+               break;
+       case MTK_PIN_CONFIG_TDSEL:
+       case MTK_PIN_CONFIG_RDSEL:
+               reg = (param == MTK_PIN_CONFIG_TDSEL) ?
+                      PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
+-
+               err = mtk_hw_set_value(hw, desc, reg, arg);
+-              if (err)
+-                      goto err;
+               break;
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+-              if (hw->soc->adv_pull_set) {
+-                      bool pullup;
+-
+-                      pullup = param == MTK_PIN_CONFIG_PU_ADV;
+-                      err = hw->soc->adv_pull_set(hw, desc, pullup,
+-                                                  arg);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->adv_pull_set)
++                      break;
++              err = hw->soc->adv_pull_set(hw, desc,
++                                          (param == MTK_PIN_CONFIG_PU_ADV),
++                                          arg);
+               break;
+       case MTK_PIN_CONFIG_DRV_ADV:
+-              if (hw->soc->adv_drive_set) {
+-                      err = hw->soc->adv_drive_set(hw, desc, arg);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              if (!hw->soc->adv_drive_set)
++                      break;
++              err = hw->soc->adv_drive_set(hw, desc, arg);
+               break;
+-      default:
+-              err = -ENOTSUPP;
+       }
+ 
+-err:
+       return err;
+ }
+ 
+@@ -690,6 +612,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
+       const struct mtk_pin_desc *desc;
+       int value, err;
+ 
++      if (gpio >= hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+ 
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
+@@ -705,6 +630,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
+       const struct mtk_pin_desc *desc;
+       int value, err;
+ 
++      if (gpio >= hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+ 
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
+@@ -719,6 +647,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
+       struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+       const struct mtk_pin_desc *desc;
+ 
++      if (gpio >= hw->soc->npins)
++              return;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+ 
+       mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
+@@ -726,12 +657,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, 
unsigned int gpio, int value)
+ 
+ static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
+ {
++      struct mtk_pinctrl *hw = gpiochip_get_data(chip);
++
++      if (gpio >= hw->soc->npins)
++              return -EINVAL;
++
+       return pinctrl_gpio_direction_input(chip->base + gpio);
+ }
+ 
+ static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int 
gpio,
+                                    int value)
+ {
++      struct mtk_pinctrl *hw = gpiochip_get_data(chip);
++
++      if (gpio >= hw->soc->npins)
++              return -EINVAL;
++
+       mtk_gpio_set(chip, gpio, value);
+ 
+       return pinctrl_gpio_direction_output(chip->base + gpio);
+diff --git a/drivers/power/supply/rt9455_charger.c 
b/drivers/power/supply/rt9455_charger.c
+index 29161ae902456..5864b31426b8f 100644
+--- a/drivers/power/supply/rt9455_charger.c
++++ b/drivers/power/supply/rt9455_charger.c
+@@ -193,6 +193,7 @@ static const int rt9455_voreg_values[] = {
+       4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000
+ };
+ 
++#if IS_ENABLED(CONFIG_USB_PHY)
+ /*
+  * When the charger is in boost mode, REG02[7:2] represent boost output
+  * voltage.
+@@ -208,6 +209,7 @@ static const int rt9455_boost_voltage_values[] = {
+       5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
+       5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
+ };
++#endif
+ 
+ /* REG07[3:0] (VMREG) in uV */
+ static const int rt9455_vmreg_values[] = {
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 894915892eaf4..5c50e7add5779 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1708,19 +1708,24 @@ static struct regulator *create_regulator(struct 
regulator_dev *rdev,
+               }
+       }
+ 
+-      if (err != -EEXIST)
++      if (err != -EEXIST) {
+               regulator->debugfs = debugfs_create_dir(supply_name, 
rdev->debugfs);
+-      if (IS_ERR(regulator->debugfs))
+-              rdev_dbg(rdev, "Failed to create debugfs directory\n");
++              if (IS_ERR(regulator->debugfs)) {
++                      rdev_dbg(rdev, "Failed to create debugfs directory\n");
++                      regulator->debugfs = NULL;
++              }
++      }
+ 
+-      debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+-                         &regulator->uA_load);
+-      debugfs_create_u32("min_uV", 0444, regulator->debugfs,
+-                         &regulator->voltage[PM_SUSPEND_ON].min_uV);
+-      debugfs_create_u32("max_uV", 0444, regulator->debugfs,
+-                         &regulator->voltage[PM_SUSPEND_ON].max_uV);
+-      debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
+-                          regulator, &constraint_flags_fops);
++      if (regulator->debugfs) {
++              debugfs_create_u32("uA_load", 0444, regulator->debugfs,
++                                 &regulator->uA_load);
++              debugfs_create_u32("min_uV", 0444, regulator->debugfs,
++                                 &regulator->voltage[PM_SUSPEND_ON].min_uV);
++              debugfs_create_u32("max_uV", 0444, regulator->debugfs,
++                                 &regulator->voltage[PM_SUSPEND_ON].max_uV);
++              debugfs_create_file("constraint_flags", 0444, 
regulator->debugfs,
++                                  regulator, &constraint_flags_fops);
++      }
+ 
+       /*
+        * Check now if the regulator is an always on regulator - if
+diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c 
b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
+index 50384b4a817c8..5b184c8384d05 100644
+--- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c
++++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
+@@ -834,7 +834,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba 
*hba,
+ 
+       BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n");
+ 
+-      spin_lock_bh(&tgt->cq_lock);
+       ctx_base_ptr = tgt->ctx_base;
+       tgt->ctx_base = NULL;
+ 
+@@ -890,7 +889,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba 
*hba,
+                                   tgt->sq, tgt->sq_dma);
+               tgt->sq = NULL;
+       }
+-      spin_unlock_bh(&tgt->cq_lock);
+ 
+       if (ctx_base_ptr)
+               iounmap(ctx_base_ptr);
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
+index 7ce0d94cdc018..98ab07c3774ed 100644
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -1039,7 +1039,6 @@ struct lpfc_hba {
+       unsigned long bit_flags;
+ #define       FABRIC_COMANDS_BLOCKED  0
+       atomic_t num_rsrc_err;
+-      atomic_t num_cmd_success;
+       unsigned long last_rsrc_error_time;
+       unsigned long last_ramp_down_time;
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index 816235ccd2992..f238e0f41f07c 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -246,11 +246,10 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
+       struct Scsi_Host  *shost;
+       struct scsi_device *sdev;
+       unsigned long new_queue_depth;
+-      unsigned long num_rsrc_err, num_cmd_success;
++      unsigned long num_rsrc_err;
+       int i;
+ 
+       num_rsrc_err = atomic_read(&phba->num_rsrc_err);
+-      num_cmd_success = atomic_read(&phba->num_cmd_success);
+ 
+       /*
+        * The error and success command counters are global per
+@@ -265,20 +264,16 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
+               for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
+                       shost = lpfc_shost_from_vport(vports[i]);
+                       shost_for_each_device(sdev, shost) {
+-                              new_queue_depth =
+-                                      sdev->queue_depth * num_rsrc_err /
+-                                      (num_rsrc_err + num_cmd_success);
+-                              if (!new_queue_depth)
+-                                      new_queue_depth = sdev->queue_depth - 1;
++                              if (num_rsrc_err >= sdev->queue_depth)
++                                      new_queue_depth = 1;
+                               else
+                                       new_queue_depth = sdev->queue_depth -
+-                                                              new_queue_depth;
++                                              num_rsrc_err;
+                               scsi_change_queue_depth(sdev, new_queue_depth);
+                       }
+               }
+       lpfc_destroy_vport_work_array(phba, vports);
+       atomic_set(&phba->num_rsrc_err, 0);
+-      atomic_set(&phba->num_cmd_success, 0);
+ }
+ 
+ /**
+diff --git a/drivers/target/target_core_configfs.c 
b/drivers/target/target_core_configfs.c
+index e6e1755978602..4edabab65b879 100644
+--- a/drivers/target/target_core_configfs.c
++++ b/drivers/target/target_core_configfs.c
+@@ -3458,6 +3458,8 @@ static int __init target_core_init_configfs(void)
+ {
+       struct configfs_subsystem *subsys = &target_core_fabrics;
+       struct t10_alua_lu_gp *lu_gp;
++      struct cred *kern_cred;
++      const struct cred *old_cred;
+       int ret;
+ 
+       pr_debug("TARGET_CORE[0]: Loading Generic Kernel Storage"
+@@ -3534,11 +3536,21 @@ static int __init target_core_init_configfs(void)
+       if (ret < 0)
+               goto out;
+ 
++      /* We use the kernel credentials to access the target directory */
++      kern_cred = prepare_kernel_cred(&init_task);
++      if (!kern_cred) {
++              ret = -ENOMEM;
++              goto out;
++      }
++      old_cred = override_creds(kern_cred);
+       target_init_dbroot();
++      revert_creds(old_cred);
++      put_cred(kern_cred);
+ 
+       return 0;
+ 
+ out:
++      target_xcopy_release_pt();
+       configfs_unregister_subsystem(subsys);
+       core_dev_release_virtual_lun0();
+       rd_module_exit();
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index a3106b179562c..17ae3b394469c 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -1925,7 +1925,7 @@ composite_setup(struct usb_gadget *gadget, const struct 
usb_ctrlrequest *ctrl)
+                       buf[5] = 0x01;
+                       switch (ctrl->bRequestType & USB_RECIP_MASK) {
+                       case USB_RECIP_DEVICE:
+-                              if (w_index != 0x4 || (w_value >> 8))
++                              if (w_index != 0x4 || (w_value & 0xff))
+                                       break;
+                               buf[6] = w_index;
+                               /* Number of ext compat interfaces */
+@@ -1941,9 +1941,9 @@ composite_setup(struct usb_gadget *gadget, const struct 
usb_ctrlrequest *ctrl)
+                               }
+                               break;
+                       case USB_RECIP_INTERFACE:
+-                              if (w_index != 0x5 || (w_value >> 8))
++                              if (w_index != 0x5 || (w_value & 0xff))
+                                       break;
+-                              interface = w_value & 0xFF;
++                              interface = w_value >> 8;
+                               if (interface >= MAX_CONFIG_INTERFACES ||
+                                   !os_desc_cfg->interface[interface])
+                                       break;
+diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
+index 588a659f245e6..1cf4f4bee019b 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -3422,7 +3422,7 @@ static int ffs_func_setup(struct usb_function *f,
+       __ffs_event_add(ffs, FUNCTIONFS_SETUP);
+       spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
+ 
+-      return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
++      return ffs->ev.setup.wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
+ }
+ 
+ static bool ffs_func_req_match(struct usb_function *f,
+diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
+index ee9cabac12041..14d6cb0316212 100644
+--- a/fs/9p/vfs_file.c
++++ b/fs/9p/vfs_file.c
+@@ -676,6 +676,7 @@ const struct file_operations v9fs_file_operations = {
+       .lock = v9fs_file_lock,
+       .mmap = generic_file_readonly_mmap,
+       .fsync = v9fs_file_fsync,
++      .setlease = simple_nosetlease,
+ };
+ 
+ const struct file_operations v9fs_file_operations_dotl = {
+@@ -711,4 +712,5 @@ const struct file_operations 
v9fs_mmap_file_operations_dotl = {
+       .flock = v9fs_file_flock_dotl,
+       .mmap = v9fs_mmap_file_mmap,
+       .fsync = v9fs_file_fsync_dotl,
++      .setlease = simple_nosetlease,
+ };
+diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
+index b82423a72f685..ffce168296bd3 100644
+--- a/fs/9p/vfs_inode.c
++++ b/fs/9p/vfs_inode.c
+@@ -86,7 +86,7 @@ static int p9mode2perm(struct v9fs_session_info *v9ses,
+       int res;
+       int mode = stat->mode;
+ 
+-      res = mode & S_IALLUGO;
++      res = mode & 0777; /* S_IRWXUGO */
+       if (v9fs_proto_dotu(v9ses)) {
+               if ((mode & P9_DMSETUID) == P9_DMSETUID)
+                       res |= S_ISUID;
+@@ -177,6 +177,9 @@ int v9fs_uflags2omode(int uflags, int extended)
+               break;
+       }
+ 
++      if (uflags & O_TRUNC)
++              ret |= P9_OTRUNC;
++
+       if (extended) {
+               if (uflags & O_EXCL)
+                       ret |= P9_OEXCL;
+diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
+index 74df32be4c6a5..46e58fdf9ba54 100644
+--- a/fs/9p/vfs_super.c
++++ b/fs/9p/vfs_super.c
+@@ -335,6 +335,7 @@ static const struct super_operations v9fs_super_ops = {
+       .alloc_inode = v9fs_alloc_inode,
+       .free_inode = v9fs_free_inode,
+       .statfs = simple_statfs,
++      .drop_inode = v9fs_drop_inode,
+       .evict_inode = v9fs_evict_inode,
+       .show_options = v9fs_show_options,
+       .umount_begin = v9fs_umount_begin,
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index c89e85a7da7d4..2c86be3fc25cd 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -2051,7 +2051,7 @@ void btrfs_clear_delalloc_extent(struct inode *vfs_inode,
+                */
+               if (*bits & EXTENT_CLEAR_META_RESV &&
+                   root != fs_info->tree_root)
+-                      btrfs_delalloc_release_metadata(inode, len, false);
++                      btrfs_delalloc_release_metadata(inode, len, true);
+ 
+               /* For sanity tests. */
+               if (btrfs_is_testing(fs_info))
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index 89ffc02554069..1d25bf0c55ccf 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -1226,6 +1226,7 @@ static noinline int commit_fs_roots(struct 
btrfs_trans_handle *trans)
+                       radix_tree_tag_clear(&fs_info->fs_roots_radix,
+                                       (unsigned long)root->root_key.objectid,
+                                       BTRFS_ROOT_TRANS_TAG);
++                      btrfs_qgroup_free_meta_all_pertrans(root);
+                       spin_unlock(&fs_info->fs_roots_radix_lock);
+ 
+                       btrfs_free_log(trans, root);
+@@ -1250,7 +1251,6 @@ static noinline int commit_fs_roots(struct 
btrfs_trans_handle *trans)
+                       if (ret2)
+                               return ret2;
+                       spin_lock(&fs_info->fs_roots_radix_lock);
+-                      btrfs_qgroup_free_meta_all_pertrans(root);
+               }
+       }
+       spin_unlock(&fs_info->fs_roots_radix_lock);
+diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
+index 63e925aa12a75..1dc0f0bca3ab3 100644
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -1760,7 +1760,8 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, 
u64 length)
+       struct buffer_head *dibh, *bh;
+       struct gfs2_holder rd_gh;
+       unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift;
+-      u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift;
++      unsigned int bsize = 1 << bsize_shift;
++      u64 lblock = (offset + bsize - 1) >> bsize_shift;
+       __u16 start_list[GFS2_MAX_META_HEIGHT];
+       __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL;
+       unsigned int start_aligned, end_aligned;
+@@ -1771,7 +1772,7 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, 
u64 length)
+       u64 prev_bnr = 0;
+       __be64 *start, *end;
+ 
+-      if (offset >= maxsize) {
++      if (offset + bsize - 1 >= maxsize) {
+               /*
+                * The starting point lies beyond the allocated meta-data;
+                * there are no blocks do deallocate.
+diff --git a/fs/nfs/client.c b/fs/nfs/client.c
+index 35abe63655a9d..323cef064f2a4 100644
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -72,7 +72,6 @@ const struct rpc_program nfs_program = {
+       .number                 = NFS_PROGRAM,
+       .nrvers                 = ARRAY_SIZE(nfs_version),
+       .version                = nfs_version,
+-      .stats                  = &nfs_rpcstat,
+       .pipe_dir_name          = NFS_PIPE_DIRNAME,
+ };
+ 
+@@ -492,6 +491,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
+                         const struct nfs_client_initdata *cl_init,
+                         rpc_authflavor_t flavor)
+ {
++      struct nfs_net          *nn = net_generic(clp->cl_net, nfs_net_id);
+       struct rpc_clnt         *clnt = NULL;
+       struct rpc_create_args args = {
+               .net            = clp->cl_net,
+@@ -503,6 +503,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
+               .servername     = clp->cl_hostname,
+               .nodename       = cl_init->nodename,
+               .program        = &nfs_program,
++              .stats          = &nn->rpcstats,
+               .version        = clp->rpc_ops->version,
+               .authflavor     = flavor,
+               .cred           = cl_init->cred,
+@@ -1077,6 +1078,8 @@ void nfs_clients_init(struct net *net)
+ #endif
+       spin_lock_init(&nn->nfs_client_lock);
+       nn->boot_time = ktime_get_real();
++      memset(&nn->rpcstats, 0, sizeof(nn->rpcstats));
++      nn->rpcstats.program = &nfs_program;
+ 
+       nfs_netns_sysfs_setup(nn, net);
+ }
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 3bddf5332b6d6..6a7a3b1d926ea 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2178,12 +2178,21 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
+ 
+ static int nfs_net_init(struct net *net)
+ {
++      struct nfs_net *nn = net_generic(net, nfs_net_id);
++
+       nfs_clients_init(net);
++
++      if (!rpc_proc_register(net, &nn->rpcstats)) {
++              nfs_clients_exit(net);
++              return -ENOMEM;
++      }
++
+       return nfs_fs_proc_net_init(net);
+ }
+ 
+ static void nfs_net_exit(struct net *net)
+ {
++      rpc_proc_unregister(net, "nfs");
+       nfs_fs_proc_net_exit(net);
+       nfs_clients_exit(net);
+ }
+@@ -2242,15 +2251,12 @@ static int __init init_nfs_fs(void)
+       if (err)
+               goto out1;
+ 
+-      rpc_proc_register(&init_net, &nfs_rpcstat);
+-
+       err = register_nfs_fs();
+       if (err)
+               goto out0;
+ 
+       return 0;
+ out0:
+-      rpc_proc_unregister(&init_net, "nfs");
+       nfs_destroy_directcache();
+ out1:
+       nfs_destroy_writepagecache();
+@@ -2283,7 +2289,6 @@ static void __exit exit_nfs_fs(void)
+       nfs_destroy_nfspagecache();
+       nfs_fscache_unregister();
+       unregister_pernet_subsys(&nfs_net_ops);
+-      rpc_proc_unregister(&init_net, "nfs");
+       unregister_nfs_fs();
+       nfs_fs_proc_exit();
+       nfsiod_stop();
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index fcd35c98a9377..fb28750da761f 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -405,8 +405,6 @@ struct dentry * nfs_xdev_mount_common(struct 
file_system_type *, int,
+ void nfs_kill_super(struct super_block *);
+ void nfs_fill_super(struct super_block *, struct nfs_mount_info *);
+ 
+-extern struct rpc_stat nfs_rpcstat;
+-
+ extern int __init register_nfs_fs(void);
+ extern void __exit unregister_nfs_fs(void);
+ extern bool nfs_sb_active(struct super_block *sb);
+diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
+index c8374f74dce11..a68b21603ea9a 100644
+--- a/fs/nfs/netns.h
++++ b/fs/nfs/netns.h
+@@ -9,6 +9,7 @@
+ #include <linux/nfs4.h>
+ #include <net/net_namespace.h>
+ #include <net/netns/generic.h>
++#include <linux/sunrpc/stats.h>
+ 
+ struct bl_dev_msg {
+       int32_t status;
+@@ -34,6 +35,7 @@ struct nfs_net {
+       struct nfs_netns_client *nfs_client;
+       spinlock_t nfs_client_lock;
+       ktime_t boot_time;
++      struct rpc_stat rpcstats;
+ #ifdef CONFIG_PROC_FS
+       struct proc_dir_entry *proc_nfsfs;
+ #endif
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 302a2ad679809..29ccc33a1c627 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -2576,6 +2576,21 @@ static inline void skb_mac_header_rebuild(struct 
sk_buff *skb)
+       }
+ }
+ 
++/* Move the full mac header up to current network_header.
++ * Leaves skb->data pointing at offset skb->mac_len into the mac_header.
++ * Must be provided the complete mac header length.
++ */
++static inline void skb_mac_header_rebuild_full(struct sk_buff *skb, u32 
full_mac_len)
++{
++      if (skb_mac_header_was_set(skb)) {
++              const unsigned char *old_mac = skb_mac_header(skb);
++
++              skb_set_mac_header(skb, -full_mac_len);
++              memmove(skb_mac_header(skb), old_mac, full_mac_len);
++              __skb_push(skb, full_mac_len - skb->mac_len);
++      }
++}
++
+ static inline int skb_checksum_start_offset(const struct sk_buff *skb)
+ {
+       return skb->csum_start - skb_headroom(skb);
+diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
+index 336802acc629b..18d4cf2d637b6 100644
+--- a/include/linux/sunrpc/clnt.h
++++ b/include/linux/sunrpc/clnt.h
+@@ -121,6 +121,7 @@ struct rpc_create_args {
+       const char              *servername;
+       const char              *nodename;
+       const struct rpc_program *program;
++      struct rpc_stat         *stats;
+       u32                     prognumber;     /* overrides program->number */
+       u32                     version;
+       rpc_authflavor_t        authflavor;
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 96faf09186945..4368dcb709f4e 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -1024,6 +1024,9 @@ struct xfrm_offload {
+ #define CRYPTO_INVALID_PACKET_SYNTAX          64
+ #define CRYPTO_INVALID_PROTOCOL                       128
+ 
++      /* Used to keep whole l2 header for transport mode GRO */
++      __u32                   orig_mac_len;
++
+       __u8                    proto;
+ };
+ 
+diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
+index 1ce2fa9dc5adc..5cb1e7e02a549 100644
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -244,7 +244,11 @@ static int ddebug_tokenize(char *buf, char *words[], int 
maxwords)
+               } else {
+                       for (end = buf; *end && !isspace(*end); end++)
+                               ;
+-                      BUG_ON(end == buf);
++                      if (end == buf) {
++                              pr_err("parse err after word:%d=%s\n", nwords,
++                                     nwords ? words[nwords - 1] : "<none>");
++                              return -EINVAL;
++                      }
+               }
+ 
+               /* `buf' is start of word, `end' is one past its end */
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 9c06f5ffd1b5f..8709c4506343f 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -434,6 +434,9 @@ static void l2cap_chan_timeout(struct work_struct *work)
+ 
+       BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
+ 
++      if (!conn)
++              return;
++
+       mutex_lock(&conn->chan_lock);
+       /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
+        * this work. No need to call l2cap_chan_hold(chan) here again.
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index a3b15b4e176ea..4c81883ba25e3 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -82,6 +82,10 @@ static void sco_sock_timeout(struct work_struct *work)
+       struct sock *sk;
+ 
+       sco_conn_lock(conn);
++      if (!conn->hcon) {
++              sco_conn_unlock(conn);
++              return;
++      }
+       sk = conn->sk;
+       if (sk)
+               sock_hold(sk);
+diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
+index 4f8eb83976f10..460d578fae4df 100644
+--- a/net/bridge/br_forward.c
++++ b/net/bridge/br_forward.c
+@@ -245,6 +245,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, 
struct sk_buff *skb,
+ {
+       struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
+       const unsigned char *src = eth_hdr(skb)->h_source;
++      struct sk_buff *nskb;
+ 
+       if (!should_deliver(p, skb))
+               return;
+@@ -253,12 +254,16 @@ static void maybe_deliver_addr(struct net_bridge_port 
*p, struct sk_buff *skb,
+       if (skb->dev == p->dev && ether_addr_equal(src, addr))
+               return;
+ 
+-      skb = skb_copy(skb, GFP_ATOMIC);
+-      if (!skb) {
++      __skb_push(skb, ETH_HLEN);
++      nskb = pskb_copy(skb, GFP_ATOMIC);
++      __skb_pull(skb, ETH_HLEN);
++      if (!nskb) {
+               DEV_STATS_INC(dev, tx_dropped);
+               return;
+       }
+ 
++      skb = nskb;
++      __skb_pull(skb, ETH_HLEN);
+       if (!is_broadcast_ether_addr(addr))
+               memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
+ 
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index 534a53124d14c..5827de79610b9 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -71,12 +71,15 @@ static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS;
+ 
+ static struct net_generic *net_alloc_generic(void)
+ {
++      unsigned int gen_ptrs = READ_ONCE(max_gen_ptrs);
++      unsigned int generic_size;
+       struct net_generic *ng;
+-      unsigned int generic_size = offsetof(struct net_generic, 
ptr[max_gen_ptrs]);
++
++      generic_size = offsetof(struct net_generic, ptr[gen_ptrs]);
+ 
+       ng = kzalloc(generic_size, GFP_KERNEL);
+       if (ng)
+-              ng->s.len = max_gen_ptrs;
++              ng->s.len = gen_ptrs;
+ 
+       return ng;
+ }
+@@ -1231,7 +1234,11 @@ static int register_pernet_operations(struct list_head 
*list,
+               if (error < 0)
+                       return error;
+               *ops->id = error;
+-              max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1);
++              /* This does not require READ_ONCE as writers already hold
++               * pernet_ops_rwsem. But WRITE_ONCE is needed to protect
++               * net_alloc_generic.
++               */
++              WRITE_ONCE(max_gen_ptrs, max(max_gen_ptrs, *ops->id + 1));
+       }
+       error = __register_pernet_operations(list, ops);
+       if (error) {
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index ee599636f817f..2b7ad5cf8fbfd 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -2252,7 +2252,7 @@ static int do_setvfinfo(struct net_device *dev, struct 
nlattr **tb)
+ 
+               nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) {
+                       if (nla_type(attr) != IFLA_VF_VLAN_INFO ||
+-                          nla_len(attr) < NLA_HDRLEN) {
++                          nla_len(attr) < sizeof(struct ifla_vf_vlan_info)) {
+                               return -EINVAL;
+                       }
+                       if (len >= MAX_VLAN_LIST_LEN)
+diff --git a/net/core/sock.c b/net/core/sock.c
+index daeb0e69c71b4..2b68a93adfa8d 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -453,7 +453,7 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff 
*skb)
+       unsigned long flags;
+       struct sk_buff_head *list = &sk->sk_receive_queue;
+ 
+-      if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) {
++      if (atomic_read(&sk->sk_rmem_alloc) >= READ_ONCE(sk->sk_rcvbuf)) {
+               atomic_inc(&sk->sk_drops);
+               trace_sock_rcvqueue_full(sk, skb);
+               return -ENOMEM;
+@@ -505,7 +505,7 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+ 
+       skb->dev = NULL;
+ 
+-      if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) {
++      if (sk_rcvqueues_full(sk, READ_ONCE(sk->sk_rcvbuf))) {
+               atomic_inc(&sk->sk_drops);
+               goto discard_and_relse;
+       }
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index ca7863f722187..9a4a3f6d9cb06 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2331,7 +2331,7 @@ void tcp_shutdown(struct sock *sk, int how)
+       /* If we've already sent a FIN, or it's a closed state, skip this. */
+       if ((1 << sk->sk_state) &
+           (TCPF_ESTABLISHED | TCPF_SYN_SENT |
+-           TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) {
++           TCPF_CLOSE_WAIT)) {
+               /* Clear out any half completed packets.  FIN if needed. */
+               if (tcp_close_state(sk))
+                       tcp_send_fin(sk);
+@@ -2416,7 +2416,7 @@ void __tcp_close(struct sock *sk, long timeout)
+                * machine. State transitions:
+                *
+                * TCP_ESTABLISHED -> TCP_FIN_WAIT1
+-               * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible)
++               * TCP_SYN_RECV -> TCP_FIN_WAIT1 (it is difficult)
+                * TCP_CLOSE_WAIT -> TCP_LAST_ACK
+                *
+                * are legal only when FIN has been sent (i.e. in window),
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 61243531a7f4c..87a10bb11eb0b 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -6342,6 +6342,8 @@ int tcp_rcv_state_process(struct sock *sk, struct 
sk_buff *skb)
+ 
+               tcp_initialize_rcv_mss(sk);
+               tcp_fast_path_on(tp);
++              if (sk->sk_shutdown & SEND_SHUTDOWN)
++                      tcp_shutdown(sk, SEND_SHUTDOWN);
+               break;
+ 
+       case TCP_FIN_WAIT1: {
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index a54505c29a5c2..0dd917c5a7da6 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -152,6 +152,12 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, 
void *twp)
+       if (tcptw->tw_ts_recent_stamp &&
+           (!twp || (reuse && time_after32(ktime_get_seconds(),
+                                           tcptw->tw_ts_recent_stamp)))) {
++              /* inet_twsk_hashdance() sets sk_refcnt after putting twsk
++               * and releasing the bucket lock.
++               */
++              if (unlikely(!refcount_inc_not_zero(&sktw->sk_refcnt)))
++                      return 0;
++
+               /* In case of repair and re-using TIME-WAIT sockets we still
+                * want to be sure that it is safe as above but honor the
+                * sequence numbers and time stamps set as part of the repair
+@@ -172,7 +178,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, 
void *twp)
+                       tp->rx_opt.ts_recent       = tcptw->tw_ts_recent;
+                       tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
+               }
+-              sock_hold(sktw);
++
+               return 1;
+       }
+ 
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 6d7f441c7dd76..4f203cbbc99b5 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -3210,7 +3210,9 @@ void tcp_send_fin(struct sock *sk)
+                       return;
+               }
+       } else {
+-              skb = alloc_skb_fclone(MAX_TCP_HEADER, sk->sk_allocation);
++              skb = alloc_skb_fclone(MAX_TCP_HEADER,
++                                     sk_gfp_mask(sk, GFP_ATOMIC |
++                                                     __GFP_NOWARN));
+               if (unlikely(!skb))
+                       return;
+ 
+diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
+index f8de2482a5292..9b062f2e45695 100644
+--- a/net/ipv4/xfrm4_input.c
++++ b/net/ipv4/xfrm4_input.c
+@@ -66,7 +66,11 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
+       ip_send_check(iph);
+ 
+       if (xo && (xo->flags & XFRM_GRO)) {
+-              skb_mac_header_rebuild(skb);
++              /* The full l2 header needs to be preserved so that 
re-injecting the packet at l2
++               * works correctly in the presence of vlan tags.
++               */
++              skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
++              skb_reset_network_header(skb);
+               skb_reset_transport_header(skb);
+               return 0;
+       }
+diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
+index cdc8a49d7fc34..3cf9dc2231036 100644
+--- a/net/ipv6/fib6_rules.c
++++ b/net/ipv6/fib6_rules.c
+@@ -227,8 +227,12 @@ static int __fib6_rule_action(struct fib_rule *rule, 
struct flowi *flp,
+ 
+       rt = lookup(net, table, flp6, arg->lookup_data, flags);
+       if (rt != net->ipv6.ip6_null_entry) {
++              struct inet6_dev *idev = ip6_dst_idev(&rt->dst);
++
++              if (!idev)
++                      goto again;
+               err = fib6_rule_saddr(net, rule, flags, flp6,
+-                                    ip6_dst_idev(&rt->dst)->dev);
++                                    idev->dev);
+ 
+               if (err == -EAGAIN)
+                       goto again;
+diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
+index a52cb3fc6df5a..c12d51f5b5893 100644
+--- a/net/ipv6/xfrm6_input.c
++++ b/net/ipv6/xfrm6_input.c
+@@ -58,7 +58,11 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
+       skb_postpush_rcsum(skb, skb_network_header(skb), nhlen);
+ 
+       if (xo && (xo->flags & XFRM_GRO)) {
+-              skb_mac_header_rebuild(skb);
++              /* The full l2 header needs to be preserved so that 
re-injecting the packet at l2
++               * works correctly in the presence of vlan tags.
++               */
++              skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
++              skb_reset_network_header(skb);
+               skb_reset_transport_header(skb);
+               return -1;
+       }
+diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
+index d3b520b9b2c9d..2c5853597aa90 100644
+--- a/net/l2tp/l2tp_eth.c
++++ b/net/l2tp/l2tp_eth.c
+@@ -149,6 +149,9 @@ static void l2tp_eth_dev_recv(struct l2tp_session 
*session, struct sk_buff *skb,
+       /* checksums verified by L2TP */
+       skb->ip_summed = CHECKSUM_NONE;
+ 
++      /* drop outer flow-hash */
++      skb_clear_hash(skb);
++
+       skb_dst_drop(skb);
+       nf_reset_ct(skb);
+ 
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 3b7151501b3ed..e26368fab65d6 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -110,7 +110,7 @@ struct ieee80211_bss {
+ };
+ 
+ /**
+- * enum ieee80211_corrupt_data_flags - BSS data corruption flags
++ * enum ieee80211_bss_corrupt_data_flags - BSS data corruption flags
+  * @IEEE80211_BSS_CORRUPT_BEACON: last beacon frame received was corrupted
+  * @IEEE80211_BSS_CORRUPT_PROBE_RESP: last probe response received was 
corrupted
+  *
+@@ -123,7 +123,7 @@ enum ieee80211_bss_corrupt_data_flags {
+ };
+ 
+ /**
+- * enum ieee80211_valid_data_flags - BSS valid data flags
++ * enum ieee80211_bss_valid_data_flags - BSS valid data flags
+  * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE
+  * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt 
IE
+  * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE
+diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c
+index 0f23e5e8e03eb..3e0fc71d95a14 100644
+--- a/net/nsh/nsh.c
++++ b/net/nsh/nsh.c
+@@ -76,13 +76,15 @@ EXPORT_SYMBOL_GPL(nsh_pop);
+ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
+                                      netdev_features_t features)
+ {
++      unsigned int outer_hlen, mac_len, nsh_len;
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
+       u16 mac_offset = skb->mac_header;
+-      unsigned int nsh_len, mac_len;
+-      __be16 proto;
++      __be16 outer_proto, proto;
+ 
+       skb_reset_network_header(skb);
+ 
++      outer_proto = skb->protocol;
++      outer_hlen = skb_mac_header_len(skb);
+       mac_len = skb->mac_len;
+ 
+       if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
+@@ -112,10 +114,10 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff 
*skb,
+       }
+ 
+       for (skb = segs; skb; skb = skb->next) {
+-              skb->protocol = htons(ETH_P_NSH);
+-              __skb_push(skb, nsh_len);
+-              skb->mac_header = mac_offset;
+-              skb->network_header = skb->mac_header + mac_len;
++              skb->protocol = outer_proto;
++              __skb_push(skb, nsh_len + outer_hlen);
++              skb_reset_mac_header(skb);
++              skb_set_network_header(skb, outer_hlen);
+               skb->mac_len = mac_len;
+       }
+ 
+diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
+index 59aebe2968907..dd4c7e9a634fb 100644
+--- a/net/phonet/pn_netlink.c
++++ b/net/phonet/pn_netlink.c
+@@ -193,7 +193,7 @@ void rtm_phonet_notify(int event, struct net_device *dev, 
u8 dst)
+       struct sk_buff *skb;
+       int err = -ENOBUFS;
+ 
+-      skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
++      skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct rtmsg)) +
+                       nla_total_size(1) + nla_total_size(4), GFP_KERNEL);
+       if (skb == NULL)
+               goto errout;
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 9071dc6928ac2..c6fe108845e8b 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -400,7 +400,7 @@ static struct rpc_clnt * rpc_new_client(const struct 
rpc_create_args *args,
+       clnt->cl_maxproc  = version->nrprocs;
+       clnt->cl_prog     = args->prognumber ? : program->number;
+       clnt->cl_vers     = version->number;
+-      clnt->cl_stats    = program->stats;
++      clnt->cl_stats    = args->stats ? : program->stats;
+       clnt->cl_metrics  = rpc_alloc_iostats(clnt);
+       rpc_init_pipe_dir_head(&clnt->cl_pipedir_objects);
+       err = -ENOMEM;
+@@ -666,6 +666,7 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
+               .version        = clnt->cl_vers,
+               .authflavor     = clnt->cl_auth->au_flavor,
+               .cred           = clnt->cl_cred,
++              .stats          = clnt->cl_stats,
+       };
+       return __rpc_clone_client(&args, clnt);
+ }
+@@ -688,6 +689,7 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, 
rpc_authflavor_t flavor)
+               .version        = clnt->cl_vers,
+               .authflavor     = flavor,
+               .cred           = clnt->cl_cred,
++              .stats          = clnt->cl_stats,
+       };
+       return __rpc_clone_client(&args, clnt);
+ }
+@@ -961,6 +963,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
+               .version        = vers,
+               .authflavor     = old->cl_auth->au_flavor,
+               .cred           = old->cl_cred,
++              .stats          = old->cl_stats,
+       };
+       struct rpc_clnt *clnt;
+       int err;
+diff --git a/net/tipc/msg.c b/net/tipc/msg.c
+index e4ea942873d49..ff167decbef16 100644
+--- a/net/tipc/msg.c
++++ b/net/tipc/msg.c
+@@ -140,9 +140,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct 
sk_buff **buf)
+       if (fragid == FIRST_FRAGMENT) {
+               if (unlikely(head))
+                       goto err;
+-              *buf = NULL;
+               if (skb_has_frag_list(frag) && __skb_linearize(frag))
+                       goto err;
++              *buf = NULL;
+               frag = skb_unshare(frag, GFP_ATOMIC);
+               if (unlikely(!frag))
+                       goto err;
+@@ -154,6 +154,11 @@ int tipc_buf_append(struct sk_buff **headbuf, struct 
sk_buff **buf)
+       if (!head)
+               goto err;
+ 
++      /* Either the input skb ownership is transferred to headskb
++       * or the input skb is freed, clear the reference to avoid
++       * bad access on error path.
++       */
++      *buf = NULL;
+       if (skb_try_coalesce(head, frag, &headstolen, &delta)) {
+               kfree_skb_partial(frag, headstolen);
+       } else {
+@@ -177,7 +182,6 @@ int tipc_buf_append(struct sk_buff **headbuf, struct 
sk_buff **buf)
+               *headbuf = NULL;
+               return 1;
+       }
+-      *buf = NULL;
+       return 0;
+ err:
+       kfree_skb(*buf);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index c698fc458f5f9..0d15dd68565cb 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -12023,6 +12023,8 @@ static int nl80211_set_coalesce(struct sk_buff *skb, 
struct genl_info *info)
+ error:
+       for (i = 0; i < new_coalesce.n_rules; i++) {
+               tmp_rule = &new_coalesce.rules[i];
++              if (!tmp_rule)
++                      continue;
+               for (j = 0; j < tmp_rule->n_patterns; j++)
+                       kfree(tmp_rule->patterns[j].mask);
+               kfree(tmp_rule->patterns);
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 8677d7ab7d692..630b72355ebb5 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -938,7 +938,7 @@ TRACE_EVENT(rdev_get_mpp,
+ TRACE_EVENT(rdev_dump_mpp,
+       TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx,
+                u8 *dst, u8 *mpp),
+-      TP_ARGS(wiphy, netdev, _idx, mpp, dst),
++      TP_ARGS(wiphy, netdev, _idx, dst, mpp),
+       TP_STRUCT__entry(
+               WIPHY_ENTRY
+               NETDEV_ENTRY
+diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
+index 4d8d7cf3d1994..2e7fd0aa5f373 100644
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -394,11 +394,15 @@ static int xfrm_prepare_input(struct xfrm_state *x, 
struct sk_buff *skb)
+  */
+ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
+ {
++      struct xfrm_offload *xo = xfrm_offload(skb);
+       int ihl = skb->data - skb_transport_header(skb);
+ 
+       if (skb->transport_header != skb->network_header) {
+               memmove(skb_transport_header(skb),
+                       skb_network_header(skb), ihl);
++              if (xo)
++                      xo->orig_mac_len =
++                              skb_mac_header_was_set(skb) ? 
skb_mac_header_len(skb) : 0;
+               skb->network_header = skb->transport_header;
+       }
+       ip_hdr(skb)->tot_len = htons(skb->len + ihl);
+@@ -409,11 +413,15 @@ static int xfrm4_transport_input(struct xfrm_state *x, 
struct sk_buff *skb)
+ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
+ {
+ #if IS_ENABLED(CONFIG_IPV6)
++      struct xfrm_offload *xo = xfrm_offload(skb);
+       int ihl = skb->data - skb_transport_header(skb);
+ 
+       if (skb->transport_header != skb->network_header) {
+               memmove(skb_transport_header(skb),
+                       skb_network_header(skb), ihl);
++              if (xo)
++                      xo->orig_mac_len =
++                              skb_mac_header_was_set(skb) ? 
skb_mac_header_len(skb) : 0;
+               skb->network_header = skb->transport_header;
+       }
+       ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
+index 22104cb84b1ca..efa8fb59d3ad2 100644
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -201,7 +201,7 @@ int line6_send_raw_message_async(struct usb_line6 *line6, 
const char *buffer,
+       struct urb *urb;
+ 
+       /* create message: */
+-      msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
++      msg = kzalloc(sizeof(struct message), GFP_ATOMIC);
+       if (msg == NULL)
+               return -ENOMEM;
+ 
+@@ -679,7 +679,7 @@ static int line6_init_cap_control(struct usb_line6 *line6)
+       int ret;
+ 
+       /* initialize USB buffers: */
+-      line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
++      line6->buffer_listen = kzalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+       if (!line6->buffer_listen)
+               return -ENOMEM;
+ 
+@@ -688,7 +688,7 @@ static int line6_init_cap_control(struct usb_line6 *line6)
+               return -ENOMEM;
+ 
+       if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
+-              line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, 
GFP_KERNEL);
++              line6->buffer_message = kzalloc(LINE6_MIDI_MESSAGE_MAXLEN, 
GFP_KERNEL);
+               if (!line6->buffer_message)
+                       return -ENOMEM;
+ 
+diff --git a/tools/power/x86/turbostat/turbostat.8 
b/tools/power/x86/turbostat/turbostat.8
+index a6db83a88e852..25a560c41321d 100644
+--- a/tools/power/x86/turbostat/turbostat.8
++++ b/tools/power/x86/turbostat/turbostat.8
+@@ -318,7 +318,7 @@ below the processor's base frequency.
+ 
+ Busy% = MPERF_delta/TSC_delta
+ 
+-Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval
++Bzy_MHz = TSC_delta*APERF_delta/MPERF_delta/measurement_interval
+ 
+ Note that these calculations depend on TSC_delta, so they
+ are not reliable during intervals when TSC_MHz is not running at the base 
frequency.
+diff --git a/tools/power/x86/turbostat/turbostat.c 
b/tools/power/x86/turbostat/turbostat.c
+index d4235d1ab912c..8a366b1d1dd91 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -1571,9 +1571,10 @@ int sum_counters(struct thread_data *t, struct 
core_data *c,
+       average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
+ 
+       for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
+-              if (mp->format == FORMAT_RAW)
+-                      continue;
+-              average.packages.counter[i] += p->counter[i];
++              if ((mp->format == FORMAT_RAW) && (topo.num_packages == 0))
++                      average.packages.counter[i] = p->counter[i];
++              else
++                      average.packages.counter[i] += p->counter[i];
+       }
+       return 0;
+ }
+diff --git a/tools/testing/selftests/timers/valid-adjtimex.c 
b/tools/testing/selftests/timers/valid-adjtimex.c
+index 48b9a803235a8..d13ebde203221 100644
+--- a/tools/testing/selftests/timers/valid-adjtimex.c
++++ b/tools/testing/selftests/timers/valid-adjtimex.c
+@@ -21,9 +21,6 @@
+  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *   GNU General Public License for more details.
+  */
+-
+-
+-
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <time.h>
+@@ -62,45 +59,47 @@ int clear_time_state(void)
+ #define NUM_FREQ_OUTOFRANGE 4
+ #define NUM_FREQ_INVALID 2
+ 
++#define SHIFTED_PPM (1 << 16)
++
+ long valid_freq[NUM_FREQ_VALID] = {
+-      -499<<16,
+-      -450<<16,
+-      -400<<16,
+-      -350<<16,
+-      -300<<16,
+-      -250<<16,
+-      -200<<16,
+-      -150<<16,
+-      -100<<16,
+-      -75<<16,
+-      -50<<16,
+-      -25<<16,
+-      -10<<16,
+-      -5<<16,
+-      -1<<16,
++       -499 * SHIFTED_PPM,
++       -450 * SHIFTED_PPM,
++       -400 * SHIFTED_PPM,
++       -350 * SHIFTED_PPM,
++       -300 * SHIFTED_PPM,
++       -250 * SHIFTED_PPM,
++       -200 * SHIFTED_PPM,
++       -150 * SHIFTED_PPM,
++       -100 * SHIFTED_PPM,
++        -75 * SHIFTED_PPM,
++        -50 * SHIFTED_PPM,
++        -25 * SHIFTED_PPM,
++        -10 * SHIFTED_PPM,
++         -5 * SHIFTED_PPM,
++         -1 * SHIFTED_PPM,
+       -1000,
+-      1<<16,
+-      5<<16,
+-      10<<16,
+-      25<<16,
+-      50<<16,
+-      75<<16,
+-      100<<16,
+-      150<<16,
+-      200<<16,
+-      250<<16,
+-      300<<16,
+-      350<<16,
+-      400<<16,
+-      450<<16,
+-      499<<16,
++          1 * SHIFTED_PPM,
++          5 * SHIFTED_PPM,
++         10 * SHIFTED_PPM,
++         25 * SHIFTED_PPM,
++         50 * SHIFTED_PPM,
++         75 * SHIFTED_PPM,
++        100 * SHIFTED_PPM,
++        150 * SHIFTED_PPM,
++        200 * SHIFTED_PPM,
++        250 * SHIFTED_PPM,
++        300 * SHIFTED_PPM,
++        350 * SHIFTED_PPM,
++        400 * SHIFTED_PPM,
++        450 * SHIFTED_PPM,
++        499 * SHIFTED_PPM,
+ };
+ 
+ long outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
+-      -1000<<16,
+-      -550<<16,
+-      550<<16,
+-      1000<<16,
++      -1000 * SHIFTED_PPM,
++       -550 * SHIFTED_PPM,
++        550 * SHIFTED_PPM,
++       1000 * SHIFTED_PPM,
+ };
+ 
+ #define LONG_MAX (~0UL>>1)


Reply via email to