diff options
author | Mike Pagano <mpagano@gentoo.org> | 2020-03-05 11:27:10 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2020-03-05 11:27:10 -0500 |
commit | b32327fabc409799ced22b412852f0b9871edd51 (patch) | |
tree | 436f6f0facf76fa907406eb6ffa123eae1d7bd18 | |
parent | Linux patch 5.5.7 (diff) | |
download | linux-patches-b32327fabc409799ced22b412852f0b9871edd51.tar.gz linux-patches-b32327fabc409799ced22b412852f0b9871edd51.tar.bz2 linux-patches-b32327fabc409799ced22b412852f0b9871edd51.zip |
Linux patch 5.5.85.5-10
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1007_linux-5.5.8.patch | 8013 |
2 files changed, 8017 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 7611ed22..e58ee4ae 100644 --- a/0000_README +++ b/0000_README @@ -71,6 +71,10 @@ Patch: 1006_linux-5.5.7.patch From: http://www.kernel.org Desc: Linux 5.5.7 +Patch: 1007_linux-5.5.8.patch +From: http://www.kernel.org +Desc: Linux 5.5.8 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1007_linux-5.5.8.patch b/1007_linux-5.5.8.patch new file mode 100644 index 00000000..e0458f60 --- /dev/null +++ b/1007_linux-5.5.8.patch @@ -0,0 +1,8013 @@ +diff --git a/Documentation/networking/nf_flowtable.txt b/Documentation/networking/nf_flowtable.txt +index ca2136c76042..0bf32d1121be 100644 +--- a/Documentation/networking/nf_flowtable.txt ++++ b/Documentation/networking/nf_flowtable.txt +@@ -76,7 +76,7 @@ flowtable and add one rule to your forward chain. + + table inet x { + flowtable f { +- hook ingress priority 0 devices = { eth0, eth1 }; ++ hook ingress priority 0; devices = { eth0, eth1 }; + } + chain y { + type filter hook forward priority 0; policy accept; +diff --git a/Documentation/sphinx/parallel-wrapper.sh b/Documentation/sphinx/parallel-wrapper.sh +index 7daf5133bdd3..e54c44ce117d 100644 +--- a/Documentation/sphinx/parallel-wrapper.sh ++++ b/Documentation/sphinx/parallel-wrapper.sh +@@ -30,4 +30,4 @@ if [ -n "$parallel" ] ; then + parallel="-j$parallel" + fi + +-exec "$sphinx" "$parallel" "$@" ++exec "$sphinx" $parallel "$@" +diff --git a/Makefile b/Makefile +index 0f64b92fa39a..a1e5190e4721 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 5 +-SUBLEVEL = 7 ++SUBLEVEL = 8 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi +index 60e11045ad76..d051f080e52e 100644 +--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi ++++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi +@@ -46,7 +46,7 @@ + /* DAC */ + format = "i2s"; + mclk-fs = <256>; +- frame-inversion = <1>; ++ frame-inversion; + cpu { + sound-dai = <&sti_uni_player2>; + }; +diff --git a/arch/arm/include/asm/vdso/vsyscall.h b/arch/arm/include/asm/vdso/vsyscall.h +index c4166f317071..cff87d8d30da 100644 +--- a/arch/arm/include/asm/vdso/vsyscall.h ++++ b/arch/arm/include/asm/vdso/vsyscall.h +@@ -34,9 +34,9 @@ struct vdso_data *__arm_get_k_vdso_data(void) + #define __arch_get_k_vdso_data __arm_get_k_vdso_data + + static __always_inline +-int __arm_update_vdso_data(void) ++bool __arm_update_vdso_data(void) + { +- return !cntvct_ok; ++ return cntvct_ok; + } + #define __arch_update_vdso_data __arm_update_vdso_data + +diff --git a/arch/mips/include/asm/sync.h b/arch/mips/include/asm/sync.h +index 7c6a1095f556..aabd097933fe 100644 +--- a/arch/mips/include/asm/sync.h ++++ b/arch/mips/include/asm/sync.h +@@ -155,9 +155,11 @@ + * effective barrier as noted by commit 6b07d38aaa52 ("MIPS: Octeon: Use + * optimized memory barrier primitives."). Here we specify that the affected + * sync instructions should be emitted twice. ++ * Note that this expression is evaluated by the assembler (not the compiler), ++ * and that the assembler evaluates '==' as 0 or -1, not 0 or 1. + */ + #ifdef CONFIG_CPU_CAVIUM_OCTEON +-# define __SYNC_rpt(type) (1 + (type == __SYNC_wmb)) ++# define __SYNC_rpt(type) (1 - (type == __SYNC_wmb)) + #else + # define __SYNC_rpt(type) 1 + #endif +diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c +index 6176b9acba95..d0d832ab3d3b 100644 +--- a/arch/mips/kernel/vpe.c ++++ b/arch/mips/kernel/vpe.c +@@ -134,7 +134,7 @@ void release_vpe(struct vpe *v) + { + list_del(&v->list); + if (v->load_addr) +- release_progmem(v); ++ release_progmem(v->load_addr); + kfree(v); + } + +diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c +index f4cad5163bf2..ffb3d94bf0cc 100644 +--- a/arch/riscv/kernel/traps.c ++++ b/arch/riscv/kernel/traps.c +@@ -156,6 +156,6 @@ void __init trap_init(void) + csr_write(CSR_SCRATCH, 0); + /* Set the exception vector address */ + csr_write(CSR_TVEC, &handle_exception); +- /* Enable all interrupts */ +- csr_write(CSR_IE, -1); ++ /* Enable interrupts */ ++ csr_write(CSR_IE, IE_SIE | IE_EIE); + } +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 3be51aa06e67..dff6623804c2 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4765,6 +4765,7 @@ __init int intel_pmu_init(void) + break; + + case INTEL_FAM6_ATOM_TREMONT_D: ++ case INTEL_FAM6_ATOM_TREMONT: + x86_pmu.late_ack = true; + memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); +diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c +index e1daf4151e11..4814c964692c 100644 +--- a/arch/x86/events/intel/cstate.c ++++ b/arch/x86/events/intel/cstate.c +@@ -40,17 +40,18 @@ + * Model specific counters: + * MSR_CORE_C1_RES: CORE C1 Residency Counter + * perf code: 0x00 +- * Available model: SLM,AMT,GLM,CNL ++ * Available model: SLM,AMT,GLM,CNL,TNT + * Scope: Core (each processor core has a MSR) + * MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM, +- * CNL,KBL,CML ++ * CNL,KBL,CML,TNT + * Scope: Core + * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter + * perf code: 0x02 + * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, +- * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL ++ * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL, ++ * TNT + * Scope: Core + * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter + * perf code: 0x03 +@@ -60,17 +61,18 @@ + * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter. + * perf code: 0x00 + * Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL, +- * KBL,CML,ICL,TGL ++ * KBL,CML,ICL,TGL,TNT + * Scope: Package (physical package) + * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter. + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, +- * GLM,CNL,KBL,CML,ICL,TGL ++ * GLM,CNL,KBL,CML,ICL,TGL,TNT + * Scope: Package (physical package) + * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. + * perf code: 0x02 +- * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW +- * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL ++ * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, ++ * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL, ++ * TNT + * Scope: Package (physical package) + * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. + * perf code: 0x03 +@@ -87,7 +89,8 @@ + * Scope: Package (physical package) + * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter. + * perf code: 0x06 +- * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL ++ * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL, ++ * TNT + * Scope: Package (physical package) + * + */ +@@ -640,8 +643,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { + + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_D, glm_cstates), +- + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), ++ X86_CSTATES_MODEL(INTEL_FAM6_ATOM_TREMONT_D, glm_cstates), ++ X86_CSTATES_MODEL(INTEL_FAM6_ATOM_TREMONT, glm_cstates), + + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, icl_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, icl_cstates), +diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c +index 6f86650b3f77..a949f6f55991 100644 +--- a/arch/x86/events/msr.c ++++ b/arch/x86/events/msr.c +@@ -75,8 +75,9 @@ static bool test_intel(int idx, void *data) + + case INTEL_FAM6_ATOM_GOLDMONT: + case INTEL_FAM6_ATOM_GOLDMONT_D: +- + case INTEL_FAM6_ATOM_GOLDMONT_PLUS: ++ case INTEL_FAM6_ATOM_TREMONT_D: ++ case INTEL_FAM6_ATOM_TREMONT: + + case INTEL_FAM6_XEON_PHI_KNL: + case INTEL_FAM6_XEON_PHI_KNM: +diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h +index e49b77283924..181c992f448c 100644 +--- a/arch/x86/kernel/cpu/resctrl/internal.h ++++ b/arch/x86/kernel/cpu/resctrl/internal.h +@@ -57,6 +57,7 @@ static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc) + } + + DECLARE_STATIC_KEY_FALSE(rdt_enable_key); ++DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); + + /** + * struct mon_evt - Entry in the event list of a resource +diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c +index 397206f23d14..773124b0e18a 100644 +--- a/arch/x86/kernel/cpu/resctrl/monitor.c ++++ b/arch/x86/kernel/cpu/resctrl/monitor.c +@@ -514,7 +514,7 @@ void mbm_handle_overflow(struct work_struct *work) + + mutex_lock(&rdtgroup_mutex); + +- if (!static_branch_likely(&rdt_enable_key)) ++ if (!static_branch_likely(&rdt_mon_enable_key)) + goto out_unlock; + + d = get_domain_from_cpu(cpu, &rdt_resources_all[RDT_RESOURCE_L3]); +@@ -543,7 +543,7 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms) + unsigned long delay = msecs_to_jiffies(delay_ms); + int cpu; + +- if (!static_branch_likely(&rdt_enable_key)) ++ if (!static_branch_likely(&rdt_mon_enable_key)) + return; + cpu = cpumask_any(&dom->cpu_mask); + dom->mbm_work_cpu = cpu; +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index f05123acaa64..a1daebe2a60f 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -1150,7 +1150,7 @@ void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq, + if (!kvm_apic_present(vcpu)) + continue; + if (!kvm_apic_match_dest(vcpu, NULL, +- irq->delivery_mode, ++ irq->shorthand, + irq->dest_id, + irq->dest_mode)) + continue; +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index aace3b6ca2f7..2b3d8feec313 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -1307,6 +1307,47 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu) + } + } + ++/* ++ * The default MMIO mask is a single bit (excluding the present bit), ++ * which could conflict with the memory encryption bit. Check for ++ * memory encryption support and override the default MMIO mask if ++ * memory encryption is enabled. ++ */ ++static __init void svm_adjust_mmio_mask(void) ++{ ++ unsigned int enc_bit, mask_bit; ++ u64 msr, mask; ++ ++ /* If there is no memory encryption support, use existing mask */ ++ if (cpuid_eax(0x80000000) < 0x8000001f) ++ return; ++ ++ /* If memory encryption is not enabled, use existing mask */ ++ rdmsrl(MSR_K8_SYSCFG, msr); ++ if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT)) ++ return; ++ ++ enc_bit = cpuid_ebx(0x8000001f) & 0x3f; ++ mask_bit = boot_cpu_data.x86_phys_bits; ++ ++ /* Increment the mask bit if it is the same as the encryption bit */ ++ if (enc_bit == mask_bit) ++ mask_bit++; ++ ++ /* ++ * If the mask bit location is below 52, then some bits above the ++ * physical addressing limit will always be reserved, so use the ++ * rsvd_bits() function to generate the mask. This mask, along with ++ * the present bit, will be used to generate a page fault with ++ * PFER.RSV = 1. ++ * ++ * If the mask bit location is 52 (or above), then clear the mask. ++ */ ++ mask = (mask_bit < 52) ? rsvd_bits(mask_bit, 51) | PT_PRESENT_MASK : 0; ++ ++ kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK); ++} ++ + static __init int svm_hardware_setup(void) + { + int cpu; +@@ -1361,6 +1402,8 @@ static __init int svm_hardware_setup(void) + } + } + ++ svm_adjust_mmio_mask(); ++ + for_each_possible_cpu(cpu) { + r = svm_cpu_init(cpu); + if (r) +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index af5a36dfc88a..63addc413d99 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -4781,32 +4781,28 @@ static int handle_vmread(struct kvm_vcpu *vcpu) + { + unsigned long field; + u64 field_value; ++ struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); + int len; + gva_t gva = 0; +- struct vmcs12 *vmcs12; ++ struct vmcs12 *vmcs12 = is_guest_mode(vcpu) ? get_shadow_vmcs12(vcpu) ++ : get_vmcs12(vcpu); + struct x86_exception e; + short offset; + + if (!nested_vmx_check_permission(vcpu)) + return 1; + +- if (to_vmx(vcpu)->nested.current_vmptr == -1ull) ++ /* ++ * In VMX non-root operation, when the VMCS-link pointer is -1ull, ++ * any VMREAD sets the ALU flags for VMfailInvalid. ++ */ ++ if (vmx->nested.current_vmptr == -1ull || ++ (is_guest_mode(vcpu) && ++ get_vmcs12(vcpu)->vmcs_link_pointer == -1ull)) + return nested_vmx_failInvalid(vcpu); + +- if (!is_guest_mode(vcpu)) +- vmcs12 = get_vmcs12(vcpu); +- else { +- /* +- * When vmcs->vmcs_link_pointer is -1ull, any VMREAD +- * to shadowed-field sets the ALU flags for VMfailInvalid. +- */ +- if (get_vmcs12(vcpu)->vmcs_link_pointer == -1ull) +- return nested_vmx_failInvalid(vcpu); +- vmcs12 = get_shadow_vmcs12(vcpu); +- } +- + /* Decode instruction info and find the field to read */ + field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); + +@@ -4885,13 +4881,20 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + */ + u64 field_value = 0; + struct x86_exception e; +- struct vmcs12 *vmcs12; ++ struct vmcs12 *vmcs12 = is_guest_mode(vcpu) ? get_shadow_vmcs12(vcpu) ++ : get_vmcs12(vcpu); + short offset; + + if (!nested_vmx_check_permission(vcpu)) + return 1; + +- if (vmx->nested.current_vmptr == -1ull) ++ /* ++ * In VMX non-root operation, when the VMCS-link pointer is -1ull, ++ * any VMWRITE sets the ALU flags for VMfailInvalid. ++ */ ++ if (vmx->nested.current_vmptr == -1ull || ++ (is_guest_mode(vcpu) && ++ get_vmcs12(vcpu)->vmcs_link_pointer == -1ull)) + return nested_vmx_failInvalid(vcpu); + + if (vmx_instruction_info & (1u << 10)) +@@ -4910,6 +4913,12 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + + + field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); ++ ++ offset = vmcs_field_to_offset(field); ++ if (offset < 0) ++ return nested_vmx_failValid(vcpu, ++ VMXERR_UNSUPPORTED_VMCS_COMPONENT); ++ + /* + * If the vCPU supports "VMWRITE to any supported field in the + * VMCS," then the "read-only" fields are actually read/write. +@@ -4919,29 +4928,12 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + return nested_vmx_failValid(vcpu, + VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT); + +- if (!is_guest_mode(vcpu)) { +- vmcs12 = get_vmcs12(vcpu); +- +- /* +- * Ensure vmcs12 is up-to-date before any VMWRITE that dirties +- * vmcs12, else we may crush a field or consume a stale value. +- */ +- if (!is_shadow_field_rw(field)) +- copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); +- } else { +- /* +- * When vmcs->vmcs_link_pointer is -1ull, any VMWRITE +- * to shadowed-field sets the ALU flags for VMfailInvalid. +- */ +- if (get_vmcs12(vcpu)->vmcs_link_pointer == -1ull) +- return nested_vmx_failInvalid(vcpu); +- vmcs12 = get_shadow_vmcs12(vcpu); +- } +- +- offset = vmcs_field_to_offset(field); +- if (offset < 0) +- return nested_vmx_failValid(vcpu, +- VMXERR_UNSUPPORTED_VMCS_COMPONENT); ++ /* ++ * Ensure vmcs12 is up-to-date before any VMWRITE that dirties ++ * vmcs12, else we may crush a field or consume a stale value. ++ */ ++ if (!is_guest_mode(vcpu) && !is_shadow_field_rw(field)) ++ copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); + + /* + * Some Intel CPUs intentionally drop the reserved bits of the AR byte +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index be438bc7cfa3..3e381b31b9a6 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -7179,6 +7179,7 @@ static int vmx_check_intercept_io(struct kvm_vcpu *vcpu, + else + intercept = nested_vmx_check_io_bitmaps(vcpu, port, size); + ++ /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ + return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; + } + +@@ -7208,6 +7209,20 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, + case x86_intercept_outs: + return vmx_check_intercept_io(vcpu, info); + ++ case x86_intercept_lgdt: ++ case x86_intercept_lidt: ++ case x86_intercept_lldt: ++ case x86_intercept_ltr: ++ case x86_intercept_sgdt: ++ case x86_intercept_sidt: ++ case x86_intercept_sldt: ++ case x86_intercept_str: ++ if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_DESC)) ++ return X86EMUL_CONTINUE; ++ ++ /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ ++ break; ++ + /* TODO: check more intercepts... */ + default: + break; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index e594fd2719dd..dafb5aff200f 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -9225,12 +9225,6 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) + + void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) + { +- vcpu->arch.apf.msr_val = 0; +- +- vcpu_load(vcpu); +- kvm_mmu_unload(vcpu); +- vcpu_put(vcpu); +- + kvm_arch_vcpu_free(vcpu); + } + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index b5516b04ffc0..d827a4a3e946 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -126,12 +126,11 @@ void __init acpi_watchdog_init(void) + gas = &entries[i].register_region; + + res.start = gas->address; ++ res.end = res.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1; + if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + res.flags = IORESOURCE_MEM; +- res.end = res.start + ALIGN(gas->access_width, 4) - 1; + } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + res.flags = IORESOURCE_IO; +- res.end = res.start + gas->access_width - 1; + } else { + pr_warn("Unsupported address space: %u\n", + gas->space_id); +diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig +index 50200d1c06ea..6095b6df8a81 100644 +--- a/drivers/bus/Kconfig ++++ b/drivers/bus/Kconfig +@@ -139,7 +139,6 @@ config TEGRA_ACONNECT + tristate "Tegra ACONNECT Bus Driver" + depends on ARCH_TEGRA_210_SOC + depends on OF && PM +- select PM_CLK + help + Driver for the Tegra ACONNECT bus which is used to interface with + the devices inside the Audio Processing Engine (APE) for Tegra210. +diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c +index 22c6a2e61236..8ac390c2b514 100644 +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -775,10 +775,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + msg = ssif_info->curr_msg; + if (msg) { ++ if (data) { ++ if (len > IPMI_MAX_MSG_LENGTH) ++ len = IPMI_MAX_MSG_LENGTH; ++ memcpy(msg->rsp, data, len); ++ } else { ++ len = 0; ++ } + msg->rsp_size = len; +- if (msg->rsp_size > IPMI_MAX_MSG_LENGTH) +- msg->rsp_size = IPMI_MAX_MSG_LENGTH; +- memcpy(msg->rsp, data, msg->rsp_size); + ssif_info->curr_msg = NULL; + } + +diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c +index 7ed313ad6e43..d9e17b91c68e 100644 +--- a/drivers/clk/qcom/clk-rpmh.c ++++ b/drivers/clk/qcom/clk-rpmh.c +@@ -481,9 +481,9 @@ static int clk_rpmh_probe(struct platform_device *pdev) + } + + static const struct of_device_id clk_rpmh_match_table[] = { ++ { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, + { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, + { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, +- { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, + { } + }; + MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 4adac3a8c265..b60d349e3b1e 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1074,9 +1074,17 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) + pol = policy->last_policy; + } else if (def_gov) { + pol = cpufreq_parse_policy(def_gov->name); +- } else { +- return -ENODATA; ++ /* ++ * In case the default governor is neiter "performance" ++ * nor "powersave", fall back to the initial policy ++ * value set by the driver. ++ */ ++ if (pol == CPUFREQ_POLICY_UNKNOWN) ++ pol = policy->policy; + } ++ if (pol != CPUFREQ_POLICY_PERFORMANCE && ++ pol != CPUFREQ_POLICY_POWERSAVE) ++ return -ENODATA; + } + + return cpufreq_set_policy(policy, gov, pol); +diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c +index e99f082d15df..c5a34be182ca 100644 +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -738,7 +738,6 @@ struct devfreq *devfreq_add_device(struct device *dev, + { + struct devfreq *devfreq; + struct devfreq_governor *governor; +- static atomic_t devfreq_no = ATOMIC_INIT(-1); + int err = 0; + + if (!dev || !profile || !governor_name) { +@@ -800,8 +799,7 @@ struct devfreq *devfreq_add_device(struct device *dev, + devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev); + atomic_set(&devfreq->suspend_count, 0); + +- dev_set_name(&devfreq->dev, "devfreq%d", +- atomic_inc_return(&devfreq_no)); ++ dev_set_name(&devfreq->dev, "%s", dev_name(dev)); + err = device_register(&devfreq->dev); + if (err) { + mutex_unlock(&devfreq->lock); +diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c +index 95662a4ff4c4..99bbaf629b8d 100644 +--- a/drivers/edac/skx_common.c ++++ b/drivers/edac/skx_common.c +@@ -256,7 +256,7 @@ int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, NULL); + if (!pdev) { +- skx_printk(KERN_ERR, "Can't get tolm/tohm\n"); ++ edac_dbg(2, "Can't get tolm/tohm\n"); + return -ENODEV; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 30a1e3ac21d6..4169abc32219 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -1357,7 +1357,7 @@ amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + + static struct drm_driver kms_driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_ATOMIC | ++ DRIVER_ATOMIC | + DRIVER_GEM | + DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ | + DRIVER_SYNCOBJ_TIMELINE, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +index b499a3de8bb6..c75cc97eca44 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +@@ -192,6 +192,7 @@ struct amdgpu_gmc { + uint32_t srbm_soft_reset; + bool prt_warning; + uint64_t stolen_size; ++ uint32_t sdpif_register; + /* apertures */ + u64 shared_aperture_start; + u64 shared_aperture_end; +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index a5b68b5e452f..0b88c9f877ec 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -1203,6 +1203,19 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) + } + } + ++/** ++ * gmc_v9_0_restore_registers - restores regs ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * This restores register values, saved at suspend. ++ */ ++static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) ++{ ++ if (adev->asic_type == CHIP_RAVEN) ++ WREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); ++} ++ + /** + * gmc_v9_0_gart_enable - gart enable + * +@@ -1307,6 +1320,20 @@ static int gmc_v9_0_hw_init(void *handle) + return r; + } + ++/** ++ * gmc_v9_0_save_registers - saves regs ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * This saves potential register values that should be ++ * restored upon resume ++ */ ++static void gmc_v9_0_save_registers(struct amdgpu_device *adev) ++{ ++ if (adev->asic_type == CHIP_RAVEN) ++ adev->gmc.sdpif_register = RREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); ++} ++ + /** + * gmc_v9_0_gart_disable - gart disable + * +@@ -1343,9 +1370,16 @@ static int gmc_v9_0_hw_fini(void *handle) + + static int gmc_v9_0_suspend(void *handle) + { ++ int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +- return gmc_v9_0_hw_fini(adev); ++ r = gmc_v9_0_hw_fini(adev); ++ if (r) ++ return r; ++ ++ gmc_v9_0_save_registers(adev); ++ ++ return 0; + } + + static int gmc_v9_0_resume(void *handle) +@@ -1353,6 +1387,7 @@ static int gmc_v9_0_resume(void *handle) + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + ++ gmc_v9_0_restore_registers(adev); + r = gmc_v9_0_hw_init(adev); + if (r) + return r; +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +index b864869cc7e3..6fa7422c51da 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +@@ -91,6 +91,12 @@ ifdef CONFIG_DRM_AMD_DC_DCN2_1 + ############################################################################### + CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o + ++# prevent build errors regarding soft-float vs hard-float FP ABI tags ++# this code is currently unused on ppc64, as it applies to Renoir APUs only ++ifdef CONFIG_PPC64 ++CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) ++endif ++ + AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) + + AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +index dbf063856846..5f683d118d2a 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +@@ -149,6 +149,12 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base, + rn_vbios_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); + } + ++ // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. ++ if (!IS_DIAG_DC(dc->ctx->dce_environment)) { ++ if (new_clocks->dppclk_khz < 100000) ++ new_clocks->dppclk_khz = 100000; ++ } ++ + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) + dpp_clock_lowered = true; +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +index 793c0cec407f..5fcffb29317e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +@@ -398,7 +398,7 @@ static bool acquire( + { + enum gpio_result result; + +- if (!is_engine_available(engine)) ++ if ((engine == NULL) || !is_engine_available(engine)) + return false; + + result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index ac8c18fadefc..448bc9b39942 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -493,7 +493,6 @@ static void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) + dpp->funcs->dpp_dppclk_control(dpp, false, false); + + hubp->power_gated = true; +- dc->optimized_required = false; /* We're powering off, no need to optimize */ + + dc->hwss.plane_atomic_power_down(dc, + pipe_ctx->plane_res.dpp, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 83cda43a1b6b..77741b18c85b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -57,6 +57,7 @@ + #include "dcn20/dcn20_dccg.h" + #include "dcn21_hubbub.h" + #include "dcn10/dcn10_resource.h" ++#include "dce110/dce110_resource.h" + + #include "dcn20/dcn20_dwb.h" + #include "dcn20/dcn20_mmhubbub.h" +@@ -867,6 +868,7 @@ static const struct dc_debug_options debug_defaults_diags = { + enum dcn20_clk_src_array_id { + DCN20_CLK_SRC_PLL0, + DCN20_CLK_SRC_PLL1, ++ DCN20_CLK_SRC_PLL2, + DCN20_CLK_SRC_TOTAL_DCN21 + }; + +@@ -1730,6 +1732,10 @@ static bool construct( + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL1, + &clk_src_regs[1], false); ++ pool->base.clock_sources[DCN20_CLK_SRC_PLL2] = ++ dcn21_clock_source_create(ctx, ctx->dc_bios, ++ CLOCK_SOURCE_COMBO_PHY_PLL2, ++ &clk_src_regs[2], false); + + pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; + +diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +index b6f74bf4af02..27bb8c1ab858 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +@@ -7376,6 +7376,8 @@ + #define mmCRTC4_CRTC_DRR_CONTROL 0x0f3e + #define mmCRTC4_CRTC_DRR_CONTROL_BASE_IDX 2 + ++#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x395d ++#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 + + // addressBlock: dce_dc_fmt4_dispdec + // base address: 0x2000 +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +index f2418a1cfe68..b5875063b97c 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +@@ -257,8 +257,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915) + with_intel_runtime_pm(&i915->runtime_pm, wakeref) { + freed = i915_gem_shrink(i915, -1UL, NULL, + I915_SHRINK_BOUND | +- I915_SHRINK_UNBOUND | +- I915_SHRINK_ACTIVE); ++ I915_SHRINK_UNBOUND); + } + + return freed; +@@ -337,7 +336,6 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) + freed_pages = 0; + with_intel_runtime_pm(&i915->runtime_pm, wakeref) + freed_pages += i915_gem_shrink(i915, -1UL, NULL, +- I915_SHRINK_ACTIVE | + I915_SHRINK_BOUND | + I915_SHRINK_UNBOUND | + I915_SHRINK_WRITEBACK); +diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c +index 2477a1e5a166..ae139f0877ae 100644 +--- a/drivers/gpu/drm/i915/gvt/dmabuf.c ++++ b/drivers/gpu/drm/i915/gvt/dmabuf.c +@@ -151,12 +151,12 @@ static void dmabuf_gem_object_free(struct kref *kref) + dmabuf_obj = container_of(pos, + struct intel_vgpu_dmabuf_obj, list); + if (dmabuf_obj == obj) { ++ list_del(pos); + intel_gvt_hypervisor_put_vfio_device(vgpu); + idr_remove(&vgpu->object_idr, + dmabuf_obj->dmabuf_id); + kfree(dmabuf_obj->info); + kfree(dmabuf_obj); +- list_del(pos); + break; + } + } +diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c +index 85bd9bf4f6ee..487af6ea9972 100644 +--- a/drivers/gpu/drm/i915/gvt/vgpu.c ++++ b/drivers/gpu/drm/i915/gvt/vgpu.c +@@ -560,9 +560,9 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, + + intel_vgpu_reset_mmio(vgpu, dmlr); + populate_pvinfo_page(vgpu); +- intel_vgpu_reset_display(vgpu); + + if (dmlr) { ++ intel_vgpu_reset_display(vgpu); + intel_vgpu_reset_cfg_space(vgpu); + /* only reset the failsafe mode when dmlr reset */ + vgpu->failsafe = false; +diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c +index c84f0a8b3f2c..b73fbb65e14b 100644 +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -441,6 +441,14 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) + if (ret) + goto err_msm_uninit; + ++ if (!dev->dma_parms) { ++ dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), ++ GFP_KERNEL); ++ if (!dev->dma_parms) ++ return -ENOMEM; ++ } ++ dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); ++ + msm_gem_shrinker_init(ddev); + + switch (get_mdp_ver(pdev)) { +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index fd74e2611185..8696af1ee14d 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -37,6 +37,7 @@ + #include <linux/vga_switcheroo.h> + #include <linux/mmu_notifier.h> + ++#include <drm/drm_agpsupport.h> + #include <drm/drm_crtc_helper.h> + #include <drm/drm_drv.h> + #include <drm/drm_fb_helper.h> +@@ -325,6 +326,7 @@ static int radeon_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { + unsigned long flags = 0; ++ struct drm_device *dev; + int ret; + + if (!ent) +@@ -365,7 +367,44 @@ static int radeon_pci_probe(struct pci_dev *pdev, + if (ret) + return ret; + +- return drm_get_pci_dev(pdev, ent, &kms_driver); ++ dev = drm_dev_alloc(&kms_driver, &pdev->dev); ++ if (IS_ERR(dev)) ++ return PTR_ERR(dev); ++ ++ ret = pci_enable_device(pdev); ++ if (ret) ++ goto err_free; ++ ++ dev->pdev = pdev; ++#ifdef __alpha__ ++ dev->hose = pdev->sysdata; ++#endif ++ ++ pci_set_drvdata(pdev, dev); ++ ++ if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP)) ++ dev->agp = drm_agp_init(dev); ++ if (dev->agp) { ++ dev->agp->agp_mtrr = arch_phys_wc_add( ++ dev->agp->agp_info.aper_base, ++ dev->agp->agp_info.aper_size * ++ 1024 * 1024); ++ } ++ ++ ret = drm_dev_register(dev, ent->driver_data); ++ if (ret) ++ goto err_agp; ++ ++ return 0; ++ ++err_agp: ++ if (dev->agp) ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ kfree(dev->agp); ++ pci_disable_device(pdev); ++err_free: ++ drm_dev_put(dev); ++ return ret; + } + + static void +@@ -575,7 +614,7 @@ radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + + static struct drm_driver kms_driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_GEM | DRIVER_RENDER, ++ DRIVER_GEM | DRIVER_RENDER, + .load = radeon_driver_load_kms, + .open = radeon_driver_open_kms, + .postclose = radeon_driver_postclose_kms, +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index e85c554eeaa9..2bb0187c5bc7 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -31,6 +31,7 @@ + #include <linux/uaccess.h> + #include <linux/vga_switcheroo.h> + ++#include <drm/drm_agpsupport.h> + #include <drm/drm_fb_helper.h> + #include <drm/drm_file.h> + #include <drm/drm_ioctl.h> +@@ -77,6 +78,11 @@ void radeon_driver_unload_kms(struct drm_device *dev) + radeon_modeset_fini(rdev); + radeon_device_fini(rdev); + ++ if (dev->agp) ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ kfree(dev->agp); ++ dev->agp = NULL; ++ + done_free: + kfree(rdev); + dev->dev_private = NULL; +diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c +index ae79a7c66737..fa704153cb00 100644 +--- a/drivers/hid/hid-alps.c ++++ b/drivers/hid/hid-alps.c +@@ -730,7 +730,7 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) + if (data->has_sp) { + input2 = input_allocate_device(); + if (!input2) { +- input_free_device(input2); ++ ret = -ENOMEM; + goto exit; + } + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 851fe54ea59e..359616e3efbb 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1741,7 +1741,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + + rsize = ((report->size - 1) >> 3) + 1; + +- if (rsize > HID_MAX_BUFFER_SIZE) ++ if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) ++ rsize = HID_MAX_BUFFER_SIZE - 1; ++ else if (rsize > HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE; + + if (csize < rsize) { +diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c +index c436e12feb23..6c55682c5974 100644 +--- a/drivers/hid/hid-ite.c ++++ b/drivers/hid/hid-ite.c +@@ -41,8 +41,9 @@ static const struct hid_device_id ite_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, + { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, + /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ +- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, +- USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, ++ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, ++ USB_VENDOR_ID_SYNAPTICS, ++ USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, + { } + }; + MODULE_DEVICE_TABLE(hid, ite_devices); +diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c +index a970b809d778..4140dea693e9 100644 +--- a/drivers/hid/usbhid/hiddev.c ++++ b/drivers/hid/usbhid/hiddev.c +@@ -932,9 +932,9 @@ void hiddev_disconnect(struct hid_device *hid) + hiddev->exist = 0; + + if (hiddev->open) { +- mutex_unlock(&hiddev->existancelock); + hid_hw_close(hiddev->hid); + wake_up_interruptible(&hiddev->wait); ++ mutex_unlock(&hiddev->existancelock); + } else { + mutex_unlock(&hiddev->existancelock); + kfree(hiddev); +diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c +index 5255d3755411..1de23b4f3809 100644 +--- a/drivers/i2c/busses/i2c-altera.c ++++ b/drivers/i2c/busses/i2c-altera.c +@@ -171,7 +171,7 @@ static void altr_i2c_init(struct altr_i2c_dev *idev) + /* SCL Low Time */ + writel(t_low, idev->base + ALTR_I2C_SCL_LOW); + /* SDA Hold Time, 300ns */ +- writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD); ++ writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD); + + /* Mask all master interrupt bits */ + altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false); +diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c +index 25dcd73acd63..8f0e1f802f2d 100644 +--- a/drivers/i2c/busses/i2c-jz4780.c ++++ b/drivers/i2c/busses/i2c-jz4780.c +@@ -73,25 +73,6 @@ + #define JZ4780_I2C_STA_TFNF BIT(1) + #define JZ4780_I2C_STA_ACT BIT(0) + +-static const char * const jz4780_i2c_abrt_src[] = { +- "ABRT_7B_ADDR_NOACK", +- "ABRT_10ADDR1_NOACK", +- "ABRT_10ADDR2_NOACK", +- "ABRT_XDATA_NOACK", +- "ABRT_GCALL_NOACK", +- "ABRT_GCALL_READ", +- "ABRT_HS_ACKD", +- "SBYTE_ACKDET", +- "ABRT_HS_NORSTRT", +- "SBYTE_NORSTRT", +- "ABRT_10B_RD_NORSTRT", +- "ABRT_MASTER_DIS", +- "ARB_LOST", +- "SLVFLUSH_TXFIFO", +- "SLV_ARBLOST", +- "SLVRD_INTX", +-}; +- + #define JZ4780_I2C_INTST_IGC BIT(11) + #define JZ4780_I2C_INTST_ISTT BIT(10) + #define JZ4780_I2C_INTST_ISTP BIT(9) +@@ -529,21 +510,8 @@ done: + + static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src) + { +- int i; +- +- dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src); +- dev_err(&i2c->adap.dev, "device addr=%x\n", +- jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)); +- dev_err(&i2c->adap.dev, "send cmd count:%d %d\n", +- i2c->cmd, i2c->cmd_buf[i2c->cmd]); +- dev_err(&i2c->adap.dev, "receive data count:%d %d\n", +- i2c->cmd, i2c->data_buf[i2c->cmd]); +- +- for (i = 0; i < 16; i++) { +- if (src & BIT(i)) +- dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n", +- i, jz4780_i2c_abrt_src[i]); +- } ++ dev_dbg(&i2c->adap.dev, "txabrt: 0x%08x, cmd: %d, send: %d, recv: %d\n", ++ src, i2c->cmd, i2c->cmd_buf[i2c->cmd], i2c->data_buf[i2c->cmd]); + } + + static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c, +diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h +index 5617434cbfb4..416341ada172 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_device.h ++++ b/drivers/infiniband/hw/hns/hns_roce_device.h +@@ -423,7 +423,7 @@ struct hns_roce_mr_table { + struct hns_roce_wq { + u64 *wrid; /* Work request ID */ + spinlock_t lock; +- int wqe_cnt; /* WQE num */ ++ u32 wqe_cnt; /* WQE num */ + int max_gs; + int offset; + int wqe_shift; /* WQE size */ +@@ -647,7 +647,6 @@ struct hns_roce_qp { + u8 sdb_en; + u32 doorbell_qpn; + u32 sq_signal_bits; +- u32 sq_next_wqe; + struct hns_roce_wq sq; + + struct ib_umem *umem; +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +index 2a2b2112f886..a31a21433f65 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +@@ -74,8 +74,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + unsigned long flags = 0; + void *wqe = NULL; + __le32 doorbell[2]; ++ u32 wqe_idx = 0; + int nreq = 0; +- u32 ind = 0; + int ret = 0; + u8 *smac; + int loopback; +@@ -88,7 +88,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + } + + spin_lock_irqsave(&qp->sq.lock, flags); +- ind = qp->sq_next_wqe; ++ + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { + ret = -ENOMEM; +@@ -96,6 +96,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > qp->sq.max_gs)) { + dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, qp->sq.max_gs); +@@ -104,9 +106,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + goto out; + } + +- wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); +- qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = +- wr->wr_id; ++ wqe = get_send_wqe(qp, wqe_idx); ++ qp->sq.wrid[wqe_idx] = wr->wr_id; + + /* Corresponding to the RC and RD type wqe process separately */ + if (ibqp->qp_type == IB_QPT_GSI) { +@@ -210,7 +211,6 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + cpu_to_le32((wr->sg_list[1].addr) >> 32); + ud_sq_wqe->l_key1 = + cpu_to_le32(wr->sg_list[1].lkey); +- ind++; + } else if (ibqp->qp_type == IB_QPT_RC) { + u32 tmp_len = 0; + +@@ -308,7 +308,6 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + ctrl->flag |= cpu_to_le32(wr->num_sge << + HNS_ROCE_WQE_SGE_NUM_BIT); + } +- ind++; + } + } + +@@ -336,7 +335,6 @@ out: + doorbell[1] = sq_db.u32_8; + + hns_roce_write64_k(doorbell, qp->sq.db_reg_l); +- qp->sq_next_wqe = ind; + } + + spin_unlock_irqrestore(&qp->sq.lock, flags); +@@ -348,12 +346,6 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + const struct ib_recv_wr *wr, + const struct ib_recv_wr **bad_wr) + { +- int ret = 0; +- int nreq = 0; +- int ind = 0; +- int i = 0; +- u32 reg_val; +- unsigned long flags = 0; + struct hns_roce_rq_wqe_ctrl *ctrl = NULL; + struct hns_roce_wqe_data_seg *scat = NULL; + struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); +@@ -361,9 +353,14 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + struct device *dev = &hr_dev->pdev->dev; + struct hns_roce_rq_db rq_db; + __le32 doorbell[2] = {0}; ++ unsigned long flags = 0; ++ unsigned int wqe_idx; ++ int ret = 0; ++ int nreq = 0; ++ int i = 0; ++ u32 reg_val; + + spin_lock_irqsave(&hr_qp->rq.lock, flags); +- ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1); + + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (hns_roce_wq_overflow(&hr_qp->rq, nreq, +@@ -373,6 +370,8 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (hr_qp->rq.head + nreq) & (hr_qp->rq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { + dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, hr_qp->rq.max_gs); +@@ -381,7 +380,7 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + goto out; + } + +- ctrl = get_recv_wqe(hr_qp, ind); ++ ctrl = get_recv_wqe(hr_qp, wqe_idx); + + roce_set_field(ctrl->rwqe_byte_12, + RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M, +@@ -393,9 +392,7 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + for (i = 0; i < wr->num_sge; i++) + set_data_seg(scat + i, wr->sg_list + i); + +- hr_qp->rq.wrid[ind] = wr->wr_id; +- +- ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1); ++ hr_qp->rq.wrid[wqe_idx] = wr->wr_id; + } + + out: +@@ -2701,7 +2698,6 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, + hr_qp->rq.tail = 0; + hr_qp->sq.head = 0; + hr_qp->sq.tail = 0; +- hr_qp->sq_next_wqe = 0; + } + + kfree(context); +@@ -3315,7 +3311,6 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, + hr_qp->rq.tail = 0; + hr_qp->sq.head = 0; + hr_qp->sq.tail = 0; +- hr_qp->sq_next_wqe = 0; + } + out: + kfree(context); +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index cb8071a3e0d5..87186446dffb 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -110,7 +110,7 @@ static void set_atomic_seg(struct hns_roce_wqe_atomic_seg *aseg, + } + + static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, +- unsigned int *sge_ind) ++ unsigned int *sge_ind, int valid_num_sge) + { + struct hns_roce_v2_wqe_data_seg *dseg; + struct ib_sge *sg; +@@ -123,7 +123,7 @@ static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + + if (qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) + num_in_wqe = HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; +- extend_sge_num = wr->num_sge - num_in_wqe; ++ extend_sge_num = valid_num_sge - num_in_wqe; + sg = wr->sg_list + num_in_wqe; + shift = qp->hr_buf.page_shift; + +@@ -159,14 +159,16 @@ static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + struct hns_roce_v2_rc_send_wqe *rc_sq_wqe, + void *wqe, unsigned int *sge_ind, ++ int valid_num_sge, + const struct ib_send_wr **bad_wr) + { + struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); + struct hns_roce_v2_wqe_data_seg *dseg = wqe; + struct hns_roce_qp *qp = to_hr_qp(ibqp); ++ int j = 0; + int i; + +- if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) { ++ if (wr->send_flags & IB_SEND_INLINE && valid_num_sge) { + if (le32_to_cpu(rc_sq_wqe->msg_len) > + hr_dev->caps.max_sq_inline) { + *bad_wr = wr; +@@ -190,7 +192,7 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, + 1); + } else { +- if (wr->num_sge <= HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) { ++ if (valid_num_sge <= HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) { + for (i = 0; i < wr->num_sge; i++) { + if (likely(wr->sg_list[i].length)) { + set_data_seg_v2(dseg, wr->sg_list + i); +@@ -203,19 +205,21 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, + (*sge_ind) & (qp->sge.sge_cnt - 1)); + +- for (i = 0; i < HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; i++) { ++ for (i = 0; i < wr->num_sge && ++ j < HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; i++) { + if (likely(wr->sg_list[i].length)) { + set_data_seg_v2(dseg, wr->sg_list + i); + dseg++; ++ j++; + } + } + +- set_extend_sge(qp, wr, sge_ind); ++ set_extend_sge(qp, wr, sge_ind, valid_num_sge); + } + + roce_set_field(rc_sq_wqe->byte_16, + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, wr->num_sge); ++ V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge); + } + + return 0; +@@ -239,10 +243,11 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + struct device *dev = hr_dev->dev; + struct hns_roce_v2_db sq_db; + struct ib_qp_attr attr; +- unsigned int sge_ind; + unsigned int owner_bit; ++ unsigned int sge_idx; ++ unsigned int wqe_idx; + unsigned long flags; +- unsigned int ind; ++ int valid_num_sge; + void *wqe = NULL; + bool loopback; + int attr_mask; +@@ -269,8 +274,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + } + + spin_lock_irqsave(&qp->sq.lock, flags); +- ind = qp->sq_next_wqe; +- sge_ind = qp->next_sge; ++ sge_idx = qp->next_sge; + + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { +@@ -279,6 +283,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > qp->sq.max_gs)) { + dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, qp->sq.max_gs); +@@ -287,14 +293,20 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + goto out; + } + +- wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); +- qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = +- wr->wr_id; +- ++ wqe = get_send_wqe(qp, wqe_idx); ++ qp->sq.wrid[wqe_idx] = wr->wr_id; + owner_bit = + ~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1); ++ valid_num_sge = 0; + tmp_len = 0; + ++ for (i = 0; i < wr->num_sge; i++) { ++ if (likely(wr->sg_list[i].length)) { ++ tmp_len += wr->sg_list[i].length; ++ valid_num_sge++; ++ } ++ } ++ + /* Corresponding to the QP type, wqe process separately */ + if (ibqp->qp_type == IB_QPT_GSI) { + ud_sq_wqe = wqe; +@@ -330,9 +342,6 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + V2_UD_SEND_WQE_BYTE_4_OPCODE_S, + HNS_ROCE_V2_WQE_OP_SEND); + +- for (i = 0; i < wr->num_sge; i++) +- tmp_len += wr->sg_list[i].length; +- + ud_sq_wqe->msg_len = + cpu_to_le32(le32_to_cpu(ud_sq_wqe->msg_len) + tmp_len); + +@@ -368,12 +377,12 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + roce_set_field(ud_sq_wqe->byte_16, + V2_UD_SEND_WQE_BYTE_16_SGE_NUM_M, + V2_UD_SEND_WQE_BYTE_16_SGE_NUM_S, +- wr->num_sge); ++ valid_num_sge); + + roce_set_field(ud_sq_wqe->byte_20, + V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M, + V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, +- sge_ind & (qp->sge.sge_cnt - 1)); ++ sge_idx & (qp->sge.sge_cnt - 1)); + + roce_set_field(ud_sq_wqe->byte_24, + V2_UD_SEND_WQE_BYTE_24_UDPSPN_M, +@@ -423,13 +432,10 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], + GID_LEN_V2); + +- set_extend_sge(qp, wr, &sge_ind); +- ind++; ++ set_extend_sge(qp, wr, &sge_idx, valid_num_sge); + } else if (ibqp->qp_type == IB_QPT_RC) { + rc_sq_wqe = wqe; + memset(rc_sq_wqe, 0, sizeof(*rc_sq_wqe)); +- for (i = 0; i < wr->num_sge; i++) +- tmp_len += wr->sg_list[i].length; + + rc_sq_wqe->msg_len = + cpu_to_le32(le32_to_cpu(rc_sq_wqe->msg_len) + tmp_len); +@@ -550,15 +556,14 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + roce_set_field(rc_sq_wqe->byte_16, + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, +- wr->num_sge); ++ valid_num_sge); + } else if (wr->opcode != IB_WR_REG_MR) { + ret = set_rwqe_data_seg(ibqp, wr, rc_sq_wqe, +- wqe, &sge_ind, bad_wr); ++ wqe, &sge_idx, ++ valid_num_sge, bad_wr); + if (ret) + goto out; + } +- +- ind++; + } else { + dev_err(dev, "Illegal qp_type(0x%x)\n", ibqp->qp_type); + spin_unlock_irqrestore(&qp->sq.lock, flags); +@@ -588,8 +593,7 @@ out: + + hns_roce_write64(hr_dev, (__le32 *)&sq_db, qp->sq.db_reg_l); + +- qp->sq_next_wqe = ind; +- qp->next_sge = sge_ind; ++ qp->next_sge = sge_idx; + + if (qp->state == IB_QPS_ERR) { + attr_mask = IB_QP_STATE; +@@ -623,13 +627,12 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + unsigned long flags; + void *wqe = NULL; + int attr_mask; ++ u32 wqe_idx; + int ret = 0; + int nreq; +- int ind; + int i; + + spin_lock_irqsave(&hr_qp->rq.lock, flags); +- ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1); + + if (hr_qp->state == IB_QPS_RESET) { + spin_unlock_irqrestore(&hr_qp->rq.lock, flags); +@@ -645,6 +648,8 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (hr_qp->rq.head + nreq) & (hr_qp->rq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { + dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, hr_qp->rq.max_gs); +@@ -653,7 +658,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + goto out; + } + +- wqe = get_recv_wqe(hr_qp, ind); ++ wqe = get_recv_wqe(hr_qp, wqe_idx); + dseg = (struct hns_roce_v2_wqe_data_seg *)wqe; + for (i = 0; i < wr->num_sge; i++) { + if (!wr->sg_list[i].length) +@@ -669,8 +674,8 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + + /* rq support inline data */ + if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) { +- sge_list = hr_qp->rq_inl_buf.wqe_list[ind].sg_list; +- hr_qp->rq_inl_buf.wqe_list[ind].sge_cnt = ++ sge_list = hr_qp->rq_inl_buf.wqe_list[wqe_idx].sg_list; ++ hr_qp->rq_inl_buf.wqe_list[wqe_idx].sge_cnt = + (u32)wr->num_sge; + for (i = 0; i < wr->num_sge; i++) { + sge_list[i].addr = +@@ -679,9 +684,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + } + } + +- hr_qp->rq.wrid[ind] = wr->wr_id; +- +- ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1); ++ hr_qp->rq.wrid[wqe_idx] = wr->wr_id; + } + + out: +@@ -4464,7 +4467,6 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, + hr_qp->rq.tail = 0; + hr_qp->sq.head = 0; + hr_qp->sq.tail = 0; +- hr_qp->sq_next_wqe = 0; + hr_qp->next_sge = 0; + if (hr_qp->rq.wqe_cnt) + *hr_qp->rdb.db_record = 0; +diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c +index 3bccfef40e7e..ac86363ce1a2 100644 +--- a/drivers/infiniband/sw/siw/siw_cm.c ++++ b/drivers/infiniband/sw/siw/siw_cm.c +@@ -1225,10 +1225,9 @@ static void siw_cm_llp_data_ready(struct sock *sk) + read_lock(&sk->sk_callback_lock); + + cep = sk_to_cep(sk); +- if (!cep) { +- WARN_ON(1); ++ if (!cep) + goto out; +- } ++ + siw_dbg_cep(cep, "state: %d\n", cep->state); + + switch (cep->state) { +diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c +index 8c744578122a..a0d87ed9da69 100644 +--- a/drivers/macintosh/therm_windtunnel.c ++++ b/drivers/macintosh/therm_windtunnel.c +@@ -300,9 +300,11 @@ static int control_loop(void *dummy) + /* i2c probing and setup */ + /************************************************************************/ + +-static int +-do_attach( struct i2c_adapter *adapter ) ++static void do_attach(struct i2c_adapter *adapter) + { ++ struct i2c_board_info info = { }; ++ struct device_node *np; ++ + /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ + static const unsigned short scan_ds1775[] = { + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +@@ -313,25 +315,24 @@ do_attach( struct i2c_adapter *adapter ) + I2C_CLIENT_END + }; + +- if( strncmp(adapter->name, "uni-n", 5) ) +- return 0; +- +- if( !x.running ) { +- struct i2c_board_info info; ++ if (x.running || strncmp(adapter->name, "uni-n", 5)) ++ return; + +- memset(&info, 0, sizeof(struct i2c_board_info)); +- strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); ++ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775"); ++ if (np) { ++ of_node_put(np); ++ } else { ++ strlcpy(info.type, "MAC,ds1775", I2C_NAME_SIZE); + i2c_new_probed_device(adapter, &info, scan_ds1775, NULL); ++ } + +- strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); ++ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030"); ++ if (np) { ++ of_node_put(np); ++ } else { ++ strlcpy(info.type, "MAC,adm1030", I2C_NAME_SIZE); + i2c_new_probed_device(adapter, &info, scan_adm1030, NULL); +- +- if( x.thermostat && x.fan ) { +- x.running = 1; +- x.poll_task = kthread_run(control_loop, NULL, "g4fand"); +- } + } +- return 0; + } + + static int +@@ -404,8 +405,8 @@ out: + enum chip { ds1775, adm1030 }; + + static const struct i2c_device_id therm_windtunnel_id[] = { +- { "therm_ds1775", ds1775 }, +- { "therm_adm1030", adm1030 }, ++ { "MAC,ds1775", ds1775 }, ++ { "MAC,adm1030", adm1030 }, + { } + }; + MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id); +@@ -414,6 +415,7 @@ static int + do_probe(struct i2c_client *cl, const struct i2c_device_id *id) + { + struct i2c_adapter *adapter = cl->adapter; ++ int ret = 0; + + if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA + | I2C_FUNC_SMBUS_WRITE_BYTE) ) +@@ -421,11 +423,19 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id) + + switch (id->driver_data) { + case adm1030: +- return attach_fan( cl ); ++ ret = attach_fan(cl); ++ break; + case ds1775: +- return attach_thermostat(cl); ++ ret = attach_thermostat(cl); ++ break; + } +- return 0; ++ ++ if (!x.running && x.thermostat && x.fan) { ++ x.running = 1; ++ x.poll_task = kthread_run(control_loop, NULL, "g4fand"); ++ } ++ ++ return ret; + } + + static struct i2c_driver g4fan_driver = { +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 48d5ec770b94..d10805e5e623 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3526,6 +3526,47 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res, + } + } + ++#ifdef CONFIG_LOCKDEP ++static int bond_get_lowest_level_rcu(struct net_device *dev) ++{ ++ struct net_device *ldev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; ++ struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; ++ int cur = 0, max = 0; ++ ++ now = dev; ++ iter = &dev->adj_list.lower; ++ ++ while (1) { ++ next = NULL; ++ while (1) { ++ ldev = netdev_next_lower_dev_rcu(now, &iter); ++ if (!ldev) ++ break; ++ ++ next = ldev; ++ niter = &ldev->adj_list.lower; ++ dev_stack[cur] = now; ++ iter_stack[cur++] = iter; ++ if (max <= cur) ++ max = cur; ++ break; ++ } ++ ++ if (!next) { ++ if (!cur) ++ return max; ++ next = dev_stack[--cur]; ++ niter = iter_stack[cur]; ++ } ++ ++ now = next; ++ iter = niter; ++ } ++ ++ return max; ++} ++#endif ++ + static void bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 *stats) + { +@@ -3533,11 +3574,17 @@ static void bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 temp; + struct list_head *iter; + struct slave *slave; ++ int nest_level = 0; + +- spin_lock(&bond->stats_lock); +- memcpy(stats, &bond->bond_stats, sizeof(*stats)); + + rcu_read_lock(); ++#ifdef CONFIG_LOCKDEP ++ nest_level = bond_get_lowest_level_rcu(bond_dev); ++#endif ++ ++ spin_lock_nested(&bond->stats_lock, nest_level); ++ memcpy(stats, &bond->bond_stats, sizeof(*stats)); ++ + bond_for_each_slave_rcu(bond, slave, iter) { + const struct rtnl_link_stats64 *new = + dev_get_stats(slave->dev, &temp); +@@ -3547,10 +3594,10 @@ static void bond_get_stats(struct net_device *bond_dev, + /* save off the slave stats for the next run */ + memcpy(&slave->slave_stats, new, sizeof(*new)); + } +- rcu_read_unlock(); + + memcpy(&bond->bond_stats, stats, sizeof(*stats)); + spin_unlock(&bond->stats_lock); ++ rcu_read_unlock(); + } + + static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) +@@ -3640,6 +3687,8 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd + case BOND_RELEASE_OLD: + case SIOCBONDRELEASE: + res = bond_release(bond_dev, slave_dev); ++ if (!res) ++ netdev_update_lockdep_key(slave_dev); + break; + case BOND_SETHWADDR_OLD: + case SIOCBONDSETHWADDR: +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index ddb3916d3506..215c10923289 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -1398,6 +1398,8 @@ static int bond_option_slaves_set(struct bonding *bond, + case '-': + slave_dbg(bond->dev, dev, "Releasing interface\n"); + ret = bond_release(bond->dev, dev); ++ if (!ret) ++ netdev_update_lockdep_key(dev); + break; + + default: +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 6a1ff4d43e3a..38b16efda4a9 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1353,6 +1353,9 @@ void b53_vlan_add(struct dsa_switch *ds, int port, + + b53_get_vlan_entry(dev, vid, vl); + ++ if (vid == 0 && vid == b53_default_pvid(dev)) ++ untagged = true; ++ + vl->members |= BIT(port); + if (untagged && !dsa_is_cpu_port(ds, port)) + vl->untag |= BIT(port); +diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c +index ea62604fdf8c..1fb58f9ad80b 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -200,6 +200,11 @@ static void comp_ctxt_release(struct ena_com_admin_queue *queue, + static struct ena_comp_ctx *get_comp_ctxt(struct ena_com_admin_queue *queue, + u16 command_id, bool capture) + { ++ if (unlikely(!queue->comp_ctx)) { ++ pr_err("Completion context is NULL\n"); ++ return NULL; ++ } ++ + if (unlikely(command_id >= queue->q_depth)) { + pr_err("command id is larger than the queue size. cmd_id: %u queue size %d\n", + command_id, queue->q_depth); +@@ -1041,9 +1046,41 @@ static int ena_com_get_feature(struct ena_com_dev *ena_dev, + feature_ver); + } + ++int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev) ++{ ++ return ena_dev->rss.hash_func; ++} ++ ++static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev) ++{ ++ struct ena_admin_feature_rss_flow_hash_control *hash_key = ++ (ena_dev->rss).hash_key; ++ ++ netdev_rss_key_fill(&hash_key->key, sizeof(hash_key->key)); ++ /* The key is stored in the device in u32 array ++ * as well as the API requires the key to be passed in this ++ * format. Thus the size of our array should be divided by 4 ++ */ ++ hash_key->keys_num = sizeof(hash_key->key) / sizeof(u32); ++} ++ + static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev) + { + struct ena_rss *rss = &ena_dev->rss; ++ struct ena_admin_feature_rss_flow_hash_control *hash_key; ++ struct ena_admin_get_feat_resp get_resp; ++ int rc; ++ ++ hash_key = (ena_dev->rss).hash_key; ++ ++ rc = ena_com_get_feature_ex(ena_dev, &get_resp, ++ ENA_ADMIN_RSS_HASH_FUNCTION, ++ ena_dev->rss.hash_key_dma_addr, ++ sizeof(ena_dev->rss.hash_key), 0); ++ if (unlikely(rc)) { ++ hash_key = NULL; ++ return -EOPNOTSUPP; ++ } + + rss->hash_key = + dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key), +@@ -1254,30 +1291,6 @@ static int ena_com_ind_tbl_convert_to_device(struct ena_com_dev *ena_dev) + return 0; + } + +-static int ena_com_ind_tbl_convert_from_device(struct ena_com_dev *ena_dev) +-{ +- u16 dev_idx_to_host_tbl[ENA_TOTAL_NUM_QUEUES] = { (u16)-1 }; +- struct ena_rss *rss = &ena_dev->rss; +- u8 idx; +- u16 i; +- +- for (i = 0; i < ENA_TOTAL_NUM_QUEUES; i++) +- dev_idx_to_host_tbl[ena_dev->io_sq_queues[i].idx] = i; +- +- for (i = 0; i < 1 << rss->tbl_log_size; i++) { +- if (rss->rss_ind_tbl[i].cq_idx > ENA_TOTAL_NUM_QUEUES) +- return -EINVAL; +- idx = (u8)rss->rss_ind_tbl[i].cq_idx; +- +- if (dev_idx_to_host_tbl[idx] > ENA_TOTAL_NUM_QUEUES) +- return -EINVAL; +- +- rss->host_rss_ind_tbl[i] = dev_idx_to_host_tbl[idx]; +- } +- +- return 0; +-} +- + static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev, + u16 intr_delay_resolution) + { +@@ -2297,15 +2310,16 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev, + + switch (func) { + case ENA_ADMIN_TOEPLITZ: +- if (key_len > sizeof(hash_key->key)) { +- pr_err("key len (%hu) is bigger than the max supported (%zu)\n", +- key_len, sizeof(hash_key->key)); +- return -EINVAL; ++ if (key) { ++ if (key_len != sizeof(hash_key->key)) { ++ pr_err("key len (%hu) doesn't equal the supported size (%zu)\n", ++ key_len, sizeof(hash_key->key)); ++ return -EINVAL; ++ } ++ memcpy(hash_key->key, key, key_len); ++ rss->hash_init_val = init_val; ++ hash_key->keys_num = key_len >> 2; + } +- +- memcpy(hash_key->key, key, key_len); +- rss->hash_init_val = init_val; +- hash_key->keys_num = key_len >> 2; + break; + case ENA_ADMIN_CRC32: + rss->hash_init_val = init_val; +@@ -2342,7 +2356,11 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev, + if (unlikely(rc)) + return rc; + +- rss->hash_func = get_resp.u.flow_hash_func.selected_func; ++ /* ffs() returns 1 in case the lsb is set */ ++ rss->hash_func = ffs(get_resp.u.flow_hash_func.selected_func); ++ if (rss->hash_func) ++ rss->hash_func--; ++ + if (func) + *func = rss->hash_func; + +@@ -2606,10 +2624,6 @@ int ena_com_indirect_table_get(struct ena_com_dev *ena_dev, u32 *ind_tbl) + if (!ind_tbl) + return 0; + +- rc = ena_com_ind_tbl_convert_from_device(ena_dev); +- if (unlikely(rc)) +- return rc; +- + for (i = 0; i < (1 << rss->tbl_log_size); i++) + ind_tbl[i] = rss->host_rss_ind_tbl[i]; + +@@ -2626,9 +2640,15 @@ int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 indr_tbl_log_size) + if (unlikely(rc)) + goto err_indr_tbl; + ++ /* The following function might return unsupported in case the ++ * device doesn't support setting the key / hash function. We can safely ++ * ignore this error and have indirection table support only. ++ */ + rc = ena_com_hash_key_allocate(ena_dev); +- if (unlikely(rc)) ++ if (unlikely(rc) && rc != -EOPNOTSUPP) + goto err_hash_key; ++ else if (rc != -EOPNOTSUPP) ++ ena_com_hash_key_fill_default_key(ena_dev); + + rc = ena_com_hash_ctrl_init(ena_dev); + if (unlikely(rc)) +diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h +index 0ce37d54ed10..469f298199a7 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_com.h ++++ b/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -44,6 +44,7 @@ + #include <linux/spinlock.h> + #include <linux/types.h> + #include <linux/wait.h> ++#include <linux/netdevice.h> + + #include "ena_common_defs.h" + #include "ena_admin_defs.h" +@@ -655,6 +656,14 @@ int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 log_size); + */ + void ena_com_rss_destroy(struct ena_com_dev *ena_dev); + ++/* ena_com_get_current_hash_function - Get RSS hash function ++ * @ena_dev: ENA communication layer struct ++ * ++ * Return the current hash function. ++ * @return: 0 or one of the ena_admin_hash_functions values. ++ */ ++int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev); ++ + /* ena_com_fill_hash_function - Fill RSS hash function + * @ena_dev: ENA communication layer struct + * @func: The hash function (Toeplitz or crc) +diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +index fc96c66b44cb..971f02ea55a1 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -636,6 +636,28 @@ static u32 ena_get_rxfh_key_size(struct net_device *netdev) + return ENA_HASH_KEY_SIZE; + } + ++static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir) ++{ ++ struct ena_com_dev *ena_dev = adapter->ena_dev; ++ int i, rc; ++ ++ if (!indir) ++ return 0; ++ ++ rc = ena_com_indirect_table_get(ena_dev, indir); ++ if (rc) ++ return rc; ++ ++ /* Our internal representation of the indices is: even indices ++ * for Tx and uneven indices for Rx. We need to convert the Rx ++ * indices to be consecutive ++ */ ++ for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) ++ indir[i] = ENA_IO_RXQ_IDX_TO_COMBINED_IDX(indir[i]); ++ ++ return rc; ++} ++ + static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 *hfunc) + { +@@ -644,11 +666,25 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 func; + int rc; + +- rc = ena_com_indirect_table_get(adapter->ena_dev, indir); ++ rc = ena_indirection_table_get(adapter, indir); + if (rc) + return rc; + ++ /* We call this function in order to check if the device ++ * supports getting/setting the hash function. ++ */ + rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func, key); ++ ++ if (rc) { ++ if (rc == -EOPNOTSUPP) { ++ key = NULL; ++ hfunc = NULL; ++ rc = 0; ++ } ++ ++ return rc; ++ } ++ + if (rc) + return rc; + +@@ -657,7 +693,7 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + func = ETH_RSS_HASH_TOP; + break; + case ENA_ADMIN_CRC32: +- func = ETH_RSS_HASH_XOR; ++ func = ETH_RSS_HASH_CRC32; + break; + default: + netif_err(adapter, drv, netdev, +@@ -700,10 +736,13 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir, + } + + switch (hfunc) { ++ case ETH_RSS_HASH_NO_CHANGE: ++ func = ena_com_get_current_hash_function(ena_dev); ++ break; + case ETH_RSS_HASH_TOP: + func = ENA_ADMIN_TOEPLITZ; + break; +- case ETH_RSS_HASH_XOR: ++ case ETH_RSS_HASH_CRC32: + func = ENA_ADMIN_CRC32; + break; + default: +@@ -812,6 +851,7 @@ static const struct ethtool_ops ena_ethtool_ops = { + .set_channels = ena_set_channels, + .get_tunable = ena_get_tunable, + .set_tunable = ena_set_tunable, ++ .get_ts_info = ethtool_op_get_ts_info, + }; + + void ena_set_ethtool_ops(struct net_device *netdev) +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index 948583fdcc28..1c1a41bd11da 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3049,8 +3049,8 @@ static void check_for_missing_keep_alive(struct ena_adapter *adapter) + if (adapter->keep_alive_timeout == ENA_HW_HINTS_NO_TIMEOUT) + return; + +- keep_alive_expired = round_jiffies(adapter->last_keep_alive_jiffies + +- adapter->keep_alive_timeout); ++ keep_alive_expired = adapter->last_keep_alive_jiffies + ++ adapter->keep_alive_timeout; + if (unlikely(time_is_before_jiffies(keep_alive_expired))) { + netif_err(adapter, drv, adapter->netdev, + "Keep alive watchdog timeout.\n"); +@@ -3152,7 +3152,7 @@ static void ena_timer_service(struct timer_list *t) + } + + /* Reset the timer */ +- mod_timer(&adapter->timer_service, jiffies + HZ); ++ mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); + } + + static int ena_calc_max_io_queue_num(struct pci_dev *pdev, +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h +index bffd778f2ce3..2fe5eeea6b69 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -129,6 +129,8 @@ + + #define ENA_IO_TXQ_IDX(q) (2 * (q)) + #define ENA_IO_RXQ_IDX(q) (2 * (q) + 1) ++#define ENA_IO_TXQ_IDX_TO_COMBINED_IDX(q) ((q) / 2) ++#define ENA_IO_RXQ_IDX_TO_COMBINED_IDX(q) (((q) - 1) / 2) + + #define ENA_MGMNT_IRQ_IDX 0 + #define ENA_IO_IRQ_FIRST_IDX 1 +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +index d8612131c55e..cc8031ae9aa3 100644 +--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +@@ -2020,7 +2020,7 @@ static int xgene_enet_probe(struct platform_device *pdev) + int ret; + + ndev = alloc_etherdev_mqs(sizeof(struct xgene_enet_pdata), +- XGENE_NUM_RX_RING, XGENE_NUM_TX_RING); ++ XGENE_NUM_TX_RING, XGENE_NUM_RX_RING); + if (!ndev) + return -ENOMEM; + +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +index a1f99bef4a68..7b55633d2cb9 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +@@ -722,6 +722,11 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags) + if (flags & ~AQ_PRIV_FLAGS_MASK) + return -EOPNOTSUPP; + ++ if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) { ++ netdev_info(ndev, "Can't enable more than one loopback simultaneously\n"); ++ return -EINVAL; ++ } ++ + cfg->priv_flags = flags; + + if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) { +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +index 6102251bb909..03ff92bc4a7f 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +@@ -163,7 +163,7 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic, + } + + if ((aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) && +- (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci), ++ (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci) & VLAN_VID_MASK, + aq_nic->active_vlans))) { + netdev_err(aq_nic->ndev, + "ethtool: unknown vlan-id specified"); +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +index c85e3e29012c..e95f6a6bef73 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +@@ -533,8 +533,10 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb, + dx_buff->len, + DMA_TO_DEVICE); + +- if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) ++ if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) { ++ ret = 0; + goto exit; ++ } + + first = dx_buff; + dx_buff->len_pkt = skb->len; +@@ -655,10 +657,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) + if (likely(frags)) { + err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, + ring, frags); +- if (err >= 0) { +- ++ring->stats.tx.packets; +- ring->stats.tx.bytes += skb->len; +- } + } else { + err = NETDEV_TX_BUSY; + } +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +index 2bb329606794..f74952674084 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +@@ -359,7 +359,8 @@ static int aq_suspend_common(struct device *dev, bool deep) + netif_device_detach(nic->ndev); + netif_tx_stop_all_queues(nic->ndev); + +- aq_nic_stop(nic); ++ if (netif_running(nic->ndev)) ++ aq_nic_stop(nic); + + if (deep) { + aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol); +@@ -375,7 +376,7 @@ static int atl_resume_common(struct device *dev, bool deep) + { + struct pci_dev *pdev = to_pci_dev(dev); + struct aq_nic_s *nic; +- int ret; ++ int ret = 0; + + nic = pci_get_drvdata(pdev); + +@@ -390,9 +391,11 @@ static int atl_resume_common(struct device *dev, bool deep) + goto err_exit; + } + +- ret = aq_nic_start(nic); +- if (ret) +- goto err_exit; ++ if (netif_running(nic->ndev)) { ++ ret = aq_nic_start(nic); ++ if (ret) ++ goto err_exit; ++ } + + netif_device_attach(nic->ndev); + netif_tx_start_all_queues(nic->ndev); +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +index 951d86f8b66e..bae95a618560 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -272,9 +272,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) + } + } + +- if (unlikely(buff->is_eop)) +- dev_kfree_skb_any(buff->skb); ++ if (unlikely(buff->is_eop)) { ++ ++self->stats.rx.packets; ++ self->stats.tx.bytes += buff->skb->len; + ++ dev_kfree_skb_any(buff->skb); ++ } + buff->pa = 0U; + buff->eop_index = 0xffffU; + self->sw_head = aq_ring_next_dx(self, self->sw_head); +@@ -351,7 +354,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self, + err = 0; + goto err_exit; + } +- if (buff->is_error || buff->is_cso_err) { ++ if (buff->is_error || ++ (buff->is_lro && buff->is_cso_err)) { + buff_ = buff; + do { + next_ = buff_->next, +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +index 991e4d31b094..2c96f20f6289 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +@@ -78,7 +78,8 @@ struct __packed aq_ring_buff_s { + u32 is_cleaned:1; + u32 is_error:1; + u32 is_vlan:1; +- u32 rsvd3:4; ++ u32 is_lro:1; ++ u32 rsvd3:3; + u16 eop_index; + u16 rsvd4; + }; +diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +index ec041f78d063..fce587aaba33 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c ++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +@@ -823,6 +823,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, + } + } + ++ buff->is_lro = !!(HW_ATL_B0_RXD_WB_STAT2_RSCCNT & ++ rxd_wb->status); + if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) { + buff->len = rxd_wb->pkt_len % + AQ_CFG_RX_FRAME_MAX; +@@ -835,8 +837,7 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, + rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ? + AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len; + +- if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT & +- rxd_wb->status) { ++ if (buff->is_lro) { + /* LRO */ + buff->next = rxd_wb->next_desc_ptr; + ++ring->stats.rx.lro_packets; +@@ -884,13 +885,16 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self, + { + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; + unsigned int i = 0U; ++ u32 vlan_promisc; ++ u32 l2_promisc; + +- hw_atl_rpfl2promiscuous_mode_en_set(self, +- IS_FILTER_ENABLED(IFF_PROMISC)); ++ l2_promisc = IS_FILTER_ENABLED(IFF_PROMISC) || ++ !!(cfg->priv_flags & BIT(AQ_HW_LOOPBACK_DMA_NET)); ++ vlan_promisc = l2_promisc || cfg->is_vlan_force_promisc; + +- hw_atl_rpf_vlan_prom_mode_en_set(self, +- IS_FILTER_ENABLED(IFF_PROMISC) || +- cfg->is_vlan_force_promisc); ++ hw_atl_rpfl2promiscuous_mode_en_set(self, l2_promisc); ++ ++ hw_atl_rpf_vlan_prom_mode_en_set(self, vlan_promisc); + + hw_atl_rpfl2multicast_flr_en_set(self, + IS_FILTER_ENABLED(IFF_ALLMULTI) && +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 9d62200b6c33..cc86038b1d96 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -11775,6 +11775,14 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + if (version_printed++ == 0) + pr_info("%s", version); + ++ /* Clear any pending DMA transactions from crash kernel ++ * while loading driver in capture kernel. ++ */ ++ if (is_kdump_kernel()) { ++ pci_clear_master(pdev); ++ pcie_flr(pdev); ++ } ++ + max_irqs = bnxt_get_max_irq(pdev); + dev = alloc_etherdev_mq(sizeof(*bp), max_irqs); + if (!dev) +@@ -11972,10 +11980,10 @@ static void bnxt_shutdown(struct pci_dev *pdev) + dev_close(dev); + + bnxt_ulp_shutdown(bp); ++ bnxt_clear_int_mode(bp); ++ pci_disable_device(pdev); + + if (system_state == SYSTEM_POWER_OFF) { +- bnxt_clear_int_mode(bp); +- pci_disable_device(pdev); + pci_wake_from_d3(pdev, bp->wol); + pci_set_power_state(pdev, PCI_D3hot); + } +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index 19fe4f4867c7..c16cc1cb5874 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -645,6 +645,7 @@ + #define MACB_CAPS_GEM_HAS_PTP 0x00000040 + #define MACB_CAPS_BD_RD_PREFETCH 0x00000080 + #define MACB_CAPS_NEEDS_RSTONUBR 0x00000100 ++#define MACB_CAPS_MACB_IS_EMAC 0x08000000 + #define MACB_CAPS_FIFO_MODE 0x10000000 + #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 + #define MACB_CAPS_SG_DISABLED 0x40000000 +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 71bb0d56533a..20db44d7cda8 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -533,8 +533,21 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode, + old_ctrl = ctrl = macb_or_gem_readl(bp, NCFGR); + + /* Clear all the bits we might set later */ +- ctrl &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD) | MACB_BIT(PAE) | +- GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL)); ++ ctrl &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | MACB_BIT(PAE)); ++ ++ if (bp->caps & MACB_CAPS_MACB_IS_EMAC) { ++ if (state->interface == PHY_INTERFACE_MODE_RMII) ++ ctrl |= MACB_BIT(RM9200_RMII); ++ } else { ++ ctrl &= ~(GEM_BIT(GBE) | GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL)); ++ ++ /* We do not support MLO_PAUSE_RX yet */ ++ if (state->pause & MLO_PAUSE_TX) ++ ctrl |= MACB_BIT(PAE); ++ ++ if (state->interface == PHY_INTERFACE_MODE_SGMII) ++ ctrl |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); ++ } + + if (state->speed == SPEED_1000) + ctrl |= GEM_BIT(GBE); +@@ -544,13 +557,6 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode, + if (state->duplex) + ctrl |= MACB_BIT(FD); + +- /* We do not support MLO_PAUSE_RX yet */ +- if (state->pause & MLO_PAUSE_TX) +- ctrl |= MACB_BIT(PAE); +- +- if (state->interface == PHY_INTERFACE_MODE_SGMII) +- ctrl |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); +- + /* Apply the new configuration, if any */ + if (old_ctrl ^ ctrl) + macb_or_gem_writel(bp, NCFGR, ctrl); +@@ -569,9 +575,10 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode, + unsigned int q; + u32 ctrl; + +- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) +- queue_writel(queue, IDR, +- bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); ++ if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) ++ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) ++ queue_writel(queue, IDR, ++ bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); + + /* Disable Rx and Tx */ + ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE)); +@@ -588,17 +595,19 @@ static void macb_mac_link_up(struct phylink_config *config, unsigned int mode, + struct macb_queue *queue; + unsigned int q; + +- macb_set_tx_clk(bp->tx_clk, bp->speed, ndev); ++ if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) { ++ macb_set_tx_clk(bp->tx_clk, bp->speed, ndev); + +- /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down +- * cleared the pipeline and control registers. +- */ +- bp->macbgem_ops.mog_init_rings(bp); +- macb_init_buffers(bp); ++ /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down ++ * cleared the pipeline and control registers. ++ */ ++ bp->macbgem_ops.mog_init_rings(bp); ++ macb_init_buffers(bp); + +- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) +- queue_writel(queue, IER, +- bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); ++ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) ++ queue_writel(queue, IER, ++ bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); ++ } + + /* Enable Rx and Tx */ + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE)); +@@ -3751,6 +3760,10 @@ static int at91ether_open(struct net_device *dev) + u32 ctl; + int ret; + ++ ret = pm_runtime_get_sync(&lp->pdev->dev); ++ if (ret < 0) ++ return ret; ++ + /* Clear internal statistics */ + ctl = macb_readl(lp, NCR); + macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); +@@ -3815,7 +3828,7 @@ static int at91ether_close(struct net_device *dev) + q->rx_buffers, q->rx_buffers_dma); + q->rx_buffers = NULL; + +- return 0; ++ return pm_runtime_put(&lp->pdev->dev); + } + + /* Transmit packet */ +@@ -3998,7 +4011,6 @@ static int at91ether_init(struct platform_device *pdev) + struct net_device *dev = platform_get_drvdata(pdev); + struct macb *bp = netdev_priv(dev); + int err; +- u32 reg; + + bp->queues[0].bp = bp; + +@@ -4012,11 +4024,7 @@ static int at91ether_init(struct platform_device *pdev) + + macb_writel(bp, NCR, 0); + +- reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); +- if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) +- reg |= MACB_BIT(RM9200_RMII); +- +- macb_writel(bp, NCFGR, reg); ++ macb_writel(bp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG)); + + return 0; + } +@@ -4175,7 +4183,7 @@ static const struct macb_config sama5d4_config = { + }; + + static const struct macb_config emac_config = { +- .caps = MACB_CAPS_NEEDS_RSTONUBR, ++ .caps = MACB_CAPS_NEEDS_RSTONUBR | MACB_CAPS_MACB_IS_EMAC, + .clk_init = at91ether_clk_init, + .init = at91ether_init, + }; +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 13dbd249f35f..5d74f5a60102 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -6106,6 +6106,9 @@ static int hclge_get_all_rules(struct hnae3_handle *handle, + static void hclge_fd_get_flow_tuples(const struct flow_keys *fkeys, + struct hclge_fd_rule_tuples *tuples) + { ++#define flow_ip6_src fkeys->addrs.v6addrs.src.in6_u.u6_addr32 ++#define flow_ip6_dst fkeys->addrs.v6addrs.dst.in6_u.u6_addr32 ++ + tuples->ether_proto = be16_to_cpu(fkeys->basic.n_proto); + tuples->ip_proto = fkeys->basic.ip_proto; + tuples->dst_port = be16_to_cpu(fkeys->ports.dst); +@@ -6114,12 +6117,12 @@ static void hclge_fd_get_flow_tuples(const struct flow_keys *fkeys, + tuples->src_ip[3] = be32_to_cpu(fkeys->addrs.v4addrs.src); + tuples->dst_ip[3] = be32_to_cpu(fkeys->addrs.v4addrs.dst); + } else { +- memcpy(tuples->src_ip, +- fkeys->addrs.v6addrs.src.in6_u.u6_addr32, +- sizeof(tuples->src_ip)); +- memcpy(tuples->dst_ip, +- fkeys->addrs.v6addrs.dst.in6_u.u6_addr32, +- sizeof(tuples->dst_ip)); ++ int i; ++ ++ for (i = 0; i < IPV6_SIZE; i++) { ++ tuples->src_ip[i] = be32_to_cpu(flow_ip6_src[i]); ++ tuples->dst_ip[i] = be32_to_cpu(flow_ip6_dst[i]); ++ } + } + } + +@@ -9821,6 +9824,13 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) + return ret; + } + ++ ret = init_mgr_tbl(hdev); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "failed to reinit manager table, ret = %d\n", ret); ++ return ret; ++ } ++ + ret = hclge_init_fd_config(hdev); + if (ret) { + dev_err(&pdev->dev, "fd table init fail, ret=%d\n", ret); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +index 180224eab1ca..28db13253a5e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +@@ -566,7 +566,7 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) + */ + kinfo->num_tc = vport->vport_id ? 1 : + min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); +- vport->qs_offset = (vport->vport_id ? hdev->tm_info.num_tc : 0) + ++ vport->qs_offset = (vport->vport_id ? HNAE3_MAX_TC : 0) + + (vport->vport_id ? (vport->vport_id - 1) : 0); + + max_rss_size = min_t(u16, hdev->rss_size_max, +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 69523ac85639..56b9e445732b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -2362,7 +2362,7 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg) + goto error_param; + } + +- if (i40e_vc_validate_vqs_bitmaps(vqs)) { ++ if (!i40e_vc_validate_vqs_bitmaps(vqs)) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } +@@ -2424,7 +2424,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) + goto error_param; + } + +- if (i40e_vc_validate_vqs_bitmaps(vqs)) { ++ if (!i40e_vc_validate_vqs_bitmaps(vqs)) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c +index 77d6a0291e97..6939c14858b2 100644 +--- a/drivers/net/ethernet/intel/ice/ice_base.c ++++ b/drivers/net/ethernet/intel/ice/ice_base.c +@@ -320,7 +320,7 @@ int ice_setup_rx_ctx(struct ice_ring *ring) + if (err) + return err; + +- dev_info(&vsi->back->pdev->dev, "Registered XDP mem model MEM_TYPE_ZERO_COPY on Rx ring %d\n", ++ dev_info(ice_pf_to_dev(vsi->back), "Registered XDP mem model MEM_TYPE_ZERO_COPY on Rx ring %d\n", + ring->q_index); + } else { + if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) +@@ -399,7 +399,7 @@ int ice_setup_rx_ctx(struct ice_ring *ring) + /* Absolute queue number out of 2K needs to be passed */ + err = ice_write_rxq_ctx(hw, &rlan_ctx, pf_q); + if (err) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Failed to set LAN Rx queue context for absolute Rx queue %d error: %d\n", + pf_q, err); + return -EIO; +@@ -422,7 +422,7 @@ int ice_setup_rx_ctx(struct ice_ring *ring) + ice_alloc_rx_bufs_slow_zc(ring, ICE_DESC_UNUSED(ring)) : + ice_alloc_rx_bufs(ring, ICE_DESC_UNUSED(ring)); + if (err) +- dev_info(&vsi->back->pdev->dev, ++ dev_info(ice_pf_to_dev(vsi->back), + "Failed allocate some buffers on %sRx ring %d (pf_q %d)\n", + ring->xsk_umem ? "UMEM enabled " : "", + ring->q_index, pf_q); +@@ -817,13 +817,13 @@ ice_vsi_stop_tx_ring(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, + * queues at the hardware level anyway. + */ + if (status == ICE_ERR_RESET_ONGOING) { +- dev_dbg(&vsi->back->pdev->dev, ++ dev_dbg(ice_pf_to_dev(vsi->back), + "Reset in progress. LAN Tx queues already disabled\n"); + } else if (status == ICE_ERR_DOES_NOT_EXIST) { +- dev_dbg(&vsi->back->pdev->dev, ++ dev_dbg(ice_pf_to_dev(vsi->back), + "LAN Tx queues do not exist, nothing to disable\n"); + } else if (status) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Failed to disable LAN Tx queues, error: %d\n", status); + return -ENODEV; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index fb1d930470c7..cb437a448305 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -937,7 +937,7 @@ void ice_deinit_hw(struct ice_hw *hw) + */ + enum ice_status ice_check_reset(struct ice_hw *hw) + { +- u32 cnt, reg = 0, grst_delay; ++ u32 cnt, reg = 0, grst_delay, uld_mask; + + /* Poll for Device Active state in case a recent CORER, GLOBR, + * or EMPR has occurred. The grst delay value is in 100ms units. +@@ -959,13 +959,20 @@ enum ice_status ice_check_reset(struct ice_hw *hw) + return ICE_ERR_RESET_FAILED; + } + +-#define ICE_RESET_DONE_MASK (GLNVM_ULD_CORER_DONE_M | \ +- GLNVM_ULD_GLOBR_DONE_M) ++#define ICE_RESET_DONE_MASK (GLNVM_ULD_PCIER_DONE_M |\ ++ GLNVM_ULD_PCIER_DONE_1_M |\ ++ GLNVM_ULD_CORER_DONE_M |\ ++ GLNVM_ULD_GLOBR_DONE_M |\ ++ GLNVM_ULD_POR_DONE_M |\ ++ GLNVM_ULD_POR_DONE_1_M |\ ++ GLNVM_ULD_PCIER_DONE_2_M) ++ ++ uld_mask = ICE_RESET_DONE_MASK; + + /* Device is Active; check Global Reset processes are done */ + for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) { +- reg = rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK; +- if (reg == ICE_RESET_DONE_MASK) { ++ reg = rd32(hw, GLNVM_ULD) & uld_mask; ++ if (reg == uld_mask) { + ice_debug(hw, ICE_DBG_INIT, + "Global reset processes done. %d\n", cnt); + break; +diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_nl.c b/drivers/net/ethernet/intel/ice/ice_dcb_nl.c +index d870c1aedc17..265cf69b321b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_dcb_nl.c ++++ b/drivers/net/ethernet/intel/ice/ice_dcb_nl.c +@@ -713,13 +713,13 @@ static int ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app) + return -EINVAL; + + mutex_lock(&pf->tc_mutex); +- ret = dcb_ieee_delapp(netdev, app); +- if (ret) +- goto delapp_out; +- + old_cfg = &pf->hw.port_info->local_dcbx_cfg; + +- if (old_cfg->numapps == 1) ++ if (old_cfg->numapps <= 1) ++ goto delapp_out; ++ ++ ret = dcb_ieee_delapp(netdev, app); ++ if (ret) + goto delapp_out; + + new_cfg = &pf->hw.port_info->desired_dcbx_cfg; +@@ -882,7 +882,7 @@ ice_dcbnl_vsi_del_app(struct ice_vsi *vsi, + sapp.protocol = app->prot_id; + sapp.priority = app->priority; + err = ice_dcbnl_delapp(vsi->netdev, &sapp); +- dev_dbg(&vsi->back->pdev->dev, ++ dev_dbg(ice_pf_to_dev(vsi->back), + "Deleting app for VSI idx=%d err=%d sel=%d proto=0x%x, prio=%d\n", + vsi->idx, err, app->selector, app->prot_id, app->priority); + } +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c +index 9ebd93e79aeb..9bd166e3dff3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c +@@ -165,13 +165,24 @@ static void + ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) + { + struct ice_netdev_priv *np = netdev_priv(netdev); ++ u8 oem_ver, oem_patch, nvm_ver_hi, nvm_ver_lo; + struct ice_vsi *vsi = np->vsi; + struct ice_pf *pf = vsi->back; ++ struct ice_hw *hw = &pf->hw; ++ u16 oem_build; + + strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); + strlcpy(drvinfo->version, ice_drv_ver, sizeof(drvinfo->version)); +- strlcpy(drvinfo->fw_version, ice_nvm_version_str(&pf->hw), +- sizeof(drvinfo->fw_version)); ++ ++ /* Display NVM version (from which the firmware version can be ++ * determined) which contains more pertinent information. ++ */ ++ ice_get_nvm_version(hw, &oem_ver, &oem_build, &oem_patch, ++ &nvm_ver_hi, &nvm_ver_lo); ++ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%x.%02x 0x%x %d.%d.%d", nvm_ver_hi, nvm_ver_lo, ++ hw->nvm.eetrack, oem_ver, oem_build, oem_patch); ++ + strlcpy(drvinfo->bus_info, pci_name(pf->pdev), + sizeof(drvinfo->bus_info)); + drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE; +@@ -1043,7 +1054,7 @@ ice_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam) + fec = ICE_FEC_NONE; + break; + default: +- dev_warn(&vsi->back->pdev->dev, "Unsupported FEC mode: %d\n", ++ dev_warn(ice_pf_to_dev(vsi->back), "Unsupported FEC mode: %d\n", + fecparam->fec); + return -EINVAL; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +index e8f32350fed2..6f4a70fa3903 100644 +--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h ++++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +@@ -276,8 +276,14 @@ + #define GLNVM_GENS_SR_SIZE_S 5 + #define GLNVM_GENS_SR_SIZE_M ICE_M(0x7, 5) + #define GLNVM_ULD 0x000B6008 ++#define GLNVM_ULD_PCIER_DONE_M BIT(0) ++#define GLNVM_ULD_PCIER_DONE_1_M BIT(1) + #define GLNVM_ULD_CORER_DONE_M BIT(3) + #define GLNVM_ULD_GLOBR_DONE_M BIT(4) ++#define GLNVM_ULD_POR_DONE_M BIT(5) ++#define GLNVM_ULD_POR_DONE_1_M BIT(8) ++#define GLNVM_ULD_PCIER_DONE_2_M BIT(9) ++#define GLNVM_ULD_PE_DONE_M BIT(10) + #define GLPCI_CNF2 0x000BE004 + #define GLPCI_CNF2_CACHELINE_SIZE_M BIT(1) + #define PF_FUNC_RID 0x0009E880 +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index e7449248fab4..b43bb51f6067 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -116,7 +116,7 @@ static void ice_vsi_set_num_desc(struct ice_vsi *vsi) + vsi->num_tx_desc = ICE_DFLT_NUM_TX_DESC; + break; + default: +- dev_dbg(&vsi->back->pdev->dev, ++ dev_dbg(ice_pf_to_dev(vsi->back), + "Not setting number of Tx/Rx descriptors for VSI type %d\n", + vsi->type); + break; +@@ -697,7 +697,7 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) + vsi->num_txq = tx_count; + + if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) { +- dev_dbg(&vsi->back->pdev->dev, "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n"); ++ dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n"); + /* since there is a chance that num_rxq could have been changed + * in the above for loop, make num_txq equal to num_rxq. + */ +@@ -1306,7 +1306,7 @@ setup_rings: + + err = ice_setup_rx_ctx(vsi->rx_rings[i]); + if (err) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "ice_setup_rx_ctx failed for RxQ %d, err %d\n", + i, err); + return err; +@@ -1476,7 +1476,7 @@ int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi) + + status = ice_update_vsi(hw, vsi->idx, ctxt, NULL); + if (status) { +- dev_err(&vsi->back->pdev->dev, "update VSI for VLAN insert failed, err %d aq_err %d\n", ++ dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN insert failed, err %d aq_err %d\n", + status, hw->adminq.sq_last_status); + ret = -EIO; + goto out; +@@ -1522,7 +1522,7 @@ int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) + + status = ice_update_vsi(hw, vsi->idx, ctxt, NULL); + if (status) { +- dev_err(&vsi->back->pdev->dev, "update VSI for VLAN strip failed, ena = %d err %d aq_err %d\n", ++ dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN strip failed, ena = %d err %d aq_err %d\n", + ena, status, hw->adminq.sq_last_status); + ret = -EIO; + goto out; +@@ -1696,7 +1696,7 @@ ice_vsi_set_q_vectors_reg_idx(struct ice_vsi *vsi) + struct ice_q_vector *q_vector = vsi->q_vectors[i]; + + if (!q_vector) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Failed to set reg_idx on q_vector %d VSI %d\n", + i, vsi->vsi_num); + goto clear_reg_idx; +@@ -2647,25 +2647,6 @@ out: + } + #endif /* CONFIG_DCB */ + +-/** +- * ice_nvm_version_str - format the NVM version strings +- * @hw: ptr to the hardware info +- */ +-char *ice_nvm_version_str(struct ice_hw *hw) +-{ +- u8 oem_ver, oem_patch, ver_hi, ver_lo; +- static char buf[ICE_NVM_VER_LEN]; +- u16 oem_build; +- +- ice_get_nvm_version(hw, &oem_ver, &oem_build, &oem_patch, &ver_hi, +- &ver_lo); +- +- snprintf(buf, sizeof(buf), "%x.%02x 0x%x %d.%d.%d", ver_hi, ver_lo, +- hw->nvm.eetrack, oem_ver, oem_build, oem_patch); +- +- return buf; +-} +- + /** + * ice_update_ring_stats - Update ring statistics + * @ring: ring to update +@@ -2737,6 +2718,6 @@ ice_vsi_cfg_mac_fltr(struct ice_vsi *vsi, const u8 *macaddr, bool set) + status = ice_remove_mac(&vsi->back->hw, &tmp_add_list); + + cfg_mac_fltr_exit: +- ice_free_fltr_list(&vsi->back->pdev->dev, &tmp_add_list); ++ ice_free_fltr_list(ice_pf_to_dev(vsi->back), &tmp_add_list); + return status; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h +index 6e31e30aba39..0d2b1119c0e3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.h ++++ b/drivers/net/ethernet/intel/ice/ice_lib.h +@@ -97,8 +97,6 @@ void ice_vsi_cfg_frame_size(struct ice_vsi *vsi); + + u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran); + +-char *ice_nvm_version_str(struct ice_hw *hw); +- + enum ice_status + ice_vsi_cfg_mac_fltr(struct ice_vsi *vsi, const u8 *macaddr, bool set); + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 69bff085acf7..7f71f06fa819 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -269,7 +269,7 @@ static int ice_cfg_promisc(struct ice_vsi *vsi, u8 promisc_m, bool set_promisc) + */ + static int ice_vsi_sync_fltr(struct ice_vsi *vsi) + { +- struct device *dev = &vsi->back->pdev->dev; ++ struct device *dev = ice_pf_to_dev(vsi->back); + struct net_device *netdev = vsi->netdev; + bool promisc_forced_on = false; + struct ice_pf *pf = vsi->back; +@@ -1235,7 +1235,7 @@ static void ice_handle_mdd_event(struct ice_pf *pf) + u16 queue = ((reg & GL_MDET_TX_TCLAN_QNUM_M) >> + GL_MDET_TX_TCLAN_QNUM_S); + +- if (netif_msg_rx_err(pf)) ++ if (netif_msg_tx_err(pf)) + dev_info(dev, "Malicious Driver Detection event %d on TX queue %d PF# %d VF# %d\n", + event, queue, pf_num, vf_num); + wr32(hw, GL_MDET_TX_TCLAN, 0xffffffff); +@@ -1364,7 +1364,7 @@ static int ice_force_phys_link_state(struct ice_vsi *vsi, bool link_up) + if (vsi->type != ICE_VSI_PF) + return 0; + +- dev = &vsi->back->pdev->dev; ++ dev = ice_pf_to_dev(vsi->back); + + pi = vsi->port_info; + +@@ -1682,7 +1682,7 @@ free_q_irqs: + */ + static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi) + { +- struct device *dev = &vsi->back->pdev->dev; ++ struct device *dev = ice_pf_to_dev(vsi->back); + int i; + + for (i = 0; i < vsi->num_xdp_txq; i++) { +@@ -3241,11 +3241,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + goto err_exit_unroll; + } + +- dev_info(dev, "firmware %d.%d.%d api %d.%d.%d nvm %s build 0x%08x\n", +- hw->fw_maj_ver, hw->fw_min_ver, hw->fw_patch, +- hw->api_maj_ver, hw->api_min_ver, hw->api_patch, +- ice_nvm_version_str(hw), hw->fw_build); +- + ice_request_fw(pf); + + /* if ice_request_fw fails, ICE_FLAG_ADV_FEATURES bit won't be +@@ -3863,14 +3858,14 @@ ice_set_features(struct net_device *netdev, netdev_features_t features) + + /* Don't set any netdev advanced features with device in Safe Mode */ + if (ice_is_safe_mode(vsi->back)) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Device is in Safe Mode - not enabling advanced netdev features\n"); + return ret; + } + + /* Do not change setting during reset */ + if (ice_is_reset_in_progress(pf->state)) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Device is resetting, changing advanced netdev features temporarily unavailable.\n"); + return -EBUSY; + } +@@ -4413,7 +4408,7 @@ int ice_vsi_setup_tx_rings(struct ice_vsi *vsi) + int i, err = 0; + + if (!vsi->num_txq) { +- dev_err(&vsi->back->pdev->dev, "VSI %d has 0 Tx queues\n", ++ dev_err(ice_pf_to_dev(vsi->back), "VSI %d has 0 Tx queues\n", + vsi->vsi_num); + return -EINVAL; + } +@@ -4444,7 +4439,7 @@ int ice_vsi_setup_rx_rings(struct ice_vsi *vsi) + int i, err = 0; + + if (!vsi->num_rxq) { +- dev_err(&vsi->back->pdev->dev, "VSI %d has 0 Rx queues\n", ++ dev_err(ice_pf_to_dev(vsi->back), "VSI %d has 0 Rx queues\n", + vsi->vsi_num); + return -EINVAL; + } +@@ -4973,7 +4968,7 @@ static int ice_vsi_update_bridge_mode(struct ice_vsi *vsi, u16 bmode) + + status = ice_update_vsi(hw, vsi->idx, ctxt, NULL); + if (status) { +- dev_err(&vsi->back->pdev->dev, "update VSI for bridge mode failed, bmode = %d err %d aq_err %d\n", ++ dev_err(ice_pf_to_dev(vsi->back), "update VSI for bridge mode failed, bmode = %d err %d aq_err %d\n", + bmode, status, hw->adminq.sq_last_status); + ret = -EIO; + goto out; +diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c +index 35bbc4ff603c..6da048a6ca7c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c +@@ -10,7 +10,7 @@ + */ + void ice_release_rx_desc(struct ice_ring *rx_ring, u32 val) + { +- u16 prev_ntu = rx_ring->next_to_use; ++ u16 prev_ntu = rx_ring->next_to_use & ~0x7; + + rx_ring->next_to_use = val; + +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +index edb374296d1f..e2114f24a19e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +@@ -508,7 +508,7 @@ static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 vid, bool enable) + + status = ice_update_vsi(hw, vsi->idx, ctxt, NULL); + if (status) { +- dev_info(&vsi->back->pdev->dev, "update VSI for port VLAN failed, err %d aq_err %d\n", ++ dev_info(ice_pf_to_dev(vsi->back), "update VSI for port VLAN failed, err %d aq_err %d\n", + status, hw->adminq.sq_last_status); + ret = -EIO; + goto out; +@@ -2019,7 +2019,7 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg) + continue; + + if (ice_vsi_ctrl_rx_ring(vsi, true, vf_q_id)) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Failed to enable Rx ring %d on VSI %d\n", + vf_q_id, vsi->vsi_num); + v_ret = VIRTCHNL_STATUS_ERR_PARAM; +@@ -2122,7 +2122,7 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) + + if (ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, + ring, &txq_meta)) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Failed to stop Tx ring %d on VSI %d\n", + vf_q_id, vsi->vsi_num); + v_ret = VIRTCHNL_STATUS_ERR_PARAM; +@@ -2149,7 +2149,7 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) + continue; + + if (ice_vsi_ctrl_rx_ring(vsi, false, vf_q_id)) { +- dev_err(&vsi->back->pdev->dev, ++ dev_err(ice_pf_to_dev(vsi->back), + "Failed to stop Rx ring %d on VSI %d\n", + vf_q_id, vsi->vsi_num); + v_ret = VIRTCHNL_STATUS_ERR_PARAM; +diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c +index 2da8eee27e98..ecbd4be145b8 100644 +--- a/drivers/net/ethernet/mscc/ocelot_board.c ++++ b/drivers/net/ethernet/mscc/ocelot_board.c +@@ -114,6 +114,14 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg) + if (err != 4) + break; + ++ /* At this point the IFH was read correctly, so it is safe to ++ * presume that there is no error. The err needs to be reset ++ * otherwise a frame could come in CPU queue between the while ++ * condition and the check for error later on. And in that case ++ * the new frame is just removed and not processed. ++ */ ++ err = 0; ++ + ocelot_parse_ifh(ifh, &info); + + ocelot_port = ocelot->ports[info.port]; +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +index 5f9d2ec70446..61c06fbe10db 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +@@ -103,7 +103,7 @@ int ionic_heartbeat_check(struct ionic *ionic) + { + struct ionic_dev *idev = &ionic->idev; + unsigned long hb_time; +- u32 fw_status; ++ u8 fw_status; + u32 hb; + + /* wait a little more than one second before testing again */ +@@ -111,9 +111,12 @@ int ionic_heartbeat_check(struct ionic *ionic) + if (time_before(hb_time, (idev->last_hb_time + ionic->watchdog_period))) + return 0; + +- /* firmware is useful only if fw_status is non-zero */ +- fw_status = ioread32(&idev->dev_info_regs->fw_status); +- if (!fw_status) ++ /* firmware is useful only if the running bit is set and ++ * fw_status != 0xff (bad PCI read) ++ */ ++ fw_status = ioread8(&idev->dev_info_regs->fw_status); ++ if (fw_status == 0xff || ++ !(fw_status & IONIC_FW_STS_F_RUNNING)) + return -ENXIO; + + /* early FW has no heartbeat, else FW will return non-zero */ +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h +index ed23a05f2642..d5e8b4e2a96e 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h ++++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h +@@ -2348,6 +2348,7 @@ union ionic_dev_info_regs { + u8 version; + u8 asic_type; + u8 asic_rev; ++#define IONIC_FW_STS_F_RUNNING 0x1 + u8 fw_status; + u32 fw_heartbeat; + char fw_version[IONIC_DEVINFO_FWVERS_BUFLEN]; +diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h +index e8a1b27db84d..234c6f30effb 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede.h ++++ b/drivers/net/ethernet/qlogic/qede/qede.h +@@ -163,6 +163,8 @@ struct qede_rdma_dev { + struct list_head entry; + struct list_head rdma_event_list; + struct workqueue_struct *rdma_wq; ++ struct kref refcnt; ++ struct completion event_comp; + bool exp_recovery; + }; + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_rdma.c b/drivers/net/ethernet/qlogic/qede/qede_rdma.c +index ffabc2d2f082..2d873ae8a234 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c +@@ -59,6 +59,9 @@ static void _qede_rdma_dev_add(struct qede_dev *edev) + static int qede_rdma_create_wq(struct qede_dev *edev) + { + INIT_LIST_HEAD(&edev->rdma_info.rdma_event_list); ++ kref_init(&edev->rdma_info.refcnt); ++ init_completion(&edev->rdma_info.event_comp); ++ + edev->rdma_info.rdma_wq = create_singlethread_workqueue("rdma_wq"); + if (!edev->rdma_info.rdma_wq) { + DP_NOTICE(edev, "qedr: Could not create workqueue\n"); +@@ -83,8 +86,23 @@ static void qede_rdma_cleanup_event(struct qede_dev *edev) + } + } + ++static void qede_rdma_complete_event(struct kref *ref) ++{ ++ struct qede_rdma_dev *rdma_dev = ++ container_of(ref, struct qede_rdma_dev, refcnt); ++ ++ /* no more events will be added after this */ ++ complete(&rdma_dev->event_comp); ++} ++ + static void qede_rdma_destroy_wq(struct qede_dev *edev) + { ++ /* Avoid race with add_event flow, make sure it finishes before ++ * we start accessing the list and cleaning up the work ++ */ ++ kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); ++ wait_for_completion(&edev->rdma_info.event_comp); ++ + qede_rdma_cleanup_event(edev); + destroy_workqueue(edev->rdma_info.rdma_wq); + } +@@ -310,15 +328,24 @@ static void qede_rdma_add_event(struct qede_dev *edev, + if (!edev->rdma_info.qedr_dev) + return; + ++ /* We don't want the cleanup flow to start while we're allocating and ++ * scheduling the work ++ */ ++ if (!kref_get_unless_zero(&edev->rdma_info.refcnt)) ++ return; /* already being destroyed */ ++ + event_node = qede_rdma_get_free_event_node(edev); + if (!event_node) +- return; ++ goto out; + + event_node->event = event; + event_node->ptr = edev; + + INIT_WORK(&event_node->work, qede_rdma_handle_event); + queue_work(edev->rdma_info.rdma_wq, &event_node->work); ++ ++out: ++ kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); + } + + void qede_rdma_dev_event_open(struct qede_dev *edev) +diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c +index eab83e71567a..6c0732fc8c25 100644 +--- a/drivers/net/hyperv/netvsc.c ++++ b/drivers/net/hyperv/netvsc.c +@@ -99,7 +99,7 @@ static struct netvsc_device *alloc_net_device(void) + + init_waitqueue_head(&net_device->wait_drain); + net_device->destroy = false; +- net_device->tx_disable = false; ++ net_device->tx_disable = true; + + net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; + net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index f3f9eb8a402a..ee1ad7ae7555 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -977,6 +977,7 @@ static int netvsc_attach(struct net_device *ndev, + } + + /* In any case device is now ready */ ++ nvdev->tx_disable = false; + netif_device_attach(ndev); + + /* Note: enable and attach happen when sub-channels setup */ +@@ -2354,6 +2355,8 @@ static int netvsc_probe(struct hv_device *dev, + else + net->max_mtu = ETH_DATA_LEN; + ++ nvdev->tx_disable = false; ++ + ret = register_netdevice(net); + if (ret != 0) { + pr_err("Unable to register netdev.\n"); +diff --git a/drivers/net/phy/mdio-bcm-iproc.c b/drivers/net/phy/mdio-bcm-iproc.c +index 7e9975d25066..f1ded03f0229 100644 +--- a/drivers/net/phy/mdio-bcm-iproc.c ++++ b/drivers/net/phy/mdio-bcm-iproc.c +@@ -178,6 +178,23 @@ static int iproc_mdio_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_PM_SLEEP ++int iproc_mdio_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct iproc_mdio_priv *priv = platform_get_drvdata(pdev); ++ ++ /* restore the mii clock configuration */ ++ iproc_mdio_config_clk(priv->base); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops iproc_mdio_pm_ops = { ++ .resume = iproc_mdio_resume ++}; ++#endif /* CONFIG_PM_SLEEP */ ++ + static const struct of_device_id iproc_mdio_of_match[] = { + { .compatible = "brcm,iproc-mdio", }, + { /* sentinel */ }, +@@ -188,6 +205,9 @@ static struct platform_driver iproc_mdio_driver = { + .driver = { + .name = "iproc-mdio", + .of_match_table = iproc_mdio_of_match, ++#ifdef CONFIG_PM_SLEEP ++ .pm = &iproc_mdio_pm_ops, ++#endif + }, + .probe = iproc_mdio_probe, + .remove = iproc_mdio_remove, +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 9485c8d1de8a..3b7a3b8a5e06 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -61,7 +61,6 @@ enum qmi_wwan_flags { + + enum qmi_wwan_quirks { + QMI_WWAN_QUIRK_DTR = 1 << 0, /* needs "set DTR" request */ +- QMI_WWAN_QUIRK_QUECTEL_DYNCFG = 1 << 1, /* check num. endpoints */ + }; + + struct qmimux_hdr { +@@ -916,16 +915,6 @@ static const struct driver_info qmi_wwan_info_quirk_dtr = { + .data = QMI_WWAN_QUIRK_DTR, + }; + +-static const struct driver_info qmi_wwan_info_quirk_quectel_dyncfg = { +- .description = "WWAN/QMI device", +- .flags = FLAG_WWAN | FLAG_SEND_ZLP, +- .bind = qmi_wwan_bind, +- .unbind = qmi_wwan_unbind, +- .manage_power = qmi_wwan_manage_power, +- .rx_fixup = qmi_wwan_rx_fixup, +- .data = QMI_WWAN_QUIRK_DTR | QMI_WWAN_QUIRK_QUECTEL_DYNCFG, +-}; +- + #define HUAWEI_VENDOR_ID 0x12D1 + + /* map QMI/wwan function by a fixed interface number */ +@@ -946,14 +935,18 @@ static const struct driver_info qmi_wwan_info_quirk_quectel_dyncfg = { + #define QMI_GOBI_DEVICE(vend, prod) \ + QMI_FIXED_INTF(vend, prod, 0) + +-/* Quectel does not use fixed interface numbers on at least some of their +- * devices. We need to check the number of endpoints to ensure that we bind to +- * the correct interface. ++/* Many devices have QMI and DIAG functions which are distinguishable ++ * from other vendor specific functions by class, subclass and ++ * protocol all being 0xff. The DIAG function has exactly 2 endpoints ++ * and is silently rejected when probed. ++ * ++ * This makes it possible to match dynamically numbered QMI functions ++ * as seen on e.g. many Quectel modems. + */ +-#define QMI_QUIRK_QUECTEL_DYNCFG(vend, prod) \ ++#define QMI_MATCH_FF_FF_FF(vend, prod) \ + USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_VENDOR_SPEC, \ + USB_SUBCLASS_VENDOR_SPEC, 0xff), \ +- .driver_info = (unsigned long)&qmi_wwan_info_quirk_quectel_dyncfg ++ .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr + + static const struct usb_device_id products[] = { + /* 1. CDC ECM like devices match on the control interface */ +@@ -1059,10 +1052,10 @@ static const struct usb_device_id products[] = { + USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), + .driver_info = (unsigned long)&qmi_wwan_info, + }, +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ + + /* 3. Combined interface devices matching on interface number */ + {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ +@@ -1363,6 +1356,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */ ++ {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */ + {QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/ + {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ + {QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */ +@@ -1454,7 +1448,6 @@ static int qmi_wwan_probe(struct usb_interface *intf, + { + struct usb_device_id *id = (struct usb_device_id *)prod; + struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; +- const struct driver_info *info; + + /* Workaround to enable dynamic IDs. This disables usbnet + * blacklisting functionality. Which, if required, can be +@@ -1490,12 +1483,8 @@ static int qmi_wwan_probe(struct usb_interface *intf, + * different. Ignore the current interface if the number of endpoints + * equals the number for the diag interface (two). + */ +- info = (void *)id->driver_info; +- +- if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) { +- if (desc->bNumEndpoints == 2) +- return -ENODEV; +- } ++ if (desc->bNumEndpoints == 2) ++ return -ENODEV; + + return usbnet_probe(intf, id); + } +diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h +index 547ff3c578ee..fa5634af40f7 100644 +--- a/drivers/net/wireless/marvell/mwifiex/main.h ++++ b/drivers/net/wireless/marvell/mwifiex/main.h +@@ -1295,19 +1295,6 @@ mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len) + return pos; + } + +-/* This function return interface number with the same bss_type. +- */ +-static inline u8 +-mwifiex_get_intf_num(struct mwifiex_adapter *adapter, u8 bss_type) +-{ +- u8 i, num = 0; +- +- for (i = 0; i < adapter->priv_num; i++) +- if (adapter->priv[i] && adapter->priv[i]->bss_type == bss_type) +- num++; +- return num; +-} +- + /* + * This function returns the correct private structure pointer based + * upon the BSS type and BSS number. +diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c +index 7caf1d26124a..f8f282ce39bd 100644 +--- a/drivers/net/wireless/marvell/mwifiex/tdls.c ++++ b/drivers/net/wireless/marvell/mwifiex/tdls.c +@@ -894,7 +894,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + u8 *peer, *pos, *end; + u8 i, action, basic; + u16 cap = 0; +- int ie_len = 0; ++ int ies_len = 0; + + if (len < (sizeof(struct ethhdr) + 3)) + return; +@@ -916,7 +916,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + pos = buf + sizeof(struct ethhdr) + 4; + /* payload 1+ category 1 + action 1 + dialog 1 */ + cap = get_unaligned_le16(pos); +- ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; ++ ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; + pos += 2; + break; + +@@ -926,7 +926,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ + pos = buf + sizeof(struct ethhdr) + 6; + cap = get_unaligned_le16(pos); +- ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; ++ ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; + pos += 2; + break; + +@@ -934,7 +934,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN)) + return; + pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN; +- ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; ++ ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; + break; + default: + mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); +@@ -947,33 +947,33 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + + sta_ptr->tdls_cap.capab = cpu_to_le16(cap); + +- for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) { +- if (pos + 2 + pos[1] > end) ++ for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) { ++ u8 ie_len = pos[1]; ++ ++ if (pos + 2 + ie_len > end) + break; + + switch (*pos) { + case WLAN_EID_SUPP_RATES: +- if (pos[1] > 32) ++ if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) + return; +- sta_ptr->tdls_cap.rates_len = pos[1]; +- for (i = 0; i < pos[1]; i++) ++ sta_ptr->tdls_cap.rates_len = ie_len; ++ for (i = 0; i < ie_len; i++) + sta_ptr->tdls_cap.rates[i] = pos[i + 2]; + break; + + case WLAN_EID_EXT_SUPP_RATES: +- if (pos[1] > 32) ++ if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) + return; + basic = sta_ptr->tdls_cap.rates_len; +- if (pos[1] > 32 - basic) ++ if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic) + return; +- for (i = 0; i < pos[1]; i++) ++ for (i = 0; i < ie_len; i++) + sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; +- sta_ptr->tdls_cap.rates_len += pos[1]; ++ sta_ptr->tdls_cap.rates_len += ie_len; + break; + case WLAN_EID_HT_CAPABILITY: +- if (pos > end - sizeof(struct ieee80211_ht_cap) - 2) +- return; +- if (pos[1] != sizeof(struct ieee80211_ht_cap)) ++ if (ie_len != sizeof(struct ieee80211_ht_cap)) + return; + /* copy the ie's value into ht_capb*/ + memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, +@@ -981,59 +981,45 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + sta_ptr->is_11n_enabled = 1; + break; + case WLAN_EID_HT_OPERATION: +- if (pos > end - +- sizeof(struct ieee80211_ht_operation) - 2) +- return; +- if (pos[1] != sizeof(struct ieee80211_ht_operation)) ++ if (ie_len != sizeof(struct ieee80211_ht_operation)) + return; + /* copy the ie's value into ht_oper*/ + memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, + sizeof(struct ieee80211_ht_operation)); + break; + case WLAN_EID_BSS_COEX_2040: +- if (pos > end - 3) +- return; +- if (pos[1] != 1) ++ if (ie_len != sizeof(pos[2])) + return; + sta_ptr->tdls_cap.coex_2040 = pos[2]; + break; + case WLAN_EID_EXT_CAPABILITY: +- if (pos > end - sizeof(struct ieee_types_header)) +- return; +- if (pos[1] < sizeof(struct ieee_types_header)) ++ if (ie_len < sizeof(struct ieee_types_header)) + return; +- if (pos[1] > 8) ++ if (ie_len > 8) + return; + memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, + sizeof(struct ieee_types_header) + +- min_t(u8, pos[1], 8)); ++ min_t(u8, ie_len, 8)); + break; + case WLAN_EID_RSN: +- if (pos > end - sizeof(struct ieee_types_header)) ++ if (ie_len < sizeof(struct ieee_types_header)) + return; +- if (pos[1] < sizeof(struct ieee_types_header)) +- return; +- if (pos[1] > IEEE_MAX_IE_SIZE - ++ if (ie_len > IEEE_MAX_IE_SIZE - + sizeof(struct ieee_types_header)) + return; + memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, + sizeof(struct ieee_types_header) + +- min_t(u8, pos[1], IEEE_MAX_IE_SIZE - ++ min_t(u8, ie_len, IEEE_MAX_IE_SIZE - + sizeof(struct ieee_types_header))); + break; + case WLAN_EID_QOS_CAPA: +- if (pos > end - 3) +- return; +- if (pos[1] != 1) ++ if (ie_len != sizeof(pos[2])) + return; + sta_ptr->tdls_cap.qos_info = pos[2]; + break; + case WLAN_EID_VHT_OPERATION: + if (priv->adapter->is_hw_11ac_capable) { +- if (pos > end - +- sizeof(struct ieee80211_vht_operation) - 2) +- return; +- if (pos[1] != ++ if (ie_len != + sizeof(struct ieee80211_vht_operation)) + return; + /* copy the ie's value into vhtoper*/ +@@ -1043,10 +1029,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + break; + case WLAN_EID_VHT_CAPABILITY: + if (priv->adapter->is_hw_11ac_capable) { +- if (pos > end - +- sizeof(struct ieee80211_vht_cap) - 2) +- return; +- if (pos[1] != sizeof(struct ieee80211_vht_cap)) ++ if (ie_len != sizeof(struct ieee80211_vht_cap)) + return; + /* copy the ie's value into vhtcap*/ + memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, +@@ -1056,9 +1039,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + break; + case WLAN_EID_AID: + if (priv->adapter->is_hw_11ac_capable) { +- if (pos > end - 4) +- return; +- if (pos[1] != 2) ++ if (ie_len != sizeof(u16)) + return; + sta_ptr->tdls_cap.aid = + get_unaligned_le16((pos + 2)); +diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c +index 720c89d6066e..4ac8cb262559 100644 +--- a/drivers/nfc/pn544/i2c.c ++++ b/drivers/nfc/pn544/i2c.c +@@ -225,6 +225,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) + + out: + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); ++ usleep_range(10000, 15000); + } + + static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 641c07347e8d..ada59df642d2 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -66,8 +66,8 @@ MODULE_PARM_DESC(streams, "turn on support for Streams write directives"); + * nvme_reset_wq - hosts nvme reset works + * nvme_delete_wq - hosts nvme delete works + * +- * nvme_wq will host works such are scan, aen handling, fw activation, +- * keep-alive error recovery, periodic reconnects etc. nvme_reset_wq ++ * nvme_wq will host works such as scan, aen handling, fw activation, ++ * keep-alive, periodic reconnects etc. nvme_reset_wq + * runs reset works which also flush works hosted on nvme_wq for + * serialization purposes. nvme_delete_wq host controller deletion + * works which flush reset works for serialization. +@@ -976,7 +976,7 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) + startka = true; + spin_unlock_irqrestore(&ctrl->lock, flags); + if (startka) +- schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); ++ queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); + } + + static int nvme_keep_alive(struct nvme_ctrl *ctrl) +@@ -1006,7 +1006,7 @@ static void nvme_keep_alive_work(struct work_struct *work) + dev_dbg(ctrl->device, + "reschedule traffic based keep-alive timer\n"); + ctrl->comp_seen = false; +- schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); ++ queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); + return; + } + +@@ -1023,7 +1023,7 @@ static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) + if (unlikely(ctrl->kato == 0)) + return; + +- schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); ++ queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); + } + + void nvme_stop_keep_alive(struct nvme_ctrl *ctrl) +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index da392b50f73e..bb5e13ad1aff 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1078,9 +1078,9 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx) + + spin_lock(&nvmeq->cq_poll_lock); + found = nvme_process_cq(nvmeq, &start, &end, -1); ++ nvme_complete_cqes(nvmeq, start, end); + spin_unlock(&nvmeq->cq_poll_lock); + +- nvme_complete_cqes(nvmeq, start, end); + return found; + } + +@@ -1401,6 +1401,23 @@ static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown) + nvme_poll_irqdisable(nvmeq, -1); + } + ++/* ++ * Called only on a device that has been disabled and after all other threads ++ * that can check this device's completion queues have synced. This is the ++ * last chance for the driver to see a natural completion before ++ * nvme_cancel_request() terminates all incomplete requests. ++ */ ++static void nvme_reap_pending_cqes(struct nvme_dev *dev) ++{ ++ u16 start, end; ++ int i; ++ ++ for (i = dev->ctrl.queue_count - 1; i > 0; i--) { ++ nvme_process_cq(&dev->queues[i], &start, &end, -1); ++ nvme_complete_cqes(&dev->queues[i], start, end); ++ } ++} ++ + static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues, + int entry_size) + { +@@ -2235,11 +2252,6 @@ static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode) + if (timeout == 0) + return false; + +- /* handle any remaining CQEs */ +- if (opcode == nvme_admin_delete_cq && +- !test_bit(NVMEQ_DELETE_ERROR, &nvmeq->flags)) +- nvme_poll_irqdisable(nvmeq, -1); +- + sent--; + if (nr_queues) + goto retry; +@@ -2428,6 +2440,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) + nvme_suspend_io_queues(dev); + nvme_suspend_queue(&dev->queues[0]); + nvme_pci_disable(dev); ++ nvme_reap_pending_cqes(dev); + + blk_mq_tagset_busy_iter(&dev->tagset, nvme_cancel_request, &dev->ctrl); + blk_mq_tagset_busy_iter(&dev->admin_tagset, nvme_cancel_request, &dev->ctrl); +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index 2a47c6c5007e..3e85c5cacefd 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -1088,7 +1088,7 @@ static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) + if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) + return; + +- queue_work(nvme_wq, &ctrl->err_work); ++ queue_work(nvme_reset_wq, &ctrl->err_work); + } + + static void nvme_rdma_wr_error(struct ib_cq *cq, struct ib_wc *wc, +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 6d43b23a0fc8..49d4373b84eb 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -422,7 +422,7 @@ static void nvme_tcp_error_recovery(struct nvme_ctrl *ctrl) + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + return; + +- queue_work(nvme_wq, &to_tcp_ctrl(ctrl)->err_work); ++ queue_work(nvme_reset_wq, &to_tcp_ctrl(ctrl)->err_work); + } + + static int nvme_tcp_process_nvme_cqe(struct nvme_tcp_queue *queue, +@@ -1054,7 +1054,12 @@ static void nvme_tcp_io_work(struct work_struct *w) + } else if (unlikely(result < 0)) { + dev_err(queue->ctrl->ctrl.device, + "failed to send request %d\n", result); +- if (result != -EPIPE) ++ ++ /* ++ * Fail the request unless peer closed the connection, ++ * in which case error recovery flow will complete all. ++ */ ++ if ((result != -EPIPE) && (result != -ECONNRESET)) + nvme_tcp_fail_request(queue->request); + nvme_tcp_done_send_req(queue); + return; +diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c +index d704eccc548f..f01a57e5a5f3 100644 +--- a/drivers/perf/arm_smmuv3_pmu.c ++++ b/drivers/perf/arm_smmuv3_pmu.c +@@ -771,7 +771,7 @@ static int smmu_pmu_probe(struct platform_device *pdev) + smmu_pmu->reloc_base = smmu_pmu->reg_base; + } + +- irq = platform_get_irq(pdev, 0); ++ irq = platform_get_irq_optional(pdev, 0); + if (irq > 0) + smmu_pmu->irq = irq; + +diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c +index e36fcad668a6..88a3c5690fea 100644 +--- a/drivers/pwm/pwm-omap-dmtimer.c ++++ b/drivers/pwm/pwm-omap-dmtimer.c +@@ -256,7 +256,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) + if (!timer_pdev) { + dev_err(&pdev->dev, "Unable to find Timer pdev\n"); + ret = -ENODEV; +- goto put; ++ goto err_find_timer_pdev; + } + + timer_pdata = dev_get_platdata(&timer_pdev->dev); +@@ -264,7 +264,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) + dev_dbg(&pdev->dev, + "dmtimer pdata structure NULL, deferring probe\n"); + ret = -EPROBE_DEFER; +- goto put; ++ goto err_platdata; + } + + pdata = timer_pdata->timer_ops; +@@ -283,19 +283,19 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) + !pdata->write_counter) { + dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); + ret = -EINVAL; +- goto put; ++ goto err_platdata; + } + + if (!of_get_property(timer, "ti,timer-pwm", NULL)) { + dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); + ret = -ENODEV; +- goto put; ++ goto err_timer_property; + } + + dm_timer = pdata->request_by_node(timer); + if (!dm_timer) { + ret = -EPROBE_DEFER; +- goto put; ++ goto err_request_timer; + } + + omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); +@@ -352,7 +352,14 @@ err_pwmchip_add: + err_alloc_omap: + + pdata->free(dm_timer); +-put: ++err_request_timer: ++ ++err_timer_property: ++err_platdata: ++ ++ put_device(&timer_pdev->dev); ++err_find_timer_pdev: ++ + of_node_put(timer); + + return ret; +@@ -372,6 +379,8 @@ static int pwm_omap_dmtimer_remove(struct platform_device *pdev) + + omap->pdata->free(omap->dm_timer); + ++ put_device(&omap->dm_timer_pdev->dev); ++ + mutex_destroy(&omap->mutex); + + return 0; +diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h +index bb35ba4a8d24..4348fdff1c61 100644 +--- a/drivers/s390/crypto/ap_bus.h ++++ b/drivers/s390/crypto/ap_bus.h +@@ -162,7 +162,7 @@ struct ap_card { + unsigned int functions; /* AP device function bitfield. */ + int queue_depth; /* AP queue depth.*/ + int id; /* AP card number. */ +- atomic_t total_request_count; /* # requests ever for this AP device.*/ ++ atomic64_t total_request_count; /* # requests ever for this AP device.*/ + }; + + #define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device) +@@ -179,7 +179,7 @@ struct ap_queue { + enum ap_state state; /* State of the AP device. */ + int pendingq_count; /* # requests on pendingq list. */ + int requestq_count; /* # requests on requestq list. */ +- int total_request_count; /* # requests ever for this AP device.*/ ++ u64 total_request_count; /* # requests ever for this AP device.*/ + int request_timeout; /* Request timeout in jiffies. */ + struct timer_list timeout; /* Timer for request timeouts. */ + struct list_head pendingq; /* List of message sent to AP queue. */ +diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c +index 63b4cc6cd7e5..e85bfca1ed16 100644 +--- a/drivers/s390/crypto/ap_card.c ++++ b/drivers/s390/crypto/ap_card.c +@@ -63,13 +63,13 @@ static ssize_t request_count_show(struct device *dev, + char *buf) + { + struct ap_card *ac = to_ap_card(dev); +- unsigned int req_cnt; ++ u64 req_cnt; + + req_cnt = 0; + spin_lock_bh(&ap_list_lock); +- req_cnt = atomic_read(&ac->total_request_count); ++ req_cnt = atomic64_read(&ac->total_request_count); + spin_unlock_bh(&ap_list_lock); +- return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); ++ return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); + } + + static ssize_t request_count_store(struct device *dev, +@@ -83,7 +83,7 @@ static ssize_t request_count_store(struct device *dev, + for_each_ap_queue(aq, ac) + aq->total_request_count = 0; + spin_unlock_bh(&ap_list_lock); +- atomic_set(&ac->total_request_count, 0); ++ atomic64_set(&ac->total_request_count, 0); + + return count; + } +diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c +index 37c3bdc3642d..a317ab484932 100644 +--- a/drivers/s390/crypto/ap_queue.c ++++ b/drivers/s390/crypto/ap_queue.c +@@ -479,12 +479,12 @@ static ssize_t request_count_show(struct device *dev, + char *buf) + { + struct ap_queue *aq = to_ap_queue(dev); +- unsigned int req_cnt; ++ u64 req_cnt; + + spin_lock_bh(&aq->lock); + req_cnt = aq->total_request_count; + spin_unlock_bh(&aq->lock); +- return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); ++ return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); + } + + static ssize_t request_count_store(struct device *dev, +@@ -676,7 +676,7 @@ void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) + list_add_tail(&ap_msg->list, &aq->requestq); + aq->requestq_count++; + aq->total_request_count++; +- atomic_inc(&aq->card->total_request_count); ++ atomic64_inc(&aq->card->total_request_count); + /* Send/receive as many request from the queue as possible. */ + ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL)); + spin_unlock_bh(&aq->lock); +diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c +index 9157e728a362..7fa0262e91af 100644 +--- a/drivers/s390/crypto/zcrypt_api.c ++++ b/drivers/s390/crypto/zcrypt_api.c +@@ -605,8 +605,8 @@ static inline bool zcrypt_card_compare(struct zcrypt_card *zc, + weight += atomic_read(&zc->load); + pref_weight += atomic_read(&pref_zc->load); + if (weight == pref_weight) +- return atomic_read(&zc->card->total_request_count) > +- atomic_read(&pref_zc->card->total_request_count); ++ return atomic64_read(&zc->card->total_request_count) > ++ atomic64_read(&pref_zc->card->total_request_count); + return weight > pref_weight; + } + +@@ -1216,11 +1216,12 @@ static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters) + spin_unlock(&zcrypt_list_lock); + } + +-static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters) ++static void zcrypt_perdev_reqcnt(u32 reqcnt[], size_t max_adapters) + { + struct zcrypt_card *zc; + struct zcrypt_queue *zq; + int card; ++ u64 cnt; + + memset(reqcnt, 0, sizeof(int) * max_adapters); + spin_lock(&zcrypt_list_lock); +@@ -1232,8 +1233,9 @@ static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters) + || card >= max_adapters) + continue; + spin_lock(&zq->queue->lock); +- reqcnt[card] = zq->queue->total_request_count; ++ cnt = zq->queue->total_request_count; + spin_unlock(&zq->queue->lock); ++ reqcnt[card] = (cnt < UINT_MAX) ? (u32) cnt : UINT_MAX; + } + } + local_bh_enable(); +@@ -1411,9 +1413,9 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, + return 0; + } + case ZCRYPT_PERDEV_REQCNT: { +- int *reqcnt; ++ u32 *reqcnt; + +- reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL); ++ reqcnt = kcalloc(AP_DEVICES, sizeof(u32), GFP_KERNEL); + if (!reqcnt) + return -ENOMEM; + zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES); +@@ -1470,7 +1472,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, + } + case Z90STAT_PERDEV_REQCNT: { + /* the old ioctl supports only 64 adapters */ +- int reqcnt[MAX_ZDEV_CARDIDS]; ++ u32 reqcnt[MAX_ZDEV_CARDIDS]; + + zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS); + if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt))) +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 29facb913671..10edfd6fc930 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -5142,7 +5142,7 @@ next_packet: + } + + use_rx_sg = (card->options.cq == QETH_CQ_ENABLED) || +- ((skb_len >= card->options.rx_sg_cb) && ++ (skb_len > card->options.rx_sg_cb && + !atomic_read(&card->force_alloc_skb) && + !IS_OSN(card)); + +diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c +index 47d37e75dda6..e26ad80ddfa3 100644 +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -1815,15 +1815,14 @@ int qeth_l2_vnicc_set_state(struct qeth_card *card, u32 vnicc, bool state) + + QETH_CARD_TEXT(card, 2, "vniccsch"); + +- /* do not change anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic and enable/disable are supported */ + if (!(card->options.vnicc.sup_chars & vnicc) || + !(card->options.vnicc.set_char_sup & vnicc)) + return -EOPNOTSUPP; + ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* set enable/disable command and store wanted characteristic */ + if (state) { + cmd = IPA_VNICC_ENABLE; +@@ -1869,14 +1868,13 @@ int qeth_l2_vnicc_get_state(struct qeth_card *card, u32 vnicc, bool *state) + + QETH_CARD_TEXT(card, 2, "vniccgch"); + +- /* do not get anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic is supported */ + if (!(card->options.vnicc.sup_chars & vnicc)) + return -EOPNOTSUPP; + ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* if card is ready, query current VNICC state */ + if (qeth_card_hw_is_reachable(card)) + rc = qeth_l2_vnicc_query_chars(card); +@@ -1894,15 +1892,14 @@ int qeth_l2_vnicc_set_timeout(struct qeth_card *card, u32 timeout) + + QETH_CARD_TEXT(card, 2, "vniccsto"); + +- /* do not change anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic and set_timeout are supported */ + if (!(card->options.vnicc.sup_chars & QETH_VNICC_LEARNING) || + !(card->options.vnicc.getset_timeout_sup & QETH_VNICC_LEARNING)) + return -EOPNOTSUPP; + ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* do we need to do anything? */ + if (card->options.vnicc.learning_timeout == timeout) + return rc; +@@ -1931,14 +1928,14 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout) + + QETH_CARD_TEXT(card, 2, "vniccgto"); + +- /* do not get anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic and get_timeout are supported */ + if (!(card->options.vnicc.sup_chars & QETH_VNICC_LEARNING) || + !(card->options.vnicc.getset_timeout_sup & QETH_VNICC_LEARNING)) + return -EOPNOTSUPP; ++ ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* if card is ready, get timeout. Otherwise, just return stored value */ + *timeout = card->options.vnicc.learning_timeout; + if (qeth_card_hw_is_reachable(card)) +diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h +index 2b1e4da1944f..4bfb79f20588 100644 +--- a/drivers/s390/scsi/zfcp_fsf.h ++++ b/drivers/s390/scsi/zfcp_fsf.h +@@ -410,7 +410,7 @@ struct fsf_qtcb_bottom_port { + u8 cb_util; + u8 a_util; + u8 res2; +- u16 temperature; ++ s16 temperature; + u16 vcc; + u16 tx_bias; + u16 tx_power; +diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c +index 494b9fe9cc94..a711a0d15100 100644 +--- a/drivers/s390/scsi/zfcp_sysfs.c ++++ b/drivers/s390/scsi/zfcp_sysfs.c +@@ -800,7 +800,7 @@ static ZFCP_DEV_ATTR(adapter_diag, b2b_credit, 0400, + static ZFCP_DEV_ATTR(adapter_diag_sfp, _name, 0400, \ + zfcp_sysfs_adapter_diag_sfp_##_name##_show, NULL) + +-ZFCP_DEFINE_DIAG_SFP_ATTR(temperature, temperature, 5, "%hu"); ++ZFCP_DEFINE_DIAG_SFP_ATTR(temperature, temperature, 6, "%hd"); + ZFCP_DEFINE_DIAG_SFP_ATTR(vcc, vcc, 5, "%hu"); + ZFCP_DEFINE_DIAG_SFP_ATTR(tx_bias, tx_bias, 5, "%hu"); + ZFCP_DEFINE_DIAG_SFP_ATTR(tx_power, tx_power, 5, "%hu"); +diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c +index e0bd4cf17230..5b75a65103bd 100644 +--- a/drivers/scsi/sd_zbc.c ++++ b/drivers/scsi/sd_zbc.c +@@ -161,6 +161,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, + unsigned int nr_zones, report_zones_cb cb, void *data) + { + struct scsi_disk *sdkp = scsi_disk(disk); ++ sector_t capacity = logical_to_sectors(sdkp->device, sdkp->capacity); + unsigned int nr, i; + unsigned char *buf; + size_t offset, buflen = 0; +@@ -171,11 +172,15 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, + /* Not a zoned device */ + return -EOPNOTSUPP; + ++ if (!capacity) ++ /* Device gone or invalid */ ++ return -ENODEV; ++ + buf = sd_zbc_alloc_report_buffer(sdkp, nr_zones, &buflen); + if (!buf) + return -ENOMEM; + +- while (zone_idx < nr_zones && sector < get_capacity(disk)) { ++ while (zone_idx < nr_zones && sector < capacity) { + ret = sd_zbc_do_report_zones(sdkp, buf, buflen, + sectors_to_logical(sdkp->device, sector), true); + if (ret) +diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c +index b8daaf5b7291..efd158b4607c 100644 +--- a/drivers/soc/tegra/fuse/fuse-tegra30.c ++++ b/drivers/soc/tegra/fuse/fuse-tegra30.c +@@ -36,7 +36,8 @@ + defined(CONFIG_ARCH_TEGRA_124_SOC) || \ + defined(CONFIG_ARCH_TEGRA_132_SOC) || \ + defined(CONFIG_ARCH_TEGRA_210_SOC) || \ +- defined(CONFIG_ARCH_TEGRA_186_SOC) ++ defined(CONFIG_ARCH_TEGRA_186_SOC) || \ ++ defined(CONFIG_ARCH_TEGRA_194_SOC) + static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) + { + if (WARN_ON(!fuse->base)) +diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c +index 5825ac581f56..680f1a070606 100644 +--- a/drivers/thermal/broadcom/brcmstb_thermal.c ++++ b/drivers/thermal/broadcom/brcmstb_thermal.c +@@ -49,7 +49,7 @@ + #define AVS_TMON_TP_TEST_ENABLE 0x20 + + /* Default coefficients */ +-#define AVS_TMON_TEMP_SLOPE -487 ++#define AVS_TMON_TEMP_SLOPE 487 + #define AVS_TMON_TEMP_OFFSET 410040 + + /* HW related temperature constants */ +@@ -108,23 +108,12 @@ struct brcmstb_thermal_priv { + struct thermal_zone_device *thermal; + }; + +-static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope, +- int *offset) +-{ +- *slope = thermal_zone_get_slope(tz); +- *offset = thermal_zone_get_offset(tz); +-} +- + /* Convert a HW code to a temperature reading (millidegree celsius) */ + static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, + u32 code) + { +- const int val = code & AVS_TMON_TEMP_MASK; +- int slope, offset; +- +- avs_tmon_get_coeffs(tz, &slope, &offset); +- +- return slope * val + offset; ++ return (AVS_TMON_TEMP_OFFSET - ++ (int)((code & AVS_TMON_TEMP_MAX) * AVS_TMON_TEMP_SLOPE)); + } + + /* +@@ -136,20 +125,18 @@ static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, + static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz, + int temp, bool low) + { +- int slope, offset; +- + if (temp < AVS_TMON_TEMP_MIN) +- return AVS_TMON_TEMP_MAX; /* Maximum code value */ +- +- avs_tmon_get_coeffs(tz, &slope, &offset); ++ return AVS_TMON_TEMP_MAX; /* Maximum code value */ + +- if (temp >= offset) ++ if (temp >= AVS_TMON_TEMP_OFFSET) + return 0; /* Minimum code value */ + + if (low) +- return (u32)(DIV_ROUND_UP(offset - temp, abs(slope))); ++ return (u32)(DIV_ROUND_UP(AVS_TMON_TEMP_OFFSET - temp, ++ AVS_TMON_TEMP_SLOPE)); + else +- return (u32)((offset - temp) / abs(slope)); ++ return (u32)((AVS_TMON_TEMP_OFFSET - temp) / ++ AVS_TMON_TEMP_SLOPE); + } + + static int brcmstb_get_temp(void *data, int *temp) +diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c +index 372dbbaaafb8..21d4d6e6409a 100644 +--- a/drivers/thermal/db8500_thermal.c ++++ b/drivers/thermal/db8500_thermal.c +@@ -152,8 +152,8 @@ static irqreturn_t prcmu_high_irq_handler(int irq, void *irq_data) + db8500_thermal_update_config(th, idx, THERMAL_TREND_RAISING, + next_low, next_high); + +- dev_info(&th->tz->device, +- "PRCMU set max %ld, min %ld\n", next_high, next_low); ++ dev_dbg(&th->tz->device, ++ "PRCMU set max %ld, min %ld\n", next_high, next_low); + } else if (idx == num_points - 1) + /* So we roof out 1 degree over the max point */ + th->interpolated_temp = db8500_thermal_points[idx] + 1; +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index e158159671fa..18e205eeb9af 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -1414,10 +1414,6 @@ static int vhost_net_release(struct inode *inode, struct file *f) + + static struct socket *get_raw_socket(int fd) + { +- struct { +- struct sockaddr_ll sa; +- char buf[MAX_ADDR_LEN]; +- } uaddr; + int r; + struct socket *sock = sockfd_lookup(fd, &r); + +@@ -1430,11 +1426,7 @@ static struct socket *get_raw_socket(int fd) + goto err; + } + +- r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa, 0); +- if (r < 0) +- goto err; +- +- if (uaddr.sa.sll_family != AF_PACKET) { ++ if (sock->sk->sk_family != AF_PACKET) { + r = -EPFNOSUPPORT; + goto err; + } +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index b069349b52f5..e1b1fcfc02af 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -389,7 +389,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + memset(&r, 0, sizeof(r)); + r.start = gas->address; +- r.end = r.start + gas->access_width - 1; ++ r.end = r.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1; + if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + r.flags = IORESOURCE_MEM; + } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index 11929d2bb594..cd09e63d682b 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -1418,6 +1418,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) + struct ceph_cap_flush *prealloc_cf; + ssize_t count, written = 0; + int err, want, got; ++ bool direct_lock = false; + loff_t pos; + loff_t limit = max(i_size_read(inode), fsc->max_file_size); + +@@ -1428,8 +1429,11 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) + if (!prealloc_cf) + return -ENOMEM; + ++ if ((iocb->ki_flags & (IOCB_DIRECT | IOCB_APPEND)) == IOCB_DIRECT) ++ direct_lock = true; ++ + retry_snap: +- if (iocb->ki_flags & IOCB_DIRECT) ++ if (direct_lock) + ceph_start_io_direct(inode); + else + ceph_start_io_write(inode); +@@ -1519,14 +1523,15 @@ retry_snap: + + /* we might need to revert back to that point */ + data = *from; +- if (iocb->ki_flags & IOCB_DIRECT) { ++ if (iocb->ki_flags & IOCB_DIRECT) + written = ceph_direct_read_write(iocb, &data, snapc, + &prealloc_cf); +- ceph_end_io_direct(inode); +- } else { ++ else + written = ceph_sync_write(iocb, &data, pos, snapc); ++ if (direct_lock) ++ ceph_end_io_direct(inode); ++ else + ceph_end_io_write(inode); +- } + if (written > 0) + iov_iter_advance(from, written); + ceph_put_snap_context(snapc); +@@ -1577,7 +1582,7 @@ retry_snap: + + goto out_unlocked; + out: +- if (iocb->ki_flags & IOCB_DIRECT) ++ if (direct_lock) + ceph_end_io_direct(inode); + else + ceph_end_io_write(inode); +diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c +index fb41e51dd574..25704beb9d4c 100644 +--- a/fs/cifs/cifsacl.c ++++ b/fs/cifs/cifsacl.c +@@ -601,7 +601,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, + ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) + *pmode |= (S_IXUGO & (*pbits_to_set)); + +- cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode); ++ cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode); + return; + } + +@@ -630,7 +630,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, + if (mode & S_IXUGO) + *pace_flags |= SET_FILE_EXEC_RIGHTS; + +- cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n", ++ cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n", + mode, *pace_flags); + return; + } +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 0aa3623ae0e1..641825cfa767 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -4151,7 +4151,7 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, + cifs_sb->mnt_gid = pvolume_info->linux_gid; + cifs_sb->mnt_file_mode = pvolume_info->file_mode; + cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; +- cifs_dbg(FYI, "file mode: 0x%hx dir mode: 0x%hx\n", ++ cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n", + cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); + + cifs_sb->actimeo = pvolume_info->actimeo; +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index ca76a9287456..b3f3675e1878 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -1649,7 +1649,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) + struct TCP_Server_Info *server; + char *full_path; + +- cifs_dbg(FYI, "In cifs_mkdir, mode = 0x%hx inode = 0x%p\n", ++ cifs_dbg(FYI, "In cifs_mkdir, mode = %04ho inode = 0x%p\n", + mode, inode); + + cifs_sb = CIFS_SB(inode->i_sb); +diff --git a/fs/dax.c b/fs/dax.c +index 1f1f0201cad1..0b0d8819cb1b 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -1207,6 +1207,9 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, + lockdep_assert_held(&inode->i_rwsem); + } + ++ if (iocb->ki_flags & IOCB_NOWAIT) ++ flags |= IOMAP_NOWAIT; ++ + while (iov_iter_count(iter)) { + ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops, + iter, dax_iomap_actor); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 12806be10a18..71e2b80ff4aa 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2346,7 +2346,7 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct flex_groups **old_groups, **new_groups; +- int size, i; ++ int size, i, j; + + if (!sbi->s_log_groups_per_flex) + return 0; +@@ -2367,8 +2367,8 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup) + sizeof(struct flex_groups)), + GFP_KERNEL); + if (!new_groups[i]) { +- for (i--; i >= sbi->s_flex_groups_allocated; i--) +- kvfree(new_groups[i]); ++ for (j = sbi->s_flex_groups_allocated; j < i; j++) ++ kvfree(new_groups[j]); + kvfree(new_groups); + ext4_msg(sb, KERN_ERR, + "not enough memory for %d flex groups", size); +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index fc40a72f7827..930706e171fd 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -3132,7 +3132,8 @@ int f2fs_migrate_page(struct address_space *mapping, + + #ifdef CONFIG_SWAP + /* Copied from generic_swapfile_activate() to check any holes */ +-static int check_swap_activate(struct file *swap_file, unsigned int max) ++static int check_swap_activate(struct swap_info_struct *sis, ++ struct file *swap_file, sector_t *span) + { + struct address_space *mapping = swap_file->f_mapping; + struct inode *inode = mapping->host; +@@ -3143,6 +3144,8 @@ static int check_swap_activate(struct file *swap_file, unsigned int max) + sector_t last_block; + sector_t lowest_block = -1; + sector_t highest_block = 0; ++ int nr_extents = 0; ++ int ret; + + blkbits = inode->i_blkbits; + blocks_per_page = PAGE_SIZE >> blkbits; +@@ -3154,7 +3157,8 @@ static int check_swap_activate(struct file *swap_file, unsigned int max) + probe_block = 0; + page_no = 0; + last_block = i_size_read(inode) >> blkbits; +- while ((probe_block + blocks_per_page) <= last_block && page_no < max) { ++ while ((probe_block + blocks_per_page) <= last_block && ++ page_no < sis->max) { + unsigned block_in_page; + sector_t first_block; + +@@ -3194,13 +3198,27 @@ static int check_swap_activate(struct file *swap_file, unsigned int max) + highest_block = first_block; + } + ++ /* ++ * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks ++ */ ++ ret = add_swap_extent(sis, page_no, 1, first_block); ++ if (ret < 0) ++ goto out; ++ nr_extents += ret; + page_no++; + probe_block += blocks_per_page; + reprobe: + continue; + } +- return 0; +- ++ ret = nr_extents; ++ *span = 1 + highest_block - lowest_block; ++ if (page_no == 0) ++ page_no = 1; /* force Empty message */ ++ sis->max = page_no; ++ sis->pages = page_no - 1; ++ sis->highest_bit = page_no - 1; ++out: ++ return ret; + bad_bmap: + pr_err("swapon: swapfile has holes\n"); + return -EINVAL; +@@ -3222,14 +3240,14 @@ static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, + if (ret) + return ret; + +- ret = check_swap_activate(file, sis->max); +- if (ret) ++ ret = check_swap_activate(sis, file, span); ++ if (ret < 0) + return ret; + + set_inode_flag(inode, FI_PIN_FILE); + f2fs_precache_extents(inode); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); +- return 0; ++ return ret; + } + + static void f2fs_swap_deactivate(struct file *file) +diff --git a/fs/io-wq.c b/fs/io-wq.c +index 0dc4bb6de656..25ffb6685bae 100644 +--- a/fs/io-wq.c ++++ b/fs/io-wq.c +@@ -666,11 +666,16 @@ static int io_wq_manager(void *data) + /* create fixed workers */ + refcount_set(&wq->refs, workers_to_create); + for_each_node(node) { ++ if (!node_online(node)) ++ continue; + if (!create_io_worker(wq, wq->wqes[node], IO_WQ_ACCT_BOUND)) + goto err; + workers_to_create--; + } + ++ while (workers_to_create--) ++ refcount_dec(&wq->refs); ++ + complete(&wq->done); + + while (!kthread_should_stop()) { +@@ -678,6 +683,9 @@ static int io_wq_manager(void *data) + struct io_wqe *wqe = wq->wqes[node]; + bool fork_worker[2] = { false, false }; + ++ if (!node_online(node)) ++ continue; ++ + spin_lock_irq(&wqe->lock); + if (io_wqe_need_worker(wqe, IO_WQ_ACCT_BOUND)) + fork_worker[IO_WQ_ACCT_BOUND] = true; +@@ -793,7 +801,9 @@ static bool io_wq_for_each_worker(struct io_wqe *wqe, + + list_for_each_entry_rcu(worker, &wqe->all_list, all_list) { + if (io_worker_get(worker)) { +- ret = func(worker, data); ++ /* no task if node is/was offline */ ++ if (worker->task) ++ ret = func(worker, data); + io_worker_release(worker); + if (ret) + break; +@@ -1006,6 +1016,8 @@ void io_wq_flush(struct io_wq *wq) + for_each_node(node) { + struct io_wqe *wqe = wq->wqes[node]; + ++ if (!node_online(node)) ++ continue; + init_completion(&data.done); + INIT_IO_WORK(&data.work, io_wq_flush_func); + data.work.flags |= IO_WQ_WORK_INTERNAL; +@@ -1038,12 +1050,15 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) + + for_each_node(node) { + struct io_wqe *wqe; ++ int alloc_node = node; + +- wqe = kzalloc_node(sizeof(struct io_wqe), GFP_KERNEL, node); ++ if (!node_online(alloc_node)) ++ alloc_node = NUMA_NO_NODE; ++ wqe = kzalloc_node(sizeof(struct io_wqe), GFP_KERNEL, alloc_node); + if (!wqe) + goto err; + wq->wqes[node] = wqe; +- wqe->node = node; ++ wqe->node = alloc_node; + wqe->acct[IO_WQ_ACCT_BOUND].max_workers = bounded; + atomic_set(&wqe->acct[IO_WQ_ACCT_BOUND].nr_running, 0); + if (wq->user) { +@@ -1051,7 +1066,6 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) + task_rlimit(current, RLIMIT_NPROC); + } + atomic_set(&wqe->acct[IO_WQ_ACCT_UNBOUND].nr_running, 0); +- wqe->node = node; + wqe->wq = wq; + spin_lock_init(&wqe->lock); + INIT_WQ_LIST(&wqe->work_list); +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 678c62782ba3..60a483208998 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2166,6 +2166,11 @@ static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) + sr->msg_flags = READ_ONCE(sqe->msg_flags); + sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr)); + ++#ifdef CONFIG_COMPAT ++ if (req->ctx->compat) ++ sr->msg_flags |= MSG_CMSG_COMPAT; ++#endif ++ + if (!io) + return 0; + +@@ -2258,6 +2263,11 @@ static int io_recvmsg_prep(struct io_kiocb *req, + sr->msg_flags = READ_ONCE(sqe->msg_flags); + sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr)); + ++#ifdef CONFIG_COMPAT ++ if (req->ctx->compat) ++ sr->msg_flags |= MSG_CMSG_COMPAT; ++#endif ++ + if (!io) + return 0; + +@@ -4970,7 +4980,7 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait) + if (READ_ONCE(ctx->rings->sq.tail) - ctx->cached_sq_head != + ctx->rings->sq_ring_entries) + mask |= EPOLLOUT | EPOLLWRNORM; +- if (READ_ONCE(ctx->rings->cq.head) != ctx->cached_cq_tail) ++ if (io_cqring_events(ctx, false)) + mask |= EPOLLIN | EPOLLRDNORM; + + return mask; +diff --git a/fs/namei.c b/fs/namei.c +index 6cc88b6d68c8..70eb4bfeaebc 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1367,7 +1367,7 @@ static int follow_dotdot_rcu(struct nameidata *nd) + nd->path.dentry = parent; + nd->seq = seq; + if (unlikely(!path_connected(&nd->path))) +- return -ENOENT; ++ return -ECHILD; + break; + } else { + struct mount *mnt = real_mount(nd->path.mnt); +diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c +index 620de905cba9..3f892035c141 100644 +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -86,7 +86,6 @@ nfs4_file_open(struct inode *inode, struct file *filp) + if (inode != d_inode(dentry)) + goto out_drop; + +- nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); + nfs_file_set_open_context(filp, ctx); + nfs_fscache_open_file(inode, filp); + err = 0; +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 6ddb4f517d37..13c2de527718 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -2962,10 +2962,13 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, + struct dentry *dentry; + struct nfs4_state *state; + fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx); ++ struct inode *dir = d_inode(opendata->dir); ++ unsigned long dir_verifier; + unsigned int seq; + int ret; + + seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); ++ dir_verifier = nfs_save_change_attribute(dir); + + ret = _nfs4_proc_open(opendata, ctx); + if (ret != 0) +@@ -2993,8 +2996,19 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, + dput(ctx->dentry); + ctx->dentry = dentry = alias; + } +- nfs_set_verifier(dentry, +- nfs_save_change_attribute(d_inode(opendata->dir))); ++ } ++ ++ switch(opendata->o_arg.claim) { ++ default: ++ break; ++ case NFS4_OPEN_CLAIM_NULL: ++ case NFS4_OPEN_CLAIM_DELEGATE_CUR: ++ case NFS4_OPEN_CLAIM_DELEGATE_PREV: ++ if (!opendata->rpc_done) ++ break; ++ if (opendata->o_res.delegation_type != 0) ++ dir_verifier = nfs_save_change_attribute(dir); ++ nfs_set_verifier(dentry, dir_verifier); + } + + /* Parse layoutget results before we check for access */ +diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c +index 54d6db61106f..edf43ddd7dce 100644 +--- a/fs/ubifs/orphan.c ++++ b/fs/ubifs/orphan.c +@@ -129,7 +129,7 @@ static void __orphan_drop(struct ubifs_info *c, struct ubifs_orphan *o) + static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph) + { + if (orph->del) { +- dbg_gen("deleted twice ino %lu", orph->inum); ++ dbg_gen("deleted twice ino %lu", (unsigned long)orph->inum); + return; + } + +@@ -137,7 +137,7 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph) + orph->del = 1; + orph->dnext = c->orph_dnext; + c->orph_dnext = orph; +- dbg_gen("delete later ino %lu", orph->inum); ++ dbg_gen("delete later ino %lu", (unsigned long)orph->inum); + return; + } + +diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h +index 94badfa1743e..91c2cb14276e 100644 +--- a/fs/xfs/libxfs/xfs_attr.h ++++ b/fs/xfs/libxfs/xfs_attr.h +@@ -26,7 +26,7 @@ struct xfs_attr_list_context; + *========================================================================*/ + + +-#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ ++#define ATTR_DONTFOLLOW 0x0001 /* -- ignored, from IRIX -- */ + #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ + #define ATTR_TRUST 0x0004 /* -- unused, from IRIX -- */ + #define ATTR_SECURE 0x0008 /* use attrs in security namespace */ +@@ -37,7 +37,10 @@ struct xfs_attr_list_context; + #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ + + #define ATTR_INCOMPLETE 0x4000 /* [kernel] return INCOMPLETE attr keys */ +-#define ATTR_ALLOC 0x8000 /* allocate xattr buffer on demand */ ++#define ATTR_ALLOC 0x8000 /* [kernel] allocate xattr buffer on demand */ ++ ++#define ATTR_KERNEL_FLAGS \ ++ (ATTR_KERNOTIME | ATTR_KERNOVAL | ATTR_INCOMPLETE | ATTR_ALLOC) + + #define XFS_ATTR_FLAGS \ + { ATTR_DONTFOLLOW, "DONTFOLLOW" }, \ +diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c +index 7b35d62ede9f..edfbdb8f85e2 100644 +--- a/fs/xfs/xfs_ioctl.c ++++ b/fs/xfs/xfs_ioctl.c +@@ -462,6 +462,8 @@ xfs_attrmulti_by_handle( + + error = 0; + for (i = 0; i < am_hreq.opcount; i++) { ++ ops[i].am_flags &= ~ATTR_KERNEL_FLAGS; ++ + ops[i].am_error = strncpy_from_user((char *)attr_name, + ops[i].am_attrname, MAXNAMELEN); + if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) +diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c +index c4c4f09113d3..bd9d9ebf85d8 100644 +--- a/fs/xfs/xfs_ioctl32.c ++++ b/fs/xfs/xfs_ioctl32.c +@@ -450,6 +450,8 @@ xfs_compat_attrmulti_by_handle( + + error = 0; + for (i = 0; i < am_hreq.opcount; i++) { ++ ops[i].am_flags &= ~ATTR_KERNEL_FLAGS; ++ + ops[i].am_error = strncpy_from_user((char *)attr_name, + compat_ptr(ops[i].am_attrname), + MAXNAMELEN); +diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h +index 2f3f28c7cea3..9373662cdb44 100644 +--- a/include/acpi/actypes.h ++++ b/include/acpi/actypes.h +@@ -532,11 +532,12 @@ typedef u64 acpi_integer; + strnlen (a, ACPI_NAMESEG_SIZE) == ACPI_NAMESEG_SIZE) + + /* +- * Algorithm to obtain access bit width. ++ * Algorithm to obtain access bit or byte width. + * Can be used with access_width of struct acpi_generic_address and access_size of + * struct acpi_resource_generic_register. + */ + #define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + 2)) ++#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) - 1)) + + /******************************************************************************* + * +diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h +index ce4103208619..cec543d9e87b 100644 +--- a/include/asm-generic/vdso/vsyscall.h ++++ b/include/asm-generic/vdso/vsyscall.h +@@ -12,9 +12,9 @@ static __always_inline struct vdso_data *__arch_get_k_vdso_data(void) + #endif /* __arch_get_k_vdso_data */ + + #ifndef __arch_update_vdso_data +-static __always_inline int __arch_update_vdso_data(void) ++static __always_inline bool __arch_update_vdso_data(void) + { +- return 0; ++ return true; + } + #endif /* __arch_update_vdso_data */ + +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 4c636c42ad68..1cb5afed5515 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -524,7 +524,7 @@ struct request_queue { + unsigned int sg_reserved_size; + int node; + #ifdef CONFIG_BLK_DEV_IO_TRACE +- struct blk_trace *blk_trace; ++ struct blk_trace __rcu *blk_trace; + struct mutex blk_trace_mutex; + #endif + /* +diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h +index 7bb2d8de9f30..3b6ff5902edc 100644 +--- a/include/linux/blktrace_api.h ++++ b/include/linux/blktrace_api.h +@@ -51,9 +51,13 @@ void __trace_note_message(struct blk_trace *, struct blkcg *blkcg, const char *f + **/ + #define blk_add_cgroup_trace_msg(q, cg, fmt, ...) \ + do { \ +- struct blk_trace *bt = (q)->blk_trace; \ ++ struct blk_trace *bt; \ ++ \ ++ rcu_read_lock(); \ ++ bt = rcu_dereference((q)->blk_trace); \ + if (unlikely(bt)) \ + __trace_note_message(bt, cg, fmt, ##__VA_ARGS__);\ ++ rcu_read_unlock(); \ + } while (0) + #define blk_add_trace_msg(q, fmt, ...) \ + blk_add_cgroup_trace_msg(q, NULL, fmt, ##__VA_ARGS__) +@@ -61,10 +65,14 @@ void __trace_note_message(struct blk_trace *, struct blkcg *blkcg, const char *f + + static inline bool blk_trace_note_message_enabled(struct request_queue *q) + { +- struct blk_trace *bt = q->blk_trace; +- if (likely(!bt)) +- return false; +- return bt->act_mask & BLK_TC_NOTIFY; ++ struct blk_trace *bt; ++ bool ret; ++ ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ ret = bt && (bt->act_mask & BLK_TC_NOTIFY); ++ rcu_read_unlock(); ++ return ret; + } + + extern void blk_add_driver_data(struct request_queue *q, struct request *rq, +diff --git a/include/linux/hid.h b/include/linux/hid.h +index cd41f209043f..875f71132b14 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -492,7 +492,7 @@ struct hid_report_enum { + }; + + #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ +-#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ ++#define HID_MAX_BUFFER_SIZE 8192 /* 8kb */ + #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ + #define HID_OUTPUT_FIFO_SIZE 64 + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index cac56fb59af8..1dabd86b232a 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -72,6 +72,8 @@ void netdev_set_default_ethtool_ops(struct net_device *dev, + #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ + #define NET_RX_DROP 1 /* packet dropped */ + ++#define MAX_NEST_DEV 8 ++ + /* + * Transmit return codes: transmit return codes originate from three different + * namespaces: +@@ -4323,11 +4325,8 @@ void *netdev_lower_get_next(struct net_device *dev, + ldev; \ + ldev = netdev_lower_get_next(dev, &(iter))) + +-struct net_device *netdev_all_lower_get_next(struct net_device *dev, ++struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, + struct list_head **iter); +-struct net_device *netdev_all_lower_get_next_rcu(struct net_device *dev, +- struct list_head **iter); +- + int netdev_walk_all_lower_dev(struct net_device *dev, + int (*fn)(struct net_device *lower_dev, + void *data), +diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h +index 908d38dbcb91..5448c8b443db 100644 +--- a/include/linux/netfilter/ipset/ip_set.h ++++ b/include/linux/netfilter/ipset/ip_set.h +@@ -121,6 +121,7 @@ struct ip_set_ext { + u32 timeout; + u8 packets_op; + u8 bytes_op; ++ bool target; + }; + + struct ip_set; +@@ -187,6 +188,14 @@ struct ip_set_type_variant { + /* Return true if "b" set is the same as "a" + * according to the create set parameters */ + bool (*same_set)(const struct ip_set *a, const struct ip_set *b); ++ /* Region-locking is used */ ++ bool region_lock; ++}; ++ ++struct ip_set_region { ++ spinlock_t lock; /* Region lock */ ++ size_t ext_size; /* Size of the dynamic extensions */ ++ u32 elements; /* Number of elements vs timeout */ + }; + + /* The core set type structure */ +@@ -501,7 +510,7 @@ ip_set_init_skbinfo(struct ip_set_skbinfo *skbinfo, + } + + #define IP_SET_INIT_KEXT(skb, opt, set) \ +- { .bytes = (skb)->len, .packets = 1, \ ++ { .bytes = (skb)->len, .packets = 1, .target = true,\ + .timeout = ip_set_adt_opt_timeout(opt, set) } + + #define IP_SET_INIT_UEXT(set) \ +diff --git a/include/linux/sched/nohz.h b/include/linux/sched/nohz.h +index 1abe91ff6e4a..6d67e9a5af6b 100644 +--- a/include/linux/sched/nohz.h ++++ b/include/linux/sched/nohz.h +@@ -15,9 +15,11 @@ static inline void nohz_balance_enter_idle(int cpu) { } + + #ifdef CONFIG_NO_HZ_COMMON + void calc_load_nohz_start(void); ++void calc_load_nohz_remote(struct rq *rq); + void calc_load_nohz_stop(void); + #else + static inline void calc_load_nohz_start(void) { } ++static inline void calc_load_nohz_remote(struct rq *rq) { } + static inline void calc_load_nohz_stop(void) { } + #endif /* CONFIG_NO_HZ_COMMON */ + +diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h +index d93017a7ce5c..e03827f702f3 100644 +--- a/include/net/flow_dissector.h ++++ b/include/net/flow_dissector.h +@@ -5,6 +5,7 @@ + #include <linux/types.h> + #include <linux/in6.h> + #include <linux/siphash.h> ++#include <linux/string.h> + #include <uapi/linux/if_ether.h> + + struct sk_buff; +@@ -349,4 +350,12 @@ struct bpf_flow_dissector { + void *data_end; + }; + ++static inline void ++flow_dissector_init_keys(struct flow_dissector_key_control *key_control, ++ struct flow_dissector_key_basic *key_basic) ++{ ++ memset(key_control, 0, sizeof(*key_control)); ++ memset(key_basic, 0, sizeof(*key_basic)); ++} ++ + #endif +diff --git a/include/uapi/linux/usb/charger.h b/include/uapi/linux/usb/charger.h +index 5f72af35b3ed..ad22079125bf 100644 +--- a/include/uapi/linux/usb/charger.h ++++ b/include/uapi/linux/usb/charger.h +@@ -14,18 +14,18 @@ + * ACA (Accessory Charger Adapters) + */ + enum usb_charger_type { +- UNKNOWN_TYPE, +- SDP_TYPE, +- DCP_TYPE, +- CDP_TYPE, +- ACA_TYPE, ++ UNKNOWN_TYPE = 0, ++ SDP_TYPE = 1, ++ DCP_TYPE = 2, ++ CDP_TYPE = 3, ++ ACA_TYPE = 4, + }; + + /* USB charger state */ + enum usb_charger_state { +- USB_CHARGER_DEFAULT, +- USB_CHARGER_PRESENT, +- USB_CHARGER_ABSENT, ++ USB_CHARGER_DEFAULT = 0, ++ USB_CHARGER_PRESENT = 1, ++ USB_CHARGER_ABSENT = 2, + }; + + #endif /* _UAPI__LINUX_USB_CHARGER_H */ +diff --git a/kernel/audit.c b/kernel/audit.c +index 8e09f0f55b4b..f971cd636426 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -1100,13 +1100,11 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature + audit_log_end(ab); + } + +-static int audit_set_feature(struct sk_buff *skb) ++static int audit_set_feature(struct audit_features *uaf) + { +- struct audit_features *uaf; + int i; + + BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names)); +- uaf = nlmsg_data(nlmsg_hdr(skb)); + + /* if there is ever a version 2 we should handle that here */ + +@@ -1174,6 +1172,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + { + u32 seq; + void *data; ++ int data_len; + int err; + struct audit_buffer *ab; + u16 msg_type = nlh->nlmsg_type; +@@ -1187,6 +1186,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + seq = nlh->nlmsg_seq; + data = nlmsg_data(nlh); ++ data_len = nlmsg_len(nlh); + + switch (msg_type) { + case AUDIT_GET: { +@@ -1210,7 +1210,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + struct audit_status s; + memset(&s, 0, sizeof(s)); + /* guard against past and future API changes */ +- memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); ++ memcpy(&s, data, min_t(size_t, sizeof(s), data_len)); + if (s.mask & AUDIT_STATUS_ENABLED) { + err = audit_set_enabled(s.enabled); + if (err < 0) +@@ -1314,7 +1314,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + return err; + break; + case AUDIT_SET_FEATURE: +- err = audit_set_feature(skb); ++ if (data_len < sizeof(struct audit_features)) ++ return -EINVAL; ++ err = audit_set_feature(data); + if (err) + return err; + break; +@@ -1326,6 +1328,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + err = audit_filter(msg_type, AUDIT_FILTER_USER); + if (err == 1) { /* match or error */ ++ char *str = data; ++ + err = 0; + if (msg_type == AUDIT_USER_TTY) { + err = tty_audit_push(); +@@ -1333,26 +1337,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + break; + } + audit_log_user_recv_msg(&ab, msg_type); +- if (msg_type != AUDIT_USER_TTY) ++ if (msg_type != AUDIT_USER_TTY) { ++ /* ensure NULL termination */ ++ str[data_len - 1] = '\0'; + audit_log_format(ab, " msg='%.*s'", + AUDIT_MESSAGE_TEXT_MAX, +- (char *)data); +- else { +- int size; +- ++ str); ++ } else { + audit_log_format(ab, " data="); +- size = nlmsg_len(nlh); +- if (size > 0 && +- ((unsigned char *)data)[size - 1] == '\0') +- size--; +- audit_log_n_untrustedstring(ab, data, size); ++ if (data_len > 0 && str[data_len - 1] == '\0') ++ data_len--; ++ audit_log_n_untrustedstring(ab, str, data_len); + } + audit_log_end(ab); + } + break; + case AUDIT_ADD_RULE: + case AUDIT_DEL_RULE: +- if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) ++ if (data_len < sizeof(struct audit_rule_data)) + return -EINVAL; + if (audit_enabled == AUDIT_LOCKED) { + audit_log_common_recv_msg(audit_context(), &ab, +@@ -1364,7 +1366,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + audit_log_end(ab); + return -EPERM; + } +- err = audit_rule_change(msg_type, seq, data, nlmsg_len(nlh)); ++ err = audit_rule_change(msg_type, seq, data, data_len); + break; + case AUDIT_LIST_RULES: + err = audit_list_rules_send(skb, seq); +@@ -1379,7 +1381,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + case AUDIT_MAKE_EQUIV: { + void *bufp = data; + u32 sizes[2]; +- size_t msglen = nlmsg_len(nlh); ++ size_t msglen = data_len; + char *old, *new; + + err = -EINVAL; +@@ -1455,7 +1457,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + memset(&s, 0, sizeof(s)); + /* guard against past and future API changes */ +- memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); ++ memcpy(&s, data, min_t(size_t, sizeof(s), data_len)); + /* check if new data is valid */ + if ((s.enabled != 0 && s.enabled != 1) || + (s.log_passwd != 0 && s.log_passwd != 1)) +diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c +index b0126e9c0743..026e34da4ace 100644 +--- a/kernel/auditfilter.c ++++ b/kernel/auditfilter.c +@@ -456,6 +456,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + bufp = data->buf; + for (i = 0; i < data->field_count; i++) { + struct audit_field *f = &entry->rule.fields[i]; ++ u32 f_val; + + err = -EINVAL; + +@@ -464,12 +465,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + goto exit_free; + + f->type = data->fields[i]; +- f->val = data->values[i]; ++ f_val = data->values[i]; + + /* Support legacy tests for a valid loginuid */ +- if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) { ++ if ((f->type == AUDIT_LOGINUID) && (f_val == AUDIT_UID_UNSET)) { + f->type = AUDIT_LOGINUID_SET; +- f->val = 0; ++ f_val = 0; + entry->rule.pflags |= AUDIT_LOGINUID_LEGACY; + } + +@@ -485,7 +486,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + case AUDIT_SUID: + case AUDIT_FSUID: + case AUDIT_OBJ_UID: +- f->uid = make_kuid(current_user_ns(), f->val); ++ f->uid = make_kuid(current_user_ns(), f_val); + if (!uid_valid(f->uid)) + goto exit_free; + break; +@@ -494,11 +495,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + case AUDIT_SGID: + case AUDIT_FSGID: + case AUDIT_OBJ_GID: +- f->gid = make_kgid(current_user_ns(), f->val); ++ f->gid = make_kgid(current_user_ns(), f_val); + if (!gid_valid(f->gid)) + goto exit_free; + break; + case AUDIT_ARCH: ++ f->val = f_val; + entry->rule.arch_f = f; + break; + case AUDIT_SUBJ_USER: +@@ -511,11 +513,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + case AUDIT_OBJ_TYPE: + case AUDIT_OBJ_LEV_LOW: + case AUDIT_OBJ_LEV_HIGH: +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; +- ++ } ++ entry->rule.buflen += f_val; ++ f->lsm_str = str; + err = security_audit_rule_init(f->type, f->op, str, + (void **)&f->lsm_rule); + /* Keep currently invalid fields around in case they +@@ -524,68 +528,71 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + pr_warn("audit rule for LSM \'%s\' is invalid\n", + str); + err = 0; +- } +- if (err) { +- kfree(str); ++ } else if (err) + goto exit_free; +- } else +- f->lsm_str = str; + break; + case AUDIT_WATCH: +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; +- +- err = audit_to_watch(&entry->rule, str, f->val, f->op); ++ } ++ err = audit_to_watch(&entry->rule, str, f_val, f->op); + if (err) { + kfree(str); + goto exit_free; + } ++ entry->rule.buflen += f_val; + break; + case AUDIT_DIR: +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; +- ++ } + err = audit_make_tree(&entry->rule, str, f->op); + kfree(str); + if (err) + goto exit_free; ++ entry->rule.buflen += f_val; + break; + case AUDIT_INODE: ++ f->val = f_val; + err = audit_to_inode(&entry->rule, f); + if (err) + goto exit_free; + break; + case AUDIT_FILTERKEY: +- if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN) ++ if (entry->rule.filterkey || f_val > AUDIT_MAX_KEY_LEN) + goto exit_free; +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; ++ } ++ entry->rule.buflen += f_val; + entry->rule.filterkey = str; + break; + case AUDIT_EXE: +- if (entry->rule.exe || f->val > PATH_MAX) ++ if (entry->rule.exe || f_val > PATH_MAX) + goto exit_free; +- str = audit_unpack_string(&bufp, &remain, f->val); ++ str = audit_unpack_string(&bufp, &remain, f_val); + if (IS_ERR(str)) { + err = PTR_ERR(str); + goto exit_free; + } +- entry->rule.buflen += f->val; +- +- audit_mark = audit_alloc_mark(&entry->rule, str, f->val); ++ audit_mark = audit_alloc_mark(&entry->rule, str, f_val); + if (IS_ERR(audit_mark)) { + kfree(str); + err = PTR_ERR(audit_mark); + goto exit_free; + } ++ entry->rule.buflen += f_val; + entry->rule.exe = audit_mark; + break; ++ default: ++ f->val = f_val; ++ break; + } + } + +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index fd81882f0521..2625c241ac00 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -510,6 +510,8 @@ static void do_unoptimize_kprobes(void) + arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); + /* Loop free_list for disarming */ + list_for_each_entry_safe(op, tmp, &freeing_list, list) { ++ /* Switching from detour code to origin */ ++ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + /* Disarm probes if marked disabled */ + if (kprobe_disabled(&op->kp)) + arch_disarm_kprobe(&op->kp); +@@ -665,6 +667,7 @@ static void force_unoptimize_kprobe(struct optimized_kprobe *op) + { + lockdep_assert_cpus_held(); + arch_unoptimize_kprobe(op); ++ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + if (kprobe_disabled(&op->kp)) + arch_disarm_kprobe(&op->kp); + } +@@ -681,7 +684,6 @@ static void unoptimize_kprobe(struct kprobe *p, bool force) + if (!kprobe_optimized(p)) + return; + +- op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + if (!list_empty(&op->list)) { + if (optprobe_queued_unopt(op)) { + /* Queued in unoptimizing queue */ +diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c +index dadb7b7fba37..9bb6d2497b04 100644 +--- a/kernel/locking/lockdep_proc.c ++++ b/kernel/locking/lockdep_proc.c +@@ -286,9 +286,9 @@ static int lockdep_stats_show(struct seq_file *m, void *v) + seq_printf(m, " stack-trace entries: %11lu [max: %lu]\n", + nr_stack_trace_entries, MAX_STACK_TRACE_ENTRIES); + #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) +- seq_printf(m, " number of stack traces: %llu\n", ++ seq_printf(m, " number of stack traces: %11llu\n", + lockdep_stack_trace_count()); +- seq_printf(m, " number of stack hash chains: %llu\n", ++ seq_printf(m, " number of stack hash chains: %11llu\n", + lockdep_stack_hash_count()); + #endif + seq_printf(m, " combined max dependencies: %11u\n", +diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h +index f504ac831779..df90d4d7ad2e 100644 +--- a/kernel/rcu/tree_exp.h ++++ b/kernel/rcu/tree_exp.h +@@ -540,14 +540,13 @@ static void rcu_exp_wait_wake(unsigned long s) + struct rcu_node *rnp; + + synchronize_sched_expedited_wait(); +- rcu_exp_gp_seq_end(); +- trace_rcu_exp_grace_period(rcu_state.name, s, TPS("end")); + +- /* +- * Switch over to wakeup mode, allowing the next GP, but -only- the +- * next GP, to proceed. +- */ ++ // Switch over to wakeup mode, allowing the next GP to proceed. ++ // End the previous grace period only after acquiring the mutex ++ // to ensure that only one GP runs concurrently with wakeups. + mutex_lock(&rcu_state.exp_wake_mutex); ++ rcu_exp_gp_seq_end(); ++ trace_rcu_exp_grace_period(rcu_state.name, s, TPS("end")); + + rcu_for_each_node_breadth_first(rnp) { + if (ULONG_CMP_LT(READ_ONCE(rnp->exp_seq_rq), s)) { +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index b2564d62a0f7..9e7768dbd92d 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -3669,28 +3669,32 @@ static void sched_tick_remote(struct work_struct *work) + * statistics and checks timeslices in a time-independent way, regardless + * of when exactly it is running. + */ +- if (idle_cpu(cpu) || !tick_nohz_tick_stopped_cpu(cpu)) ++ if (!tick_nohz_tick_stopped_cpu(cpu)) + goto out_requeue; + + rq_lock_irq(rq, &rf); + curr = rq->curr; +- if (is_idle_task(curr) || cpu_is_offline(cpu)) ++ if (cpu_is_offline(cpu)) + goto out_unlock; + ++ curr = rq->curr; + update_rq_clock(rq); +- delta = rq_clock_task(rq) - curr->se.exec_start; + +- /* +- * Make sure the next tick runs within a reasonable +- * amount of time. +- */ +- WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3); ++ if (!is_idle_task(curr)) { ++ /* ++ * Make sure the next tick runs within a reasonable ++ * amount of time. ++ */ ++ delta = rq_clock_task(rq) - curr->se.exec_start; ++ WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3); ++ } + curr->sched_class->task_tick(rq, curr, 0); + ++ calc_load_nohz_remote(rq); + out_unlock: + rq_unlock_irq(rq, &rf); +- + out_requeue: ++ + /* + * Run the remote tick once per second (1Hz). This arbitrary + * frequency is large enough to avoid overload but short enough +@@ -7064,8 +7068,15 @@ void sched_move_task(struct task_struct *tsk) + + if (queued) + enqueue_task(rq, tsk, queue_flags); +- if (running) ++ if (running) { + set_next_task(rq, tsk); ++ /* ++ * After changing group, the running task may have joined a ++ * throttled one but it's still the running task. Trigger a ++ * resched to make sure that task can still run. ++ */ ++ resched_curr(rq); ++ } + + task_rq_unlock(rq, tsk, &rf); + } +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index ba749f579714..b0ee5eedeccd 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -5828,6 +5828,7 @@ static inline int select_idle_smt(struct task_struct *p, int target) + */ + static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target) + { ++ struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask); + struct sched_domain *this_sd; + u64 avg_cost, avg_idle; + u64 time, cost; +@@ -5859,11 +5860,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t + + time = cpu_clock(this); + +- for_each_cpu_wrap(cpu, sched_domain_span(sd), target) { ++ cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr); ++ ++ for_each_cpu_wrap(cpu, cpus, target) { + if (!--nr) + return si_cpu; +- if (!cpumask_test_cpu(cpu, p->cpus_ptr)) +- continue; + if (available_idle_cpu(cpu)) + break; + if (si_cpu == -1 && sched_idle_cpu(cpu)) +diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c +index 28a516575c18..de22da666ac7 100644 +--- a/kernel/sched/loadavg.c ++++ b/kernel/sched/loadavg.c +@@ -231,16 +231,11 @@ static inline int calc_load_read_idx(void) + return calc_load_idx & 1; + } + +-void calc_load_nohz_start(void) ++static void calc_load_nohz_fold(struct rq *rq) + { +- struct rq *this_rq = this_rq(); + long delta; + +- /* +- * We're going into NO_HZ mode, if there's any pending delta, fold it +- * into the pending NO_HZ delta. +- */ +- delta = calc_load_fold_active(this_rq, 0); ++ delta = calc_load_fold_active(rq, 0); + if (delta) { + int idx = calc_load_write_idx(); + +@@ -248,6 +243,24 @@ void calc_load_nohz_start(void) + } + } + ++void calc_load_nohz_start(void) ++{ ++ /* ++ * We're going into NO_HZ mode, if there's any pending delta, fold it ++ * into the pending NO_HZ delta. ++ */ ++ calc_load_nohz_fold(this_rq()); ++} ++ ++/* ++ * Keep track of the load for NOHZ_FULL, must be called between ++ * calc_load_nohz_{start,stop}(). ++ */ ++void calc_load_nohz_remote(struct rq *rq) ++{ ++ calc_load_nohz_fold(rq); ++} ++ + void calc_load_nohz_stop(void) + { + struct rq *this_rq = this_rq(); +@@ -268,7 +281,7 @@ void calc_load_nohz_stop(void) + this_rq->calc_load_update += LOAD_FREQ; + } + +-static long calc_load_nohz_fold(void) ++static long calc_load_nohz_read(void) + { + int idx = calc_load_read_idx(); + long delta = 0; +@@ -323,7 +336,7 @@ static void calc_global_nohz(void) + } + #else /* !CONFIG_NO_HZ_COMMON */ + +-static inline long calc_load_nohz_fold(void) { return 0; } ++static inline long calc_load_nohz_read(void) { return 0; } + static inline void calc_global_nohz(void) { } + + #endif /* CONFIG_NO_HZ_COMMON */ +@@ -346,7 +359,7 @@ void calc_global_load(unsigned long ticks) + /* + * Fold the 'old' NO_HZ-delta to include all NO_HZ CPUs. + */ +- delta = calc_load_nohz_fold(); ++ delta = calc_load_nohz_read(); + if (delta) + atomic_long_add(delta, &calc_load_tasks); + +diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c +index 5ee0f7709410..9577c89179cd 100644 +--- a/kernel/time/vsyscall.c ++++ b/kernel/time/vsyscall.c +@@ -28,11 +28,6 @@ static inline void update_vdso_data(struct vdso_data *vdata, + vdata[CS_RAW].mult = tk->tkr_raw.mult; + vdata[CS_RAW].shift = tk->tkr_raw.shift; + +- /* CLOCK_REALTIME */ +- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME]; +- vdso_ts->sec = tk->xtime_sec; +- vdso_ts->nsec = tk->tkr_mono.xtime_nsec; +- + /* CLOCK_MONOTONIC */ + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC]; + vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; +@@ -70,12 +65,6 @@ static inline void update_vdso_data(struct vdso_data *vdata, + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI]; + vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset; + vdso_ts->nsec = tk->tkr_mono.xtime_nsec; +- +- /* +- * Read without the seqlock held by clock_getres(). +- * Note: No need to have a second copy. +- */ +- WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution); + } + + void update_vsyscall(struct timekeeper *tk) +@@ -84,20 +73,17 @@ void update_vsyscall(struct timekeeper *tk) + struct vdso_timestamp *vdso_ts; + u64 nsec; + +- if (__arch_update_vdso_data()) { +- /* +- * Some architectures might want to skip the update of the +- * data page. +- */ +- return; +- } +- + /* copy vsyscall data */ + vdso_write_begin(vdata); + + vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk); + vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk); + ++ /* CLOCK_REALTIME also required for time() */ ++ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME]; ++ vdso_ts->sec = tk->xtime_sec; ++ vdso_ts->nsec = tk->tkr_mono.xtime_nsec; ++ + /* CLOCK_REALTIME_COARSE */ + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE]; + vdso_ts->sec = tk->xtime_sec; +@@ -110,7 +96,18 @@ void update_vsyscall(struct timekeeper *tk) + nsec = nsec + tk->wall_to_monotonic.tv_nsec; + vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec); + +- update_vdso_data(vdata, tk); ++ /* ++ * Read without the seqlock held by clock_getres(). ++ * Note: No need to have a second copy. ++ */ ++ WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution); ++ ++ /* ++ * Architectures can opt out of updating the high resolution part ++ * of the VDSO. ++ */ ++ if (__arch_update_vdso_data()) ++ update_vdso_data(vdata, tk); + + __arch_update_vsyscall(vdata, tk); + +diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c +index 475e29498bca..a6d3016410eb 100644 +--- a/kernel/trace/blktrace.c ++++ b/kernel/trace/blktrace.c +@@ -335,6 +335,7 @@ static void put_probe_ref(void) + + static void blk_trace_cleanup(struct blk_trace *bt) + { ++ synchronize_rcu(); + blk_trace_free(bt); + put_probe_ref(); + } +@@ -629,8 +630,10 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, + static int __blk_trace_startstop(struct request_queue *q, int start) + { + int ret; +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); + if (bt == NULL) + return -EINVAL; + +@@ -740,8 +743,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) + void blk_trace_shutdown(struct request_queue *q) + { + mutex_lock(&q->blk_trace_mutex); +- +- if (q->blk_trace) { ++ if (rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex))) { + __blk_trace_startstop(q, 0); + __blk_trace_remove(q); + } +@@ -752,8 +755,10 @@ void blk_trace_shutdown(struct request_queue *q) + #ifdef CONFIG_BLK_CGROUP + static u64 blk_trace_bio_get_cgid(struct request_queue *q, struct bio *bio) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ /* We don't use the 'bt' value here except as an optimization... */ ++ bt = rcu_dereference_protected(q->blk_trace, 1); + if (!bt || !(blk_tracer_flags.val & TRACE_BLK_OPT_CGROUP)) + return 0; + +@@ -796,10 +801,14 @@ blk_trace_request_get_cgid(struct request_queue *q, struct request *rq) + static void blk_add_trace_rq(struct request *rq, int error, + unsigned int nr_bytes, u32 what, u64 cgid) + { +- struct blk_trace *bt = rq->q->blk_trace; ++ struct blk_trace *bt; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(rq->q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + if (blk_rq_is_passthrough(rq)) + what |= BLK_TC_ACT(BLK_TC_PC); +@@ -808,6 +817,7 @@ static void blk_add_trace_rq(struct request *rq, int error, + + __blk_add_trace(bt, blk_rq_trace_sector(rq), nr_bytes, req_op(rq), + rq->cmd_flags, what, error, 0, NULL, cgid); ++ rcu_read_unlock(); + } + + static void blk_add_trace_rq_insert(void *ignore, +@@ -853,14 +863,19 @@ static void blk_add_trace_rq_complete(void *ignore, struct request *rq, + static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, + u32 what, int error) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, + bio_op(bio), bio->bi_opf, what, error, 0, NULL, + blk_trace_bio_get_cgid(q, bio)); ++ rcu_read_unlock(); + } + + static void blk_add_trace_bio_bounce(void *ignore, +@@ -905,11 +920,14 @@ static void blk_add_trace_getrq(void *ignore, + if (bio) + blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0); + else { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) + __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_GETRQ, 0, 0, + NULL, 0); ++ rcu_read_unlock(); + } + } + +@@ -921,27 +939,35 @@ static void blk_add_trace_sleeprq(void *ignore, + if (bio) + blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0); + else { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) + __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_SLEEPRQ, + 0, 0, NULL, 0); ++ rcu_read_unlock(); + } + } + + static void blk_add_trace_plug(void *ignore, struct request_queue *q) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) + __blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL, 0); ++ rcu_read_unlock(); + } + + static void blk_add_trace_unplug(void *ignore, struct request_queue *q, + unsigned int depth, bool explicit) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) { + __be64 rpdu = cpu_to_be64(depth); + u32 what; +@@ -953,14 +979,17 @@ static void blk_add_trace_unplug(void *ignore, struct request_queue *q, + + __blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu, 0); + } ++ rcu_read_unlock(); + } + + static void blk_add_trace_split(void *ignore, + struct request_queue *q, struct bio *bio, + unsigned int pdu) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) { + __be64 rpdu = cpu_to_be64(pdu); + +@@ -969,6 +998,7 @@ static void blk_add_trace_split(void *ignore, + BLK_TA_SPLIT, bio->bi_status, sizeof(rpdu), + &rpdu, blk_trace_bio_get_cgid(q, bio)); + } ++ rcu_read_unlock(); + } + + /** +@@ -988,11 +1018,15 @@ static void blk_add_trace_bio_remap(void *ignore, + struct request_queue *q, struct bio *bio, + dev_t dev, sector_t from) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + struct blk_io_trace_remap r; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + r.device_from = cpu_to_be32(dev); + r.device_to = cpu_to_be32(bio_dev(bio)); +@@ -1001,6 +1035,7 @@ static void blk_add_trace_bio_remap(void *ignore, + __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, + bio_op(bio), bio->bi_opf, BLK_TA_REMAP, bio->bi_status, + sizeof(r), &r, blk_trace_bio_get_cgid(q, bio)); ++ rcu_read_unlock(); + } + + /** +@@ -1021,11 +1056,15 @@ static void blk_add_trace_rq_remap(void *ignore, + struct request *rq, dev_t dev, + sector_t from) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + struct blk_io_trace_remap r; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + r.device_from = cpu_to_be32(dev); + r.device_to = cpu_to_be32(disk_devt(rq->rq_disk)); +@@ -1034,6 +1073,7 @@ static void blk_add_trace_rq_remap(void *ignore, + __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), + rq_data_dir(rq), 0, BLK_TA_REMAP, 0, + sizeof(r), &r, blk_trace_request_get_cgid(q, rq)); ++ rcu_read_unlock(); + } + + /** +@@ -1051,14 +1091,19 @@ void blk_add_driver_data(struct request_queue *q, + struct request *rq, + void *data, size_t len) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + __blk_add_trace(bt, blk_rq_trace_sector(rq), blk_rq_bytes(rq), 0, 0, + BLK_TA_DRV_DATA, 0, len, data, + blk_trace_request_get_cgid(q, rq)); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(blk_add_driver_data); + +@@ -1597,6 +1642,7 @@ static int blk_trace_remove_queue(struct request_queue *q) + return -EINVAL; + + put_probe_ref(); ++ synchronize_rcu(); + blk_trace_free(bt); + return 0; + } +@@ -1758,6 +1804,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, + struct hd_struct *p = dev_to_part(dev); + struct request_queue *q; + struct block_device *bdev; ++ struct blk_trace *bt; + ssize_t ret = -ENXIO; + + bdev = bdget(part_devt(p)); +@@ -1770,21 +1817,23 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, + + mutex_lock(&q->blk_trace_mutex); + ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); + if (attr == &dev_attr_enable) { +- ret = sprintf(buf, "%u\n", !!q->blk_trace); ++ ret = sprintf(buf, "%u\n", !!bt); + goto out_unlock_bdev; + } + +- if (q->blk_trace == NULL) ++ if (bt == NULL) + ret = sprintf(buf, "disabled\n"); + else if (attr == &dev_attr_act_mask) +- ret = blk_trace_mask2str(buf, q->blk_trace->act_mask); ++ ret = blk_trace_mask2str(buf, bt->act_mask); + else if (attr == &dev_attr_pid) +- ret = sprintf(buf, "%u\n", q->blk_trace->pid); ++ ret = sprintf(buf, "%u\n", bt->pid); + else if (attr == &dev_attr_start_lba) +- ret = sprintf(buf, "%llu\n", q->blk_trace->start_lba); ++ ret = sprintf(buf, "%llu\n", bt->start_lba); + else if (attr == &dev_attr_end_lba) +- ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba); ++ ret = sprintf(buf, "%llu\n", bt->end_lba); + + out_unlock_bdev: + mutex_unlock(&q->blk_trace_mutex); +@@ -1801,6 +1850,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + struct block_device *bdev; + struct request_queue *q; + struct hd_struct *p; ++ struct blk_trace *bt; + u64 value; + ssize_t ret = -EINVAL; + +@@ -1831,8 +1881,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + + mutex_lock(&q->blk_trace_mutex); + ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); + if (attr == &dev_attr_enable) { +- if (!!value == !!q->blk_trace) { ++ if (!!value == !!bt) { + ret = 0; + goto out_unlock_bdev; + } +@@ -1844,18 +1896,18 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + } + + ret = 0; +- if (q->blk_trace == NULL) ++ if (bt == NULL) + ret = blk_trace_setup_queue(q, bdev); + + if (ret == 0) { + if (attr == &dev_attr_act_mask) +- q->blk_trace->act_mask = value; ++ bt->act_mask = value; + else if (attr == &dev_attr_pid) +- q->blk_trace->pid = value; ++ bt->pid = value; + else if (attr == &dev_attr_start_lba) +- q->blk_trace->start_lba = value; ++ bt->start_lba = value; + else if (attr == &dev_attr_end_lba) +- q->blk_trace->end_lba = value; ++ bt->end_lba = value; + } + + out_unlock_bdev: +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 5b6ee4aadc26..256ac508196f 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1827,6 +1827,7 @@ static __init int init_trace_selftests(void) + + pr_info("Running postponed tracer tests:\n"); + ++ tracing_selftest_running = true; + list_for_each_entry_safe(p, n, &postponed_selftests, list) { + /* This loop can take minutes when sanitizers are enabled, so + * lets make sure we allow RCU processing. +@@ -1849,6 +1850,7 @@ static __init int init_trace_selftests(void) + list_del(&p->list); + kfree(p); + } ++ tracing_selftest_running = false; + + out: + mutex_unlock(&trace_types_lock); +diff --git a/mm/debug.c b/mm/debug.c +index 0461df1207cb..6a52316af839 100644 +--- a/mm/debug.c ++++ b/mm/debug.c +@@ -47,6 +47,7 @@ void __dump_page(struct page *page, const char *reason) + struct address_space *mapping; + bool page_poisoned = PagePoisoned(page); + int mapcount; ++ char *type = ""; + + /* + * If struct page is poisoned don't access Page*() functions as that +@@ -78,9 +79,9 @@ void __dump_page(struct page *page, const char *reason) + page, page_ref_count(page), mapcount, + page->mapping, page_to_pgoff(page)); + if (PageKsm(page)) +- pr_warn("ksm flags: %#lx(%pGp)\n", page->flags, &page->flags); ++ type = "ksm "; + else if (PageAnon(page)) +- pr_warn("anon flags: %#lx(%pGp)\n", page->flags, &page->flags); ++ type = "anon "; + else if (mapping) { + if (mapping->host && mapping->host->i_dentry.first) { + struct dentry *dentry; +@@ -88,10 +89,11 @@ void __dump_page(struct page *page, const char *reason) + pr_warn("%ps name:\"%pd\"\n", mapping->a_ops, dentry); + } else + pr_warn("%ps\n", mapping->a_ops); +- pr_warn("flags: %#lx(%pGp)\n", page->flags, &page->flags); + } + BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1); + ++ pr_warn("%sflags: %#lx(%pGp)\n", type, page->flags, &page->flags); ++ + hex_only: + print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32, + sizeof(unsigned long), page, +diff --git a/mm/gup.c b/mm/gup.c +index 7646bf993b25..5244b8090440 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -2415,7 +2415,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, + unsigned long addr, len, end; + int nr = 0, ret = 0; + +- if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM))) ++ if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM | ++ FOLL_FORCE))) + return -EINVAL; + + start = untagged_addr(start) & PAGE_MASK; +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index a88093213674..54c106bdbafd 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -177,16 +177,13 @@ static ssize_t enabled_store(struct kobject *kobj, + { + ssize_t ret = count; + +- if (!memcmp("always", buf, +- min(sizeof("always")-1, count))) { ++ if (sysfs_streq(buf, "always")) { + clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("madvise", buf, +- min(sizeof("madvise")-1, count))) { ++ } else if (sysfs_streq(buf, "madvise")) { + clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("never", buf, +- min(sizeof("never")-1, count))) { ++ } else if (sysfs_streq(buf, "never")) { + clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); + } else +@@ -250,32 +247,27 @@ static ssize_t defrag_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) + { +- if (!memcmp("always", buf, +- min(sizeof("always")-1, count))) { ++ if (sysfs_streq(buf, "always")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("defer+madvise", buf, +- min(sizeof("defer+madvise")-1, count))) { ++ } else if (sysfs_streq(buf, "defer+madvise")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("defer", buf, +- min(sizeof("defer")-1, count))) { ++ } else if (sysfs_streq(buf, "defer")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("madvise", buf, +- min(sizeof("madvise")-1, count))) { ++ } else if (sysfs_streq(buf, "madvise")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("never", buf, +- min(sizeof("never")-1, count))) { ++ } else if (sysfs_streq(buf, "never")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); +@@ -2712,7 +2704,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) + unsigned long flags; + pgoff_t end; + +- VM_BUG_ON_PAGE(is_huge_zero_page(page), page); ++ VM_BUG_ON_PAGE(is_huge_zero_page(head), head); + VM_BUG_ON_PAGE(!PageLocked(page), page); + VM_BUG_ON_PAGE(!PageCompound(page), page); + +diff --git a/net/core/dev.c b/net/core/dev.c +index 466f2e4144b0..c3da35f3c7e4 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -146,7 +146,6 @@ + #include "net-sysfs.h" + + #define MAX_GRO_SKBS 8 +-#define MAX_NEST_DEV 8 + + /* This should be increased if a protocol with a bigger head is added. */ + #define GRO_MAX_HEAD (MAX_HEADER + 128) +@@ -331,6 +330,12 @@ int netdev_name_node_alt_destroy(struct net_device *dev, const char *name) + name_node = netdev_name_node_lookup(net, name); + if (!name_node) + return -ENOENT; ++ /* lookup might have found our primary name or a name belonging ++ * to another device. ++ */ ++ if (name_node == dev->name_node || name_node->dev != dev) ++ return -EINVAL; ++ + __netdev_name_node_alt_destroy(name_node); + + return 0; +@@ -3607,26 +3612,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, + qdisc_calculate_pkt_len(skb, q); + + if (q->flags & TCQ_F_NOLOCK) { +- if ((q->flags & TCQ_F_CAN_BYPASS) && READ_ONCE(q->empty) && +- qdisc_run_begin(q)) { +- if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, +- &q->state))) { +- __qdisc_drop(skb, &to_free); +- rc = NET_XMIT_DROP; +- goto end_run; +- } +- qdisc_bstats_cpu_update(q, skb); +- +- rc = NET_XMIT_SUCCESS; +- if (sch_direct_xmit(skb, q, dev, txq, NULL, true)) +- __qdisc_run(q); +- +-end_run: +- qdisc_run_end(q); +- } else { +- rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; +- qdisc_run(q); +- } ++ rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; ++ qdisc_run(q); + + if (unlikely(to_free)) + kfree_skb_list(to_free); +@@ -7153,8 +7140,8 @@ static int __netdev_walk_all_lower_dev(struct net_device *dev, + return 0; + } + +-static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, +- struct list_head **iter) ++struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, ++ struct list_head **iter) + { + struct netdev_adjacent *lower; + +@@ -7166,6 +7153,7 @@ static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, + + return lower->dev; + } ++EXPORT_SYMBOL(netdev_next_lower_dev_rcu); + + static u8 __netdev_upper_depth(struct net_device *dev) + { +diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c +index 3e7e15278c46..bd7eba9066f8 100644 +--- a/net/core/fib_rules.c ++++ b/net/core/fib_rules.c +@@ -974,7 +974,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, + + frh = nlmsg_data(nlh); + frh->family = ops->family; +- frh->table = rule->table; ++ frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT; + if (nla_put_u32(skb, FRA_TABLE, rule->table)) + goto nla_put_failure; + if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index f02705ff0e5e..1737bac74c45 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -3499,27 +3499,25 @@ static int rtnl_alt_ifname(int cmd, struct net_device *dev, struct nlattr *attr, + if (err) + return err; + +- alt_ifname = nla_data(attr); ++ alt_ifname = nla_strdup(attr, GFP_KERNEL); ++ if (!alt_ifname) ++ return -ENOMEM; ++ + if (cmd == RTM_NEWLINKPROP) { +- alt_ifname = kstrdup(alt_ifname, GFP_KERNEL); +- if (!alt_ifname) +- return -ENOMEM; + err = netdev_name_node_alt_create(dev, alt_ifname); +- if (err) { +- kfree(alt_ifname); +- return err; +- } ++ if (!err) ++ alt_ifname = NULL; + } else if (cmd == RTM_DELLINKPROP) { + err = netdev_name_node_alt_destroy(dev, alt_ifname); +- if (err) +- return err; + } else { +- WARN_ON(1); +- return 0; ++ WARN_ON_ONCE(1); ++ err = -EINVAL; + } + +- *changed = true; +- return 0; ++ kfree(alt_ifname); ++ if (!err) ++ *changed = true; ++ return err; + } + + static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh, +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 030d43c7c957..be5c5903cfe1 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1856,8 +1856,12 @@ int __udp_disconnect(struct sock *sk, int flags) + inet->inet_dport = 0; + sock_rps_reset_rxhash(sk); + sk->sk_bound_dev_if = 0; +- if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) ++ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) { + inet_reset_saddr(sk); ++ if (sk->sk_prot->rehash && ++ (sk->sk_userlocks & SOCK_BINDPORT_LOCK)) ++ sk->sk_prot->rehash(sk); ++ } + + if (!(sk->sk_userlocks & SOCK_BINDPORT_LOCK)) { + sk->sk_prot->unhash(sk); +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index cfae0a1529a1..bde3bf180871 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1068,8 +1068,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + found++; + break; + } +- if (rt_can_ecmp) +- fallback_ins = fallback_ins ?: ins; ++ fallback_ins = fallback_ins ?: ins; + goto next_iter; + } + +@@ -1112,7 +1111,9 @@ next_iter: + } + + if (fallback_ins && !found) { +- /* No ECMP-able route found, replace first non-ECMP one */ ++ /* No matching route with same ecmp-able-ness found, replace ++ * first matching route ++ */ + ins = fallback_ins; + iter = rcu_dereference_protected(*ins, + lockdep_is_held(&rt->fib6_table->tb6_lock)); +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index affb51c11a25..119c7226c4be 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -5152,6 +5152,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg, + */ + cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL | + NLM_F_REPLACE); ++ cfg->fc_nlinfo.nlh->nlmsg_flags |= NLM_F_CREATE; + nhn++; + } + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index e041af2f021a..88d7a692a965 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2959,7 +2959,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, + (auth_transaction == 2 && + ifmgd->auth_data->expected_transaction == 2)) { + if (!ieee80211_mark_sta_auth(sdata, bssid)) +- goto out_err; ++ return; /* ignore frame -- wait for timeout */ + } else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && + auth_transaction == 2) { + sdata_info(sdata, "SAE peer confirmed\n"); +@@ -2967,10 +2967,6 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, + } + + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); +- return; +- out_err: +- mutex_unlock(&sdata->local->sta_mtx); +- /* ignore frame -- wait for timeout */ + } + + #define case_WLAN(type) \ +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 32a7a53833c0..decd46b38393 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1063,16 +1063,22 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + elem_parse_failed = true; + break; + case WLAN_EID_VHT_OPERATION: +- if (elen >= sizeof(struct ieee80211_vht_operation)) ++ if (elen >= sizeof(struct ieee80211_vht_operation)) { + elems->vht_operation = (void *)pos; +- else +- elem_parse_failed = true; ++ if (calc_crc) ++ crc = crc32_be(crc, pos - 2, elen + 2); ++ break; ++ } ++ elem_parse_failed = true; + break; + case WLAN_EID_OPMODE_NOTIF: +- if (elen > 0) ++ if (elen > 0) { + elems->opmode_notif = pos; +- else +- elem_parse_failed = true; ++ if (calc_crc) ++ crc = crc32_be(crc, pos - 2, elen + 2); ++ break; ++ } ++ elem_parse_failed = true; + break; + case WLAN_EID_MESH_ID: + elems->mesh_id = pos; +@@ -2987,10 +2993,22 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, + int cf0, cf1; + int ccfs0, ccfs1, ccfs2; + int ccf0, ccf1; ++ u32 vht_cap; ++ bool support_80_80 = false; ++ bool support_160 = false; + + if (!oper || !htop) + return false; + ++ vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap; ++ support_160 = (vht_cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK | ++ IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)); ++ support_80_80 = ((vht_cap & ++ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) || ++ (vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && ++ vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) || ++ ((vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >> ++ IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT > 1)); + ccfs0 = oper->center_freq_seg0_idx; + ccfs1 = oper->center_freq_seg1_idx; + ccfs2 = (le16_to_cpu(htop->operation_mode) & +@@ -3018,10 +3036,10 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, + unsigned int diff; + + diff = abs(ccf1 - ccf0); +- if (diff == 8) { ++ if ((diff == 8) && support_160) { + new.width = NL80211_CHAN_WIDTH_160; + new.center_freq1 = cf1; +- } else if (diff > 8) { ++ } else if ((diff > 8) && support_80_80) { + new.width = NL80211_CHAN_WIDTH_80P80; + new.center_freq2 = cf1; + } +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 69c107f9ba8d..8dd17589217d 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -723,6 +723,20 @@ ip_set_rcu_get(struct net *net, ip_set_id_t index) + return set; + } + ++static inline void ++ip_set_lock(struct ip_set *set) ++{ ++ if (!set->variant->region_lock) ++ spin_lock_bh(&set->lock); ++} ++ ++static inline void ++ip_set_unlock(struct ip_set *set) ++{ ++ if (!set->variant->region_lock) ++ spin_unlock_bh(&set->lock); ++} ++ + int + ip_set_test(ip_set_id_t index, const struct sk_buff *skb, + const struct xt_action_param *par, struct ip_set_adt_opt *opt) +@@ -744,9 +758,9 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb, + if (ret == -EAGAIN) { + /* Type requests element to be completed */ + pr_debug("element must be completed, ADD is triggered\n"); +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + set->variant->kadt(set, skb, par, IPSET_ADD, opt); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + ret = 1; + } else { + /* --return-nomatch: invert matched element */ +@@ -775,9 +789,9 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb, + !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) + return -IPSET_ERR_TYPE_MISMATCH; + +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + ret = set->variant->kadt(set, skb, par, IPSET_ADD, opt); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + + return ret; + } +@@ -797,9 +811,9 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb, + !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) + return -IPSET_ERR_TYPE_MISMATCH; + +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + ret = set->variant->kadt(set, skb, par, IPSET_DEL, opt); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + + return ret; + } +@@ -1264,9 +1278,9 @@ ip_set_flush_set(struct ip_set *set) + { + pr_debug("set: %s\n", set->name); + +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + set->variant->flush(set); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + } + + static int ip_set_flush(struct net *net, struct sock *ctnl, struct sk_buff *skb, +@@ -1713,9 +1727,9 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set, + bool eexist = flags & IPSET_FLAG_EXIST, retried = false; + + do { +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + retried = true; + } while (ret == -EAGAIN && + set->variant->resize && +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index 7480ce55b5c8..e52d7b7597a0 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -7,13 +7,21 @@ + #include <linux/rcupdate.h> + #include <linux/jhash.h> + #include <linux/types.h> ++#include <linux/netfilter/nfnetlink.h> + #include <linux/netfilter/ipset/ip_set.h> + +-#define __ipset_dereference_protected(p, c) rcu_dereference_protected(p, c) +-#define ipset_dereference_protected(p, set) \ +- __ipset_dereference_protected(p, lockdep_is_held(&(set)->lock)) +- +-#define rcu_dereference_bh_nfnl(p) rcu_dereference_bh_check(p, 1) ++#define __ipset_dereference(p) \ ++ rcu_dereference_protected(p, 1) ++#define ipset_dereference_nfnl(p) \ ++ rcu_dereference_protected(p, \ ++ lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) ++#define ipset_dereference_set(p, set) \ ++ rcu_dereference_protected(p, \ ++ lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ ++ lockdep_is_held(&(set)->lock)) ++#define ipset_dereference_bh_nfnl(p) \ ++ rcu_dereference_bh_check(p, \ ++ lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) + + /* Hashing which uses arrays to resolve clashing. The hash table is resized + * (doubled) when searching becomes too long. +@@ -72,11 +80,35 @@ struct hbucket { + __aligned(__alignof__(u64)); + }; + ++/* Region size for locking == 2^HTABLE_REGION_BITS */ ++#define HTABLE_REGION_BITS 10 ++#define ahash_numof_locks(htable_bits) \ ++ ((htable_bits) < HTABLE_REGION_BITS ? 1 \ ++ : jhash_size((htable_bits) - HTABLE_REGION_BITS)) ++#define ahash_sizeof_regions(htable_bits) \ ++ (ahash_numof_locks(htable_bits) * sizeof(struct ip_set_region)) ++#define ahash_region(n, htable_bits) \ ++ ((n) % ahash_numof_locks(htable_bits)) ++#define ahash_bucket_start(h, htable_bits) \ ++ ((htable_bits) < HTABLE_REGION_BITS ? 0 \ ++ : (h) * jhash_size(HTABLE_REGION_BITS)) ++#define ahash_bucket_end(h, htable_bits) \ ++ ((htable_bits) < HTABLE_REGION_BITS ? jhash_size(htable_bits) \ ++ : ((h) + 1) * jhash_size(HTABLE_REGION_BITS)) ++ ++struct htable_gc { ++ struct delayed_work dwork; ++ struct ip_set *set; /* Set the gc belongs to */ ++ u32 region; /* Last gc run position */ ++}; ++ + /* The hash table: the table size stored here in order to make resizing easy */ + struct htable { + atomic_t ref; /* References for resizing */ +- atomic_t uref; /* References for dumping */ ++ atomic_t uref; /* References for dumping and gc */ + u8 htable_bits; /* size of hash table == 2^htable_bits */ ++ u32 maxelem; /* Maxelem per region */ ++ struct ip_set_region *hregion; /* Region locks and ext sizes */ + struct hbucket __rcu *bucket[0]; /* hashtable buckets */ + }; + +@@ -162,6 +194,10 @@ htable_bits(u32 hashsize) + #define NLEN 0 + #endif /* IP_SET_HASH_WITH_NETS */ + ++#define SET_ELEM_EXPIRED(set, d) \ ++ (SET_WITH_TIMEOUT(set) && \ ++ ip_set_timeout_expired(ext_timeout(d, set))) ++ + #endif /* _IP_SET_HASH_GEN_H */ + + #ifndef MTYPE +@@ -205,10 +241,12 @@ htable_bits(u32 hashsize) + #undef mtype_test_cidrs + #undef mtype_test + #undef mtype_uref +-#undef mtype_expire + #undef mtype_resize ++#undef mtype_ext_size ++#undef mtype_resize_ad + #undef mtype_head + #undef mtype_list ++#undef mtype_gc_do + #undef mtype_gc + #undef mtype_gc_init + #undef mtype_variant +@@ -247,10 +285,12 @@ htable_bits(u32 hashsize) + #define mtype_test_cidrs IPSET_TOKEN(MTYPE, _test_cidrs) + #define mtype_test IPSET_TOKEN(MTYPE, _test) + #define mtype_uref IPSET_TOKEN(MTYPE, _uref) +-#define mtype_expire IPSET_TOKEN(MTYPE, _expire) + #define mtype_resize IPSET_TOKEN(MTYPE, _resize) ++#define mtype_ext_size IPSET_TOKEN(MTYPE, _ext_size) ++#define mtype_resize_ad IPSET_TOKEN(MTYPE, _resize_ad) + #define mtype_head IPSET_TOKEN(MTYPE, _head) + #define mtype_list IPSET_TOKEN(MTYPE, _list) ++#define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do) + #define mtype_gc IPSET_TOKEN(MTYPE, _gc) + #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) + #define mtype_variant IPSET_TOKEN(MTYPE, _variant) +@@ -275,8 +315,7 @@ htable_bits(u32 hashsize) + /* The generic hash structure */ + struct htype { + struct htable __rcu *table; /* the hash table */ +- struct timer_list gc; /* garbage collection when timeout enabled */ +- struct ip_set *set; /* attached to this ip_set */ ++ struct htable_gc gc; /* gc workqueue */ + u32 maxelem; /* max elements in the hash */ + u32 initval; /* random jhash init value */ + #ifdef IP_SET_HASH_WITH_MARKMASK +@@ -288,21 +327,33 @@ struct htype { + #ifdef IP_SET_HASH_WITH_NETMASK + u8 netmask; /* netmask value for subnets to store */ + #endif ++ struct list_head ad; /* Resize add|del backlist */ + struct mtype_elem next; /* temporary storage for uadd */ + #ifdef IP_SET_HASH_WITH_NETS + struct net_prefixes nets[NLEN]; /* book-keeping of prefixes */ + #endif + }; + ++/* ADD|DEL entries saved during resize */ ++struct mtype_resize_ad { ++ struct list_head list; ++ enum ipset_adt ad; /* ADD|DEL element */ ++ struct mtype_elem d; /* Element value */ ++ struct ip_set_ext ext; /* Extensions for ADD */ ++ struct ip_set_ext mext; /* Target extensions for ADD */ ++ u32 flags; /* Flags for ADD */ ++}; ++ + #ifdef IP_SET_HASH_WITH_NETS + /* Network cidr size book keeping when the hash stores different + * sized networks. cidr == real cidr + 1 to support /0. + */ + static void +-mtype_add_cidr(struct htype *h, u8 cidr, u8 n) ++mtype_add_cidr(struct ip_set *set, struct htype *h, u8 cidr, u8 n) + { + int i, j; + ++ spin_lock_bh(&set->lock); + /* Add in increasing prefix order, so larger cidr first */ + for (i = 0, j = -1; i < NLEN && h->nets[i].cidr[n]; i++) { + if (j != -1) { +@@ -311,7 +362,7 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 n) + j = i; + } else if (h->nets[i].cidr[n] == cidr) { + h->nets[CIDR_POS(cidr)].nets[n]++; +- return; ++ goto unlock; + } + } + if (j != -1) { +@@ -320,24 +371,29 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 n) + } + h->nets[i].cidr[n] = cidr; + h->nets[CIDR_POS(cidr)].nets[n] = 1; ++unlock: ++ spin_unlock_bh(&set->lock); + } + + static void +-mtype_del_cidr(struct htype *h, u8 cidr, u8 n) ++mtype_del_cidr(struct ip_set *set, struct htype *h, u8 cidr, u8 n) + { + u8 i, j, net_end = NLEN - 1; + ++ spin_lock_bh(&set->lock); + for (i = 0; i < NLEN; i++) { + if (h->nets[i].cidr[n] != cidr) + continue; + h->nets[CIDR_POS(cidr)].nets[n]--; + if (h->nets[CIDR_POS(cidr)].nets[n] > 0) +- return; ++ goto unlock; + for (j = i; j < net_end && h->nets[j].cidr[n]; j++) + h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; + h->nets[j].cidr[n] = 0; +- return; ++ goto unlock; + } ++unlock: ++ spin_unlock_bh(&set->lock); + } + #endif + +@@ -345,7 +401,7 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 n) + static size_t + mtype_ahash_memsize(const struct htype *h, const struct htable *t) + { +- return sizeof(*h) + sizeof(*t); ++ return sizeof(*h) + sizeof(*t) + ahash_sizeof_regions(t->htable_bits); + } + + /* Get the ith element from the array block n */ +@@ -369,24 +425,29 @@ mtype_flush(struct ip_set *set) + struct htype *h = set->data; + struct htable *t; + struct hbucket *n; +- u32 i; +- +- t = ipset_dereference_protected(h->table, set); +- for (i = 0; i < jhash_size(t->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(t, i), 1); +- if (!n) +- continue; +- if (set->extensions & IPSET_EXT_DESTROY) +- mtype_ext_cleanup(set, n); +- /* FIXME: use slab cache */ +- rcu_assign_pointer(hbucket(t, i), NULL); +- kfree_rcu(n, rcu); ++ u32 r, i; ++ ++ t = ipset_dereference_nfnl(h->table); ++ for (r = 0; r < ahash_numof_locks(t->htable_bits); r++) { ++ spin_lock_bh(&t->hregion[r].lock); ++ for (i = ahash_bucket_start(r, t->htable_bits); ++ i < ahash_bucket_end(r, t->htable_bits); i++) { ++ n = __ipset_dereference(hbucket(t, i)); ++ if (!n) ++ continue; ++ if (set->extensions & IPSET_EXT_DESTROY) ++ mtype_ext_cleanup(set, n); ++ /* FIXME: use slab cache */ ++ rcu_assign_pointer(hbucket(t, i), NULL); ++ kfree_rcu(n, rcu); ++ } ++ t->hregion[r].ext_size = 0; ++ t->hregion[r].elements = 0; ++ spin_unlock_bh(&t->hregion[r].lock); + } + #ifdef IP_SET_HASH_WITH_NETS + memset(h->nets, 0, sizeof(h->nets)); + #endif +- set->elements = 0; +- set->ext_size = 0; + } + + /* Destroy the hashtable part of the set */ +@@ -397,7 +458,7 @@ mtype_ahash_destroy(struct ip_set *set, struct htable *t, bool ext_destroy) + u32 i; + + for (i = 0; i < jhash_size(t->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(t, i), 1); ++ n = __ipset_dereference(hbucket(t, i)); + if (!n) + continue; + if (set->extensions & IPSET_EXT_DESTROY && ext_destroy) +@@ -406,6 +467,7 @@ mtype_ahash_destroy(struct ip_set *set, struct htable *t, bool ext_destroy) + kfree(n); + } + ++ ip_set_free(t->hregion); + ip_set_free(t); + } + +@@ -414,28 +476,21 @@ static void + mtype_destroy(struct ip_set *set) + { + struct htype *h = set->data; ++ struct list_head *l, *lt; + + if (SET_WITH_TIMEOUT(set)) +- del_timer_sync(&h->gc); ++ cancel_delayed_work_sync(&h->gc.dwork); + +- mtype_ahash_destroy(set, +- __ipset_dereference_protected(h->table, 1), true); ++ mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true); ++ list_for_each_safe(l, lt, &h->ad) { ++ list_del(l); ++ kfree(l); ++ } + kfree(h); + + set->data = NULL; + } + +-static void +-mtype_gc_init(struct ip_set *set, void (*gc)(struct timer_list *t)) +-{ +- struct htype *h = set->data; +- +- timer_setup(&h->gc, gc, 0); +- mod_timer(&h->gc, jiffies + IPSET_GC_PERIOD(set->timeout) * HZ); +- pr_debug("gc initialized, run in every %u\n", +- IPSET_GC_PERIOD(set->timeout)); +-} +- + static bool + mtype_same_set(const struct ip_set *a, const struct ip_set *b) + { +@@ -454,11 +509,9 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b) + a->extensions == b->extensions; + } + +-/* Delete expired elements from the hashtable */ + static void +-mtype_expire(struct ip_set *set, struct htype *h) ++mtype_gc_do(struct ip_set *set, struct htype *h, struct htable *t, u32 r) + { +- struct htable *t; + struct hbucket *n, *tmp; + struct mtype_elem *data; + u32 i, j, d; +@@ -466,10 +519,12 @@ mtype_expire(struct ip_set *set, struct htype *h) + #ifdef IP_SET_HASH_WITH_NETS + u8 k; + #endif ++ u8 htable_bits = t->htable_bits; + +- t = ipset_dereference_protected(h->table, set); +- for (i = 0; i < jhash_size(t->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(t, i), 1); ++ spin_lock_bh(&t->hregion[r].lock); ++ for (i = ahash_bucket_start(r, htable_bits); ++ i < ahash_bucket_end(r, htable_bits); i++) { ++ n = __ipset_dereference(hbucket(t, i)); + if (!n) + continue; + for (j = 0, d = 0; j < n->pos; j++) { +@@ -485,58 +540,100 @@ mtype_expire(struct ip_set *set, struct htype *h) + smp_mb__after_atomic(); + #ifdef IP_SET_HASH_WITH_NETS + for (k = 0; k < IPSET_NET_COUNT; k++) +- mtype_del_cidr(h, ++ mtype_del_cidr(set, h, + NCIDR_PUT(DCIDR_GET(data->cidr, k)), + k); + #endif ++ t->hregion[r].elements--; + ip_set_ext_destroy(set, data); +- set->elements--; + d++; + } + if (d >= AHASH_INIT_SIZE) { + if (d >= n->size) { ++ t->hregion[r].ext_size -= ++ ext_size(n->size, dsize); + rcu_assign_pointer(hbucket(t, i), NULL); + kfree_rcu(n, rcu); + continue; + } + tmp = kzalloc(sizeof(*tmp) + +- (n->size - AHASH_INIT_SIZE) * dsize, +- GFP_ATOMIC); ++ (n->size - AHASH_INIT_SIZE) * dsize, ++ GFP_ATOMIC); + if (!tmp) +- /* Still try to delete expired elements */ ++ /* Still try to delete expired elements. */ + continue; + tmp->size = n->size - AHASH_INIT_SIZE; + for (j = 0, d = 0; j < n->pos; j++) { + if (!test_bit(j, n->used)) + continue; + data = ahash_data(n, j, dsize); +- memcpy(tmp->value + d * dsize, data, dsize); ++ memcpy(tmp->value + d * dsize, ++ data, dsize); + set_bit(d, tmp->used); + d++; + } + tmp->pos = d; +- set->ext_size -= ext_size(AHASH_INIT_SIZE, dsize); ++ t->hregion[r].ext_size -= ++ ext_size(AHASH_INIT_SIZE, dsize); + rcu_assign_pointer(hbucket(t, i), tmp); + kfree_rcu(n, rcu); + } + } ++ spin_unlock_bh(&t->hregion[r].lock); + } + + static void +-mtype_gc(struct timer_list *t) ++mtype_gc(struct work_struct *work) + { +- struct htype *h = from_timer(h, t, gc); +- struct ip_set *set = h->set; ++ struct htable_gc *gc; ++ struct ip_set *set; ++ struct htype *h; ++ struct htable *t; ++ u32 r, numof_locks; ++ unsigned int next_run; ++ ++ gc = container_of(work, struct htable_gc, dwork.work); ++ set = gc->set; ++ h = set->data; + +- pr_debug("called\n"); + spin_lock_bh(&set->lock); +- mtype_expire(set, h); ++ t = ipset_dereference_set(h->table, set); ++ atomic_inc(&t->uref); ++ numof_locks = ahash_numof_locks(t->htable_bits); ++ r = gc->region++; ++ if (r >= numof_locks) { ++ r = gc->region = 0; ++ } ++ next_run = (IPSET_GC_PERIOD(set->timeout) * HZ) / numof_locks; ++ if (next_run < HZ/10) ++ next_run = HZ/10; + spin_unlock_bh(&set->lock); + +- h->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ; +- add_timer(&h->gc); ++ mtype_gc_do(set, h, t, r); ++ ++ if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { ++ pr_debug("Table destroy after resize by expire: %p\n", t); ++ mtype_ahash_destroy(set, t, false); ++ } ++ ++ queue_delayed_work(system_power_efficient_wq, &gc->dwork, next_run); ++ ++} ++ ++static void ++mtype_gc_init(struct htable_gc *gc) ++{ ++ INIT_DEFERRABLE_WORK(&gc->dwork, mtype_gc); ++ queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ); + } + ++static int ++mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, ++ struct ip_set_ext *mext, u32 flags); ++static int ++mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, ++ struct ip_set_ext *mext, u32 flags); ++ + /* Resize a hash: create a new hash table with doubling the hashsize + * and inserting the elements to it. Repeat until we succeed or + * fail due to memory pressures. +@@ -547,7 +644,7 @@ mtype_resize(struct ip_set *set, bool retried) + struct htype *h = set->data; + struct htable *t, *orig; + u8 htable_bits; +- size_t extsize, dsize = set->dsize; ++ size_t dsize = set->dsize; + #ifdef IP_SET_HASH_WITH_NETS + u8 flags; + struct mtype_elem *tmp; +@@ -555,7 +652,9 @@ mtype_resize(struct ip_set *set, bool retried) + struct mtype_elem *data; + struct mtype_elem *d; + struct hbucket *n, *m; +- u32 i, j, key; ++ struct list_head *l, *lt; ++ struct mtype_resize_ad *x; ++ u32 i, j, r, nr, key; + int ret; + + #ifdef IP_SET_HASH_WITH_NETS +@@ -563,10 +662,8 @@ mtype_resize(struct ip_set *set, bool retried) + if (!tmp) + return -ENOMEM; + #endif +- rcu_read_lock_bh(); +- orig = rcu_dereference_bh_nfnl(h->table); ++ orig = ipset_dereference_bh_nfnl(h->table); + htable_bits = orig->htable_bits; +- rcu_read_unlock_bh(); + + retry: + ret = 0; +@@ -583,88 +680,124 @@ retry: + ret = -ENOMEM; + goto out; + } ++ t->hregion = ip_set_alloc(ahash_sizeof_regions(htable_bits)); ++ if (!t->hregion) { ++ kfree(t); ++ ret = -ENOMEM; ++ goto out; ++ } + t->htable_bits = htable_bits; ++ t->maxelem = h->maxelem / ahash_numof_locks(htable_bits); ++ for (i = 0; i < ahash_numof_locks(htable_bits); i++) ++ spin_lock_init(&t->hregion[i].lock); + +- spin_lock_bh(&set->lock); +- orig = __ipset_dereference_protected(h->table, 1); +- /* There can't be another parallel resizing, but dumping is possible */ ++ /* There can't be another parallel resizing, ++ * but dumping, gc, kernel side add/del are possible ++ */ ++ orig = ipset_dereference_bh_nfnl(h->table); + atomic_set(&orig->ref, 1); + atomic_inc(&orig->uref); +- extsize = 0; + pr_debug("attempt to resize set %s from %u to %u, t %p\n", + set->name, orig->htable_bits, htable_bits, orig); +- for (i = 0; i < jhash_size(orig->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(orig, i), 1); +- if (!n) +- continue; +- for (j = 0; j < n->pos; j++) { +- if (!test_bit(j, n->used)) ++ for (r = 0; r < ahash_numof_locks(orig->htable_bits); r++) { ++ /* Expire may replace a hbucket with another one */ ++ rcu_read_lock_bh(); ++ for (i = ahash_bucket_start(r, orig->htable_bits); ++ i < ahash_bucket_end(r, orig->htable_bits); i++) { ++ n = __ipset_dereference(hbucket(orig, i)); ++ if (!n) + continue; +- data = ahash_data(n, j, dsize); ++ for (j = 0; j < n->pos; j++) { ++ if (!test_bit(j, n->used)) ++ continue; ++ data = ahash_data(n, j, dsize); ++ if (SET_ELEM_EXPIRED(set, data)) ++ continue; + #ifdef IP_SET_HASH_WITH_NETS +- /* We have readers running parallel with us, +- * so the live data cannot be modified. +- */ +- flags = 0; +- memcpy(tmp, data, dsize); +- data = tmp; +- mtype_data_reset_flags(data, &flags); ++ /* We have readers running parallel with us, ++ * so the live data cannot be modified. ++ */ ++ flags = 0; ++ memcpy(tmp, data, dsize); ++ data = tmp; ++ mtype_data_reset_flags(data, &flags); + #endif +- key = HKEY(data, h->initval, htable_bits); +- m = __ipset_dereference_protected(hbucket(t, key), 1); +- if (!m) { +- m = kzalloc(sizeof(*m) + ++ key = HKEY(data, h->initval, htable_bits); ++ m = __ipset_dereference(hbucket(t, key)); ++ nr = ahash_region(key, htable_bits); ++ if (!m) { ++ m = kzalloc(sizeof(*m) + + AHASH_INIT_SIZE * dsize, + GFP_ATOMIC); +- if (!m) { +- ret = -ENOMEM; +- goto cleanup; +- } +- m->size = AHASH_INIT_SIZE; +- extsize += ext_size(AHASH_INIT_SIZE, dsize); +- RCU_INIT_POINTER(hbucket(t, key), m); +- } else if (m->pos >= m->size) { +- struct hbucket *ht; +- +- if (m->size >= AHASH_MAX(h)) { +- ret = -EAGAIN; +- } else { +- ht = kzalloc(sizeof(*ht) + ++ if (!m) { ++ ret = -ENOMEM; ++ goto cleanup; ++ } ++ m->size = AHASH_INIT_SIZE; ++ t->hregion[nr].ext_size += ++ ext_size(AHASH_INIT_SIZE, ++ dsize); ++ RCU_INIT_POINTER(hbucket(t, key), m); ++ } else if (m->pos >= m->size) { ++ struct hbucket *ht; ++ ++ if (m->size >= AHASH_MAX(h)) { ++ ret = -EAGAIN; ++ } else { ++ ht = kzalloc(sizeof(*ht) + + (m->size + AHASH_INIT_SIZE) + * dsize, + GFP_ATOMIC); +- if (!ht) +- ret = -ENOMEM; ++ if (!ht) ++ ret = -ENOMEM; ++ } ++ if (ret < 0) ++ goto cleanup; ++ memcpy(ht, m, sizeof(struct hbucket) + ++ m->size * dsize); ++ ht->size = m->size + AHASH_INIT_SIZE; ++ t->hregion[nr].ext_size += ++ ext_size(AHASH_INIT_SIZE, ++ dsize); ++ kfree(m); ++ m = ht; ++ RCU_INIT_POINTER(hbucket(t, key), ht); + } +- if (ret < 0) +- goto cleanup; +- memcpy(ht, m, sizeof(struct hbucket) + +- m->size * dsize); +- ht->size = m->size + AHASH_INIT_SIZE; +- extsize += ext_size(AHASH_INIT_SIZE, dsize); +- kfree(m); +- m = ht; +- RCU_INIT_POINTER(hbucket(t, key), ht); +- } +- d = ahash_data(m, m->pos, dsize); +- memcpy(d, data, dsize); +- set_bit(m->pos++, m->used); ++ d = ahash_data(m, m->pos, dsize); ++ memcpy(d, data, dsize); ++ set_bit(m->pos++, m->used); ++ t->hregion[nr].elements++; + #ifdef IP_SET_HASH_WITH_NETS +- mtype_data_reset_flags(d, &flags); ++ mtype_data_reset_flags(d, &flags); + #endif ++ } + } ++ rcu_read_unlock_bh(); + } +- rcu_assign_pointer(h->table, t); +- set->ext_size = extsize; + +- spin_unlock_bh(&set->lock); ++ /* There can't be any other writer. */ ++ rcu_assign_pointer(h->table, t); + + /* Give time to other readers of the set */ + synchronize_rcu(); + + pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name, + orig->htable_bits, orig, t->htable_bits, t); +- /* If there's nobody else dumping the table, destroy it */ ++ /* Add/delete elements processed by the SET target during resize. ++ * Kernel-side add cannot trigger a resize and userspace actions ++ * are serialized by the mutex. ++ */ ++ list_for_each_safe(l, lt, &h->ad) { ++ x = list_entry(l, struct mtype_resize_ad, list); ++ if (x->ad == IPSET_ADD) { ++ mtype_add(set, &x->d, &x->ext, &x->mext, x->flags); ++ } else { ++ mtype_del(set, &x->d, NULL, NULL, 0); ++ } ++ list_del(l); ++ kfree(l); ++ } ++ /* If there's nobody else using the table, destroy it */ + if (atomic_dec_and_test(&orig->uref)) { + pr_debug("Table destroy by resize %p\n", orig); + mtype_ahash_destroy(set, orig, false); +@@ -677,15 +810,44 @@ out: + return ret; + + cleanup: ++ rcu_read_unlock_bh(); + atomic_set(&orig->ref, 0); + atomic_dec(&orig->uref); +- spin_unlock_bh(&set->lock); + mtype_ahash_destroy(set, t, false); + if (ret == -EAGAIN) + goto retry; + goto out; + } + ++/* Get the current number of elements and ext_size in the set */ ++static void ++mtype_ext_size(struct ip_set *set, u32 *elements, size_t *ext_size) ++{ ++ struct htype *h = set->data; ++ const struct htable *t; ++ u32 i, j, r; ++ struct hbucket *n; ++ struct mtype_elem *data; ++ ++ t = rcu_dereference_bh(h->table); ++ for (r = 0; r < ahash_numof_locks(t->htable_bits); r++) { ++ for (i = ahash_bucket_start(r, t->htable_bits); ++ i < ahash_bucket_end(r, t->htable_bits); i++) { ++ n = rcu_dereference_bh(hbucket(t, i)); ++ if (!n) ++ continue; ++ for (j = 0; j < n->pos; j++) { ++ if (!test_bit(j, n->used)) ++ continue; ++ data = ahash_data(n, j, set->dsize); ++ if (!SET_ELEM_EXPIRED(set, data)) ++ (*elements)++; ++ } ++ } ++ *ext_size += t->hregion[r].ext_size; ++ } ++} ++ + /* Add an element to a hash and update the internal counters when succeeded, + * otherwise report the proper error code. + */ +@@ -698,32 +860,49 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + const struct mtype_elem *d = value; + struct mtype_elem *data; + struct hbucket *n, *old = ERR_PTR(-ENOENT); +- int i, j = -1; ++ int i, j = -1, ret; + bool flag_exist = flags & IPSET_FLAG_EXIST; + bool deleted = false, forceadd = false, reuse = false; +- u32 key, multi = 0; ++ u32 r, key, multi = 0, elements, maxelem; + +- if (set->elements >= h->maxelem) { +- if (SET_WITH_TIMEOUT(set)) +- /* FIXME: when set is full, we slow down here */ +- mtype_expire(set, h); +- if (set->elements >= h->maxelem && SET_WITH_FORCEADD(set)) ++ rcu_read_lock_bh(); ++ t = rcu_dereference_bh(h->table); ++ key = HKEY(value, h->initval, t->htable_bits); ++ r = ahash_region(key, t->htable_bits); ++ atomic_inc(&t->uref); ++ elements = t->hregion[r].elements; ++ maxelem = t->maxelem; ++ if (elements >= maxelem) { ++ u32 e; ++ if (SET_WITH_TIMEOUT(set)) { ++ rcu_read_unlock_bh(); ++ mtype_gc_do(set, h, t, r); ++ rcu_read_lock_bh(); ++ } ++ maxelem = h->maxelem; ++ elements = 0; ++ for (e = 0; e < ahash_numof_locks(t->htable_bits); e++) ++ elements += t->hregion[e].elements; ++ if (elements >= maxelem && SET_WITH_FORCEADD(set)) + forceadd = true; + } ++ rcu_read_unlock_bh(); + +- t = ipset_dereference_protected(h->table, set); +- key = HKEY(value, h->initval, t->htable_bits); +- n = __ipset_dereference_protected(hbucket(t, key), 1); ++ spin_lock_bh(&t->hregion[r].lock); ++ n = rcu_dereference_bh(hbucket(t, key)); + if (!n) { +- if (forceadd || set->elements >= h->maxelem) ++ if (forceadd || elements >= maxelem) + goto set_full; + old = NULL; + n = kzalloc(sizeof(*n) + AHASH_INIT_SIZE * set->dsize, + GFP_ATOMIC); +- if (!n) +- return -ENOMEM; ++ if (!n) { ++ ret = -ENOMEM; ++ goto unlock; ++ } + n->size = AHASH_INIT_SIZE; +- set->ext_size += ext_size(AHASH_INIT_SIZE, set->dsize); ++ t->hregion[r].ext_size += ++ ext_size(AHASH_INIT_SIZE, set->dsize); + goto copy_elem; + } + for (i = 0; i < n->pos; i++) { +@@ -737,38 +916,37 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + } + data = ahash_data(n, i, set->dsize); + if (mtype_data_equal(data, d, &multi)) { +- if (flag_exist || +- (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(data, set)))) { ++ if (flag_exist || SET_ELEM_EXPIRED(set, data)) { + /* Just the extensions could be overwritten */ + j = i; + goto overwrite_extensions; + } +- return -IPSET_ERR_EXIST; ++ ret = -IPSET_ERR_EXIST; ++ goto unlock; + } + /* Reuse first timed out entry */ +- if (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(data, set)) && +- j == -1) { ++ if (SET_ELEM_EXPIRED(set, data) && j == -1) { + j = i; + reuse = true; + } + } + if (reuse || forceadd) { ++ if (j == -1) ++ j = 0; + data = ahash_data(n, j, set->dsize); + if (!deleted) { + #ifdef IP_SET_HASH_WITH_NETS + for (i = 0; i < IPSET_NET_COUNT; i++) +- mtype_del_cidr(h, ++ mtype_del_cidr(set, h, + NCIDR_PUT(DCIDR_GET(data->cidr, i)), + i); + #endif + ip_set_ext_destroy(set, data); +- set->elements--; ++ t->hregion[r].elements--; + } + goto copy_data; + } +- if (set->elements >= h->maxelem) ++ if (elements >= maxelem) + goto set_full; + /* Create a new slot */ + if (n->pos >= n->size) { +@@ -776,28 +954,32 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + if (n->size >= AHASH_MAX(h)) { + /* Trigger rehashing */ + mtype_data_next(&h->next, d); +- return -EAGAIN; ++ ret = -EAGAIN; ++ goto resize; + } + old = n; + n = kzalloc(sizeof(*n) + + (old->size + AHASH_INIT_SIZE) * set->dsize, + GFP_ATOMIC); +- if (!n) +- return -ENOMEM; ++ if (!n) { ++ ret = -ENOMEM; ++ goto unlock; ++ } + memcpy(n, old, sizeof(struct hbucket) + + old->size * set->dsize); + n->size = old->size + AHASH_INIT_SIZE; +- set->ext_size += ext_size(AHASH_INIT_SIZE, set->dsize); ++ t->hregion[r].ext_size += ++ ext_size(AHASH_INIT_SIZE, set->dsize); + } + + copy_elem: + j = n->pos++; + data = ahash_data(n, j, set->dsize); + copy_data: +- set->elements++; ++ t->hregion[r].elements++; + #ifdef IP_SET_HASH_WITH_NETS + for (i = 0; i < IPSET_NET_COUNT; i++) +- mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)), i); ++ mtype_add_cidr(set, h, NCIDR_PUT(DCIDR_GET(d->cidr, i)), i); + #endif + memcpy(data, d, sizeof(struct mtype_elem)); + overwrite_extensions: +@@ -820,13 +1002,41 @@ overwrite_extensions: + if (old) + kfree_rcu(old, rcu); + } ++ ret = 0; ++resize: ++ spin_unlock_bh(&t->hregion[r].lock); ++ if (atomic_read(&t->ref) && ext->target) { ++ /* Resize is in process and kernel side add, save values */ ++ struct mtype_resize_ad *x; ++ ++ x = kzalloc(sizeof(struct mtype_resize_ad), GFP_ATOMIC); ++ if (!x) ++ /* Don't bother */ ++ goto out; ++ x->ad = IPSET_ADD; ++ memcpy(&x->d, value, sizeof(struct mtype_elem)); ++ memcpy(&x->ext, ext, sizeof(struct ip_set_ext)); ++ memcpy(&x->mext, mext, sizeof(struct ip_set_ext)); ++ x->flags = flags; ++ spin_lock_bh(&set->lock); ++ list_add_tail(&x->list, &h->ad); ++ spin_unlock_bh(&set->lock); ++ } ++ goto out; + +- return 0; + set_full: + if (net_ratelimit()) + pr_warn("Set %s is full, maxelem %u reached\n", +- set->name, h->maxelem); +- return -IPSET_ERR_HASH_FULL; ++ set->name, maxelem); ++ ret = -IPSET_ERR_HASH_FULL; ++unlock: ++ spin_unlock_bh(&t->hregion[r].lock); ++out: ++ if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { ++ pr_debug("Table destroy after resize by add: %p\n", t); ++ mtype_ahash_destroy(set, t, false); ++ } ++ return ret; + } + + /* Delete an element from the hash and free up space if possible. +@@ -840,13 +1050,23 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + const struct mtype_elem *d = value; + struct mtype_elem *data; + struct hbucket *n; +- int i, j, k, ret = -IPSET_ERR_EXIST; ++ struct mtype_resize_ad *x = NULL; ++ int i, j, k, r, ret = -IPSET_ERR_EXIST; + u32 key, multi = 0; + size_t dsize = set->dsize; + +- t = ipset_dereference_protected(h->table, set); ++ /* Userspace add and resize is excluded by the mutex. ++ * Kernespace add does not trigger resize. ++ */ ++ rcu_read_lock_bh(); ++ t = rcu_dereference_bh(h->table); + key = HKEY(value, h->initval, t->htable_bits); +- n = __ipset_dereference_protected(hbucket(t, key), 1); ++ r = ahash_region(key, t->htable_bits); ++ atomic_inc(&t->uref); ++ rcu_read_unlock_bh(); ++ ++ spin_lock_bh(&t->hregion[r].lock); ++ n = rcu_dereference_bh(hbucket(t, key)); + if (!n) + goto out; + for (i = 0, k = 0; i < n->pos; i++) { +@@ -857,8 +1077,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + data = ahash_data(n, i, dsize); + if (!mtype_data_equal(data, d, &multi)) + continue; +- if (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(data, set))) ++ if (SET_ELEM_EXPIRED(set, data)) + goto out; + + ret = 0; +@@ -866,20 +1085,33 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + smp_mb__after_atomic(); + if (i + 1 == n->pos) + n->pos--; +- set->elements--; ++ t->hregion[r].elements--; + #ifdef IP_SET_HASH_WITH_NETS + for (j = 0; j < IPSET_NET_COUNT; j++) +- mtype_del_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, j)), +- j); ++ mtype_del_cidr(set, h, ++ NCIDR_PUT(DCIDR_GET(d->cidr, j)), j); + #endif + ip_set_ext_destroy(set, data); + ++ if (atomic_read(&t->ref) && ext->target) { ++ /* Resize is in process and kernel side del, ++ * save values ++ */ ++ x = kzalloc(sizeof(struct mtype_resize_ad), ++ GFP_ATOMIC); ++ if (x) { ++ x->ad = IPSET_DEL; ++ memcpy(&x->d, value, ++ sizeof(struct mtype_elem)); ++ x->flags = flags; ++ } ++ } + for (; i < n->pos; i++) { + if (!test_bit(i, n->used)) + k++; + } + if (n->pos == 0 && k == 0) { +- set->ext_size -= ext_size(n->size, dsize); ++ t->hregion[r].ext_size -= ext_size(n->size, dsize); + rcu_assign_pointer(hbucket(t, key), NULL); + kfree_rcu(n, rcu); + } else if (k >= AHASH_INIT_SIZE) { +@@ -898,7 +1130,8 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + k++; + } + tmp->pos = k; +- set->ext_size -= ext_size(AHASH_INIT_SIZE, dsize); ++ t->hregion[r].ext_size -= ++ ext_size(AHASH_INIT_SIZE, dsize); + rcu_assign_pointer(hbucket(t, key), tmp); + kfree_rcu(n, rcu); + } +@@ -906,6 +1139,16 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + } + + out: ++ spin_unlock_bh(&t->hregion[r].lock); ++ if (x) { ++ spin_lock_bh(&set->lock); ++ list_add(&x->list, &h->ad); ++ spin_unlock_bh(&set->lock); ++ } ++ if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { ++ pr_debug("Table destroy after resize by del: %p\n", t); ++ mtype_ahash_destroy(set, t, false); ++ } + return ret; + } + +@@ -991,6 +1234,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, + int i, ret = 0; + u32 key, multi = 0; + ++ rcu_read_lock_bh(); + t = rcu_dereference_bh(h->table); + #ifdef IP_SET_HASH_WITH_NETS + /* If we test an IP address and not a network address, +@@ -1022,6 +1266,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, + goto out; + } + out: ++ rcu_read_unlock_bh(); + return ret; + } + +@@ -1033,23 +1278,14 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) + const struct htable *t; + struct nlattr *nested; + size_t memsize; ++ u32 elements = 0; ++ size_t ext_size = 0; + u8 htable_bits; + +- /* If any members have expired, set->elements will be wrong +- * mytype_expire function will update it with the right count. +- * we do not hold set->lock here, so grab it first. +- * set->elements can still be incorrect in the case of a huge set, +- * because elements might time out during the listing. +- */ +- if (SET_WITH_TIMEOUT(set)) { +- spin_lock_bh(&set->lock); +- mtype_expire(set, h); +- spin_unlock_bh(&set->lock); +- } +- + rcu_read_lock_bh(); +- t = rcu_dereference_bh_nfnl(h->table); +- memsize = mtype_ahash_memsize(h, t) + set->ext_size; ++ t = rcu_dereference_bh(h->table); ++ mtype_ext_size(set, &elements, &ext_size); ++ memsize = mtype_ahash_memsize(h, t) + ext_size + set->ext_size; + htable_bits = t->htable_bits; + rcu_read_unlock_bh(); + +@@ -1071,7 +1307,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) + #endif + if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || + nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) || +- nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(set->elements))) ++ nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(elements))) + goto nla_put_failure; + if (unlikely(ip_set_put_flags(skb, set))) + goto nla_put_failure; +@@ -1091,15 +1327,15 @@ mtype_uref(struct ip_set *set, struct netlink_callback *cb, bool start) + + if (start) { + rcu_read_lock_bh(); +- t = rcu_dereference_bh_nfnl(h->table); ++ t = ipset_dereference_bh_nfnl(h->table); + atomic_inc(&t->uref); + cb->args[IPSET_CB_PRIVATE] = (unsigned long)t; + rcu_read_unlock_bh(); + } else if (cb->args[IPSET_CB_PRIVATE]) { + t = (struct htable *)cb->args[IPSET_CB_PRIVATE]; + if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { +- /* Resizing didn't destroy the hash table */ +- pr_debug("Table destroy by dump: %p\n", t); ++ pr_debug("Table destroy after resize " ++ " by dump: %p\n", t); + mtype_ahash_destroy(set, t, false); + } + cb->args[IPSET_CB_PRIVATE] = 0; +@@ -1141,8 +1377,7 @@ mtype_list(const struct ip_set *set, + if (!test_bit(i, n->used)) + continue; + e = ahash_data(n, i, set->dsize); +- if (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(e, set))) ++ if (SET_ELEM_EXPIRED(set, e)) + continue; + pr_debug("list hash %lu hbucket %p i %u, data %p\n", + cb->args[IPSET_CB_ARG0], n, i, e); +@@ -1208,6 +1443,7 @@ static const struct ip_set_type_variant mtype_variant = { + .uref = mtype_uref, + .resize = mtype_resize, + .same_set = mtype_same_set, ++ .region_lock = true, + }; + + #ifdef IP_SET_EMIT_CREATE +@@ -1226,6 +1462,7 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + size_t hsize; + struct htype *h; + struct htable *t; ++ u32 i; + + pr_debug("Create set %s with family %s\n", + set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6"); +@@ -1294,6 +1531,15 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + kfree(h); + return -ENOMEM; + } ++ t->hregion = ip_set_alloc(ahash_sizeof_regions(hbits)); ++ if (!t->hregion) { ++ kfree(t); ++ kfree(h); ++ return -ENOMEM; ++ } ++ h->gc.set = set; ++ for (i = 0; i < ahash_numof_locks(hbits); i++) ++ spin_lock_init(&t->hregion[i].lock); + h->maxelem = maxelem; + #ifdef IP_SET_HASH_WITH_NETMASK + h->netmask = netmask; +@@ -1304,9 +1550,10 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + get_random_bytes(&h->initval, sizeof(h->initval)); + + t->htable_bits = hbits; ++ t->maxelem = h->maxelem / ahash_numof_locks(hbits); + RCU_INIT_POINTER(h->table, t); + +- h->set = set; ++ INIT_LIST_HEAD(&h->ad); + set->data = h; + #ifndef IP_SET_PROTO_UNDEF + if (set->family == NFPROTO_IPV4) { +@@ -1329,12 +1576,10 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + #ifndef IP_SET_PROTO_UNDEF + if (set->family == NFPROTO_IPV4) + #endif +- IPSET_TOKEN(HTYPE, 4_gc_init)(set, +- IPSET_TOKEN(HTYPE, 4_gc)); ++ IPSET_TOKEN(HTYPE, 4_gc_init)(&h->gc); + #ifndef IP_SET_PROTO_UNDEF + else +- IPSET_TOKEN(HTYPE, 6_gc_init)(set, +- IPSET_TOKEN(HTYPE, 6_gc)); ++ IPSET_TOKEN(HTYPE, 6_gc_init)(&h->gc); + #endif + } + pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", +diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c +index f8d2919cf9fd..037e8fce9b30 100644 +--- a/net/netfilter/nft_tunnel.c ++++ b/net/netfilter/nft_tunnel.c +@@ -505,8 +505,8 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb, + static int nft_tunnel_ports_dump(struct sk_buff *skb, + struct ip_tunnel_info *info) + { +- if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, htons(info->key.tp_src)) < 0 || +- nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, htons(info->key.tp_dst)) < 0) ++ if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, info->key.tp_src) < 0 || ++ nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, info->key.tp_dst) < 0) + return -1; + + return 0; +diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c +index 6520d9ec1297..1b68a131083c 100644 +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -36,6 +36,7 @@ + #include <linux/netfilter_ipv6/ip6_tables.h> + #include <linux/mutex.h> + #include <linux/kernel.h> ++#include <linux/refcount.h> + #include <uapi/linux/netfilter/xt_hashlimit.h> + + #define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ +@@ -114,7 +115,7 @@ struct dsthash_ent { + + struct xt_hashlimit_htable { + struct hlist_node node; /* global list of all htables */ +- int use; ++ refcount_t use; + u_int8_t family; + bool rnd_initialized; + +@@ -315,7 +316,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, + for (i = 0; i < hinfo->cfg.size; i++) + INIT_HLIST_HEAD(&hinfo->hash[i]); + +- hinfo->use = 1; ++ refcount_set(&hinfo->use, 1); + hinfo->count = 0; + hinfo->family = family; + hinfo->rnd_initialized = false; +@@ -434,7 +435,7 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net, + hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) { + if (!strcmp(name, hinfo->name) && + hinfo->family == family) { +- hinfo->use++; ++ refcount_inc(&hinfo->use); + return hinfo; + } + } +@@ -443,12 +444,11 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net, + + static void htable_put(struct xt_hashlimit_htable *hinfo) + { +- mutex_lock(&hashlimit_mutex); +- if (--hinfo->use == 0) { ++ if (refcount_dec_and_mutex_lock(&hinfo->use, &hashlimit_mutex)) { + hlist_del(&hinfo->node); ++ mutex_unlock(&hashlimit_mutex); + htable_destroy(hinfo); + } +- mutex_unlock(&hashlimit_mutex); + } + + /* The algorithm used is the Simple Token Bucket Filter (TBF) +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 4e31721e7293..edf3e285e242 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1014,7 +1014,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, + if (nlk->netlink_bind && groups) { + int group; + +- for (group = 0; group < nlk->ngroups; group++) { ++ /* nl_groups is a u32, so cap the maximum groups we can bind */ ++ for (group = 0; group < BITS_PER_TYPE(u32); group++) { + if (!test_bit(group, &groups)) + continue; + err = nlk->netlink_bind(net, group + 1); +@@ -1033,7 +1034,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, + netlink_insert(sk, nladdr->nl_pid) : + netlink_autobind(sock); + if (err) { +- netlink_undo_bind(nlk->ngroups, groups, sk); ++ netlink_undo_bind(BITS_PER_TYPE(u32), groups, sk); + goto unlock; + } + } +diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c +index 7e54d2ab5254..d32d4233d337 100644 +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -305,6 +305,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, + struct cls_fl_filter *f; + + list_for_each_entry_rcu(mask, &head->masks, list) { ++ flow_dissector_init_keys(&skb_key.control, &skb_key.basic); + fl_clear_masked_range(&skb_key, mask); + + skb_flow_dissect_meta(skb, &mask->dissector, &skb_key); +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 4ab8208a2dd4..c6d83a64eac3 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -170,6 +170,16 @@ static inline bool sctp_chunk_length_valid(struct sctp_chunk *chunk, + return true; + } + ++/* Check for format error in an ABORT chunk */ ++static inline bool sctp_err_chunk_valid(struct sctp_chunk *chunk) ++{ ++ struct sctp_errhdr *err; ++ ++ sctp_walk_errors(err, chunk->chunk_hdr); ++ ++ return (void *)err == (void *)chunk->chunk_end; ++} ++ + /********************************************************** + * These are the state functions for handling chunk events. + **********************************************************/ +@@ -2255,6 +2265,9 @@ enum sctp_disposition sctp_sf_shutdown_pending_abort( + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); + } + +@@ -2298,6 +2311,9 @@ enum sctp_disposition sctp_sf_shutdown_sent_abort( + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + /* Stop the T2-shutdown timer. */ + sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, + SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); +@@ -2565,6 +2581,9 @@ enum sctp_disposition sctp_sf_do_9_1_abort( + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); + } + +@@ -2582,16 +2601,8 @@ static enum sctp_disposition __sctp_sf_do_9_1_abort( + + /* See if we have an error cause code in the chunk. */ + len = ntohs(chunk->chunk_hdr->length); +- if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) { +- struct sctp_errhdr *err; +- +- sctp_walk_errors(err, chunk->chunk_hdr); +- if ((void *)err != (void *)chunk->chunk_end) +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, +- commands); +- ++ if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) + error = ((struct sctp_errhdr *)chunk->skb->data)->cause; +- } + + sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); + /* ASSOC_FAILED will DELETE_TCB. */ +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index cee5bf4a9bb9..90988a511cd5 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -470,6 +470,8 @@ static void smc_switch_to_fallback(struct smc_sock *smc) + if (smc->sk.sk_socket && smc->sk.sk_socket->file) { + smc->clcsock->file = smc->sk.sk_socket->file; + smc->clcsock->file->private_data = smc->clcsock; ++ smc->clcsock->wq.fasync_list = ++ smc->sk.sk_socket->wq.fasync_list; + } + } + +diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c +index 0879f7bed967..86cccc24e52e 100644 +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -372,7 +372,9 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info) + dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline)); + dclc.hdr.version = SMC_CLC_V1; + dclc.hdr.flag = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ? 1 : 0; +- memcpy(dclc.id_for_peer, local_systemid, sizeof(local_systemid)); ++ if (smc->conn.lgr && !smc->conn.lgr->is_smcd) ++ memcpy(dclc.id_for_peer, local_systemid, ++ sizeof(local_systemid)); + dclc.peer_diagnosis = htonl(peer_diag_info); + memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); + +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index f9b4fb92c0b1..693e8902161e 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -2441,6 +2441,8 @@ static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) + return -ETIMEDOUT; + if (signal_pending(current)) + return sock_intr_errno(*timeo_p); ++ if (sk->sk_state == TIPC_DISCONNECTING) ++ break; + + add_wait_queue(sk_sleep(sk), &wait); + done = sk_wait_event(sk, timeo_p, tipc_sk_connected(sk), +diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c +index cd91ad812291..e72d7d787935 100644 +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -592,7 +592,7 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, + u32 seq, u64 *p_record_sn) + { + u64 record_sn = context->hint_record_sn; +- struct tls_record_info *info; ++ struct tls_record_info *info, *last; + + info = context->retransmit_hint; + if (!info || +@@ -604,6 +604,24 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, + struct tls_record_info, list); + if (!info) + return NULL; ++ /* send the start_marker record if seq number is before the ++ * tls offload start marker sequence number. This record is ++ * required to handle TCP packets which are before TLS offload ++ * started. ++ * And if it's not start marker, look if this seq number ++ * belongs to the list. ++ */ ++ if (likely(!tls_record_is_start_marker(info))) { ++ /* we have the first record, get the last record to see ++ * if this seq number belongs to the list. ++ */ ++ last = list_last_entry(&context->records_list, ++ struct tls_record_info, list); ++ ++ if (!between(seq, tls_record_start_seq(info), ++ last->end_seq)) ++ return NULL; ++ } + record_sn = context->unacked_record_sn; + } + +diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c +index a9c0f368db5d..24e18405cdb4 100644 +--- a/net/wireless/ethtool.c ++++ b/net/wireless/ethtool.c +@@ -7,9 +7,13 @@ + void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct wireless_dev *wdev = dev->ieee80211_ptr; ++ struct device *pdev = wiphy_dev(wdev->wiphy); + +- strlcpy(info->driver, wiphy_dev(wdev->wiphy)->driver->name, +- sizeof(info->driver)); ++ if (pdev->driver) ++ strlcpy(info->driver, pdev->driver->name, ++ sizeof(info->driver)); ++ else ++ strlcpy(info->driver, "N/A", sizeof(info->driver)); + + strlcpy(info->version, init_utsname()->release, sizeof(info->version)); + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 1e97ac5435b2..114397d737b3 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -437,6 +437,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, + [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG }, + [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 }, + [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, + [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, + [NL80211_ATTR_PID] = { .type = NLA_U32 }, +@@ -4799,8 +4800,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + err = nl80211_parse_he_obss_pd( + info->attrs[NL80211_ATTR_HE_OBSS_PD], + ¶ms.he_obss_pd); +- if (err) +- return err; ++ goto out; + } + + nl80211_calculate_ap_params(¶ms); +@@ -4822,6 +4822,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + } + wdev_unlock(wdev); + ++out: + kfree(params.acl); + + return err; +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 3fa32f83b2d7..a66fc0acad1e 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -291,13 +291,13 @@ DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.yaml + quiet_cmd_dtb_check = CHECK $@ + cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ ; + +-define rule_dtc_dt_yaml ++define rule_dtc + $(call cmd_and_fixdep,dtc,yaml) + $(call cmd,dtb_check) + endef + + $(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE +- $(call if_changed_rule,dtc_dt_yaml) ++ $(call if_changed_rule,dtc) + + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index ef8dfd47c7e3..0cac399ce713 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -263,7 +263,7 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry) + static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + { + struct ima_rule_entry *nentry; +- int i, result; ++ int i; + + nentry = kmalloc(sizeof(*nentry), GFP_KERNEL); + if (!nentry) +@@ -277,7 +277,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + memset(nentry->lsm, 0, sizeof_field(struct ima_rule_entry, lsm)); + + for (i = 0; i < MAX_LSM_RULES; i++) { +- if (!entry->lsm[i].rule) ++ if (!entry->lsm[i].args_p) + continue; + + nentry->lsm[i].type = entry->lsm[i].type; +@@ -286,13 +286,13 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + if (!nentry->lsm[i].args_p) + goto out_err; + +- result = security_filter_rule_init(nentry->lsm[i].type, +- Audit_equal, +- nentry->lsm[i].args_p, +- &nentry->lsm[i].rule); +- if (result == -EINVAL) +- pr_warn("ima: rule for LSM \'%d\' is undefined\n", +- entry->lsm[i].type); ++ security_filter_rule_init(nentry->lsm[i].type, ++ Audit_equal, ++ nentry->lsm[i].args_p, ++ &nentry->lsm[i].rule); ++ if (!nentry->lsm[i].rule) ++ pr_warn("rule for LSM \'%s\' is undefined\n", ++ (char *)entry->lsm[i].args_p); + } + return nentry; + +@@ -329,7 +329,7 @@ static void ima_lsm_update_rules(void) + list_for_each_entry_safe(entry, e, &ima_policy_rules, list) { + needs_update = 0; + for (i = 0; i < MAX_LSM_RULES; i++) { +- if (entry->lsm[i].rule) { ++ if (entry->lsm[i].args_p) { + needs_update = 1; + break; + } +@@ -339,8 +339,7 @@ static void ima_lsm_update_rules(void) + + result = ima_lsm_update_rule(entry); + if (result) { +- pr_err("ima: lsm rule update error %d\n", +- result); ++ pr_err("lsm rule update error %d\n", result); + return; + } + } +@@ -357,7 +356,7 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, + } + + /** +- * ima_match_rules - determine whether an inode matches the measure rule. ++ * ima_match_rules - determine whether an inode matches the policy rule. + * @rule: a pointer to a rule + * @inode: a pointer to an inode + * @cred: a pointer to a credentials structure for user validation +@@ -415,9 +414,12 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, + int rc = 0; + u32 osid; + +- if (!rule->lsm[i].rule) +- continue; +- ++ if (!rule->lsm[i].rule) { ++ if (!rule->lsm[i].args_p) ++ continue; ++ else ++ return false; ++ } + switch (i) { + case LSM_OBJ_USER: + case LSM_OBJ_ROLE: +@@ -823,8 +825,14 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, + entry->lsm[lsm_rule].args_p, + &entry->lsm[lsm_rule].rule); + if (!entry->lsm[lsm_rule].rule) { +- kfree(entry->lsm[lsm_rule].args_p); +- return -EINVAL; ++ pr_warn("rule for LSM \'%s\' is undefined\n", ++ (char *)entry->lsm[lsm_rule].args_p); ++ ++ if (ima_rules == &ima_default_rules) { ++ kfree(entry->lsm[lsm_rule].args_p); ++ result = -EINVAL; ++ } else ++ result = 0; + } + + return result; +diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c +index de988589d99b..66cd97cc8b92 100644 +--- a/tools/perf/builtin-report.c ++++ b/tools/perf/builtin-report.c +@@ -412,10 +412,10 @@ static int report__setup_sample_type(struct report *rep) + PERF_SAMPLE_BRANCH_ANY)) + rep->nonany_branch_mode = true; + +-#ifndef HAVE_LIBUNWIND_SUPPORT ++#if !defined(HAVE_LIBUNWIND_SUPPORT) && !defined(HAVE_DWARF_SUPPORT) + if (dwarf_callchain_users) { +- ui__warning("Please install libunwind development packages " +- "during the perf build.\n"); ++ ui__warning("Please install libunwind or libdw " ++ "development packages during the perf build.\n"); + } + #endif + +diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c +index d4d3558fdef4..cfc6172ecab7 100644 +--- a/tools/perf/ui/browsers/hists.c ++++ b/tools/perf/ui/browsers/hists.c +@@ -3062,6 +3062,7 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, + + continue; + } ++ actions->ms.map = map; + top = pstack__peek(browser->pstack); + if (top == &browser->hists->dso_filter) { + /* +diff --git a/tools/perf/ui/gtk/Build b/tools/perf/ui/gtk/Build +index ec22e899a224..9b5d5cbb7af7 100644 +--- a/tools/perf/ui/gtk/Build ++++ b/tools/perf/ui/gtk/Build +@@ -7,3 +7,8 @@ gtk-y += util.o + gtk-y += helpline.o + gtk-y += progress.o + gtk-y += annotate.o ++gtk-y += zalloc.o ++ ++$(OUTPUT)ui/gtk/zalloc.o: ../lib/zalloc.c FORCE ++ $(call rule_mkdir) ++ $(call if_changed_dep,cc_o_c) +diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c +index fdd5bddb3075..f67960bedebb 100644 +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -549,6 +549,7 @@ void maps__insert(struct maps *maps, struct map *map) + + if (maps_by_name == NULL) { + __maps__free_maps_by_name(maps); ++ up_write(&maps->lock); + return; + } + +diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile +index cd1f5b3a7774..d6e106fbce11 100644 +--- a/tools/testing/selftests/ftrace/Makefile ++++ b/tools/testing/selftests/ftrace/Makefile +@@ -2,7 +2,7 @@ + all: + + TEST_PROGS := ftracetest +-TEST_FILES := test.d ++TEST_FILES := test.d settings + EXTRA_CLEAN := $(OUTPUT)/logs/* + + include ../lib.mk +diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile +index 3876d8d62494..1acc9e1fa3fb 100644 +--- a/tools/testing/selftests/livepatch/Makefile ++++ b/tools/testing/selftests/livepatch/Makefile +@@ -8,4 +8,6 @@ TEST_PROGS := \ + test-state.sh \ + test-ftrace.sh + ++TEST_FILES := settings ++ + include ../lib.mk +diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh +index 6dd403103800..60273f1bc7d9 100755 +--- a/tools/testing/selftests/net/fib_tests.sh ++++ b/tools/testing/selftests/net/fib_tests.sh +@@ -910,6 +910,12 @@ ipv6_rt_replace_mpath() + check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" + log_test $? 0 "Multipath with single path via multipath attribute" + ++ # multipath with dev-only ++ add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" ++ run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" ++ check_route6 "2001:db8:104::/64 dev veth1 metric 1024" ++ log_test $? 0 "Multipath with dev-only" ++ + # route replace fails - invalid nexthop 1 + add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" + run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" +diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile +index d6469535630a..f1053630bb6f 100644 +--- a/tools/testing/selftests/rseq/Makefile ++++ b/tools/testing/selftests/rseq/Makefile +@@ -19,6 +19,8 @@ TEST_GEN_PROGS_EXTENDED = librseq.so + + TEST_PROGS = run_param_test.sh + ++TEST_FILES := settings ++ + include ../lib.mk + + $(OUTPUT)/librseq.so: rseq.c rseq.h rseq-*.h +diff --git a/tools/testing/selftests/rtc/Makefile b/tools/testing/selftests/rtc/Makefile +index de9c8566672a..90fa1a346908 100644 +--- a/tools/testing/selftests/rtc/Makefile ++++ b/tools/testing/selftests/rtc/Makefile +@@ -6,4 +6,6 @@ TEST_GEN_PROGS = rtctest + + TEST_GEN_PROGS_EXTENDED = setdate + ++TEST_FILES := settings ++ + include ../lib.mk +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 2b3f36df3d85..75b7ee1af1c3 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -2287,12 +2287,12 @@ int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + if (slots->generation != ghc->generation) + __kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len); + +- if (unlikely(!ghc->memslot)) +- return kvm_write_guest(kvm, gpa, data, len); +- + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; + ++ if (unlikely(!ghc->memslot)) ++ return kvm_write_guest(kvm, gpa, data, len); ++ + r = __copy_to_user((void __user *)ghc->hva + offset, data, len); + if (r) + return -EFAULT; +@@ -2320,12 +2320,12 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + if (slots->generation != ghc->generation) + __kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len); + +- if (unlikely(!ghc->memslot)) +- return kvm_read_guest(kvm, ghc->gpa, data, len); +- + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; + ++ if (unlikely(!ghc->memslot)) ++ return kvm_read_guest(kvm, ghc->gpa, data, len); ++ + r = __copy_from_user(data, (void __user *)ghc->hva, len); + if (r) + return -EFAULT; |