commit:     48b8bf888cf34f1466dc95b4d64ca224564d1036
Author:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Sep  4 15:33:46 2025 +0000
Commit:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Sep  4 15:33:46 2025 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=48b8bf88

Linux patch 6.12.45

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

 0000_README              |    4 +
 1044_linux-6.12.45.patch | 3752 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3756 insertions(+)

diff --git a/0000_README b/0000_README
index ab6b7b1d..deb0a996 100644
--- a/0000_README
+++ b/0000_README
@@ -219,6 +219,10 @@ Patch:  1043_linux-6.12.44.patch
 From:   https://www.kernel.org
 Desc:   Linux 6.12.44
 
+Patch:  1044_linux-6.12.45.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.12.45
+
 Patch:  1500_fortify-copy-size-value-range-tracking-fix.patch
 From:   https://git.kernel.org/
 Desc:   fortify: Hide run-time copy size from value range tracking

diff --git a/1044_linux-6.12.45.patch b/1044_linux-6.12.45.patch
new file mode 100644
index 00000000..182f8678
--- /dev/null
+++ b/1044_linux-6.12.45.patch
@@ -0,0 +1,3752 @@
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index e153f8d26e7aae..2735c78b0b67af 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -60,7 +60,6 @@ properties:
+           - const: bus
+           - const: core
+           - const: vsync
+-          - const: lut
+           - const: tbu
+           - const: tbu_rt
+         # MSM8996 has additional iommu clock
+diff --git a/Makefile b/Makefile
+index 208a50953301b2..cc59990e379679 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 12
+-SUBLEVEL = 44
++SUBLEVEL = 45
+ EXTRAVERSION =
+ NAME = Baby Opossum Posse
+ 
+diff --git a/arch/mips/boot/dts/lantiq/danube_easy50712.dts 
b/arch/mips/boot/dts/lantiq/danube_easy50712.dts
+index 1ce20b7d05cb8c..c4d7aa5753b043 100644
+--- a/arch/mips/boot/dts/lantiq/danube_easy50712.dts
++++ b/arch/mips/boot/dts/lantiq/danube_easy50712.dts
+@@ -82,13 +82,16 @@ conf_out {
+                       };
+               };
+ 
+-              etop@e180000 {
++              ethernet@e180000 {
+                       compatible = "lantiq,etop-xway";
+                       reg = <0xe180000 0x40000>;
+                       interrupt-parent = <&icu0>;
+                       interrupts = <73 78>;
++                      interrupt-names = "tx", "rx";
+                       phy-mode = "rmii";
+                       mac-address = [ 00 11 22 33 44 55 ];
++                      lantiq,rx-burst-length = <4>;
++                      lantiq,tx-burst-length = <4>;
+               };
+ 
+               stp0: stp@e100bb0 {
+diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
+index 5a75283d17f10e..6031a0272d8743 100644
+--- a/arch/mips/lantiq/xway/sysctrl.c
++++ b/arch/mips/lantiq/xway/sysctrl.c
+@@ -497,7 +497,7 @@ void __init ltq_soc_init(void)
+               ifccr = CGU_IFCCR_VR9;
+               pcicr = CGU_PCICR_VR9;
+       } else {
+-              clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE);
++              clkdev_add_pmu("1e180000.ethernet", NULL, 1, 0, PMU_PPE);
+       }
+ 
+       if (!of_machine_is_compatible("lantiq,ase"))
+@@ -531,9 +531,9 @@ void __init ltq_soc_init(void)
+                                               CLOCK_133M, CLOCK_133M);
+               clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
+-              clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
+-              clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
+-              clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
++              clkdev_add_pmu("1e180000.ethernet", "ppe", 1, 0, PMU_PPE);
++              clkdev_add_cgu("1e180000.ethernet", "ephycgu", CGU_EPHY);
++              clkdev_add_pmu("1e180000.ethernet", "ephy", 1, 0, PMU_EPHY);
+               clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+       } else if (of_machine_is_compatible("lantiq,grx390")) {
+@@ -592,7 +592,7 @@ void __init ltq_soc_init(void)
+               clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | 
PMU_AHBM);
+               clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
+               clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | 
PMU_AHBM);
+-              clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
++              clkdev_add_pmu("1e180000.ethernet", "switch", 1, 0, PMU_SWITCH);
+               clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+               clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf1..7209d00a9c2576 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+ 
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+ 
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ 
+ extern u32 kvm_template_start[];
+diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
+index d92d1348045c8c..8454c1c3655a4c 100644
+--- a/arch/riscv/kvm/vcpu_vector.c
++++ b/arch/riscv/kvm/vcpu_vector.c
+@@ -181,6 +181,8 @@ int kvm_riscv_vcpu_set_reg_vector(struct kvm_vcpu *vcpu,
+               struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
+               unsigned long reg_val;
+ 
++              if (reg_size != sizeof(reg_val))
++                      return -EINVAL;
+               if (copy_from_user(&reg_val, uaddr, reg_size))
+                       return -EFAULT;
+               if (reg_val != cntx->vector.vlenb)
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
+index 765b4646648f7b..910accfeb78569 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -159,8 +159,28 @@ static int cmp_id(const void *key, const void *elem)
+               return 1;
+ }
+ 
++static u32 cpuid_to_ucode_rev(unsigned int val)
++{
++      union zen_patch_rev p = {};
++      union cpuid_1_eax c;
++
++      c.full = val;
++
++      p.stepping  = c.stepping;
++      p.model     = c.model;
++      p.ext_model = c.ext_model;
++      p.ext_fam   = c.ext_fam;
++
++      return p.ucode_rev;
++}
++
+ static bool need_sha_check(u32 cur_rev)
+ {
++      if (!cur_rev) {
++              cur_rev = cpuid_to_ucode_rev(bsp_cpuid_1_eax);
++              pr_info_once("No current revision, generating the lowest one: 
0x%x\n", cur_rev);
++      }
++
+       switch (cur_rev >> 8) {
+       case 0x80012: return cur_rev <= 0x800126f; break;
+       case 0x80082: return cur_rev <= 0x800820f; break;
+@@ -741,8 +761,6 @@ static struct ucode_patch *cache_find_patch(struct 
ucode_cpu_info *uci, u16 equi
+       n.equiv_cpu = equiv_cpu;
+       n.patch_id  = uci->cpu_sig.rev;
+ 
+-      WARN_ON_ONCE(!n.patch_id);
+-
+       list_for_each_entry(p, &microcode_cache, plist)
+               if (patch_cpus_equivalent(p, &n, false))
+                       return p;
+diff --git a/arch/x86/kernel/cpu/topology_amd.c 
b/arch/x86/kernel/cpu/topology_amd.c
+index 7d476fa697ca53..0fab130a8249ef 100644
+--- a/arch/x86/kernel/cpu/topology_amd.c
++++ b/arch/x86/kernel/cpu/topology_amd.c
+@@ -80,20 +80,25 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool 
has_topoext)
+ 
+       cpuid_leaf(0x8000001e, &leaf);
+ 
+-      tscan->c->topo.initial_apicid = leaf.ext_apic_id;
+-
+       /*
+-       * If leaf 0xb is available, then the domain shifts are set
+-       * already and nothing to do here. Only valid for family >= 0x17.
++       * If leaf 0xb/0x26 is available, then the APIC ID and the domain
++       * shifts are set already.
+        */
+-      if (!has_topoext && tscan->c->x86 >= 0x17) {
++      if (!has_topoext) {
++              tscan->c->topo.initial_apicid = leaf.ext_apic_id;
++
+               /*
+-               * Leaf 0x80000008 set the CORE domain shift already.
+-               * Update the SMT domain, but do not propagate it.
++               * Leaf 0x8000008 sets the CORE domain shift but not the
++               * SMT domain shift. On CPUs with family >= 0x17, there
++               * might be hyperthreads.
+                */
+-              unsigned int nthreads = leaf.core_nthreads + 1;
++              if (tscan->c->x86 >= 0x17) {
++                      /* Update the SMT domain, but do not propagate it. */
++                      unsigned int nthreads = leaf.core_nthreads + 1;
+ 
+-              topology_update_dom(tscan, TOPO_SMT_DOMAIN, 
get_count_order(nthreads), nthreads);
++                      topology_update_dom(tscan, TOPO_SMT_DOMAIN,
++                                          get_count_order(nthreads), 
nthreads);
++              }
+       }
+ 
+       store_node(tscan, leaf.nnodes_per_socket + 1, leaf.node_id);
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index 1a8148dec4afe9..33a6cb1ac6031e 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -860,6 +860,8 @@ static int __pv_send_ipi(unsigned long *ipi_bitmap, struct 
kvm_apic_map *map,
+       if (min > map->max_apic_id)
+               return 0;
+ 
++      min = array_index_nospec(min, map->max_apic_id + 1);
++
+       for_each_set_bit(i, ipi_bitmap,
+               min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) {
+               if (map->phys_map[min + i]) {
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index dbd295ef3eba2e..17ec4c4a3d92e6 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -9969,8 +9969,11 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, 
unsigned long dest_id)
+       rcu_read_lock();
+       map = rcu_dereference(vcpu->kvm->arch.apic_map);
+ 
+-      if (likely(map) && dest_id <= map->max_apic_id && 
map->phys_map[dest_id])
+-              target = map->phys_map[dest_id]->vcpu;
++      if (likely(map) && dest_id <= map->max_apic_id) {
++              dest_id = array_index_nospec(dest_id, map->max_apic_id + 1);
++              if (map->phys_map[dest_id])
++                      target = map->phys_map[dest_id]->vcpu;
++      }
+ 
+       rcu_read_unlock();
+ 
+diff --git a/block/blk-zoned.c b/block/blk-zoned.c
+index 24c80078ca442e..5915fb98ffdcea 100644
+--- a/block/blk-zoned.c
++++ b/block/blk-zoned.c
+@@ -1281,14 +1281,14 @@ static void blk_zone_wplug_bio_work(struct work_struct 
*work)
+       struct block_device *bdev;
+       unsigned long flags;
+       struct bio *bio;
++      bool prepared;
+ 
+       /*
+        * Submit the next plugged BIO. If we do not have any, clear
+        * the plugged flag.
+        */
+-      spin_lock_irqsave(&zwplug->lock, flags);
+-
+ again:
++      spin_lock_irqsave(&zwplug->lock, flags);
+       bio = bio_list_pop(&zwplug->bio_list);
+       if (!bio) {
+               zwplug->flags &= ~BLK_ZONE_WPLUG_PLUGGED;
+@@ -1296,13 +1296,14 @@ static void blk_zone_wplug_bio_work(struct work_struct 
*work)
+               goto put_zwplug;
+       }
+ 
+-      if (!blk_zone_wplug_prepare_bio(zwplug, bio)) {
++      prepared = blk_zone_wplug_prepare_bio(zwplug, bio);
++      spin_unlock_irqrestore(&zwplug->lock, flags);
++
++      if (!prepared) {
+               blk_zone_wplug_bio_io_error(zwplug, bio);
+               goto again;
+       }
+ 
+-      spin_unlock_irqrestore(&zwplug->lock, flags);
+-
+       bdev = bio->bi_bdev;
+ 
+       /*
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index e614e4bef9ea1b..a813bc97cf4258 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -2329,6 +2329,12 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = 
{
+                       DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"),
+               }
+       },
++      {
++              // TUXEDO InfinityBook Pro AMD Gen9
++              .matches = {
++                      DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"),
++              },
++      },
+       { },
+ };
+ 
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index eeae160c898d38..fa3c76a2b49d1f 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, 
short vpi, int vci)
+         return NULL;
+ }
+ 
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ 
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct 
sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+ 
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ 
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+ 
+diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c 
b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+index f741ca279052bb..e15d11ed165eef 100644
+--- a/drivers/firmware/efi/stmm/tee_stmm_efi.c
++++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+@@ -143,6 +143,10 @@ static efi_status_t mm_communicate(u8 *comm_buf, size_t 
payload_size)
+       return var_hdr->ret_status;
+ }
+ 
++#define COMM_BUF_SIZE(__payload_size) (MM_COMMUNICATE_HEADER_SIZE + \
++                                       MM_VARIABLE_COMMUNICATE_SIZE + \
++                                       (__payload_size))
++
+ /**
+  * setup_mm_hdr() -   Allocate a buffer for StandAloneMM and initialize the
+  *                    header data.
+@@ -173,9 +177,8 @@ static void *setup_mm_hdr(u8 **dptr, size_t payload_size, 
size_t func,
+               return NULL;
+       }
+ 
+-      comm_buf = kzalloc(MM_COMMUNICATE_HEADER_SIZE +
+-                                 MM_VARIABLE_COMMUNICATE_SIZE + payload_size,
+-                         GFP_KERNEL);
++      comm_buf = alloc_pages_exact(COMM_BUF_SIZE(payload_size),
++                                   GFP_KERNEL | __GFP_ZERO);
+       if (!comm_buf) {
+               *ret = EFI_OUT_OF_RESOURCES;
+               return NULL;
+@@ -239,7 +242,7 @@ static efi_status_t get_max_payload(size_t *size)
+        */
+       *size -= 2;
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+ 
+@@ -282,7 +285,7 @@ static efi_status_t get_property_int(u16 *name, size_t 
name_size,
+       memcpy(var_property, &smm_property->property, sizeof(*var_property));
+ 
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+ 
+@@ -347,7 +350,7 @@ static efi_status_t tee_get_variable(u16 *name, efi_guid_t 
*vendor,
+       memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
+              var_acc->data_size);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+ 
+@@ -404,7 +407,7 @@ static efi_status_t tee_get_next_variable(unsigned long 
*name_size,
+       memcpy(name, var_getnext->name, var_getnext->name_size);
+ 
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+ 
+@@ -467,7 +470,7 @@ static efi_status_t tee_set_variable(efi_char16_t *name, 
efi_guid_t *vendor,
+       ret = mm_communicate(comm_buf, payload_size);
+       dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, 
ret);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+ 
+@@ -507,7 +510,7 @@ static efi_status_t tee_query_variable_info(u32 attributes,
+       *max_variable_size = mm_query_info->max_variable_size;
+ 
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+index dfb6cfd8376069..02138aa557935e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+@@ -88,8 +88,8 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
+       }
+ 
+       r = amdgpu_vm_bo_map(adev, *bo_va, csa_addr, 0, size,
+-                           AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE 
|
+-                           AMDGPU_VM_PAGE_EXECUTABLE);
++                           AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
++                           AMDGPU_PTE_EXECUTABLE);
+ 
+       if (r) {
+               DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
+diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+index c4fdd82a00429c..57b5d90ca89b3f 100644
+--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+@@ -3668,14 +3668,16 @@ static umode_t hwmon_attributes_visible(struct kobject 
*kobj,
+               effective_mode &= ~S_IWUSR;
+ 
+       /* not implemented yet for APUs other than GC 10.3.1 (vangogh) and 
9.4.3 */
+-      if (((adev->family == AMDGPU_FAMILY_SI) ||
+-           ((adev->flags & AMD_IS_APU) && (gc_ver != IP_VERSION(10, 3, 1)) &&
+-            (gc_ver != IP_VERSION(9, 4, 3) && gc_ver != IP_VERSION(9, 4, 
4)))) &&
+-          (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr ||
+-           attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr ||
+-           attr == &sensor_dev_attr_power1_cap.dev_attr.attr ||
+-           attr == &sensor_dev_attr_power1_cap_default.dev_attr.attr))
+-              return 0;
++      if (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr ||
++          attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr ||
++          attr == &sensor_dev_attr_power1_cap.dev_attr.attr ||
++          attr == &sensor_dev_attr_power1_cap_default.dev_attr.attr) {
++              if (adev->family == AMDGPU_FAMILY_SI ||
++                  ((adev->flags & AMD_IS_APU) && gc_ver != IP_VERSION(10, 3, 
1) &&
++                   (gc_ver != IP_VERSION(9, 4, 3) && gc_ver != IP_VERSION(9, 
4, 4))) ||
++                  (amdgpu_sriov_vf(adev) && gc_ver == IP_VERSION(11, 0, 3)))
++                      return 0;
++      }
+ 
+       /* not implemented yet for APUs having < GC 9.3.0 (Renoir) */
+       if (((adev->family == AMDGPU_FAMILY_SI) ||
+diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
+index bb61bbdcce5b3c..9fa13da513d24e 100644
+--- a/drivers/gpu/drm/display/drm_dp_helper.c
++++ b/drivers/gpu/drm/display/drm_dp_helper.c
+@@ -664,7 +664,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned 
int offset,
+        * monitor doesn't power down exactly after the throw away read.
+        */
+       if (!aux->is_remote) {
+-              ret = drm_dp_dpcd_probe(aux, DP_LANE0_1_STATUS);
++              ret = drm_dp_dpcd_probe(aux, DP_DPCD_REV);
+               if (ret < 0)
+                       return ret;
+       }
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 42e62b0409612e..2508e9e9431dcd 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -381,19 +381,19 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
+ 
+               of_id = of_match_node(mtk_drm_of_ids, node);
+               if (!of_id)
+-                      continue;
++                      goto next_put_node;
+ 
+               pdev = of_find_device_by_node(node);
+               if (!pdev)
+-                      continue;
++                      goto next_put_node;
+ 
+               drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
+               if (!drm_dev)
+-                      continue;
++                      goto next_put_device_pdev_dev;
+ 
+               temp_drm_priv = dev_get_drvdata(drm_dev);
+               if (!temp_drm_priv)
+-                      continue;
++                      goto next_put_device_drm_dev;
+ 
+               if (temp_drm_priv->data->main_len)
+                       all_drm_priv[CRTC_MAIN] = temp_drm_priv;
+@@ -405,10 +405,17 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
+               if (temp_drm_priv->mtk_drm_bound)
+                       cnt++;
+ 
+-              if (cnt == MAX_CRTC) {
+-                      of_node_put(node);
++next_put_device_drm_dev:
++              put_device(drm_dev);
++
++next_put_device_pdev_dev:
++              put_device(&pdev->dev);
++
++next_put_node:
++              of_node_put(node);
++
++              if (cnt == MAX_CRTC)
+                       break;
+-              }
+       }
+ 
+       if (drm_priv->data->mmsys_dev_num == cnt) {
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c 
b/drivers/gpu/drm/mediatek/mtk_plane.c
+index 74c2704efb6642..6e20f7037b5bbc 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -292,7 +292,8 @@ static void mtk_plane_atomic_disable(struct drm_plane 
*plane,
+       wmb(); /* Make sure the above parameter is set before update */
+       mtk_plane_state->pending.dirty = true;
+ 
+-      mtk_crtc_plane_disable(old_state->crtc, plane);
++      if (old_state && old_state->crtc)
++              mtk_crtc_plane_disable(old_state->crtc, plane);
+ }
+ 
+ static void mtk_plane_atomic_update(struct drm_plane *plane,
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 4b3a8ee8e278f0..3eee6517541e3f 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -879,12 +879,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
*data,
+ 
+       if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               sync_file = sync_file_create(submit->user_fence);
+-              if (!sync_file) {
++              if (!sync_file)
+                       ret = -ENOMEM;
+-              } else {
+-                      fd_install(out_fence_fd, sync_file->file);
+-                      args->fence_fd = out_fence_fd;
+-              }
+       }
+ 
+       if (ret)
+@@ -912,10 +908,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
*data,
+ out_unlock:
+       mutex_unlock(&queue->lock);
+ out_post_unlock:
+-      if (ret && (out_fence_fd >= 0)) {
+-              put_unused_fd(out_fence_fd);
++      if (ret) {
++              if (out_fence_fd >= 0)
++                      put_unused_fd(out_fence_fd);
+               if (sync_file)
+                       fput(sync_file->file);
++      } else if (sync_file) {
++              fd_install(out_fence_fd, sync_file->file);
++              args->fence_fd = out_fence_fd;
+       }
+ 
+       if (!IS_ERR_OR_NULL(submit)) {
+diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c
+index 6749f0fbca96d5..52464a1346f810 100644
+--- a/drivers/gpu/drm/msm/msm_kms.c
++++ b/drivers/gpu/drm/msm/msm_kms.c
+@@ -241,6 +241,12 @@ int msm_drm_kms_init(struct device *dev, const struct 
drm_driver *drv)
+       if (ret)
+               return ret;
+ 
++      ret = msm_disp_snapshot_init(ddev);
++      if (ret) {
++              DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", 
ret);
++              return ret;
++      }
++
+       ret = priv->kms_init(ddev);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to load kms\n");
+@@ -293,10 +299,6 @@ int msm_drm_kms_init(struct device *dev, const struct 
drm_driver *drv)
+               goto err_msm_uninit;
+       }
+ 
+-      ret = msm_disp_snapshot_init(ddev);
+-      if (ret)
+-              DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", 
ret);
+-
+       drm_mode_config_reset(ddev);
+ 
+       return 0;
+diff --git a/drivers/gpu/drm/msm/registers/display/dsi.xml 
b/drivers/gpu/drm/msm/registers/display/dsi.xml
+index 501ffc585a9f69..c7a7b633d747bc 100644
+--- a/drivers/gpu/drm/msm/registers/display/dsi.xml
++++ b/drivers/gpu/drm/msm/registers/display/dsi.xml
+@@ -159,28 +159,28 @@ 
xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+               <bitfield name="RGB_SWAP" low="12" high="14" 
type="dsi_rgb_swap"/>
+       </reg32>
+       <reg32 offset="0x00020" name="ACTIVE_H">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00024" name="ACTIVE_V">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00028" name="TOTAL">
+-              <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+-              <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++              <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++              <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+ 
+       <reg32 offset="0x00038" name="CMD_DMA_CTRL">
+@@ -209,8 +209,8 @@ 
xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+               <bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+-              <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+-              <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++              <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++              <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+               <bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c 
b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+index 7a2cceaee6e97f..1199dfc1194c80 100644
+--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+@@ -663,6 +663,10 @@ static bool nv50_plane_format_mod_supported(struct 
drm_plane *plane,
+       struct nouveau_drm *drm = nouveau_drm(plane->dev);
+       uint8_t i;
+ 
++      /* All chipsets can display all formats in linear layout */
++      if (modifier == DRM_FORMAT_MOD_LINEAR)
++              return true;
++
+       if (drm->client.device.info.chipset < 0xc0) {
+               const struct drm_format_info *info = drm_format_info(format);
+               const uint8_t kind = (modifier >> 12) & 0xff;
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c 
b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277d..7c43397c19e61d 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 
port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, 
int len, u16 tag)
+ {
+-      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+       while (len >= 4) {
+               nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+               img += 4;
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+       struct nvkm_falcon *falcon = fw->falcon;
+-      int target, ret;
++      int ret;
+ 
+       if (fw->inst) {
++              int target;
++
+               nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+ 
+               switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+       }
+ 
+       if (fw->boot) {
+-              switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+-              case NVKM_MEM_TARGET_VRAM: target = 4; break;
+-              case NVKM_MEM_TARGET_HOST: target = 5; break;
+-              case NVKM_MEM_TARGET_NCOH: target = 6; break;
+-              default:
+-                      WARN_ON(1);
+-                      return -EINVAL;
+-              }
+-
+               ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+                                        IMEM, falcon->code.limit - 
fw->boot_size, fw->boot_size,
+                                        fw->boot_addr >> 8, false);
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c
+index 52412965fac107..5b721bd9d79949 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c
+@@ -209,11 +209,12 @@ nvkm_gsp_fwsec_v2(struct nvkm_gsp *gsp, const char *name,
+       fw->boot_addr = bld->start_tag << 8;
+       fw->boot_size = bld->code_size;
+       fw->boot = kmemdup(bl->data + hdr->data_offset + bld->code_off, 
fw->boot_size, GFP_KERNEL);
+-      if (!fw->boot)
+-              ret = -ENOMEM;
+ 
+       nvkm_firmware_put(bl);
+ 
++      if (!fw->boot)
++              return -ENOMEM;
++
+       /* Patch in interface data. */
+       return nvkm_gsp_fwsec_patch(gsp, fw, desc->InterfaceOffset, init_cmd);
+ }
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 5f745d9ed6cc25..445bbe0299b08f 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -671,7 +671,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, 
bool evict,
+       }
+ 
+       if (ttm_bo->type == ttm_bo_type_sg) {
+-              ret = xe_bo_move_notify(bo, ctx);
++              if (new_mem->mem_type == XE_PL_SYSTEM)
++                      ret = xe_bo_move_notify(bo, ctx);
+               if (!ret)
+                       ret = xe_bo_move_dmabuf(ttm_bo, new_mem);
+               return ret;
+diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
+index b0684e6d2047b1..dd7bd766ae1845 100644
+--- a/drivers/gpu/drm/xe/xe_sync.c
++++ b/drivers/gpu/drm/xe/xe_sync.c
+@@ -77,6 +77,7 @@ static void user_fence_worker(struct work_struct *w)
+ {
+       struct xe_user_fence *ufence = container_of(w, struct xe_user_fence, 
worker);
+ 
++      WRITE_ONCE(ufence->signalled, 1);
+       if (mmget_not_zero(ufence->mm)) {
+               kthread_use_mm(ufence->mm);
+               if (copy_to_user(ufence->addr, &ufence->value, 
sizeof(ufence->value)))
+@@ -89,7 +90,6 @@ static void user_fence_worker(struct work_struct *w)
+        * Wake up waiters only after updating the ufence state, allowing the 
UMD
+        * to safely reuse the same ufence without encountering -EBUSY errors.
+        */
+-      WRITE_ONCE(ufence->signalled, 1);
+       wake_up_all(&ufence->xe->ufence_wq);
+       user_fence_put(ufence);
+ }
+diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
+index 15fd497c920c8e..a4845d4213b006 100644
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -1402,8 +1402,12 @@ static int xe_vm_create_scratch(struct xe_device *xe, 
struct xe_tile *tile,
+ 
+       for (i = MAX_HUGEPTE_LEVEL; i < vm->pt_root[id]->level; i++) {
+               vm->scratch_pt[id][i] = xe_pt_create(vm, tile, i);
+-              if (IS_ERR(vm->scratch_pt[id][i]))
+-                      return PTR_ERR(vm->scratch_pt[id][i]);
++              if (IS_ERR(vm->scratch_pt[id][i])) {
++                      int err = PTR_ERR(vm->scratch_pt[id][i]);
++
++                      vm->scratch_pt[id][i] = NULL;
++                      return err;
++              }
+ 
+               xe_pt_populate_empty(tile, vm, vm->scratch_pt[id][i]);
+       }
+diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
+index c5bdf0f1b32f76..6b90d2c03e889a 100644
+--- a/drivers/hid/hid-asus.c
++++ b/drivers/hid/hid-asus.c
+@@ -1210,7 +1210,13 @@ static int asus_probe(struct hid_device *hdev, const 
struct hid_device_id *id)
+               return ret;
+       }
+ 
+-      if (!drvdata->input) {
++      /*
++       * Check that input registration succeeded. Checking that
++       * HID_CLAIMED_INPUT is set prevents a UAF when all input devices
++       * were freed during registration due to no usages being mapped,
++       * leaving drvdata->input pointing to freed memory.
++       */
++      if (!drvdata->input || !(hdev->claimed & HID_CLAIMED_INPUT)) {
+               hid_err(hdev, "Asus input not registered\n");
+               ret = -ENOMEM;
+               goto err_stop_hw;
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index b472140421f5af..18c4e5f143a77a 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -825,6 +825,8 @@
+ #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019    0x6019
+ #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E    0x602e
+ #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093    0x6093
++#define USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT    0x6184
++#define USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT   0x61ed
+ 
+ #define USB_VENDOR_ID_LETSKETCH               0x6161
+ #define USB_DEVICE_ID_WP9620N         0x4d15
+@@ -898,6 +900,7 @@
+ #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2                0xc534
+ #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1     0xc539
+ #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1   0xc53f
++#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2   0xc543
+ #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY        0xc53a
+ #define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER  0xc548
+ #define USB_DEVICE_ID_SPACETRAVELLER  0xc623
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7f..6f5c71660d823b 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+ 
+ #include <kunit/test.h>
+ 
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+       struct hid_device *dev;
+       bool handled;
+@@ -15,15 +15,15 @@ static void 
hid_test_input_set_battery_charge_status(struct kunit *test)
+       dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+ 
+-      handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+       KUNIT_EXPECT_FALSE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, 
POWER_SUPPLY_STATUS_UNKNOWN);
+ 
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 
0);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, 
POWER_SUPPLY_STATUS_DISCHARGING);
+ 
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 
1);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, 
POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit 
*test)
+ }
+ 
+ static struct kunit_case hid_input_tests[] = {
+-      KUNIT_CASE(hid_test_input_set_battery_charge_status),
++      KUNIT_CASE(hid_test_input_update_battery_charge_status),
+       KUNIT_CASE(hid_test_input_get_battery_property),
+       { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 9d80635a91ebd8..f5c217ac4bfaa7 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,13 +595,33 @@ static void hidinput_cleanup_battery(struct hid_device 
*dev)
+       dev->battery = NULL;
+ }
+ 
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
++{
++      switch (usage) {
++      case HID_BAT_CHARGING:
++              dev->battery_charge_status = value ?
++                                           POWER_SUPPLY_STATUS_CHARGING :
++                                           POWER_SUPPLY_STATUS_DISCHARGING;
++              return true;
++      }
++
++      return false;
++}
++
++static void hidinput_update_battery(struct hid_device *dev, unsigned int 
usage,
++                                  int value)
+ {
+       int capacity;
+ 
+       if (!dev->battery)
+               return;
+ 
++      if (hidinput_update_battery_charge_status(dev, usage, value)) {
++              power_supply_changed(dev->battery);
++              return;
++      }
++
+       if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+               return;
+ 
+@@ -617,20 +637,6 @@ static void hidinput_update_battery(struct hid_device 
*dev, int value)
+               power_supply_changed(dev->battery);
+       }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
+-{
+-      switch (usage) {
+-      case HID_BAT_CHARGING:
+-              dev->battery_charge_status = value ?
+-                                           POWER_SUPPLY_STATUS_CHARGING :
+-                                           POWER_SUPPLY_STATUS_DISCHARGING;
+-              return true;
+-      }
+-
+-      return false;
+-}
+ #else  /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned 
report_type,
+                                 struct hid_field *field, bool is_percentage)
+@@ -642,14 +648,9 @@ static void hidinput_cleanup_battery(struct hid_device 
*dev)
+ {
+ }
+ 
+-static void hidinput_update_battery(struct hid_device *dev, int value)
+-{
+-}
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int 
usage,
++                                  int value)
+ {
+-      return false;
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+ 
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct 
hid_field *field, struct
+               return;
+ 
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_set_battery_charge_status(hid, 
usage->hid, value);
+-
+-              if (!handled)
+-                      hidinput_update_battery(hid, value);
+-
++              hidinput_update_battery(hid, usage->hid, value);
+               return;
+       }
+ 
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 34fa71ceec2b20..cce54dd9884a3e 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1983,6 +1983,10 @@ static const struct hid_device_id logi_dj_receivers[] = 
{
+         HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
+               USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
+        .driver_data = recvr_type_gaming_hidpp},
++      { /* Logitech lightspeed receiver (0xc543) */
++        HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
++              USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
++       .driver_data = recvr_type_gaming_hidpp},
+ 
+       { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
+         HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
+diff --git a/drivers/hid/hid-logitech-hidpp.c 
b/drivers/hid/hid-logitech-hidpp.c
+index cf7a6986cf2013..234ddd4422d902 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -4624,6 +4624,8 @@ static const struct hid_device_id hidpp_devices[] = {
+         HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
+       { /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
+         HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
++      { /* Logitech G PRO 2 LIGHTSPEED Wireless Mouse over USB */
++        HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xc09a) },
+ 
+       { /* G935 Gaming Headset */
+         HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 641292cfdaa6f9..5c424010bc025c 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1453,6 +1453,14 @@ static const __u8 *mt_report_fixup(struct hid_device 
*hdev, __u8 *rdesc,
+       if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
+           (hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
+            hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
++              if (*size < 608) {
++                      dev_info(
++                              &hdev->dev,
++                              "GT7868Q fixup: report descriptor is only %u 
bytes, skipping\n",
++                              *size);
++                      return rdesc;
++              }
++
+               if (rdesc[607] == 0x15) {
+                       rdesc[607] = 0x25;
+                       dev_info(
+diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
+index 2738ce947434f9..0f76e241e0afb4 100644
+--- a/drivers/hid/hid-ntrig.c
++++ b/drivers/hid/hid-ntrig.c
+@@ -144,6 +144,9 @@ static void ntrig_report_version(struct hid_device *hdev)
+       struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+       unsigned char *data = kmalloc(8, GFP_KERNEL);
+ 
++      if (!hid_is_usb(hdev))
++              return;
++
+       if (!data)
+               goto err_free;
+ 
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 80372342c176af..64f9728018b885 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -124,6 +124,8 @@ static const struct hid_device_id hid_quirks[] = {
+       { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 
USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A), 
HID_QUIRK_MULTI_INPUT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, 
USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE), HID_QUIRK_ALWAYS_POLL },
++      { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 
USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
++      { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 
USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 
USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 
USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 
USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index c7033ffaba3919..a076dc0b60ee20 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -684,6 +684,7 @@ static bool wacom_is_art_pen(int tool_id)
+       case 0x885:     /* Intuos3 Marker Pen */
+       case 0x804:     /* Intuos4/5 13HD/24HD Marker Pen */
+       case 0x10804:   /* Intuos4/5 13HD/24HD Art Pen */
++      case 0x204:     /* Art Pen 2 */
+               is_art_pen = true;
+               break;
+       }
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c 
b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index f4bafc71a7399b..08886c3a28c61c 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -7780,7 +7780,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+       }
+       rx_rings = min_t(int, rx_rings, hwr.grp);
+       hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings);
+-      if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
++      if (bnxt_ulp_registered(bp->edev) &&
++          hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
+               hwr.stat -= bnxt_get_ulp_stat_ctxs(bp);
+       hwr.cp = min_t(int, hwr.cp, hwr.stat);
+       rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh);
+@@ -7788,6 +7789,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+               hwr.rx = rx_rings << 1;
+       tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx);
+       hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings;
++      if (hwr.tx != bp->tx_nr_rings) {
++              netdev_warn(bp->dev,
++                          "Able to reserve only %d out of %d requested TX 
rings\n",
++                          hwr.tx, bp->tx_nr_rings);
++      }
+       bp->tx_nr_rings = hwr.tx;
+ 
+       /* If we cannot reserve all the RX rings, reset the RSS map only
+@@ -12241,6 +12247,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
+       return rc;
+ }
+ 
++static int bnxt_tx_nr_rings(struct bnxt *bp)
++{
++      return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
++                          bp->tx_nr_rings_per_tc;
++}
++
++static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
++{
++      return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
++}
++
+ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool 
link_re_init)
+ {
+       int rc = 0;
+@@ -12258,6 +12275,13 @@ static int __bnxt_open_nic(struct bnxt *bp, bool 
irq_re_init, bool link_re_init)
+       if (rc)
+               return rc;
+ 
++      /* Make adjustments if reserved TX rings are less than requested */
++      bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
++      if (bp->tx_nr_rings_xdp) {
++              bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
++              bp->tx_nr_rings += bp->tx_nr_rings_xdp;
++      }
+       rc = bnxt_alloc_mem(bp, irq_re_init);
+       if (rc) {
+               netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
+@@ -15676,7 +15700,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
+       bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
+       bp->rx_nr_rings = bp->cp_nr_rings;
+       bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
+-      bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++      bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ }
+ 
+ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+@@ -15708,7 +15732,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool 
sh)
+               bnxt_trim_dflt_sh_rings(bp);
+       else
+               bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+-      bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++      bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ 
+       avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
+       if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
+@@ -15721,7 +15745,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool 
sh)
+       rc = __bnxt_reserve_rings(bp);
+       if (rc && rc != -ENODEV)
+               netdev_warn(bp->dev, "Unable to reserve tx rings\n");
+-      bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       if (sh)
+               bnxt_trim_dflt_sh_rings(bp);
+ 
+@@ -15730,7 +15754,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool 
sh)
+               rc = __bnxt_reserve_rings(bp);
+               if (rc && rc != -ENODEV)
+                       netdev_warn(bp->dev, "2nd rings reservation failed.\n");
+-              bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++              bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       }
+       if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+               bp->rx_nr_rings++;
+@@ -15764,7 +15788,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
+       if (rc)
+               goto init_dflt_ring_err;
+ 
+-      bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ 
+       bnxt_set_dflt_rfs(bp);
+ 
+diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
+index 3c2a7919b1289d..6c2d69ef1a8dbd 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5225,19 +5225,16 @@ static void macb_remove(struct platform_device *pdev)
+ 
+       if (dev) {
+               bp = netdev_priv(dev);
++              unregister_netdev(dev);
+               phy_exit(bp->sgmii_phy);
+               mdiobus_unregister(bp->mii_bus);
+               mdiobus_free(bp->mii_bus);
+ 
+-              unregister_netdev(dev);
++              device_set_wakeup_enable(&bp->pdev->dev, 0);
+               cancel_work_sync(&bp->hresp_err_bh_work);
+               pm_runtime_disable(&pdev->dev);
+               pm_runtime_dont_use_autosuspend(&pdev->dev);
+-              if (!pm_runtime_suspended(&pdev->dev)) {
+-                      macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk,
+-                                        bp->rx_clk, bp->tsu_clk);
+-                      pm_runtime_set_suspended(&pdev->dev);
+-              }
++              pm_runtime_set_suspended(&pdev->dev);
+               phylink_destroy(bp->phylink);
+               free_netdev(dev);
+       }
+diff --git a/drivers/net/ethernet/dlink/dl2k.c 
b/drivers/net/ethernet/dlink/dl2k.c
+index 787218d60c6b16..2c1b551e144231 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1091,7 +1091,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+ 
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+ 
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c 
b/drivers/net/ethernet/intel/ice/ice_adapter.c
+index 66e070095d1bbe..10285995c9eddd 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.c
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c
+@@ -13,16 +13,45 @@
+ static DEFINE_XARRAY(ice_adapters);
+ static DEFINE_MUTEX(ice_adapters_mutex);
+ 
+-static unsigned long ice_adapter_index(u64 dsn)
++#define ICE_ADAPTER_FIXED_INDEX       BIT_ULL(63)
++
++#define ICE_ADAPTER_INDEX_E825C       \
++      (ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX)
++
++static u64 ice_adapter_index(struct pci_dev *pdev)
+ {
++      switch (pdev->device) {
++      case ICE_DEV_ID_E825C_BACKPLANE:
++      case ICE_DEV_ID_E825C_QSFP:
++      case ICE_DEV_ID_E825C_SFP:
++      case ICE_DEV_ID_E825C_SGMII:
++              /* E825C devices have multiple NACs which are connected to the
++               * same clock source, and which must share the same
++               * ice_adapter structure. We can't use the serial number since
++               * each NAC has its own NVM generated with its own unique
++               * Device Serial Number. Instead, rely on the embedded nature
++               * of the E825C devices, and use a fixed index. This relies on
++               * the fact that all E825C physical functions in a given
++               * system are part of the same overall device.
++               */
++              return ICE_ADAPTER_INDEX_E825C;
++      default:
++              return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX;
++      }
++}
++
++static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
++{
++      u64 index = ice_adapter_index(pdev);
++
+ #if BITS_PER_LONG == 64
+-      return dsn;
++      return index;
+ #else
+-      return (u32)dsn ^ (u32)(dsn >> 32);
++      return (u32)index ^ (u32)(index >> 32);
+ #endif
+ }
+ 
+-static struct ice_adapter *ice_adapter_new(u64 dsn)
++static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
+ {
+       struct ice_adapter *adapter;
+ 
+@@ -30,7 +59,7 @@ static struct ice_adapter *ice_adapter_new(u64 dsn)
+       if (!adapter)
+               return NULL;
+ 
+-      adapter->device_serial_number = dsn;
++      adapter->index = ice_adapter_index(pdev);
+       spin_lock_init(&adapter->ptp_gltsyn_time_lock);
+       refcount_set(&adapter->refcount, 1);
+ 
+@@ -63,24 +92,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
+  */
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ {
+-      u64 dsn = pci_get_dsn(pdev);
+       struct ice_adapter *adapter;
+       unsigned long index;
+       int err;
+ 
+-      index = ice_adapter_index(dsn);
++      index = ice_adapter_xa_index(pdev);
+       scoped_guard(mutex, &ice_adapters_mutex) {
+               err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
+               if (err == -EBUSY) {
+                       adapter = xa_load(&ice_adapters, index);
+                       refcount_inc(&adapter->refcount);
+-                      WARN_ON_ONCE(adapter->device_serial_number != dsn);
++                      WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
+                       return adapter;
+               }
+               if (err)
+                       return ERR_PTR(err);
+ 
+-              adapter = ice_adapter_new(dsn);
++              adapter = ice_adapter_new(pdev);
+               if (!adapter)
+                       return ERR_PTR(-ENOMEM);
+               xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
+@@ -99,11 +127,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+  */
+ void ice_adapter_put(struct pci_dev *pdev)
+ {
+-      u64 dsn = pci_get_dsn(pdev);
+       struct ice_adapter *adapter;
+       unsigned long index;
+ 
+-      index = ice_adapter_index(dsn);
++      index = ice_adapter_xa_index(pdev);
+       scoped_guard(mutex, &ice_adapters_mutex) {
+               adapter = xa_load(&ice_adapters, index);
+               if (WARN_ON(!adapter))
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h 
b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index ac15c0d2bc1a47..409467847c7536 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -32,7 +32,7 @@ struct ice_port_list {
+  * @refcount: Reference count. struct ice_pf objects hold the references.
+  * @ctrl_pf: Control PF of the adapter
+  * @ports: Ports list
+- * @device_serial_number: DSN cached for collision detection on 32bit systems
++ * @index: 64-bit index cached for collision detection on 32bit systems
+  */
+ struct ice_adapter {
+       refcount_t refcount;
+@@ -41,7 +41,7 @@ struct ice_adapter {
+ 
+       struct ice_pf *ctrl_pf;
+       struct ice_port_list ports;
+-      u64 device_serial_number;
++      u64 index;
+ };
+ 
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c 
b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index e4c8cd12a41d13..04bec5d8e70841 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2352,7 +2352,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 
buf_size,
+  * The function will apply the new Tx topology from the package buffer
+  * if available.
+  *
+- * Return: zero when update was successful, negative values otherwise.
++ * Return:
++ * * 0 - Successfully applied topology configuration.
++ * * -EBUSY - Failed to acquire global configuration lock.
++ * * -EEXIST - Topology configuration has already been applied.
++ * * -EIO - Unable to apply topology configuration.
++ * * -ENODEV - Failed to re-initialize device after applying configuration.
++ * * Other negative error codes indicate unexpected failures.
+  */
+ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ {
+@@ -2385,7 +2391,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, 
u32 len)
+ 
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
+-              return status;
++              return -EIO;
+       }
+ 
+       /* Is default topology already applied ? */
+@@ -2472,31 +2478,45 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void 
*buf, u32 len)
+                                ICE_GLOBAL_CFG_LOCK_TIMEOUT);
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
+-              return status;
++              return -EBUSY;
+       }
+ 
+       /* Check if reset was triggered already. */
+       reg = rd32(hw, GLGEN_RSTAT);
+       if (reg & GLGEN_RSTAT_DEVSTATE_M) {
+-              /* Reset is in progress, re-init the HW again */
+               ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer 
topology might be applied already\n");
+               ice_check_reset(hw);
+-              return 0;
++              /* Reset is in progress, re-init the HW again */
++              goto reinit_hw;
+       }
+ 
+       /* Set new topology */
+       status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
+       if (status) {
+-              ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");
+-              return status;
++              ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status 
%pe\n",
++                        ERR_PTR(status));
++              /* only report -EIO here as the caller checks the error value
++               * and reports an informational error message informing that
++               * the driver failed to program Tx topology.
++               */
++              status = -EIO;
+       }
+ 
+-      /* New topology is updated, delay 1 second before issuing the CORER */
++      /* Even if Tx topology config failed, we need to CORE reset here to
++       * clear the global configuration lock. Delay 1 second to allow
++       * hardware to settle then issue a CORER
++       */
+       msleep(1000);
+       ice_reset(hw, ICE_RESET_CORER);
+-      /* CORER will clear the global lock, so no explicit call
+-       * required for release.
+-       */
++      ice_check_reset(hw);
++
++reinit_hw:
++      /* Since we triggered a CORER, re-initialize hardware */
++      ice_deinit_hw(hw);
++      if (ice_init_hw(hw)) {
++              ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after 
setting Tx topology\n");
++              return -ENODEV;
++      }
+ 
+-      return 0;
++      return status;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c 
b/drivers/net/ethernet/intel/ice/ice_main.c
+index d1abd21cfc647c..74d4f2fde3e0f1 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4559,17 +4559,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct 
firmware *firmware)
+                       dev_info(dev, "Tx scheduling layers switching feature 
disabled\n");
+               else
+                       dev_info(dev, "Tx scheduling layers switching feature 
enabled\n");
+-              /* if there was a change in topology ice_cfg_tx_topo triggered
+-               * a CORER and we need to re-init hw
++              return 0;
++      } else if (err == -ENODEV) {
++              /* If we failed to re-initialize the device, we can no longer
++               * continue loading.
+                */
+-              ice_deinit_hw(hw);
+-              err = ice_init_hw(hw);
+-
++              dev_warn(dev, "Failed to initialize hardware after applying Tx 
scheduling configuration.\n");
+               return err;
+       } else if (err == -EIO) {
+               dev_info(dev, "DDP package does not support Tx scheduling 
layers switching feature - please update to the latest DDP package and try 
again\n");
++              return 0;
++      } else if (err == -EEXIST) {
++              return 0;
+       }
+ 
++      /* Do not treat this as a fatal error. */
++      dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n",
++               ERR_PTR(err));
+       return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c 
b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index f522dd42093a9f..cde69f56866562 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1295,7 +1295,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int 
budget)
+                       skb = ice_construct_skb(rx_ring, xdp);
+               /* exit if we failed to retrieve a buffer */
+               if (!skb) {
+-                      rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++                      rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+                       xdp_verdict = ICE_XDP_CONSUMED;
+               }
+               ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c 
b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index a2cf3e79693dd8..511b3ba2454207 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink 
*devlink, struct netli
+       if (err)
+               return err;
+ 
+-      mlx5_unload_one_devl_locked(dev, true);
++      mlx5_sync_reset_unload_flow(dev, true);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail 
after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index 3efa8bf1d14ef4..4720523813b976 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv 
*priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+ 
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv 
*priv,
+                       return err;
+       }
+ 
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h 
b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index f4a19ffbb641c0..66d276a1be836a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
+ 
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ 
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 4a2f58a9d70660..6176457b846bc1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -47,6 +47,7 @@
+ #include "en.h"
+ #include "en/dim.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -134,6 +135,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (up) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+@@ -2917,9 +2920,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
+ 
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2929,6 +2934,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev 
mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
+ 
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values 
with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c 
b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 4f55e55ecb5513..516df7f1997ebc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,13 +6,15 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+ 
+ enum {
+       MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+       MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+       MLX5_FW_RESET_FLAGS_PENDING_COMP,
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+-      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++      MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+ 
+ struct mlx5_fw_reset {
+@@ -218,7 +220,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+       return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+ 
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool 
unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+       struct devlink *devlink = priv_to_devlink(dev);
+@@ -227,8 +229,7 @@ static void mlx5_fw_reset_complete_reload(struct 
mlx5_core_dev *dev, bool unload
+       if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) 
{
+               complete(&fw_reset->done);
+       } else {
+-              if (!unloaded)
+-                      mlx5_unload_one(dev, false);
++              mlx5_sync_reset_unload_flow(dev, false);
+               if (mlx5_health_wait_pci_up(dev))
+                       mlx5_core_err(dev, "reset reload flow aborted, PCI 
reads still not working\n");
+               else
+@@ -271,7 +272,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct 
*work)
+ 
+       mlx5_sync_reset_clear_reset_requested(dev, false);
+       mlx5_enter_error_state(dev, true);
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ 
+ #define MLX5_RESET_POLL_INTERVAL      (HZ / 10)
+@@ -423,6 +424,11 @@ static bool mlx5_is_reset_now_capable(struct 
mlx5_core_dev *dev,
+               return false;
+       }
+ 
++      if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++              mlx5_core_warn(dev, "SFs should be removed before reset\n");
++              return false;
++      }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+       if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) {
+               err = mlx5_check_hotplug_interrupt(dev);
+@@ -581,6 +587,59 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, 
u8 reset_method)
+       return err;
+ }
+ 
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++      unsigned long timeout;
++      bool reset_action;
++      u8 rst_state;
++      int err;
++
++      if (locked)
++              mlx5_unload_one_devl_locked(dev, false);
++      else
++              mlx5_unload_one(dev, false);
++
++      if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++              return;
++
++      mlx5_set_fw_rst_ack(dev);
++      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++      reset_action = false;
++      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++      do {
++              rst_state = mlx5_get_fw_rst_state(dev);
++              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++                  rst_state == MLX5_FW_RST_STATE_IDLE) {
++                      reset_action = true;
++                      break;
++              }
++              msleep(20);
++      } while (!time_after(jiffies, timeout));
++
++      if (!reset_action) {
++              mlx5_core_err(dev, "Got timeout waiting for sync reset action, 
state = %u\n",
++                            rst_state);
++              fw_reset->ret = -ETIMEDOUT;
++              goto done;
++      }
++
++      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++                     rst_state);
++      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++              if (err) {
++                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err 
%d\n",
++                                     err);
++                      fw_reset->ret = err;
++              }
++      }
++
++done:
++      clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct 
mlx5_fw_reset,
+@@ -608,16 +667,13 @@ static void mlx5_sync_reset_now_event(struct work_struct 
*work)
+       mlx5_enter_error_state(dev, true);
+ done:
+       fw_reset->ret = err;
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ 
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset;
+       struct mlx5_core_dev *dev;
+-      unsigned long timeout;
+-      bool reset_action;
+-      u8 rst_state;
+       int err;
+ 
+       fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -626,6 +682,7 @@ static void mlx5_sync_reset_unload_event(struct 
work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, false))
+               return;
+ 
++      set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+ 
+       err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -634,44 +691,7 @@ static void mlx5_sync_reset_unload_event(struct 
work_struct *work)
+       else
+               mlx5_enter_error_state(dev, true);
+ 
+-      if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+-              mlx5_unload_one_devl_locked(dev, false);
+-      else
+-              mlx5_unload_one(dev, false);
+-
+-      mlx5_set_fw_rst_ack(dev);
+-      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+-      reset_action = false;
+-      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+-      do {
+-              rst_state = mlx5_get_fw_rst_state(dev);
+-              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+-                  rst_state == MLX5_FW_RST_STATE_IDLE) {
+-                      reset_action = true;
+-                      break;
+-              }
+-              msleep(20);
+-      } while (!time_after(jiffies, timeout));
+-
+-      if (!reset_action) {
+-              mlx5_core_err(dev, "Got timeout waiting for sync reset action, 
state = %u\n",
+-                            rst_state);
+-              fw_reset->ret = -ETIMEDOUT;
+-              goto done;
+-      }
+-
+-      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", 
rst_state);
+-      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+-              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+-              if (err) {
+-                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err 
%d\n", err);
+-                      fw_reset->ret = err;
+-              }
+-      }
+-
+-done:
+-      mlx5_fw_reset_complete_reload(dev, true);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ 
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h 
b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f07..d5b28525c960dc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, 
u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+ 
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+                                    struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c 
b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index b96909fbeb12de..bdac3db1bd61de 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -518,3 +518,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+       WARN_ON(!xa_empty(&table->function_ids));
+       kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      struct mlx5_sf_table *table = dev->priv.sf_table;
++
++      if (!table)
++              return true;
++
++      return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h 
b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b8..89559a37997ad6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+ 
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+ 
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+                            const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct 
mlx5_core_dev *dev)
+ {
+ }
+ 
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      return true;
++}
++
+ #endif
+ 
+ #endif
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c 
b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 79e94632533c80..a8c95b1732f4d8 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -53,6 +53,8 @@ int __fbnic_open(struct fbnic_net *fbn)
+       fbnic_bmc_rpc_init(fbd);
+       fbnic_rss_reinit(fbd, fbn);
+ 
++      phylink_resume(fbn->phylink);
++
+       return 0;
+ release_ownership:
+       fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
+@@ -79,6 +81,8 @@ static int fbnic_stop(struct net_device *netdev)
+ {
+       struct fbnic_net *fbn = netdev_priv(netdev);
+ 
++      phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd));
++
+       fbnic_down(fbn);
+       fbnic_pcs_irq_disable(fbn->fbd);
+ 
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c 
b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 268489b15616fd..72bdc6c76c0c5e 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -116,14 +116,12 @@ static void fbnic_service_task_start(struct fbnic_net 
*fbn)
+       struct fbnic_dev *fbd = fbn->fbd;
+ 
+       schedule_delayed_work(&fbd->service_task, HZ);
+-      phylink_resume(fbn->phylink);
+ }
+ 
+ static void fbnic_service_task_stop(struct fbnic_net *fbn)
+ {
+       struct fbnic_dev *fbd = fbn->fbd;
+ 
+-      phylink_suspend(fbn->phylink, fbnic_bmc_present(fbd));
+       cancel_delayed_work(&fbd->service_task);
+ }
+ 
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index f519d43738b080..445259f2ee9353 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -47,6 +47,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+       writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
+ 
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++      if (!priv->dma_cap.mbps_10_100)
++              priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++      else if (!priv->dma_cap.half_duplex)
++              priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+       u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1532,6 +1540,7 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr,
+ 
+ const struct stmmac_ops dwxgmac210_ops = {
+       .core_init = dwxgmac2_core_init,
++      .update_caps = dwxgmac2_update_caps,
+       .set_mac = dwxgmac2_set_mac,
+       .rx_ipc = dwxgmac2_rx_ipc,
+       .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1646,8 +1655,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+               mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+ 
+       mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+-                       MAC_1000FD | MAC_2500FD | MAC_5000FD |
+-                       MAC_10000FD;
++                       MAC_10 | MAC_100 | MAC_1000FD |
++                       MAC_2500FD | MAC_5000FD | MAC_10000FD;
+       mac->link.duplex = 0;
+       mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+       mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5dcc95bc0ad28b..4d6bb995d8d84c 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv 
*priv, void __iomem *ioaddr,
+       }
+ 
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ 
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem 
*ioaddr,
+@@ -386,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv 
*priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+                                  struct dma_features *dma_cap)
+ {
++      struct stmmac_priv *priv;
+       u32 hw_cap;
+ 
++      priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+       /* MAC HW feature 0 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+       dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -410,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+       dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+       dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+       dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++      if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++              dma_cap->mbps_10_100 = 1;
+ 
+       /* MAC HW feature 1 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 058cd9e9fd71dc..40d56ff66b6a82 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2488,6 +2488,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, 
u32 queue, u32 budget)
+       struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       struct xsk_buff_pool *pool = tx_q->xsk_pool;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc = NULL;
+@@ -2573,7 +2574,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, 
u32 queue, u32 budget)
+               }
+ 
+               stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+-                                     true, priv->mode, true, true,
++                                     csum, priv->mode, true, true,
+                                      xdp_desc.len);
+ 
+               stmmac_enable_dma_transmission(priv, priv->ioaddr, queue);
+@@ -4902,6 +4903,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv 
*priv, int queue,
+ {
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc;
+       dma_addr_t dma_addr;
+@@ -4953,7 +4955,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv 
*priv, int queue,
+       stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+ 
+       stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+-                             true, priv->mode, true, true,
++                             csum, priv->mode, true, true,
+                              xdpf->len);
+ 
+       tx_q->tx_count_frames++;
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 807465dd4c8e34..5f14799b68c532 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -712,8 +712,13 @@ void netvsc_device_remove(struct hv_device *device)
+       for (i = 0; i < net_device->num_chn; i++) {
+               /* See also vmbus_reset_channel_cb(). */
+               /* only disable enabled NAPI channel */
+-              if (i < ndev->real_num_rx_queues)
++              if (i < ndev->real_num_rx_queues) {
++                      netif_queue_set_napi(ndev, i, NETDEV_QUEUE_TYPE_TX,
++                                           NULL);
++                      netif_queue_set_napi(ndev, i, NETDEV_QUEUE_TYPE_RX,
++                                           NULL);
+                       napi_disable(&net_device->chan_table[i].napi);
++              }
+ 
+               netif_napi_del(&net_device->chan_table[i].napi);
+       }
+@@ -1806,6 +1811,11 @@ struct netvsc_device *netvsc_device_add(struct 
hv_device *device,
+ 
+       /* Enable NAPI handler before init callbacks */
+       netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll);
++      napi_enable(&net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++                           &net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++                           &net_device->chan_table[0].napi);
+ 
+       /* Open the channel */
+       device->channel->next_request_id_callback = vmbus_next_request_id;
+@@ -1825,8 +1835,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device 
*device,
+       /* Channel is opened */
+       netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+ 
+-      napi_enable(&net_device->chan_table[0].napi);
+-
+       /* Connect with the NetVsp */
+       ret = netvsc_connect_vsp(device, net_device, device_info);
+       if (ret != 0) {
+@@ -1844,12 +1852,14 @@ struct netvsc_device *netvsc_device_add(struct 
hv_device *device,
+ 
+ close:
+       RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
+-      napi_disable(&net_device->chan_table[0].napi);
+ 
+       /* Now, we can close the channel safely */
+       vmbus_close(device->channel);
+ 
+ cleanup:
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
++      napi_disable(&net_device->chan_table[0].napi);
+       netif_napi_del(&net_device->chan_table[0].napi);
+ 
+ cleanup2:
+diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
+index e457f809fe3110..9a92552ee35c28 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1252,13 +1252,27 @@ static void netvsc_sc_open(struct vmbus_channel 
*new_sc)
+       new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes);
+       new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE;
+ 
++      /* Enable napi before opening the vmbus channel to avoid races
++       * as the host placing data on the host->guest ring may be left
++       * out if napi was not enabled.
++       */
++      napi_enable(&nvchan->napi);
++      netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                           &nvchan->napi);
++      netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                           &nvchan->napi);
++
+       ret = vmbus_open(new_sc, netvsc_ring_bytes,
+                        netvsc_ring_bytes, NULL, 0,
+                        netvsc_channel_cb, nvchan);
+-      if (ret == 0)
+-              napi_enable(&nvchan->napi);
+-      else
++      if (ret != 0) {
+               netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                                   NULL);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                                   NULL);
++              napi_disable(&nvchan->napi);
++      }
+ 
+       if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+               wake_up(&nvscdev->subchan_open);
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 58c6d47fbe046d..2bfe314ef881c3 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -481,6 +481,7 @@ static inline void vsc8584_config_macsec_intr(struct 
phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -495,6 +496,9 @@ static inline int vsc8584_ptp_init(struct phy_device 
*phydev)
+ {
+       return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+       return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c 
b/drivers/net/phy/mscc/mscc_main.c
+index 42cafa68c40098..19983b206405c6 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2337,9 +2337,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+ 
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *priv = phydev->priv;
+-
+-      skb_queue_purge(&priv->rx_skbs_list);
++      vsc8584_ptp_deinit(phydev);
+ }
+ 
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index 80992827a3bdd1..920f35f8f84e71 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1295,7 +1295,6 @@ static void vsc8584_set_input_clk_configured(struct 
phy_device *phydev)
+ 
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *vsc8531 = phydev->priv;
+       static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+       static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+       u32 val;
+@@ -1512,17 +1511,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ 
+       vsc85xx_ts_eth_cmp1_sig(phydev);
+ 
+-      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+-      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+-      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+-      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+-      phydev->mii_ts = &vsc8531->mii_ts;
+-
+-      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, 
sizeof(vsc85xx_clk_caps));
+-
+-      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+-                                                   &phydev->mdio.dev);
+-      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++      return 0;
+ }
+ 
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1549,6 +1538,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+       return 0;
+ }
+ 
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++      struct vsc8531_private *vsc8531 = phydev->priv;
++
++      if (vsc8531->ptp->ptp_clock) {
++              ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++              skb_queue_purge(&vsc8531->rx_skbs_list);
++      }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+       struct vsc8531_private *priv = phydev->priv;
+@@ -1609,7 +1608,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+ 
+       vsc8531->ptp->phydev = phydev;
+ 
+-      return 0;
++      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
++      phydev->mii_ts = &vsc8531->mii_ts;
++
++      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, 
sizeof(vsc85xx_clk_caps));
++      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++                                                   &phydev->mdio.dev);
++      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+ 
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 7e0608f5683531..0a0f0e18762bb1 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1355,6 +1355,9 @@ static const struct usb_device_id products[] = {
+       {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
+       {QMI_FIXED_INTF(0x2357, 0x9000, 4)},    /* TP-LINK MA260 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */
++      {QMI_QUIRK_SET_DTR(0x1bc7, 0x1034, 2)}, /* Telit LE910C4-WWX */
++      {QMI_QUIRK_SET_DTR(0x1bc7, 0x1037, 4)}, /* Telit LE910C4-WWX */
++      {QMI_QUIRK_SET_DTR(0x1bc7, 0x1038, 3)}, /* Telit LE910C4-WWX */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */
+diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
+index 110104a936d9c1..492f0354a79227 100644
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -935,10 +935,15 @@ static int of_changeset_add_prop_helper(struct 
of_changeset *ocs,
+               return -ENOMEM;
+ 
+       ret = of_changeset_add_property(ocs, np, new_pp);
+-      if (ret)
++      if (ret) {
+               __of_prop_free(new_pp);
++              return ret;
++      }
+ 
+-      return ret;
++      new_pp->next = np->deadprops;
++      np->deadprops = new_pp;
++
++      return 0;
+ }
+ 
+ /**
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index 45445a1600a968..7b5d6562fe4a02 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -24,6 +24,7 @@
+ #include <linux/memblock.h>
+ #include <linux/kmemleak.h>
+ #include <linux/cma.h>
++#include <linux/dma-map-ops.h>
+ 
+ #include "of_private.h"
+ 
+@@ -128,13 +129,17 @@ static int __init __reserved_mem_reserve_reg(unsigned 
long node,
+               base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+               size = dt_mem_next_cell(dt_root_size_cells, &prop);
+ 
+-              if (size &&
+-                  early_init_dt_reserve_memory(base, size, nomap) == 0)
++              if (size && early_init_dt_reserve_memory(base, size, nomap) == 
0) {
++                      /* Architecture specific contiguous memory fixup. */
++                      if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++                          of_get_flat_dt_prop(node, "reusable", NULL))
++                              dma_contiguous_early_fixup(base, size);
+                       pr_debug("Reserved memory: reserved region for node 
'%s': base %pa, size %lu MiB\n",
+                               uname, &base, (unsigned long)(size / SZ_1M));
+-              else
++              } else {
+                       pr_err("Reserved memory: failed to reserve memory for 
node '%s': base %pa, size %lu MiB\n",
+                              uname, &base, (unsigned long)(size / SZ_1M));
++              }
+ 
+               len -= t_len;
+       }
+@@ -417,7 +422,10 @@ static int __init __reserved_mem_alloc_size(unsigned long 
node, const char *unam
+                      uname, (unsigned long)(size / SZ_1M));
+               return -ENOMEM;
+       }
+-
++      /* Architecture specific contiguous memory fixup. */
++      if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++          of_get_flat_dt_prop(node, "reusable", NULL))
++              dma_contiguous_early_fixup(base, size);
+       /* Save region in the reserved_mem array */
+       fdt_reserved_mem_save_node(node, uname, base, size);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c 
b/drivers/pci/controller/dwc/pcie-designware.c
+index d40afe74ddd1a3..f9473b8160778c 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -655,6 +655,14 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
+               return -ETIMEDOUT;
+       }
+ 
++      /*
++       * As per PCIe r6.0, sec 6.6.1, a Downstream Port that supports Link
++       * speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms
++       * after Link training completes before sending a Configuration Request.
++       */
++      if (pci->max_link_speed > 2)
++              msleep(PCIE_RESET_CONFIG_WAIT_MS);
++
+       offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+       val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
+ 
+diff --git a/drivers/pci/controller/plda/pcie-starfive.c 
b/drivers/pci/controller/plda/pcie-starfive.c
+index 0564fdce47c2a3..0a0b5a7d84d7ef 100644
+--- a/drivers/pci/controller/plda/pcie-starfive.c
++++ b/drivers/pci/controller/plda/pcie-starfive.c
+@@ -368,7 +368,7 @@ static int starfive_pcie_host_init(struct plda_pcie_rp 
*plda)
+        * of 100ms following exit from a conventional reset before
+        * sending a configuration request to the device.
+        */
+-      msleep(PCIE_RESET_CONFIG_DEVICE_WAIT_MS);
++      msleep(PCIE_RESET_CONFIG_WAIT_MS);
+ 
+       if (starfive_pcie_host_wait_for_link(pcie))
+               dev_info(dev, "port link down\n");
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index b65868e7095179..c951f861a69b27 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -57,7 +57,7 @@
+  *    completes before sending a Configuration Request to the device
+  *    immediately below that Port."
+  */
+-#define PCIE_RESET_CONFIG_DEVICE_WAIT_MS      100
++#define PCIE_RESET_CONFIG_WAIT_MS     100
+ 
+ /* Message Routing (r[2:0]); PCIe r6.0, sec 2.2.8 */
+ #define PCIE_MSG_TYPE_R_RC    0
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 354536de564b67..e05174e5efbc3a 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -504,6 +504,7 @@ config PINCTRL_STMFX
+       tristate "STMicroelectronics STMFX GPIO expander pinctrl driver"
+       depends on I2C
+       depends on OF_GPIO
++      depends on HAS_IOMEM
+       select GENERIC_PINCONF
+       select GPIOLIB_IRQCHIP
+       select MFD_STMFX
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 32f94db6d6bf5d..e669768a7a5bf5 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -265,7 +265,7 @@ show_shost_supported_mode(struct device *dev, struct 
device_attribute *attr,
+       return show_shost_mode(supported_mode, buf);
+ }
+ 
+-static DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, 
show_shost_supported_mode, NULL);
++static DEVICE_ATTR(supported_mode, S_IRUGO, show_shost_supported_mode, NULL);
+ 
+ static ssize_t
+ show_shost_active_mode(struct device *dev,
+@@ -279,7 +279,7 @@ show_shost_active_mode(struct device *dev,
+               return show_shost_mode(shost->active_mode, buf);
+ }
+ 
+-static DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, 
NULL);
++static DEVICE_ATTR(active_mode, S_IRUGO, show_shost_active_mode, NULL);
+ 
+ static int check_reset_type(const char *str)
+ {
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c 
b/drivers/thermal/mediatek/lvts_thermal.c
+index ae063d1bc95f86..017191b9f8645f 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -121,7 +121,11 @@ struct lvts_ctrl_data {
+ 
+ struct lvts_data {
+       const struct lvts_ctrl_data *lvts_ctrl;
++      const u32 *conn_cmd;
++      const u32 *init_cmd;
+       int num_lvts_ctrl;
++      int num_conn_cmd;
++      int num_init_cmd;
+       int temp_factor;
+       int temp_offset;
+       int gt_calib_bit_offset;
+@@ -880,7 +884,7 @@ static void lvts_ctrl_monitor_enable(struct device *dev, 
struct lvts_ctrl *lvts_
+  * each write in the configuration register must be separated by a
+  * delay of 2 us.
+  */
+-static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, u32 *cmds, int 
nr_cmds)
++static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, const u32 *cmds, 
int nr_cmds)
+ {
+       int i;
+ 
+@@ -963,9 +967,10 @@ static int lvts_ctrl_set_enable(struct lvts_ctrl 
*lvts_ctrl, int enable)
+ 
+ static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+ {
+-      u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
++      const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
++      u32 id;
+ 
+-      lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
++      lvts_write_config(lvts_ctrl, lvts_data->conn_cmd, 
lvts_data->num_conn_cmd);
+ 
+       /*
+        * LVTS_ID : Get ID and status of the thermal controller
+@@ -984,17 +989,9 @@ static int lvts_ctrl_connect(struct device *dev, struct 
lvts_ctrl *lvts_ctrl)
+ 
+ static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl 
*lvts_ctrl)
+ {
+-      /*
+-       * Write device mask: 0xC1030000
+-       */
+-      u32 cmds[] = {
+-              0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
+-              0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
+-              0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
+-              0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
+-      };
++      const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
+ 
+-      lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
++      lvts_write_config(lvts_ctrl, lvts_data->init_cmd, 
lvts_data->num_init_cmd);
+ 
+       return 0;
+ }
+@@ -1423,6 +1420,25 @@ static int lvts_resume(struct device *dev)
+       return 0;
+ }
+ 
++static const u32 default_conn_cmds[] = { 0xC103FFFF, 0xC502FF55 };
++static const u32 mt7988_conn_cmds[] = { 0xC103FFFF, 0xC502FC55 };
++
++/*
++ * Write device mask: 0xC1030000
++ */
++static const u32 default_init_cmds[] = {
++      0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
++      0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
++      0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
++      0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
++};
++
++static const u32 mt7988_init_cmds[] = {
++      0xC1030300, 0xC1030420, 0xC1030500, 0xC10307A6, 0xC1030CFC,
++      0xC1030A8C, 0xC103098D, 0xC10308F1, 0xC1030B04, 0xC1030E01,
++      0xC10306B8
++};
++
+ /*
+  * The MT8186 calibration data is stored as packed 3-byte little-endian
+  * values using a weird layout that makes sense only when viewed as a 32-bit
+@@ -1717,7 +1733,11 @@ static const struct lvts_ctrl_data 
mt8195_lvts_ap_data_ctrl[] = {
+ 
+ static const struct lvts_data mt7988_lvts_ap_data = {
+       .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
++      .conn_cmd       = mt7988_conn_cmds,
++      .init_cmd       = mt7988_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt7988_lvts_ap_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(mt7988_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(mt7988_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT7988,
+       .temp_offset    = LVTS_COEFF_B_MT7988,
+       .gt_calib_bit_offset = 24,
+@@ -1725,7 +1745,11 @@ static const struct lvts_data mt7988_lvts_ap_data = {
+ 
+ static const struct lvts_data mt8186_lvts_data = {
+       .lvts_ctrl      = mt8186_lvts_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8186_lvts_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT7988,
+       .temp_offset    = LVTS_COEFF_B_MT7988,
+       .gt_calib_bit_offset = 24,
+@@ -1734,7 +1758,11 @@ static const struct lvts_data mt8186_lvts_data = {
+ 
+ static const struct lvts_data mt8188_lvts_mcu_data = {
+       .lvts_ctrl      = mt8188_lvts_mcu_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8188_lvts_mcu_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT8195,
+       .temp_offset    = LVTS_COEFF_B_MT8195,
+       .gt_calib_bit_offset = 20,
+@@ -1743,7 +1771,11 @@ static const struct lvts_data mt8188_lvts_mcu_data = {
+ 
+ static const struct lvts_data mt8188_lvts_ap_data = {
+       .lvts_ctrl      = mt8188_lvts_ap_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8188_lvts_ap_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT8195,
+       .temp_offset    = LVTS_COEFF_B_MT8195,
+       .gt_calib_bit_offset = 20,
+@@ -1752,7 +1784,11 @@ static const struct lvts_data mt8188_lvts_ap_data = {
+ 
+ static const struct lvts_data mt8192_lvts_mcu_data = {
+       .lvts_ctrl      = mt8192_lvts_mcu_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8192_lvts_mcu_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT8195,
+       .temp_offset    = LVTS_COEFF_B_MT8195,
+       .gt_calib_bit_offset = 24,
+@@ -1761,7 +1797,11 @@ static const struct lvts_data mt8192_lvts_mcu_data = {
+ 
+ static const struct lvts_data mt8192_lvts_ap_data = {
+       .lvts_ctrl      = mt8192_lvts_ap_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8192_lvts_ap_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT8195,
+       .temp_offset    = LVTS_COEFF_B_MT8195,
+       .gt_calib_bit_offset = 24,
+@@ -1770,7 +1810,11 @@ static const struct lvts_data mt8192_lvts_ap_data = {
+ 
+ static const struct lvts_data mt8195_lvts_mcu_data = {
+       .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT8195,
+       .temp_offset    = LVTS_COEFF_B_MT8195,
+       .gt_calib_bit_offset = 24,
+@@ -1779,7 +1823,11 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
+ 
+ static const struct lvts_data mt8195_lvts_ap_data = {
+       .lvts_ctrl      = mt8195_lvts_ap_data_ctrl,
++      .conn_cmd       = default_conn_cmds,
++      .init_cmd       = default_init_cmds,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(default_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(default_init_cmds),
+       .temp_factor    = LVTS_COEFF_A_MT8195,
+       .temp_offset    = LVTS_COEFF_B_MT8195,
+       .gt_calib_bit_offset = 24,
+diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
+index f16279351db56e..aff4ec78356287 100644
+--- a/drivers/vhost/net.c
++++ b/drivers/vhost/net.c
+@@ -96,6 +96,7 @@ struct vhost_net_ubuf_ref {
+       atomic_t refcount;
+       wait_queue_head_t wait;
+       struct vhost_virtqueue *vq;
++      struct rcu_head rcu;
+ };
+ 
+ #define VHOST_NET_BATCH 64
+@@ -247,9 +248,13 @@ vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool 
zcopy)
+ 
+ static int vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs)
+ {
+-      int r = atomic_sub_return(1, &ubufs->refcount);
++      int r;
++
++      rcu_read_lock();
++      r = atomic_sub_return(1, &ubufs->refcount);
+       if (unlikely(!r))
+               wake_up(&ubufs->wait);
++      rcu_read_unlock();
+       return r;
+ }
+ 
+@@ -262,7 +267,7 @@ static void vhost_net_ubuf_put_and_wait(struct 
vhost_net_ubuf_ref *ubufs)
+ static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs)
+ {
+       vhost_net_ubuf_put_and_wait(ubufs);
+-      kfree(ubufs);
++      kfree_rcu(ubufs, rcu);
+ }
+ 
+ static void vhost_net_clear_ubuf_info(struct vhost_net *n)
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 11ebddc57bc73a..1831e015b2f26f 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -127,6 +127,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
+ 
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+ 
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index f35d2eb0ed11c5..63acd91d15aada 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -1410,6 +1410,16 @@ static void z_erofs_decompressqueue_kthread_work(struct 
kthread_work *work)
+ }
+ #endif
+ 
++/* Use (kthread_)work in atomic contexts to minimize scheduling overhead */
++static inline bool z_erofs_in_atomic(void)
++{
++      if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth())
++              return true;
++      if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
++              return true;
++      return !preemptible();
++}
++
+ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
+                                      int bios)
+ {
+@@ -1424,8 +1434,7 @@ static void z_erofs_decompress_kickoff(struct 
z_erofs_decompressqueue *io,
+ 
+       if (atomic_add_return(bios, &io->pending_bios))
+               return;
+-      /* Use (kthread_)work and sync decompression for atomic contexts only */
+-      if (!in_task() || irqs_disabled() || rcu_read_lock_any_held()) {
++      if (z_erofs_in_atomic()) {
+ #ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
+               struct kthread_worker *worker;
+ 
+diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
+index 9d96b833015c82..64dc7ec045d87d 100644
+--- a/fs/smb/client/cifsfs.c
++++ b/fs/smb/client/cifsfs.c
+@@ -1348,6 +1348,20 @@ static loff_t cifs_remap_file_range(struct file 
*src_file, loff_t off,
+                       truncate_setsize(target_inode, new_size);
+                       fscache_resize_cookie(cifs_inode_cookie(target_inode),
+                                             new_size);
++              } else if (rc == -EOPNOTSUPP) {
++                      /*
++                       * copy_file_range syscall man page indicates EINVAL
++                       * is returned e.g when "fd_in and fd_out refer to the
++                       * same file and the source and target ranges overlap."
++                       * Test generic/157 was what showed these cases where
++                       * we need to remap EOPNOTSUPP to EINVAL
++                       */
++                      if (off >= src_inode->i_size) {
++                              rc = -EINVAL;
++                      } else if (src_inode == target_inode) {
++                              if (off + len > destoff)
++                                      rc = -EINVAL;
++                      }
+               }
+               if (rc == 0 && new_size > target_cifsi->netfs.zero_point)
+                       target_cifsi->netfs.zero_point = new_size;
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index 31fce0a1b57191..c0df2c1841243e 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -1917,15 +1917,24 @@ int cifs_unlink(struct inode *dir, struct dentry 
*dentry)
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       struct tcon_link *tlink;
+       struct cifs_tcon *tcon;
++      __u32 dosattr = 0, origattr = 0;
+       struct TCP_Server_Info *server;
+       struct iattr *attrs = NULL;
+-      __u32 dosattr = 0, origattr = 0;
++      bool rehash = false;
+ 
+       cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry);
+ 
+       if (unlikely(cifs_forced_shutdown(cifs_sb)))
+               return -EIO;
+ 
++      /* Unhash dentry in advance to prevent any concurrent opens */
++      spin_lock(&dentry->d_lock);
++      if (!d_unhashed(dentry)) {
++              __d_drop(dentry);
++              rehash = true;
++      }
++      spin_unlock(&dentry->d_lock);
++
+       tlink = cifs_sb_tlink(cifs_sb);
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
+@@ -1977,7 +1986,8 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
+                       cifs_drop_nlink(inode);
+               }
+       } else if (rc == -ENOENT) {
+-              d_drop(dentry);
++              if (simple_positive(dentry))
++                      d_delete(dentry);
+       } else if (rc == -EBUSY) {
+               if (server->ops->rename_pending_delete) {
+                       rc = server->ops->rename_pending_delete(full_path,
+@@ -2030,6 +2040,8 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
+       kfree(attrs);
+       free_xid(xid);
+       cifs_put_tlink(tlink);
++      if (rehash)
++              d_rehash(dentry);
+       return rc;
+ }
+ 
+@@ -2429,6 +2441,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode 
*source_dir,
+       struct cifs_sb_info *cifs_sb;
+       struct tcon_link *tlink;
+       struct cifs_tcon *tcon;
++      bool rehash = false;
+       unsigned int xid;
+       int rc, tmprc;
+       int retry_count = 0;
+@@ -2444,6 +2457,17 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode 
*source_dir,
+       if (unlikely(cifs_forced_shutdown(cifs_sb)))
+               return -EIO;
+ 
++      /*
++       * Prevent any concurrent opens on the target by unhashing the dentry.
++       * VFS already unhashes the target when renaming directories.
++       */
++      if (d_is_positive(target_dentry) && !d_is_dir(target_dentry)) {
++              if (!d_unhashed(target_dentry)) {
++                      d_drop(target_dentry);
++                      rehash = true;
++              }
++      }
++
+       tlink = cifs_sb_tlink(cifs_sb);
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
+@@ -2485,6 +2509,8 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode 
*source_dir,
+               }
+       }
+ 
++      if (!rc)
++              rehash = false;
+       /*
+        * No-replace is the natural behavior for CIFS, so skip unlink hacks.
+        */
+@@ -2543,12 +2569,16 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode 
*source_dir,
+                       goto cifs_rename_exit;
+               rc = cifs_do_rename(xid, source_dentry, from_name,
+                                   target_dentry, to_name);
++              if (!rc)
++                      rehash = false;
+       }
+ 
+       /* force revalidate to go get info when needed */
+       CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0;
+ 
+ cifs_rename_exit:
++      if (rehash)
++              d_rehash(target_dentry);
+       kfree(info_buf_source);
+       free_dentry_path(page2);
+       free_dentry_path(page1);
+diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
+index 6048b3fed3e787..b51ccfb8843941 100644
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -206,8 +206,10 @@ static int smb2_compound_op(const unsigned int xid, 
struct cifs_tcon *tcon,
+       server = cifs_pick_channel(ses);
+ 
+       vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
+-      if (vars == NULL)
+-              return -ENOMEM;
++      if (vars == NULL) {
++              rc = -ENOMEM;
++              goto out;
++      }
+       rqst = &vars->rqst[0];
+       rsp_iov = &vars->rsp_iov[0];
+ 
+@@ -832,6 +834,7 @@ static int smb2_compound_op(const unsigned int xid, struct 
cifs_tcon *tcon,
+           smb2_should_replay(tcon, &retries, &cur_sleep))
+               goto replay_again;
+ 
++out:
+       if (cfile)
+               cifsFileInfo_put(cfile);
+ 
+diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
+index 4c44ce1c8a644b..bff3dc226f8128 100644
+--- a/fs/xfs/libxfs/xfs_attr_remote.c
++++ b/fs/xfs/libxfs/xfs_attr_remote.c
+@@ -435,6 +435,13 @@ xfs_attr_rmtval_get(
+                                       0, &bp, &xfs_attr3_rmt_buf_ops);
+                       if (xfs_metadata_is_sick(error))
+                               xfs_dirattr_mark_sick(args->dp, XFS_ATTR_FORK);
++                      /*
++                       * ENODATA from disk implies a disk medium failure;
++                       * ENODATA for xattrs means attribute not found, so
++                       * disambiguate that here.
++                       */
++                      if (error == -ENODATA)
++                              error = -EIO;
+                       if (error)
+                               return error;
+ 
+diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
+index 17d9e6154f1978..723a0643b8386c 100644
+--- a/fs/xfs/libxfs/xfs_da_btree.c
++++ b/fs/xfs/libxfs/xfs_da_btree.c
+@@ -2833,6 +2833,12 @@ xfs_da_read_buf(
+                       &bp, ops);
+       if (xfs_metadata_is_sick(error))
+               xfs_dirattr_mark_sick(dp, whichfork);
++      /*
++       * ENODATA from disk implies a disk medium failure; ENODATA for
++       * xattrs means attribute not found, so disambiguate that here.
++       */
++      if (error == -ENODATA && whichfork == XFS_ATTR_FORK)
++              error = -EIO;
+       if (error)
+               goto out_free;
+ 
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8a..70807c679f1abc 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
+index b7773201414c27..b42408a24ad13a 100644
+--- a/include/linux/dma-map-ops.h
++++ b/include/linux/dma-map-ops.h
+@@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, 
struct page *page,
+ {
+       __free_pages(page, get_order(size));
+ }
++static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long 
size)
++{
++}
+ #endif /* CONFIG_DMA_CMA*/
+ 
+ #ifdef CONFIG_DMA_DECLARE_COHERENT
+diff --git a/include/net/bluetooth/hci_sync.h 
b/include/net/bluetooth/hci_sync.h
+index dbabc17b30cdfa..17e5112f7840e0 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+ 
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+ 
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa32..2b5491bbf39ab5 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H 
+ 
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+       ax25_cb                 *ax25;
+       struct net_device               *dev;
+       unsigned short          count;
+-      unsigned short          use;
++      refcount_t              use;
+       unsigned int            number;
+       char                    restarted;
+       char                    dce_mode;
+@@ -151,6 +152,21 @@ struct rose_sock {
+ 
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+ 
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++      refcount_inc(&rose_neigh->use);
++}
++
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++      if (refcount_dec_and_test(&rose_neigh->use)) {
++              if (rose_neigh->ax25)
++                      ax25_cb_put(rose_neigh->ax25);
++              kfree(rose_neigh->digipeat);
++              kfree(rose_neigh);
++      }
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int  sysctl_rose_restart_request_timeout;
+diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
+index 1c7e7035fc49d1..96b178f1bd5ca5 100644
+--- a/include/uapi/linux/vhost.h
++++ b/include/uapi/linux/vhost.h
+@@ -254,7 +254,7 @@
+  * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD:
+  *   - Vhost will create vhost workers as kernel threads.
+  */
+-#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x83, __u8)
++#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x84, __u8)
+ 
+ /**
+  * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost 
device.
+@@ -262,6 +262,6 @@
+  *
+  * @return: An 8-bit value indicating the current thread mode.
+  */
+-#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x84, __u8)
++#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x85, __u8)
+ 
+ #endif
+diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
+index 8df0dfaaca18ee..9e5d63efe7c577 100644
+--- a/kernel/dma/contiguous.c
++++ b/kernel/dma/contiguous.c
+@@ -480,8 +480,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
+               pr_err("Reserved memory: unable to setup CMA region\n");
+               return err;
+       }
+-      /* Architecture specific contiguous memory fixup. */
+-      dma_contiguous_early_fixup(rmem->base, rmem->size);
+ 
+       if (default_cma)
+               dma_contiguous_default_area = cma;
+diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
+index 7b04f7575796b8..ee45dee33d4916 100644
+--- a/kernel/dma/pool.c
++++ b/kernel/dma/pool.c
+@@ -102,8 +102,8 @@ static int atomic_pool_expand(struct gen_pool *pool, 
size_t pool_size,
+ 
+ #ifdef CONFIG_DMA_DIRECT_REMAP
+       addr = dma_common_contiguous_remap(page, pool_size,
+-                                         pgprot_dmacoherent(PAGE_KERNEL),
+-                                         __builtin_return_address(0));
++                      pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
++                      __builtin_return_address(0));
+       if (!addr)
+               goto free_page;
+ #else
+diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
+index c12335499ec91e..2eed8bc672f913 100644
+--- a/kernel/trace/fgraph.c
++++ b/kernel/trace/fgraph.c
+@@ -1316,6 +1316,7 @@ int register_ftrace_graph(struct fgraph_ops *gops)
+               ftrace_graph_active--;
+               gops->saved_func = NULL;
+               fgraph_lru_release_index(i);
++              unregister_pm_notifier(&ftrace_suspend_notifier);
+       }
+       return ret;
+ }
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 2f662ca4d3ffd7..ba3358eef34baa 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -10130,10 +10130,10 @@ static void ftrace_dump_one(struct trace_array *tr, 
enum ftrace_dump_mode dump_m
+                       ret = print_trace_line(&iter);
+                       if (ret != TRACE_TYPE_NO_CONSUME)
+                               trace_consume(&iter);
++
++                      trace_printk_seq(&iter.seq);
+               }
+               touch_nmi_watchdog();
+-
+-              trace_printk_seq(&iter.seq);
+       }
+ 
+       if (!cnt)
+diff --git a/net/atm/common.c b/net/atm/common.c
+index d7f7976ea13ac6..881c7f259dbd46 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, 
size_t size)
+ 
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ 
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 768bd5fd808f2b..262ff30261d67d 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2694,7 +2694,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 
status)
+       if (!conn)
+               goto unlock;
+ 
+-      if (status) {
++      if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, status);
+ 
+@@ -2709,6 +2709,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 
status)
+               goto done;
+       }
+ 
++      /* During suspend, mark connection as closed immediately
++       * since we might not receive HCI_EV_DISCONN_COMPLETE
++       */
++      if (hdev->suspended)
++              conn->state = BT_CLOSED;
++
+       mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+ 
+       if (conn->type == ACL_LINK) {
+@@ -4389,7 +4395,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, 
void *data,
+               if (!conn)
+                       continue;
+ 
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+ 
+               switch (conn->type) {
+               case ACL_LINK:
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index af86df9de941df..bc2aa514b8c5d8 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3491,13 +3491,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+       return hci_write_scan_enable_sync(hdev, scan);
+ }
+ 
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+       struct hci_cp_write_local_name cp;
+ 
+       memset(&cp, 0, sizeof(cp));
+ 
+-      memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++      memcpy(cp.name, name, sizeof(cp.name));
+ 
+       return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+                                           sizeof(cp), &cp,
+@@ -3550,7 +3550,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+                       hci_write_fast_connectable_sync(hdev, false);
+               hci_update_scan_sync(hdev);
+               hci_update_class_sync(hdev);
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, hdev->dev_name);
+               hci_update_eir_sync(hdev);
+       }
+ 
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index ade93532db34b5..8b75647076baec 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3826,8 +3826,11 @@ static void set_name_complete(struct hci_dev *hdev, 
void *data, int err)
+ 
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++      struct mgmt_pending_cmd *cmd = data;
++      struct mgmt_cp_set_local_name *cp = cmd->param;
++
+       if (lmp_bredr_capable(hdev)) {
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, cp->name);
+               hci_update_eir_sync(hdev);
+       }
+ 
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 9a5c9497b3931d..261ddb6542a40f 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2532,12 +2532,16 @@ static struct rtable *__mkroute_output(const struct 
fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+ 
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+ 
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 53baf2dd5d5dab..16c514f628eaca 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -129,22 +129,12 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = {
+ 
+ static const struct proto_ops pppol2tp_ops;
+ 
+-/* Retrieves the pppol2tp socket associated to a session.
+- * A reference is held on the returned socket, so this function must be paired
+- * with sock_put().
+- */
++/* Retrieves the pppol2tp socket associated to a session. */
+ static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session)
+ {
+       struct pppol2tp_session *ps = l2tp_session_priv(session);
+-      struct sock *sk;
+-
+-      rcu_read_lock();
+-      sk = rcu_dereference(ps->sk);
+-      if (sk)
+-              sock_hold(sk);
+-      rcu_read_unlock();
+ 
+-      return sk;
++      return rcu_dereference(ps->sk);
+ }
+ 
+ /* Helpers to obtain tunnel/session contexts from sockets.
+@@ -206,14 +196,13 @@ static int pppol2tp_recvmsg(struct socket *sock, struct 
msghdr *msg,
+ 
+ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, 
int data_len)
+ {
+-      struct pppol2tp_session *ps = l2tp_session_priv(session);
+-      struct sock *sk = NULL;
++      struct sock *sk;
+ 
+       /* If the socket is bound, send it in to PPP's input queue. Otherwise
+        * queue it on the session socket.
+        */
+       rcu_read_lock();
+-      sk = rcu_dereference(ps->sk);
++      sk = pppol2tp_session_get_sock(session);
+       if (!sk)
+               goto no_sock;
+ 
+@@ -510,13 +499,14 @@ static void pppol2tp_show(struct seq_file *m, void *arg)
+       struct l2tp_session *session = arg;
+       struct sock *sk;
+ 
++      rcu_read_lock();
+       sk = pppol2tp_session_get_sock(session);
+       if (sk) {
+               struct pppox_sock *po = pppox_sk(sk);
+ 
+               seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
+-              sock_put(sk);
+       }
++      rcu_read_unlock();
+ }
+ 
+ static void pppol2tp_session_init(struct l2tp_session *session)
+@@ -1529,6 +1519,7 @@ static void pppol2tp_seq_session_show(struct seq_file 
*m, void *v)
+               port = ntohs(inet->inet_sport);
+       }
+ 
++      rcu_read_lock();
+       sk = pppol2tp_session_get_sock(session);
+       if (sk) {
+               state = sk->sk_state;
+@@ -1564,8 +1555,8 @@ static void pppol2tp_seq_session_show(struct seq_file 
*m, void *v)
+               struct pppox_sock *po = pppox_sk(sk);
+ 
+               seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
+-              sock_put(sk);
+       }
++      rcu_read_unlock();
+ }
+ 
+ static int pppol2tp_seq_show(struct seq_file *m, void *v)
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index a4a668b88a8f27..b8078b42f5de67 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+ 
+               if (rose->neighbour == neigh) {
+                       rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour = NULL;
+               }
+       }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+               if (rose->device == dev) {
+                       rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+                       if (rose->neighbour)
+-                              rose->neighbour->use--;
++                              rose_neigh_put(rose->neighbour);
+                       netdev_put(rose->device, &rose->dev_tracker);
+                       rose->device = NULL;
+               }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+               break;
+ 
+       case ROSE_STATE_2:
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               release_sock(sk);
+               rose_disconnect(sk, 0, -1, -1);
+               lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct 
sockaddr *uaddr, int addr_le
+       rose->lci = rose_new_lci(rose->neighbour);
+       if (!rose->lci) {
+               err = -ENETUNREACH;
++              rose_neigh_put(rose->neighbour);
+               goto out_release;
+       }
+ 
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct 
sockaddr *uaddr, int addr_le
+               dev = rose_dev_first();
+               if (!dev) {
+                       err = -ENETUNREACH;
++                      rose_neigh_put(rose->neighbour);
+                       goto out_release;
+               }
+ 
+               user = ax25_findbyuid(current_euid());
+               if (!user) {
+                       err = -EINVAL;
++                      rose_neigh_put(rose->neighbour);
+                       dev_put(dev);
+                       goto out_release;
+               }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct 
sockaddr *uaddr, int addr_le
+ 
+       rose->state = ROSE_STATE_1;
+ 
+-      rose->neighbour->use++;
+-
+       rose_write_internal(sk, ROSE_CALL_REQUEST);
+       rose_start_heartbeat(sk);
+       rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct 
net_device *dev, struct ros
+                            GFP_ATOMIC);
+       make_rose->facilities    = facilities;
+ 
+-      make_rose->neighbour->use++;
++      rose_neigh_hold(make_rose->neighbour);
+ 
+       if (rose_sk(sk)->defer) {
+               make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b49..7caae93937ee9b 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct 
sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+ 
+       default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct 
sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+ 
+       case ROSE_CLEAR_CONFIRMATION:
+               rose_disconnect(sk, 0, -1, -1);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+ 
+       default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct 
sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+ 
+       case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct 
sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+ 
+       default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct 
sk_buff *skb, int framety
+       if (frametype == ROSE_CLEAR_REQUEST) {
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose_sk(sk)->neighbour->use--;
++              rose_neigh_put(rose_sk(sk)->neighbour);
+       }
+ 
+       return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52dfa..28746ae5a25828 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct 
rose_route_struct *rose_route,
+               rose_neigh->ax25      = NULL;
+               rose_neigh->dev       = dev;
+               rose_neigh->count     = 0;
+-              rose_neigh->use       = 0;
+               rose_neigh->dce_mode  = 0;
+               rose_neigh->loopback  = 0;
+               rose_neigh->number    = rose_neigh_no++;
+               rose_neigh->restarted = 0;
++              refcount_set(&rose_neigh->use, 1);
+ 
+               skb_queue_head_init(&rose_neigh->queue);
+ 
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct 
rose_route_struct *rose_route,
+                       }
+               }
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+ 
+               goto out;
+       }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct 
rose_route_struct *rose_route,
+               rose_node->neighbour[rose_node->count] = rose_neigh;
+               rose_node->count++;
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+       }
+ 
+ out:
+@@ -234,20 +236,12 @@ static void rose_remove_neigh(struct rose_neigh 
*rose_neigh)
+ 
+       if ((s = rose_neigh_list) == rose_neigh) {
+               rose_neigh_list = rose_neigh->next;
+-              if (rose_neigh->ax25)
+-                      ax25_cb_put(rose_neigh->ax25);
+-              kfree(rose_neigh->digipeat);
+-              kfree(rose_neigh);
+               return;
+       }
+ 
+       while (s != NULL && s->next != NULL) {
+               if (s->next == rose_neigh) {
+                       s->next = rose_neigh->next;
+-                      if (rose_neigh->ax25)
+-                              ax25_cb_put(rose_neigh->ax25);
+-                      kfree(rose_neigh->digipeat);
+-                      kfree(rose_neigh);
+                       return;
+               }
+ 
+@@ -263,10 +257,10 @@ static void rose_remove_route(struct rose_route 
*rose_route)
+       struct rose_route *s;
+ 
+       if (rose_route->neigh1 != NULL)
+-              rose_route->neigh1->use--;
++              rose_neigh_put(rose_route->neigh1);
+ 
+       if (rose_route->neigh2 != NULL)
+-              rose_route->neigh2->use--;
++              rose_neigh_put(rose_route->neigh2);
+ 
+       if ((s = rose_route_list) == rose_route) {
+               rose_route_list = rose_route->next;
+@@ -330,9 +324,12 @@ static int rose_del_node(struct rose_route_struct 
*rose_route,
+       for (i = 0; i < rose_node->count; i++) {
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
++                      rose_neigh_put(rose_neigh);
+ 
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0)
++                      if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
++                              rose_neigh_put(rose_neigh);
++                      }
+ 
+                       rose_node->count--;
+ 
+@@ -381,11 +378,11 @@ void rose_add_loopback_neigh(void)
+       sn->ax25      = NULL;
+       sn->dev       = NULL;
+       sn->count     = 0;
+-      sn->use       = 0;
+       sn->dce_mode  = 1;
+       sn->loopback  = 1;
+       sn->number    = rose_neigh_no++;
+       sn->restarted = 1;
++      refcount_set(&sn->use, 1);
+ 
+       skb_queue_head_init(&sn->queue);
+ 
+@@ -436,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+       rose_node_list  = rose_node;
+ 
+       rose_loopback_neigh->count++;
++      rose_neigh_hold(rose_loopback_neigh);
+ 
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -467,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+       rose_remove_node(rose_node);
+ 
+       rose_loopback_neigh->count--;
++      rose_neigh_put(rose_loopback_neigh);
+ 
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -506,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+                               memmove(&t->neighbour[i], &t->neighbour[i + 1],
+                                       sizeof(t->neighbour[0]) *
+                                               (t->count - i));
++                              rose_neigh_put(s);
+                       }
+ 
+                       if (t->count <= 0)
+@@ -513,6 +513,7 @@ void rose_rt_device_down(struct net_device *dev)
+               }
+ 
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       spin_unlock_bh(&rose_neigh_list_lock);
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -548,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+       struct rose_neigh *s, *rose_neigh;
+       struct rose_node  *t, *rose_node;
++      int i;
+ 
+       spin_lock_bh(&rose_node_list_lock);
+       spin_lock_bh(&rose_neigh_list_lock);
+@@ -558,17 +560,21 @@ static int rose_clear_routes(void)
+       while (rose_node != NULL) {
+               t         = rose_node;
+               rose_node = rose_node->next;
+-              if (!t->loopback)
++
++              if (!t->loopback) {
++                      for (i = 0; i < t->count; i++)
++                              rose_neigh_put(t->neighbour[i]);
+                       rose_remove_node(t);
++              }
+       }
+ 
+       while (rose_neigh != NULL) {
+               s          = rose_neigh;
+               rose_neigh = rose_neigh->next;
+ 
+-              if (s->use == 0 && !s->loopback) {
+-                      s->count = 0;
++              if (!s->loopback) {
+                       rose_remove_neigh(s);
++                      rose_neigh_put(s);
+               }
+       }
+ 
+@@ -684,6 +690,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, 
unsigned char *cause,
+                       for (i = 0; i < node->count; i++) {
+                               if (node->neighbour[i]->restarted) {
+                                       res = node->neighbour[i];
++                                      rose_neigh_hold(node->neighbour[i]);
+                                       goto out;
+                               }
+                       }
+@@ -695,6 +702,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, 
unsigned char *cause,
+                               for (i = 0; i < node->count; i++) {
+                                       if 
(!rose_ftimer_running(node->neighbour[i])) {
+                                               res = node->neighbour[i];
++                                              
rose_neigh_hold(node->neighbour[i]);
+                                               goto out;
+                                       }
+                                       failed = 1;
+@@ -784,13 +792,13 @@ static void rose_del_route_by_neigh(struct rose_neigh 
*rose_neigh)
+               }
+ 
+               if (rose_route->neigh1 == rose_neigh) {
+-                      rose_route->neigh1->use--;
++                      rose_neigh_put(rose_route->neigh1);
+                       rose_route->neigh1 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh2, 
rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+               }
+ 
+               if (rose_route->neigh2 == rose_neigh) {
+-                      rose_route->neigh2->use--;
++                      rose_neigh_put(rose_route->neigh2);
+                       rose_route->neigh2 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh1, 
rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+               }
+@@ -919,7 +927,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+                       rose_clear_queues(sk);
+                       rose->cause      = ROSE_NETWORK_CONGESTION;
+                       rose->diagnostic = 0;
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour  = NULL;
+                       rose->lci        = 0;
+                       rose->state      = ROSE_STATE_0;
+@@ -1044,12 +1052,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb 
*ax25)
+ 
+       if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+               rose_transmit_clear_request(rose_neigh, lci, 
ROSE_NETWORK_CONGESTION, 71);
+-              goto out;
++              goto put_neigh;
+       }
+ 
+       if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+               rose_transmit_clear_request(rose_neigh, lci, 
ROSE_NETWORK_CONGESTION, 120);
+-              goto out;
++              goto put_neigh;
+       }
+ 
+       rose_route->lci1      = lci;
+@@ -1062,8 +1070,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_route->lci2      = new_lci;
+       rose_route->neigh2    = new_neigh;
+ 
+-      rose_route->neigh1->use++;
+-      rose_route->neigh2->use++;
++      rose_neigh_hold(rose_route->neigh1);
++      rose_neigh_hold(rose_route->neigh2);
+ 
+       rose_route->next = rose_route_list;
+       rose_route_list  = rose_route;
+@@ -1075,6 +1083,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_transmit_link(skb, rose_route->neigh2);
+       res = 1;
+ 
++put_neigh:
++      rose_neigh_put(new_neigh);
+ out:
+       spin_unlock_bh(&rose_route_list_lock);
+       spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1190,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, 
&rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         rose_neigh->use,
++                         refcount_read(&rose_neigh->use) - rose_neigh->count 
- 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1295,18 +1305,22 @@ void __exit rose_rt_free(void)
+       struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+       struct rose_node  *t, *rose_node  = rose_node_list;
+       struct rose_route *u, *rose_route = rose_route_list;
++      int i;
+ 
+       while (rose_neigh != NULL) {
+               s          = rose_neigh;
+               rose_neigh = rose_neigh->next;
+ 
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+ 
+       while (rose_node != NULL) {
+               t         = rose_node;
+               rose_node = rose_node->next;
+ 
++              for (i = 0; i < t->count; i++)
++                      rose_neigh_put(t->neighbour[i]);
+               rose_remove_node(t);
+       }
+ 
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa17..c52d7d20c5199b 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+               break;
+ 
+       case ROSE_STATE_2:      /* T3 */
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               rose_disconnect(sk, ETIMEDOUT, -1, -1);
+               break;
+ 
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 38e2fbdcbeac4b..9f835e674c599a 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -546,7 +546,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct 
sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ 
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+diff --git a/sound/soc/codecs/lpass-tx-macro.c 
b/sound/soc/codecs/lpass-tx-macro.c
+index a134584acf909e..74e69572796b58 100644
+--- a/sound/soc/codecs/lpass-tx-macro.c
++++ b/sound/soc/codecs/lpass-tx-macro.c
+@@ -2230,7 +2230,7 @@ static int tx_macro_register_mclk_output(struct tx_macro 
*tx)
+ }
+ 
+ static const struct snd_soc_component_driver tx_macro_component_drv = {
+-      .name = "RX-MACRO",
++      .name = "TX-MACRO",
+       .probe = tx_macro_component_probe,
+       .controls = tx_macro_snd_controls,
+       .num_controls = ARRAY_SIZE(tx_macro_snd_controls),
+diff --git a/tools/perf/util/symbol-minimal.c 
b/tools/perf/util/symbol-minimal.c
+index 36c1d3090689fc..f114f75ebeb989 100644
+--- a/tools/perf/util/symbol-minimal.c
++++ b/tools/perf/util/symbol-minimal.c
+@@ -4,7 +4,6 @@
+ 
+ #include <errno.h>
+ #include <unistd.h>
+-#include <stdio.h>
+ #include <fcntl.h>
+ #include <string.h>
+ #include <stdlib.h>
+@@ -88,11 +87,8 @@ int filename__read_debuglink(const char *filename 
__maybe_unused,
+  */
+ int filename__read_build_id(const char *filename, struct build_id *bid)
+ {
+-      FILE *fp;
+-      int ret = -1;
++      int fd, ret = -1;
+       bool need_swap = false, elf32;
+-      u8 e_ident[EI_NIDENT];
+-      int i;
+       union {
+               struct {
+                       Elf32_Ehdr ehdr32;
+@@ -103,28 +99,27 @@ int filename__read_build_id(const char *filename, struct 
build_id *bid)
+                       Elf64_Phdr *phdr64;
+               };
+       } hdrs;
+-      void *phdr;
+-      size_t phdr_size;
+-      void *buf = NULL;
+-      size_t buf_size = 0;
++      void *phdr, *buf = NULL;
++      ssize_t phdr_size, ehdr_size, buf_size = 0;
+ 
+-      fp = fopen(filename, "r");
+-      if (fp == NULL)
++      fd = open(filename, O_RDONLY);
++      if (fd < 0)
+               return -1;
+ 
+-      if (fread(e_ident, sizeof(e_ident), 1, fp) != 1)
++      if (read(fd, hdrs.ehdr32.e_ident, EI_NIDENT) != EI_NIDENT)
+               goto out;
+ 
+-      if (memcmp(e_ident, ELFMAG, SELFMAG) ||
+-          e_ident[EI_VERSION] != EV_CURRENT)
++      if (memcmp(hdrs.ehdr32.e_ident, ELFMAG, SELFMAG) ||
++          hdrs.ehdr32.e_ident[EI_VERSION] != EV_CURRENT)
+               goto out;
+ 
+-      need_swap = check_need_swap(e_ident[EI_DATA]);
+-      elf32 = e_ident[EI_CLASS] == ELFCLASS32;
++      need_swap = check_need_swap(hdrs.ehdr32.e_ident[EI_DATA]);
++      elf32 = hdrs.ehdr32.e_ident[EI_CLASS] == ELFCLASS32;
++      ehdr_size = (elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64)) - 
EI_NIDENT;
+ 
+-      if (fread(elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64,
+-                elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64),
+-                1, fp) != 1)
++      if (read(fd,
++               (elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64) + 
EI_NIDENT,
++               ehdr_size) != ehdr_size)
+               goto out;
+ 
+       if (need_swap) {
+@@ -138,14 +133,18 @@ int filename__read_build_id(const char *filename, struct 
build_id *bid)
+                       hdrs.ehdr64.e_phnum = bswap_16(hdrs.ehdr64.e_phnum);
+               }
+       }
+-      phdr_size = elf32 ? hdrs.ehdr32.e_phentsize * hdrs.ehdr32.e_phnum
+-                        : hdrs.ehdr64.e_phentsize * hdrs.ehdr64.e_phnum;
++      if ((elf32 && hdrs.ehdr32.e_phentsize != sizeof(Elf32_Phdr)) ||
++          (!elf32 && hdrs.ehdr64.e_phentsize != sizeof(Elf64_Phdr)))
++              goto out;
++
++      phdr_size = elf32 ? sizeof(Elf32_Phdr) * hdrs.ehdr32.e_phnum
++                        : sizeof(Elf64_Phdr) * hdrs.ehdr64.e_phnum;
+       phdr = malloc(phdr_size);
+       if (phdr == NULL)
+               goto out;
+ 
+-      fseek(fp, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET);
+-      if (fread(phdr, phdr_size, 1, fp) != 1)
++      lseek(fd, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET);
++      if (read(fd, phdr, phdr_size) != phdr_size)
+               goto out_free;
+ 
+       if (elf32)
+@@ -153,8 +152,8 @@ int filename__read_build_id(const char *filename, struct 
build_id *bid)
+       else
+               hdrs.phdr64 = phdr;
+ 
+-      for (i = 0; i < elf32 ? hdrs.ehdr32.e_phnum : hdrs.ehdr64.e_phnum; i++) 
{
+-              size_t p_filesz;
++      for (int i = 0; i < (elf32 ? hdrs.ehdr32.e_phnum : 
hdrs.ehdr64.e_phnum); i++) {
++              ssize_t p_filesz;
+ 
+               if (need_swap) {
+                       if (elf32) {
+@@ -180,8 +179,8 @@ int filename__read_build_id(const char *filename, struct 
build_id *bid)
+                               goto out_free;
+                       buf = tmp;
+               }
+-              fseek(fp, elf32 ? hdrs.phdr32[i].p_offset : 
hdrs.phdr64[i].p_offset, SEEK_SET);
+-              if (fread(buf, p_filesz, 1, fp) != 1)
++              lseek(fd, elf32 ? hdrs.phdr32[i].p_offset : 
hdrs.phdr64[i].p_offset, SEEK_SET);
++              if (read(fd, buf, p_filesz) != p_filesz)
+                       goto out_free;
+ 
+               ret = read_build_id(buf, p_filesz, bid, need_swap);
+@@ -194,7 +193,7 @@ int filename__read_build_id(const char *filename, struct 
build_id *bid)
+       free(buf);
+       free(phdr);
+ out:
+-      fclose(fp);
++      close(fd);
+       return ret;
+ }
+ 
+diff --git a/tools/tracing/latency/Makefile.config 
b/tools/tracing/latency/Makefile.config
+index 0fe6b50f029bf7..6efa13e3ca93fd 100644
+--- a/tools/tracing/latency/Makefile.config
++++ b/tools/tracing/latency/Makefile.config
+@@ -1,7 +1,15 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ 
++include $(srctree)/tools/scripts/utilities.mak
++
+ STOP_ERROR :=
+ 
++ifndef ($(NO_LIBTRACEEVENT),1)
++  ifeq ($(call get-executable,$(PKG_CONFIG)),)
++    $(error Error: $(PKG_CONFIG) needed by libtraceevent/libtracefs is 
missing on this system, please install it)
++  endif
++endif
++
+ define lib_setup
+   $(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)"))
+   $(eval LDFLAGS += $(shell sh -c "$(PKG_CONFIG) --libs-only-L lib$(1)"))
+diff --git a/tools/tracing/rtla/Makefile.config 
b/tools/tracing/rtla/Makefile.config
+index 5f8c286712d4c1..a35d6ee55ffcd7 100644
+--- a/tools/tracing/rtla/Makefile.config
++++ b/tools/tracing/rtla/Makefile.config
+@@ -1,10 +1,18 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ 
++include $(srctree)/tools/scripts/utilities.mak
++
+ STOP_ERROR :=
+ 
+ LIBTRACEEVENT_MIN_VERSION = 1.5
+ LIBTRACEFS_MIN_VERSION = 1.6
+ 
++ifndef ($(NO_LIBTRACEEVENT),1)
++  ifeq ($(call get-executable,$(PKG_CONFIG)),)
++    $(error Error: $(PKG_CONFIG) needed by libtraceevent/libtracefs is 
missing on this system, please install it)
++  endif
++endif
++
+ define lib_setup
+   $(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)"))
+   $(eval LDFLAGS += $(shell sh -c "$(PKG_CONFIG) --libs-only-L lib$(1)"))

Reply via email to