diff options
author | 2017-03-22 12:55:18 -0400 | |
---|---|---|
committer | 2017-03-22 12:55:18 -0400 | |
commit | 81829230c28d23865ae8b0139826128a718c7017 (patch) | |
tree | 756f5ccb0f1363a1022c76bcda5b2498ef22ba0d | |
parent | Linux patch 4.10.4 (diff) | |
download | linux-patches-81829230c28d23865ae8b0139826128a718c7017.tar.gz linux-patches-81829230c28d23865ae8b0139826128a718c7017.tar.bz2 linux-patches-81829230c28d23865ae8b0139826128a718c7017.zip |
Linux patch 4.10.54.10-6
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1004_linux-4.10.5.patch | 2238 |
2 files changed, 2242 insertions, 0 deletions
diff --git a/0000_README b/0000_README index a80feb87..464eea37 100644 --- a/0000_README +++ b/0000_README @@ -59,6 +59,10 @@ Patch: 1003_linux-4.10.4.patch From: http://www.kernel.org Desc: Linux 4.10.4 +Patch: 1004_linux-4.10.5.patch +From: http://www.kernel.org +Desc: Linux 4.10.5 + 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/1004_linux-4.10.5.patch b/1004_linux-4.10.5.patch new file mode 100644 index 00000000..0772bdca --- /dev/null +++ b/1004_linux-4.10.5.patch @@ -0,0 +1,2238 @@ +diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt +index 405da11fc3e4..d11af52427b4 100644 +--- a/Documentation/arm64/silicon-errata.txt ++++ b/Documentation/arm64/silicon-errata.txt +@@ -42,24 +42,26 @@ file acts as a registry of software workarounds in the Linux Kernel and + will be updated when new workarounds are committed and backported to + stable kernels. + +-| Implementor | Component | Erratum ID | Kconfig | +-+----------------+-----------------+-----------------+-------------------------+ +-| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | +-| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | +-| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 | +-| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 | +-| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 | +-| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 | +-| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 | +-| ARM | Cortex-A57 | #852523 | N/A | +-| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 | +-| ARM | Cortex-A72 | #853709 | N/A | +-| ARM | MMU-500 | #841119,#826419 | N/A | +-| | | | | +-| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | +-| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 | +-| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | +-| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | +-| Cavium | ThunderX SMMUv2 | #27704 | N/A | +-| | | | | +-| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | ++| Implementor | Component | Erratum ID | Kconfig | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | ++| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | ++| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 | ++| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 | ++| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 | ++| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 | ++| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 | ++| ARM | Cortex-A57 | #852523 | N/A | ++| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 | ++| ARM | Cortex-A72 | #853709 | N/A | ++| ARM | MMU-500 | #841119,#826419 | N/A | ++| | | | | ++| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | ++| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 | ++| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | ++| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | ++| Cavium | ThunderX SMMUv2 | #27704 | N/A | ++| | | | | ++| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | ++| | | | | ++| Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 | +diff --git a/Makefile b/Makefile +index 8df819e31882..48e18096913f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 10 +-SUBLEVEL = 4 ++SUBLEVEL = 5 + EXTRAVERSION = + NAME = Fearless Coyote + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 111742126897..51634f7f0aff 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -479,6 +479,16 @@ config CAVIUM_ERRATUM_27456 + + If unsure, say Y. + ++config QCOM_QDF2400_ERRATUM_0065 ++ bool "QDF2400 E0065: Incorrect GITS_TYPER.ITT_Entry_size" ++ default y ++ help ++ On Qualcomm Datacenter Technologies QDF2400 SoC, ITS hardware reports ++ ITE size incorrectly. The GITS_TYPER.ITT_Entry_size field should have ++ been indicated as 16Bytes (0xf), not 8Bytes (0x7). ++ ++ If unsure, say Y. ++ + endmenu + + +diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c +index 88e2f2b938f0..55889d057757 100644 +--- a/arch/arm64/kvm/hyp/tlb.c ++++ b/arch/arm64/kvm/hyp/tlb.c +@@ -17,14 +17,62 @@ + + #include <asm/kvm_hyp.h> + ++static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) ++{ ++ u64 val; ++ ++ /* ++ * With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and ++ * most TLB operations target EL2/EL0. In order to affect the ++ * guest TLBs (EL1/EL0), we need to change one of these two ++ * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so ++ * let's flip TGE before executing the TLB operation. ++ */ ++ write_sysreg(kvm->arch.vttbr, vttbr_el2); ++ val = read_sysreg(hcr_el2); ++ val &= ~HCR_TGE; ++ write_sysreg(val, hcr_el2); ++ isb(); ++} ++ ++static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm) ++{ ++ write_sysreg(kvm->arch.vttbr, vttbr_el2); ++ isb(); ++} ++ ++static hyp_alternate_select(__tlb_switch_to_guest, ++ __tlb_switch_to_guest_nvhe, ++ __tlb_switch_to_guest_vhe, ++ ARM64_HAS_VIRT_HOST_EXTN); ++ ++static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm) ++{ ++ /* ++ * We're done with the TLB operation, let's restore the host's ++ * view of HCR_EL2. ++ */ ++ write_sysreg(0, vttbr_el2); ++ write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2); ++} ++ ++static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm) ++{ ++ write_sysreg(0, vttbr_el2); ++} ++ ++static hyp_alternate_select(__tlb_switch_to_host, ++ __tlb_switch_to_host_nvhe, ++ __tlb_switch_to_host_vhe, ++ ARM64_HAS_VIRT_HOST_EXTN); ++ + void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) + { + dsb(ishst); + + /* Switch to requested VMID */ + kvm = kern_hyp_va(kvm); +- write_sysreg(kvm->arch.vttbr, vttbr_el2); +- isb(); ++ __tlb_switch_to_guest()(kvm); + + /* + * We could do so much better if we had the VA as well. +@@ -45,7 +93,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) + dsb(ish); + isb(); + +- write_sysreg(0, vttbr_el2); ++ __tlb_switch_to_host()(kvm); + } + + void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm) +@@ -54,14 +102,13 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm) + + /* Switch to requested VMID */ + kvm = kern_hyp_va(kvm); +- write_sysreg(kvm->arch.vttbr, vttbr_el2); +- isb(); ++ __tlb_switch_to_guest()(kvm); + + asm volatile("tlbi vmalls12e1is" : : ); + dsb(ish); + isb(); + +- write_sysreg(0, vttbr_el2); ++ __tlb_switch_to_host()(kvm); + } + + void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) +@@ -69,14 +116,13 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) + struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); + + /* Switch to requested VMID */ +- write_sysreg(kvm->arch.vttbr, vttbr_el2); +- isb(); ++ __tlb_switch_to_guest()(kvm); + + asm volatile("tlbi vmalle1" : : ); + dsb(nsh); + isb(); + +- write_sysreg(0, vttbr_el2); ++ __tlb_switch_to_host()(kvm); + } + + void __hyp_text __kvm_flush_vm_context(void) +diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c +index 9fa046d56eba..411994551afc 100644 +--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c ++++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c +@@ -52,7 +52,7 @@ static int crc32c_vpmsum_cra_init(struct crypto_tfm *tfm) + { + u32 *key = crypto_tfm_ctx(tfm); + +- *key = 0; ++ *key = ~0; + + return 0; + } +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index 1635c0c8df23..e07b36c5588a 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -2100,8 +2100,8 @@ static int x86_pmu_event_init(struct perf_event *event) + + static void refresh_pce(void *ignored) + { +- if (current->mm) +- load_mm_cr4(current->mm); ++ if (current->active_mm) ++ load_mm_cr4(current->active_mm); + } + + static void x86_pmu_event_mapped(struct perf_event *event) +diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +index 8af04afdfcb9..84c0f23ea644 100644 +--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c ++++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +@@ -727,7 +727,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn) + if (atomic_dec_and_test(&rdtgrp->waitcount) && + (rdtgrp->flags & RDT_DELETED)) { + kernfs_unbreak_active_protection(kn); +- kernfs_put(kn); ++ kernfs_put(rdtgrp->kn); + kfree(rdtgrp); + } else { + kernfs_unbreak_active_protection(kn); +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index 54a2372f5dbb..b5785c197e53 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -4,6 +4,7 @@ + * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE + */ + ++#define DISABLE_BRANCH_PROFILING + #include <linux/init.h> + #include <linux/linkage.h> + #include <linux/types.h> +diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c +index 37e7cf544e51..62d55e34d373 100644 +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -1310,6 +1310,8 @@ static int __init init_tsc_clocksource(void) + * the refined calibration and directly register it as a clocksource. + */ + if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) { ++ if (boot_cpu_has(X86_FEATURE_ART)) ++ art_related_clocksource = &clocksource_tsc; + clocksource_register_khz(&clocksource_tsc, tsc_khz); + return 0; + } +diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c +index 23d15565d02a..919a7b78f945 100644 +--- a/arch/x86/kernel/unwind_frame.c ++++ b/arch/x86/kernel/unwind_frame.c +@@ -80,19 +80,43 @@ static size_t regs_size(struct pt_regs *regs) + return sizeof(*regs); + } + ++#ifdef CONFIG_X86_32 ++#define GCC_REALIGN_WORDS 3 ++#else ++#define GCC_REALIGN_WORDS 1 ++#endif ++ + static bool is_last_task_frame(struct unwind_state *state) + { +- unsigned long bp = (unsigned long)state->bp; +- unsigned long regs = (unsigned long)task_pt_regs(state->task); ++ unsigned long *last_bp = (unsigned long *)task_pt_regs(state->task) - 2; ++ unsigned long *aligned_bp = last_bp - GCC_REALIGN_WORDS; + + /* + * We have to check for the last task frame at two different locations + * because gcc can occasionally decide to realign the stack pointer and +- * change the offset of the stack frame by a word in the prologue of a +- * function called by head/entry code. ++ * change the offset of the stack frame in the prologue of a function ++ * called by head/entry code. Examples: ++ * ++ * <start_secondary>: ++ * push %edi ++ * lea 0x8(%esp),%edi ++ * and $0xfffffff8,%esp ++ * pushl -0x4(%edi) ++ * push %ebp ++ * mov %esp,%ebp ++ * ++ * <x86_64_start_kernel>: ++ * lea 0x8(%rsp),%r10 ++ * and $0xfffffffffffffff0,%rsp ++ * pushq -0x8(%r10) ++ * push %rbp ++ * mov %rsp,%rbp ++ * ++ * Note that after aligning the stack, it pushes a duplicate copy of ++ * the return address before pushing the frame pointer. + */ +- return bp == regs - FRAME_HEADER_SIZE || +- bp == regs - FRAME_HEADER_SIZE - sizeof(long); ++ return (state->bp == last_bp || ++ (state->bp == aligned_bp && *(aligned_bp+1) == *(last_bp+1))); + } + + /* +diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c +index 0493c17b8a51..333362f992e4 100644 +--- a/arch/x86/mm/kasan_init_64.c ++++ b/arch/x86/mm/kasan_init_64.c +@@ -1,3 +1,4 @@ ++#define DISABLE_BRANCH_PROFILING + #define pr_fmt(fmt) "kasan: " fmt + #include <linux/bootmem.h> + #include <linux/kasan.h> +diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c +index dce1af0ce85c..4721d50c4628 100644 +--- a/drivers/crypto/s5p-sss.c ++++ b/drivers/crypto/s5p-sss.c +@@ -270,7 +270,7 @@ static void s5p_sg_copy_buf(void *buf, struct scatterlist *sg, + scatterwalk_done(&walk, out, 0); + } + +-static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) ++static void s5p_sg_done(struct s5p_aes_dev *dev) + { + if (dev->sg_dst_cpy) { + dev_dbg(dev->dev, +@@ -281,8 +281,11 @@ static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) + } + s5p_free_sg_cpy(dev, &dev->sg_src_cpy); + s5p_free_sg_cpy(dev, &dev->sg_dst_cpy); ++} + +- /* holding a lock outside */ ++/* Calls the completion. Cannot be called with dev->lock hold. */ ++static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) ++{ + dev->req->base.complete(&dev->req->base, err); + dev->busy = false; + } +@@ -368,51 +371,44 @@ static int s5p_set_indata(struct s5p_aes_dev *dev, struct scatterlist *sg) + } + + /* +- * Returns true if new transmitting (output) data is ready and its +- * address+length have to be written to device (by calling +- * s5p_set_dma_outdata()). False otherwise. ++ * Returns -ERRNO on error (mapping of new data failed). ++ * On success returns: ++ * - 0 if there is no more data, ++ * - 1 if new transmitting (output) data is ready and its address+length ++ * have to be written to device (by calling s5p_set_dma_outdata()). + */ +-static bool s5p_aes_tx(struct s5p_aes_dev *dev) ++static int s5p_aes_tx(struct s5p_aes_dev *dev) + { +- int err = 0; +- bool ret = false; ++ int ret = 0; + + s5p_unset_outdata(dev); + + if (!sg_is_last(dev->sg_dst)) { +- err = s5p_set_outdata(dev, sg_next(dev->sg_dst)); +- if (err) +- s5p_aes_complete(dev, err); +- else +- ret = true; +- } else { +- s5p_aes_complete(dev, err); +- +- dev->busy = true; +- tasklet_schedule(&dev->tasklet); ++ ret = s5p_set_outdata(dev, sg_next(dev->sg_dst)); ++ if (!ret) ++ ret = 1; + } + + return ret; + } + + /* +- * Returns true if new receiving (input) data is ready and its +- * address+length have to be written to device (by calling +- * s5p_set_dma_indata()). False otherwise. ++ * Returns -ERRNO on error (mapping of new data failed). ++ * On success returns: ++ * - 0 if there is no more data, ++ * - 1 if new receiving (input) data is ready and its address+length ++ * have to be written to device (by calling s5p_set_dma_indata()). + */ +-static bool s5p_aes_rx(struct s5p_aes_dev *dev) ++static int s5p_aes_rx(struct s5p_aes_dev *dev/*, bool *set_dma*/) + { +- int err; +- bool ret = false; ++ int ret = 0; + + s5p_unset_indata(dev); + + if (!sg_is_last(dev->sg_src)) { +- err = s5p_set_indata(dev, sg_next(dev->sg_src)); +- if (err) +- s5p_aes_complete(dev, err); +- else +- ret = true; ++ ret = s5p_set_indata(dev, sg_next(dev->sg_src)); ++ if (!ret) ++ ret = 1; + } + + return ret; +@@ -422,33 +418,73 @@ static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id) + { + struct platform_device *pdev = dev_id; + struct s5p_aes_dev *dev = platform_get_drvdata(pdev); +- bool set_dma_tx = false; +- bool set_dma_rx = false; ++ int err_dma_tx = 0; ++ int err_dma_rx = 0; ++ bool tx_end = false; + unsigned long flags; + uint32_t status; ++ int err; + + spin_lock_irqsave(&dev->lock, flags); + ++ /* ++ * Handle rx or tx interrupt. If there is still data (scatterlist did not ++ * reach end), then map next scatterlist entry. ++ * In case of such mapping error, s5p_aes_complete() should be called. ++ * ++ * If there is no more data in tx scatter list, call s5p_aes_complete() ++ * and schedule new tasklet. ++ */ + status = SSS_READ(dev, FCINTSTAT); + if (status & SSS_FCINTSTAT_BRDMAINT) +- set_dma_rx = s5p_aes_rx(dev); +- if (status & SSS_FCINTSTAT_BTDMAINT) +- set_dma_tx = s5p_aes_tx(dev); ++ err_dma_rx = s5p_aes_rx(dev); ++ ++ if (status & SSS_FCINTSTAT_BTDMAINT) { ++ if (sg_is_last(dev->sg_dst)) ++ tx_end = true; ++ err_dma_tx = s5p_aes_tx(dev); ++ } + + SSS_WRITE(dev, FCINTPEND, status); + +- /* +- * Writing length of DMA block (either receiving or transmitting) +- * will start the operation immediately, so this should be done +- * at the end (even after clearing pending interrupts to not miss the +- * interrupt). +- */ +- if (set_dma_tx) +- s5p_set_dma_outdata(dev, dev->sg_dst); +- if (set_dma_rx) +- s5p_set_dma_indata(dev, dev->sg_src); ++ if (err_dma_rx < 0) { ++ err = err_dma_rx; ++ goto error; ++ } ++ if (err_dma_tx < 0) { ++ err = err_dma_tx; ++ goto error; ++ } ++ ++ if (tx_end) { ++ s5p_sg_done(dev); ++ ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ s5p_aes_complete(dev, 0); ++ dev->busy = true; ++ tasklet_schedule(&dev->tasklet); ++ } else { ++ /* ++ * Writing length of DMA block (either receiving or ++ * transmitting) will start the operation immediately, so this ++ * should be done at the end (even after clearing pending ++ * interrupts to not miss the interrupt). ++ */ ++ if (err_dma_tx == 1) ++ s5p_set_dma_outdata(dev, dev->sg_dst); ++ if (err_dma_rx == 1) ++ s5p_set_dma_indata(dev, dev->sg_src); + ++ spin_unlock_irqrestore(&dev->lock, flags); ++ } ++ ++ return IRQ_HANDLED; ++ ++error: ++ s5p_sg_done(dev); + spin_unlock_irqrestore(&dev->lock, flags); ++ s5p_aes_complete(dev, err); + + return IRQ_HANDLED; + } +@@ -597,8 +633,9 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode) + s5p_unset_indata(dev); + + indata_error: +- s5p_aes_complete(dev, err); ++ s5p_sg_done(dev); + spin_unlock_irqrestore(&dev->lock, flags); ++ s5p_aes_complete(dev, err); + } + + static void s5p_tasklet_cb(unsigned long data) +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 728ca3ea74d2..f02da12f2860 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1573,18 +1573,21 @@ static int i915_drm_resume(struct drm_device *dev) + intel_opregion_setup(dev_priv); + + intel_init_pch_refclk(dev); +- drm_mode_config_reset(dev); + + /* + * Interrupts have to be enabled before any batches are run. If not the + * GPU will hang. i915_gem_init_hw() will initiate batches to + * update/restore the context. + * ++ * drm_mode_config_reset() needs AUX interrupts. ++ * + * Modeset enabling in intel_modeset_init_hw() also needs working + * interrupts. + */ + intel_runtime_pm_enable_interrupts(dev_priv); + ++ drm_mode_config_reset(dev); ++ + mutex_lock(&dev->struct_mutex); + if (i915_gem_init_hw(dev)) { + DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 07ca71cabb2b..f914581b1729 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -3089,19 +3089,16 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) + I915_WRITE(PCH_PORT_HOTPLUG, hotplug); + } + +-static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) ++static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) + { +- u32 hotplug_irqs, hotplug, enabled_irqs; +- +- hotplug_irqs = SDE_HOTPLUG_MASK_SPT; +- enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_spt); +- +- ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); ++ u32 hotplug; + + /* Enable digital hotplug on the PCH */ + hotplug = I915_READ(PCH_PORT_HOTPLUG); +- hotplug |= PORTD_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE | +- PORTB_HOTPLUG_ENABLE | PORTA_HOTPLUG_ENABLE; ++ hotplug |= PORTA_HOTPLUG_ENABLE | ++ PORTB_HOTPLUG_ENABLE | ++ PORTC_HOTPLUG_ENABLE | ++ PORTD_HOTPLUG_ENABLE; + I915_WRITE(PCH_PORT_HOTPLUG, hotplug); + + hotplug = I915_READ(PCH_PORT_HOTPLUG2); +@@ -3109,6 +3106,18 @@ static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) + I915_WRITE(PCH_PORT_HOTPLUG2, hotplug); + } + ++static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) ++{ ++ u32 hotplug_irqs, enabled_irqs; ++ ++ hotplug_irqs = SDE_HOTPLUG_MASK_SPT; ++ enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_spt); ++ ++ ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); ++ ++ spt_hpd_detection_setup(dev_priv); ++} ++ + static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) + { + u32 hotplug_irqs, hotplug, enabled_irqs; +@@ -3143,18 +3152,15 @@ static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) + ibx_hpd_irq_setup(dev_priv); + } + +-static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) ++static void __bxt_hpd_detection_setup(struct drm_i915_private *dev_priv, ++ u32 enabled_irqs) + { +- u32 hotplug_irqs, hotplug, enabled_irqs; +- +- enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_bxt); +- hotplug_irqs = BXT_DE_PORT_HOTPLUG_MASK; +- +- bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs); ++ u32 hotplug; + + hotplug = I915_READ(PCH_PORT_HOTPLUG); +- hotplug |= PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | +- PORTA_HOTPLUG_ENABLE; ++ hotplug |= PORTA_HOTPLUG_ENABLE | ++ PORTB_HOTPLUG_ENABLE | ++ PORTC_HOTPLUG_ENABLE; + + DRM_DEBUG_KMS("Invert bit setting: hp_ctl:%x hp_port:%x\n", + hotplug, enabled_irqs); +@@ -3164,7 +3170,6 @@ static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) + * For BXT invert bit has to be set based on AOB design + * for HPD detection logic, update it based on VBT fields. + */ +- + if ((enabled_irqs & BXT_DE_PORT_HP_DDIA) && + intel_bios_is_port_hpd_inverted(dev_priv, PORT_A)) + hotplug |= BXT_DDIA_HPD_INVERT; +@@ -3178,6 +3183,23 @@ static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) + I915_WRITE(PCH_PORT_HOTPLUG, hotplug); + } + ++static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv) ++{ ++ __bxt_hpd_detection_setup(dev_priv, BXT_DE_PORT_HOTPLUG_MASK); ++} ++ ++static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) ++{ ++ u32 hotplug_irqs, enabled_irqs; ++ ++ enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_bxt); ++ hotplug_irqs = BXT_DE_PORT_HOTPLUG_MASK; ++ ++ bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs); ++ ++ __bxt_hpd_detection_setup(dev_priv, enabled_irqs); ++} ++ + static void ibx_irq_postinstall(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = to_i915(dev); +@@ -3193,6 +3215,12 @@ static void ibx_irq_postinstall(struct drm_device *dev) + + gen5_assert_iir_is_zero(dev_priv, SDEIIR); + I915_WRITE(SDEIMR, ~mask); ++ ++ if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) || ++ HAS_PCH_LPT(dev_priv)) ++ ; /* TODO: Enable HPD detection on older PCH platforms too */ ++ else ++ spt_hpd_detection_setup(dev_priv); + } + + static void gen5_gt_irq_postinstall(struct drm_device *dev) +@@ -3404,6 +3432,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) + + GEN5_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables); + GEN5_IRQ_INIT(GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); ++ ++ if (IS_BROXTON(dev_priv)) ++ bxt_hpd_detection_setup(dev_priv); + } + + static int gen8_irq_postinstall(struct drm_device *dev) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 4daf7dda9cca..c3ab0240691a 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -4289,8 +4289,8 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, + * + * Return %true if @port is connected, %false otherwise. + */ +-static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +- struct intel_digital_port *port) ++bool intel_digital_port_connected(struct drm_i915_private *dev_priv, ++ struct intel_digital_port *port) + { + if (HAS_PCH_IBX(dev_priv)) + return ibx_digital_port_connected(dev_priv, port); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 03a2112004f9..a0af54bba85b 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -1451,6 +1451,8 @@ bool intel_dp_read_dpcd(struct intel_dp *intel_dp); + bool __intel_dp_read_desc(struct intel_dp *intel_dp, + struct intel_dp_desc *desc); + bool intel_dp_read_desc(struct intel_dp *intel_dp); ++bool intel_digital_port_connected(struct drm_i915_private *dev_priv, ++ struct intel_digital_port *port); + + /* intel_dp_aux_backlight.c */ + int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector); +diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c +index daa523410953..12695616f673 100644 +--- a/drivers/gpu/drm/i915/intel_lspcon.c ++++ b/drivers/gpu/drm/i915/intel_lspcon.c +@@ -100,6 +100,8 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) + static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) + { + struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); ++ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); ++ struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + unsigned long start = jiffies; + + if (!lspcon->desc_valid) +@@ -115,7 +117,8 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) + if (!__intel_dp_read_desc(intel_dp, &desc)) + return; + +- if (!memcmp(&intel_dp->desc, &desc, sizeof(desc))) { ++ if (intel_digital_port_connected(dev_priv, dig_port) && ++ !memcmp(&intel_dp->desc, &desc, sizeof(desc))) { + DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u ms\n", + jiffies_to_msecs(jiffies - start)); + return; +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index 69b040f47d56..519ff7a18b5b 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -1597,6 +1597,14 @@ static void __maybe_unused its_enable_quirk_cavium_23144(void *data) + its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144; + } + ++static void __maybe_unused its_enable_quirk_qdf2400_e0065(void *data) ++{ ++ struct its_node *its = data; ++ ++ /* On QDF2400, the size of the ITE is 16Bytes */ ++ its->ite_size = 16; ++} ++ + static const struct gic_quirk its_quirks[] = { + #ifdef CONFIG_CAVIUM_ERRATUM_22375 + { +@@ -1614,6 +1622,14 @@ static const struct gic_quirk its_quirks[] = { + .init = its_enable_quirk_cavium_23144, + }, + #endif ++#ifdef CONFIG_QCOM_QDF2400_ERRATUM_0065 ++ { ++ .desc = "ITS: QDF2400 erratum 0065", ++ .iidr = 0x00001070, /* QDF2400 ITS rev 1.x */ ++ .mask = 0xffffffff, ++ .init = its_enable_quirk_qdf2400_e0065, ++ }, ++#endif + { + } + }; +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 8029dd4912b6..644d2bf0c451 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4185,6 +4185,7 @@ void bond_setup(struct net_device *bond_dev) + + /* Initialize the device entry points */ + ether_setup(bond_dev); ++ bond_dev->max_mtu = ETH_MAX_MTU; + bond_dev->netdev_ops = &bond_netdev_ops; + bond_dev->ethtool_ops = &bond_ethtool_ops; + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +index a7d16db5c4b2..937f37a5dcb2 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +@@ -1323,7 +1323,7 @@ static int xgbe_read_ext_mii_regs(struct xgbe_prv_data *pdata, int addr, + static int xgbe_set_ext_mii_mode(struct xgbe_prv_data *pdata, unsigned int port, + enum xgbe_mdio_mode mode) + { +- unsigned int reg_val = 0; ++ unsigned int reg_val = XGMAC_IOREAD(pdata, MAC_MDIOCL22R); + + switch (mode) { + case XGBE_MDIO_MODE_CL22: +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +index 1c87cc204075..742e5d1b5da4 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +@@ -1131,12 +1131,12 @@ static void xgbe_stop(struct xgbe_prv_data *pdata) + hw_if->disable_tx(pdata); + hw_if->disable_rx(pdata); + ++ phy_if->phy_stop(pdata); ++ + xgbe_free_irqs(pdata); + + xgbe_napi_disable(pdata, 1); + +- phy_if->phy_stop(pdata); +- + hw_if->exit(pdata); + + channel = pdata->channel; +@@ -2274,10 +2274,7 @@ static int xgbe_one_poll(struct napi_struct *napi, int budget) + processed = xgbe_rx_poll(channel, budget); + + /* If we processed everything, we are done */ +- if (processed < budget) { +- /* Turn off polling */ +- napi_complete_done(napi, processed); +- ++ if ((processed < budget) && napi_complete_done(napi, processed)) { + /* Enable Tx and Rx interrupts */ + if (pdata->channel_irq_mode) + xgbe_enable_rx_tx_int(pdata, channel); +@@ -2319,10 +2316,7 @@ static int xgbe_all_poll(struct napi_struct *napi, int budget) + } while ((processed < budget) && (processed != last_processed)); + + /* If we processed everything, we are done */ +- if (processed < budget) { +- /* Turn off polling */ +- napi_complete_done(napi, processed); +- ++ if ((processed < budget) && napi_complete_done(napi, processed)) { + /* Enable Tx and Rx interrupts */ + xgbe_enable_rx_tx_ints(pdata); + } +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +index 9d8c953083b4..e707c49cc55a 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +@@ -716,6 +716,8 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata) + pdata->phy.duplex = DUPLEX_UNKNOWN; + pdata->phy.autoneg = AUTONEG_ENABLE; + pdata->phy.advertising = pdata->phy.supported; ++ ++ return; + } + + pdata->phy.advertising &= ~ADVERTISED_Autoneg; +@@ -875,6 +877,16 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) + !phy_data->sfp_phy_avail) + return 0; + ++ /* Set the proper MDIO mode for the PHY */ ++ ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr, ++ phy_data->phydev_mode); ++ if (ret) { ++ netdev_err(pdata->netdev, ++ "mdio port/clause not compatible (%u/%u)\n", ++ phy_data->mdio_addr, phy_data->phydev_mode); ++ return ret; ++ } ++ + /* Create and connect to the PHY device */ + phydev = get_phy_device(phy_data->mii, phy_data->mdio_addr, + (phy_data->phydev_mode == XGBE_MDIO_MODE_CL45)); +@@ -2722,6 +2734,18 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) + if (ret) + return ret; + ++ /* Set the proper MDIO mode for the re-driver */ ++ if (phy_data->redrv && !phy_data->redrv_if) { ++ ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr, ++ XGBE_MDIO_MODE_CL22); ++ if (ret) { ++ netdev_err(pdata->netdev, ++ "redriver mdio port not compatible (%u)\n", ++ phy_data->redrv_addr); ++ return ret; ++ } ++ } ++ + /* Start in highest supported mode */ + xgbe_phy_set_mode(pdata, phy_data->start_mode); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index d5ecb8f53fd4..c69a1f827b65 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -803,6 +803,7 @@ int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); + + void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, + u8 cq_period_mode); ++void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type); + + static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq, + struct mlx5_wqe_ctrl_seg *ctrl, int bf_sz) +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index bb67863aa361..6906deae06e0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -1477,6 +1477,7 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev, + + MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, enable); + priv->params.rx_cqe_compress_def = enable; ++ mlx5e_set_rq_type_params(priv, priv->params.rq_wq_type); + + if (reset) + err = mlx5e_open_locked(netdev); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index f14ca3385fdd..9d9c64927372 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -78,9 +78,10 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) + MLX5_CAP_ETH(mdev, reg_umr_sq); + } + +-static void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type) ++void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type) + { + priv->params.rq_wq_type = rq_type; ++ priv->params.lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; + switch (priv->params.rq_wq_type) { + case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: + priv->params.log_rq_size = MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW; +@@ -93,6 +94,10 @@ static void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type) + break; + default: /* MLX5_WQ_TYPE_LINKED_LIST */ + priv->params.log_rq_size = MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE; ++ ++ /* Extra room needed for build_skb */ ++ priv->params.lro_wqe_sz -= MLX5_RX_HEADROOM + ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + } + priv->params.min_rx_wqes = mlx5_min_rx_wqes(priv->params.rq_wq_type, + BIT(priv->params.log_rq_size)); +@@ -3495,6 +3500,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, + cqe_compress_heuristic(link_speed, pci_bw); + } + ++ MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, ++ priv->params.rx_cqe_compress_def); ++ + mlx5e_set_rq_priv_params(priv); + if (priv->params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) + priv->params.lro_en = true; +@@ -3517,16 +3525,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, + mlx5e_build_default_indir_rqt(mdev, priv->params.indirection_rqt, + MLX5E_INDIR_RQT_SIZE, profile->max_nch(mdev)); + +- priv->params.lro_wqe_sz = +- MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ - +- /* Extra room needed for build_skb */ +- MLX5_RX_HEADROOM - +- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- + /* Initialize pflags */ + MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_BASED_MODER, + priv->params.rx_cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE); +- MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, priv->params.rx_cqe_compress_def); + + mutex_init(&priv->state_lock); + +@@ -3940,6 +3941,19 @@ static void mlx5e_register_vport_rep(struct mlx5_core_dev *mdev) + } + } + ++static void mlx5e_unregister_vport_rep(struct mlx5_core_dev *mdev) ++{ ++ struct mlx5_eswitch *esw = mdev->priv.eswitch; ++ int total_vfs = MLX5_TOTAL_VPORTS(mdev); ++ int vport; ++ ++ if (!MLX5_CAP_GEN(mdev, vport_group_manager)) ++ return; ++ ++ for (vport = 1; vport < total_vfs; vport++) ++ mlx5_eswitch_unregister_vport_rep(esw, vport); ++} ++ + void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev) + { + struct mlx5e_priv *priv = netdev_priv(netdev); +@@ -3986,6 +4000,7 @@ static int mlx5e_attach(struct mlx5_core_dev *mdev, void *vpriv) + return err; + } + ++ mlx5e_register_vport_rep(mdev); + return 0; + } + +@@ -3997,6 +4012,7 @@ static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv) + if (!netif_device_present(netdev)) + return; + ++ mlx5e_unregister_vport_rep(mdev); + mlx5e_detach_netdev(mdev, netdev); + mlx5e_destroy_mdev_resources(mdev); + } +@@ -4015,8 +4031,6 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev) + if (err) + return NULL; + +- mlx5e_register_vport_rep(mdev); +- + if (MLX5_CAP_GEN(mdev, vport_group_manager)) + ppriv = &esw->offloads.vport_reps[0]; + +@@ -4068,13 +4082,7 @@ void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv) + + static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv) + { +- struct mlx5_eswitch *esw = mdev->priv.eswitch; +- int total_vfs = MLX5_TOTAL_VPORTS(mdev); + struct mlx5e_priv *priv = vpriv; +- int vport; +- +- for (vport = 1; vport < total_vfs; vport++) +- mlx5_eswitch_unregister_vport_rep(esw, vport); + + unregister_netdev(priv->netdev); + mlx5e_detach(mdev, vpriv); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 06d5e6fecb0a..e3b88bbb9dcf 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -92,19 +92,18 @@ static inline void mlx5e_cqes_update_owner(struct mlx5e_cq *cq, u32 cqcc, int n) + static inline void mlx5e_decompress_cqe(struct mlx5e_rq *rq, + struct mlx5e_cq *cq, u32 cqcc) + { +- u16 wqe_cnt_step; +- + cq->title.byte_cnt = cq->mini_arr[cq->mini_arr_idx].byte_cnt; + cq->title.check_sum = cq->mini_arr[cq->mini_arr_idx].checksum; + cq->title.op_own &= 0xf0; + cq->title.op_own |= 0x01 & (cqcc >> cq->wq.log_sz); + cq->title.wqe_counter = cpu_to_be16(cq->decmprs_wqe_counter); + +- wqe_cnt_step = +- rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ? +- mpwrq_get_cqe_consumed_strides(&cq->title) : 1; +- cq->decmprs_wqe_counter = +- (cq->decmprs_wqe_counter + wqe_cnt_step) & rq->wq.sz_m1; ++ if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) ++ cq->decmprs_wqe_counter += ++ mpwrq_get_cqe_consumed_strides(&cq->title); ++ else ++ cq->decmprs_wqe_counter = ++ (cq->decmprs_wqe_counter + 1) & rq->wq.sz_m1; + } + + static inline void mlx5e_decompress_cqe_no_hash(struct mlx5e_rq *rq, +@@ -172,6 +171,7 @@ void mlx5e_modify_rx_cqe_compression(struct mlx5e_priv *priv, bool val) + mlx5e_close_locked(priv->netdev); + + MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, val); ++ mlx5e_set_rq_type_params(priv, priv->params.rq_wq_type); + + if (was_opened) + mlx5e_open_locked(priv->netdev); +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +index 9e494a446b7e..f17f906f1d3a 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +@@ -496,30 +496,40 @@ static int + mlxsw_sp_vr_lpm_tree_check(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr, + struct mlxsw_sp_prefix_usage *req_prefix_usage) + { +- struct mlxsw_sp_lpm_tree *lpm_tree; ++ struct mlxsw_sp_lpm_tree *lpm_tree = vr->lpm_tree; ++ struct mlxsw_sp_lpm_tree *new_tree; ++ int err; + +- if (mlxsw_sp_prefix_usage_eq(req_prefix_usage, +- &vr->lpm_tree->prefix_usage)) ++ if (mlxsw_sp_prefix_usage_eq(req_prefix_usage, &lpm_tree->prefix_usage)) + return 0; + +- lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, req_prefix_usage, ++ new_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, req_prefix_usage, + vr->proto, false); +- if (IS_ERR(lpm_tree)) { ++ if (IS_ERR(new_tree)) { + /* We failed to get a tree according to the required + * prefix usage. However, the current tree might be still good + * for us if our requirement is subset of the prefixes used + * in the tree. + */ + if (mlxsw_sp_prefix_usage_subset(req_prefix_usage, +- &vr->lpm_tree->prefix_usage)) ++ &lpm_tree->prefix_usage)) + return 0; +- return PTR_ERR(lpm_tree); ++ return PTR_ERR(new_tree); + } + +- mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, vr); +- mlxsw_sp_lpm_tree_put(mlxsw_sp, vr->lpm_tree); ++ /* Prevent packet loss by overwriting existing binding */ ++ vr->lpm_tree = new_tree; ++ err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, vr); ++ if (err) ++ goto err_tree_bind; ++ mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree); ++ ++ return 0; ++ ++err_tree_bind: + vr->lpm_tree = lpm_tree; +- return mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, vr); ++ mlxsw_sp_lpm_tree_put(mlxsw_sp, new_tree); ++ return err; + } + + static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp, +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index 45301cb98bc1..7074b40ebd7f 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -881,12 +881,14 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) + info = &geneve->info; + } + ++ rcu_read_lock(); + #if IS_ENABLED(CONFIG_IPV6) + if (info->mode & IP_TUNNEL_INFO_IPV6) + err = geneve6_xmit_skb(skb, dev, geneve, info); + else + #endif + err = geneve_xmit_skb(skb, dev, geneve, info); ++ rcu_read_unlock(); + + if (likely(!err)) + return NETDEV_TX_OK; +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index bdc58567d10e..707321508c69 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2075,6 +2075,7 @@ static int team_dev_type_check_change(struct net_device *dev, + static void team_setup(struct net_device *dev) + { + ether_setup(dev); ++ dev->max_mtu = ETH_MAX_MTU; + + dev->netdev_ops = &team_netdev_ops; + dev->ethtool_ops = &team_ethtool_ops; +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index bfabe180053e..cdf6339827e6 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -819,7 +819,18 @@ static void tun_net_uninit(struct net_device *dev) + /* Net device open. */ + static int tun_net_open(struct net_device *dev) + { ++ struct tun_struct *tun = netdev_priv(dev); ++ int i; ++ + netif_tx_start_all_queues(dev); ++ ++ for (i = 0; i < tun->numqueues; i++) { ++ struct tun_file *tfile; ++ ++ tfile = rtnl_dereference(tun->tfiles[i]); ++ tfile->socket.sk->sk_write_space(tfile->socket.sk); ++ } ++ + return 0; + } + +@@ -1101,9 +1112,10 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait) + if (!skb_array_empty(&tfile->tx_array)) + mask |= POLLIN | POLLRDNORM; + +- if (sock_writeable(sk) || +- (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && +- sock_writeable(sk))) ++ if (tun->dev->flags & IFF_UP && ++ (sock_writeable(sk) || ++ (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && ++ sock_writeable(sk)))) + mask |= POLLOUT | POLLWRNORM; + + if (tun->dev->reg_state != NETREG_REGISTERED) +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index 454f907d419a..682aac0a2267 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -341,6 +341,7 @@ static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev) + + static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) + { ++ int len = skb->len; + netdev_tx_t ret = is_ip_tx_frame(skb, dev); + + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { +@@ -348,7 +349,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) + + u64_stats_update_begin(&dstats->syncp); + dstats->tx_pkts++; +- dstats->tx_bytes += skb->len; ++ dstats->tx_bytes += len; + u64_stats_update_end(&dstats->syncp); + } else { + this_cpu_inc(dev->dstats->tx_drps); +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 30b04cf2bb1e..0e204f1a5072 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1992,7 +1992,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + const struct iphdr *old_iph = ip_hdr(skb); + union vxlan_addr *dst; + union vxlan_addr remote_ip, local_ip; +- union vxlan_addr *src; + struct vxlan_metadata _md; + struct vxlan_metadata *md = &_md; + __be16 src_port = 0, dst_port; +@@ -2019,7 +2018,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + + dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port; + vni = rdst->remote_vni; +- src = &vxlan->cfg.saddr; ++ local_ip = vxlan->cfg.saddr; + dst_cache = &rdst->dst_cache; + md->gbp = skb->mark; + ttl = vxlan->cfg.ttl; +@@ -2052,7 +2051,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + dst = &remote_ip; + dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port; + vni = tunnel_id_to_key32(info->key.tun_id); +- src = &local_ip; + dst_cache = &info->dst_cache; + if (info->options_len) + md = ip_tunnel_info_opts(info); +@@ -2064,6 +2062,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min, + vxlan->cfg.port_max, true); + ++ rcu_read_lock(); + if (dst->sa.sa_family == AF_INET) { + struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock); + struct rtable *rt; +@@ -2072,7 +2071,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + rt = vxlan_get_route(vxlan, dev, sock4, skb, + rdst ? rdst->remote_ifindex : 0, tos, + dst->sin.sin_addr.s_addr, +- &src->sin.sin_addr.s_addr, ++ &local_ip.sin.sin_addr.s_addr, + dst_port, src_port, + dst_cache, info); + if (IS_ERR(rt)) { +@@ -2086,7 +2085,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + dst_port, vni, &rt->dst, + rt->rt_flags); + if (err) +- return; ++ goto out_unlock; + } else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT) { + df = htons(IP_DF); + } +@@ -2099,7 +2098,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + if (err < 0) + goto tx_error; + +- udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, src->sin.sin_addr.s_addr, ++ udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, local_ip.sin.sin_addr.s_addr, + dst->sin.sin_addr.s_addr, tos, ttl, df, + src_port, dst_port, xnet, !udp_sum); + #if IS_ENABLED(CONFIG_IPV6) +@@ -2109,7 +2108,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + ndst = vxlan6_get_route(vxlan, dev, sock6, skb, + rdst ? rdst->remote_ifindex : 0, tos, + label, &dst->sin6.sin6_addr, +- &src->sin6.sin6_addr, ++ &local_ip.sin6.sin6_addr, + dst_port, src_port, + dst_cache, info); + if (IS_ERR(ndst)) { +@@ -2125,7 +2124,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + dst_port, vni, ndst, + rt6i_flags); + if (err) +- return; ++ goto out_unlock; + } + + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); +@@ -2137,11 +2136,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + goto tx_error; + + udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, +- &src->sin6.sin6_addr, ++ &local_ip.sin6.sin6_addr, + &dst->sin6.sin6_addr, tos, ttl, + label, src_port, dst_port, !udp_sum); + #endif + } ++out_unlock: ++ rcu_read_unlock(); + return; + + drop: +@@ -2150,6 +2151,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + return; + + tx_error: ++ rcu_read_unlock(); + if (err == -ELOOP) + dev->stats.collisions++; + else if (err == -ENETUNREACH) +@@ -2626,7 +2628,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) + + if (data[IFLA_VXLAN_ID]) { + __u32 id = nla_get_u32(data[IFLA_VXLAN_ID]); +- if (id >= VXLAN_VID_MASK) ++ if (id >= VXLAN_N_VID) + return -ERANGE; + } + +diff --git a/include/linux/dccp.h b/include/linux/dccp.h +index 61d042bbbf60..68449293c4b6 100644 +--- a/include/linux/dccp.h ++++ b/include/linux/dccp.h +@@ -163,6 +163,7 @@ struct dccp_request_sock { + __u64 dreq_isr; + __u64 dreq_gsr; + __be32 dreq_service; ++ spinlock_t dreq_lock; + struct list_head dreq_featneg; + __u32 dreq_timestamp_echo; + __u32 dreq_timestamp_time; +diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h +index d08c63f3dd6f..0c5d5dd61b6a 100644 +--- a/include/uapi/linux/packet_diag.h ++++ b/include/uapi/linux/packet_diag.h +@@ -64,7 +64,7 @@ struct packet_diag_mclist { + __u32 pdmc_count; + __u16 pdmc_type; + __u16 pdmc_alen; +- __u8 pdmc_addr[MAX_ADDR_LEN]; ++ __u8 pdmc_addr[32]; /* MAX_ADDR_LEN */ + }; + + struct packet_diag_ring { +diff --git a/kernel/futex.c b/kernel/futex.c +index cdf365036141..dda00f03337d 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2813,7 +2813,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + { + struct hrtimer_sleeper timeout, *to = NULL; + struct rt_mutex_waiter rt_waiter; +- struct rt_mutex *pi_mutex = NULL; + struct futex_hash_bucket *hb; + union futex_key key2 = FUTEX_KEY_INIT; + struct futex_q q = futex_q_init; +@@ -2897,6 +2896,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + if (q.pi_state && (q.pi_state->owner != current)) { + spin_lock(q.lock_ptr); + ret = fixup_pi_state_owner(uaddr2, &q, current); ++ if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) ++ rt_mutex_unlock(&q.pi_state->pi_mutex); + /* + * Drop the reference to the pi state which + * the requeue_pi() code acquired for us. +@@ -2905,6 +2906,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + spin_unlock(q.lock_ptr); + } + } else { ++ struct rt_mutex *pi_mutex; ++ + /* + * We have been woken up by futex_unlock_pi(), a timeout, or a + * signal. futex_unlock_pi() will not destroy the lock_ptr nor +@@ -2928,18 +2931,19 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + if (res) + ret = (res < 0) ? res : 0; + ++ /* ++ * If fixup_pi_state_owner() faulted and was unable to handle ++ * the fault, unlock the rt_mutex and return the fault to ++ * userspace. ++ */ ++ if (ret && rt_mutex_owner(pi_mutex) == current) ++ rt_mutex_unlock(pi_mutex); ++ + /* Unqueue and drop the lock. */ + unqueue_me_pi(&q); + } + +- /* +- * If fixup_pi_state_owner() faulted and was unable to handle the +- * fault, unlock the rt_mutex and return the fault to userspace. +- */ +- if (ret == -EFAULT) { +- if (pi_mutex && rt_mutex_owner(pi_mutex) == current) +- rt_mutex_unlock(pi_mutex); +- } else if (ret == -EINTR) { ++ if (ret == -EINTR) { + /* + * We've already been requeued, but cannot restart by calling + * futex_lock_pi() directly. We could restart this syscall, but +diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c +index 1591f6b3539f..2bef4ab94003 100644 +--- a/kernel/locking/rwsem-spinlock.c ++++ b/kernel/locking/rwsem-spinlock.c +@@ -216,10 +216,8 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state) + */ + if (sem->count == 0) + break; +- if (signal_pending_state(state, current)) { +- ret = -EINTR; +- goto out; +- } ++ if (signal_pending_state(state, current)) ++ goto out_nolock; + set_task_state(tsk, state); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); + schedule(); +@@ -227,12 +225,19 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state) + } + /* got the lock */ + sem->count = -1; +-out: + list_del(&waiter.list); + + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); + + return ret; ++ ++out_nolock: ++ list_del(&waiter.list); ++ if (!list_empty(&sem->wait_list)) ++ __rwsem_do_wake(sem, 1); ++ raw_spin_unlock_irqrestore(&sem->wait_lock, flags); ++ ++ return -EINTR; + } + + void __sched __down_write(struct rw_semaphore *sem) +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c +index 7cb41aee4c82..8498e3503605 100644 +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -186,8 +186,9 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb, + /* Do not flood unicast traffic to ports that turn it off */ + if (pkt_type == BR_PKT_UNICAST && !(p->flags & BR_FLOOD)) + continue; ++ /* Do not flood if mc off, except for traffic we originate */ + if (pkt_type == BR_PKT_MULTICAST && +- !(p->flags & BR_MCAST_FLOOD)) ++ !(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) + continue; + + /* Do not flood to ports that enable proxy ARP */ +diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c +index 855b72fbe1da..267b46af407f 100644 +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -29,6 +29,7 @@ EXPORT_SYMBOL(br_should_route_hook); + static int + br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) + { ++ br_drop_fake_rtable(skb); + return netif_receive_skb(skb); + } + +diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c +index 95087e6e8258..fa87fbd62bb7 100644 +--- a/net/bridge/br_netfilter_hooks.c ++++ b/net/bridge/br_netfilter_hooks.c +@@ -521,21 +521,6 @@ static unsigned int br_nf_pre_routing(void *priv, + } + + +-/* PF_BRIDGE/LOCAL_IN ************************************************/ +-/* The packet is locally destined, which requires a real +- * dst_entry, so detach the fake one. On the way up, the +- * packet would pass through PRE_ROUTING again (which already +- * took place when the packet entered the bridge), but we +- * register an IPv4 PRE_ROUTING 'sabotage' hook that will +- * prevent this from happening. */ +-static unsigned int br_nf_local_in(void *priv, +- struct sk_buff *skb, +- const struct nf_hook_state *state) +-{ +- br_drop_fake_rtable(skb); +- return NF_ACCEPT; +-} +- + /* PF_BRIDGE/FORWARD *************************************************/ + static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb) + { +@@ -908,12 +893,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { + .priority = NF_BR_PRI_BRNF, + }, + { +- .hook = br_nf_local_in, +- .pf = NFPROTO_BRIDGE, +- .hooknum = NF_BR_LOCAL_IN, +- .priority = NF_BR_PRI_BRNF, +- }, +- { + .hook = br_nf_forward_ip, + .pf = NFPROTO_BRIDGE, + .hooknum = NF_BR_FORWARD, +diff --git a/net/core/dev.c b/net/core/dev.c +index 29101c98399f..fd6e2dfda45f 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1696,27 +1696,54 @@ EXPORT_SYMBOL_GPL(net_dec_egress_queue); + static struct static_key netstamp_needed __read_mostly; + #ifdef HAVE_JUMP_LABEL + static atomic_t netstamp_needed_deferred; ++static atomic_t netstamp_wanted; + static void netstamp_clear(struct work_struct *work) + { + int deferred = atomic_xchg(&netstamp_needed_deferred, 0); ++ int wanted; + +- while (deferred--) +- static_key_slow_dec(&netstamp_needed); ++ wanted = atomic_add_return(deferred, &netstamp_wanted); ++ if (wanted > 0) ++ static_key_enable(&netstamp_needed); ++ else ++ static_key_disable(&netstamp_needed); + } + static DECLARE_WORK(netstamp_work, netstamp_clear); + #endif + + void net_enable_timestamp(void) + { ++#ifdef HAVE_JUMP_LABEL ++ int wanted; ++ ++ while (1) { ++ wanted = atomic_read(&netstamp_wanted); ++ if (wanted <= 0) ++ break; ++ if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted + 1) == wanted) ++ return; ++ } ++ atomic_inc(&netstamp_needed_deferred); ++ schedule_work(&netstamp_work); ++#else + static_key_slow_inc(&netstamp_needed); ++#endif + } + EXPORT_SYMBOL(net_enable_timestamp); + + void net_disable_timestamp(void) + { + #ifdef HAVE_JUMP_LABEL +- /* net_disable_timestamp() can be called from non process context */ +- atomic_inc(&netstamp_needed_deferred); ++ int wanted; ++ ++ while (1) { ++ wanted = atomic_read(&netstamp_wanted); ++ if (wanted <= 1) ++ break; ++ if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted - 1) == wanted) ++ return; ++ } ++ atomic_dec(&netstamp_needed_deferred); + schedule_work(&netstamp_work); + #else + static_key_slow_dec(&netstamp_needed); +diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c +index b0c04cf4851d..1004418d937e 100644 +--- a/net/core/net-sysfs.c ++++ b/net/core/net-sysfs.c +@@ -952,7 +952,7 @@ net_rx_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) + while (--i >= new_num) { + struct kobject *kobj = &dev->_rx[i].kobj; + +- if (!list_empty(&dev_net(dev)->exit_list)) ++ if (!atomic_read(&dev_net(dev)->count)) + kobj->uevent_suppress = 1; + if (dev->sysfs_rx_queue_group) + sysfs_remove_group(kobj, dev->sysfs_rx_queue_group); +@@ -1370,7 +1370,7 @@ netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) + while (--i >= new_num) { + struct netdev_queue *queue = dev->_tx + i; + +- if (!list_empty(&dev_net(dev)->exit_list)) ++ if (!atomic_read(&dev_net(dev)->count)) + queue->kobj.uevent_suppress = 1; + #ifdef CONFIG_BQL + sysfs_remove_group(&queue->kobj, &dql_group); +@@ -1557,7 +1557,7 @@ void netdev_unregister_kobject(struct net_device *ndev) + { + struct device *dev = &(ndev->dev); + +- if (!list_empty(&dev_net(ndev)->exit_list)) ++ if (!atomic_read(&dev_net(ndev)->count)) + dev_set_uevent_suppress(dev, 1); + + kobject_get(&dev->kobj); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 734c71468b01..aa3a13378c90 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3824,13 +3824,14 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, + if (!skb_may_tx_timestamp(sk, false)) + return; + +- /* take a reference to prevent skb_orphan() from freeing the socket */ +- sock_hold(sk); +- +- *skb_hwtstamps(skb) = *hwtstamps; +- __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); +- +- sock_put(sk); ++ /* Take a reference to prevent skb_orphan() from freeing the socket, ++ * but only if the socket refcount is not zero. ++ */ ++ if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { ++ *skb_hwtstamps(skb) = *hwtstamps; ++ __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); ++ sock_put(sk); ++ } + } + EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); + +@@ -3889,7 +3890,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) + { + struct sock *sk = skb->sk; + struct sock_exterr_skb *serr; +- int err; ++ int err = 1; + + skb->wifi_acked_valid = 1; + skb->wifi_acked = acked; +@@ -3899,14 +3900,15 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) + serr->ee.ee_errno = ENOMSG; + serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; + +- /* take a reference to prevent skb_orphan() from freeing the socket */ +- sock_hold(sk); +- +- err = sock_queue_err_skb(sk, skb); ++ /* Take a reference to prevent skb_orphan() from freeing the socket, ++ * but only if the socket refcount is not zero. ++ */ ++ if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { ++ err = sock_queue_err_skb(sk, skb); ++ sock_put(sk); ++ } + if (err) + kfree_skb(skb); +- +- sock_put(sk); + } + EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); + +diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c +index f053198e730c..5e3a7302f774 100644 +--- a/net/dccp/ccids/ccid2.c ++++ b/net/dccp/ccids/ccid2.c +@@ -749,6 +749,7 @@ static void ccid2_hc_tx_exit(struct sock *sk) + for (i = 0; i < hc->tx_seqbufc; i++) + kfree(hc->tx_seqbuf[i]); + hc->tx_seqbufc = 0; ++ dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); + } + + static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) +diff --git a/net/dccp/input.c b/net/dccp/input.c +index 8fedc2d49770..4a05d7876850 100644 +--- a/net/dccp/input.c ++++ b/net/dccp/input.c +@@ -577,6 +577,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + struct dccp_sock *dp = dccp_sk(sk); + struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); + const int old_state = sk->sk_state; ++ bool acceptable; + int queued = 0; + + /* +@@ -603,8 +604,13 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + */ + if (sk->sk_state == DCCP_LISTEN) { + if (dh->dccph_type == DCCP_PKT_REQUEST) { +- if (inet_csk(sk)->icsk_af_ops->conn_request(sk, +- skb) < 0) ++ /* It is possible that we process SYN packets from backlog, ++ * so we need to make sure to disable BH right there. ++ */ ++ local_bh_disable(); ++ acceptable = inet_csk(sk)->icsk_af_ops->conn_request(sk, skb) >= 0; ++ local_bh_enable(); ++ if (!acceptable) + return 1; + consume_skb(skb); + return 0; +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index d859a5c36e70..b0a1ba968ed5 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -289,7 +289,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) + + switch (type) { + case ICMP_REDIRECT: +- dccp_do_redirect(skb, sk); ++ if (!sock_owned_by_user(sk)) ++ dccp_do_redirect(skb, sk); + goto out; + case ICMP_SOURCE_QUENCH: + /* Just silently ignore these. */ +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index c4e879c02186..2f3e8bbe2cb9 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -122,10 +122,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + np = inet6_sk(sk); + + if (type == NDISC_REDIRECT) { +- struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); ++ if (!sock_owned_by_user(sk)) { ++ struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); + +- if (dst) +- dst->ops->redirect(dst, sk, skb); ++ if (dst) ++ dst->ops->redirect(dst, sk, skb); ++ } + goto out; + } + +diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c +index 53eddf99e4f6..39e7e2bca8db 100644 +--- a/net/dccp/minisocks.c ++++ b/net/dccp/minisocks.c +@@ -122,6 +122,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk, + /* It is still raw copy of parent, so invalidate + * destructor and make plain sk_free() */ + newsk->sk_destruct = NULL; ++ bh_unlock_sock(newsk); + sk_free(newsk); + return NULL; + } +@@ -145,6 +146,13 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, + struct dccp_request_sock *dreq = dccp_rsk(req); + bool own_req; + ++ /* TCP/DCCP listeners became lockless. ++ * DCCP stores complex state in its request_sock, so we need ++ * a protection for them, now this code runs without being protected ++ * by the parent (listener) lock. ++ */ ++ spin_lock_bh(&dreq->dreq_lock); ++ + /* Check for retransmitted REQUEST */ + if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { + +@@ -159,7 +167,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, + inet_rtx_syn_ack(sk, req); + } + /* Network Duplicate, discard packet */ +- return NULL; ++ goto out; + } + + DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; +@@ -185,20 +193,20 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, + + child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, + req, &own_req); +- if (!child) +- goto listen_overflow; +- +- return inet_csk_complete_hashdance(sk, child, req, own_req); ++ if (child) { ++ child = inet_csk_complete_hashdance(sk, child, req, own_req); ++ goto out; ++ } + +-listen_overflow: +- dccp_pr_debug("listen_overflow!\n"); + DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY; + drop: + if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) + req->rsk_ops->send_reset(sk, skb); + + inet_csk_reqsk_queue_drop(sk, req); +- return NULL; ++out: ++ spin_unlock_bh(&dreq->dreq_lock); ++ return child; + } + + EXPORT_SYMBOL_GPL(dccp_check_req); +@@ -249,6 +257,7 @@ int dccp_reqsk_init(struct request_sock *req, + { + struct dccp_request_sock *dreq = dccp_rsk(req); + ++ spin_lock_init(&dreq->dreq_lock); + inet_rsk(req)->ir_rmt_port = dccp_hdr(skb)->dccph_sport; + inet_rsk(req)->ir_num = ntohs(dccp_hdr(skb)->dccph_dport); + inet_rsk(req)->acked = 0; +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index f75069883f2b..4391da91789f 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1470,8 +1470,10 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff) + int proto = iph->protocol; + int err = -ENOSYS; + +- if (skb->encapsulation) ++ if (skb->encapsulation) { ++ skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IP)); + skb_set_inner_network_header(skb, nhoff); ++ } + + csum_replace2(&iph->check, iph->tot_len, newlen); + iph->tot_len = newlen; +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index 7db2ad2e82d3..b39a791f6756 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -319,7 +319,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, + int ret, no_addr; + struct fib_result res; + struct flowi4 fl4; +- struct net *net; ++ struct net *net = dev_net(dev); + bool dev_match; + + fl4.flowi4_oif = 0; +@@ -332,6 +332,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, + fl4.flowi4_scope = RT_SCOPE_UNIVERSE; + fl4.flowi4_tun_key.tun_id = 0; + fl4.flowi4_flags = 0; ++ fl4.flowi4_uid = sock_net_uid(net, NULL); + + no_addr = idev->ifa_list == NULL; + +@@ -339,13 +340,12 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, + + trace_fib_validate_source(dev, &fl4); + +- net = dev_net(dev); + if (fib_lookup(net, &fl4, &res, 0)) + goto last_resort; + if (res.type != RTN_UNICAST && + (res.type != RTN_LOCAL || !IN_DEV_ACCEPT_LOCAL(idev))) + goto e_inval; +- if (!rpf && !fib_num_tclassid_users(dev_net(dev)) && ++ if (!rpf && !fib_num_tclassid_users(net) && + (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) + goto last_resort; + fib_combine_itag(itag, &res); +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 709ffe67d1de..8976887dc83e 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1858,6 +1858,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, + fl4.flowi4_flags = 0; + fl4.daddr = daddr; + fl4.saddr = saddr; ++ fl4.flowi4_uid = sock_net_uid(net, NULL); + err = fib_lookup(net, &fl4, &res, 0); + if (err != 0) { + if (!IN_DEV_FORWARD(in_dev)) +@@ -1990,6 +1991,7 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr, + { + int res; + ++ tos &= IPTOS_RT_MASK; + rcu_read_lock(); + + /* Multicast recognition logic is moved from route cache to here. +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 41dcbd568cbe..28777a0307c8 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5916,9 +5916,15 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) + if (th->syn) { + if (th->fin) + goto discard; +- if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) +- return 1; ++ /* It is possible that we process SYN packets from backlog, ++ * so we need to make sure to disable BH right there. ++ */ ++ local_bh_disable(); ++ acceptable = icsk->icsk_af_ops->conn_request(sk, skb) >= 0; ++ local_bh_enable(); + ++ if (!acceptable) ++ return 1; + consume_skb(skb); + return 0; + } +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index fe9da4fb96bf..bb629dc2bfb0 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -269,10 +269,13 @@ EXPORT_SYMBOL(tcp_v4_connect); + */ + void tcp_v4_mtu_reduced(struct sock *sk) + { +- struct dst_entry *dst; + struct inet_sock *inet = inet_sk(sk); +- u32 mtu = tcp_sk(sk)->mtu_info; ++ struct dst_entry *dst; ++ u32 mtu; + ++ if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) ++ return; ++ mtu = tcp_sk(sk)->mtu_info; + dst = inet_csk_update_pmtu(sk, mtu); + if (!dst) + return; +@@ -418,7 +421,8 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) + + switch (type) { + case ICMP_REDIRECT: +- do_redirect(icmp_skb, sk); ++ if (!sock_owned_by_user(sk)) ++ do_redirect(icmp_skb, sk); + goto out; + case ICMP_SOURCE_QUENCH: + /* Just silently ignore these. */ +diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c +index 3705075f42c3..45d707569af6 100644 +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -249,7 +249,8 @@ void tcp_delack_timer_handler(struct sock *sk) + + sk_mem_reclaim_partial(sk); + +- if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) ++ if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || ++ !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) + goto out; + + if (time_after(icsk->icsk_ack.timeout, jiffies)) { +@@ -552,7 +553,8 @@ void tcp_write_timer_handler(struct sock *sk) + struct inet_connection_sock *icsk = inet_csk(sk); + int event; + +- if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending) ++ if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || ++ !icsk->icsk_pending) + goto out; + + if (time_after(icsk->icsk_timeout, jiffies)) { +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index ef5485204522..8c88a37392d0 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -908,6 +908,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, + ins = &rt->dst.rt6_next; + iter = *ins; + while (iter) { ++ if (iter->rt6i_metric > rt->rt6i_metric) ++ break; + if (rt6_qualify_for_ecmp(iter)) { + *ins = iter->dst.rt6_next; + fib6_purge_rt(iter, fn, info->nl_net); +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index fc7b4017ba24..33b04ec2744a 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -294,8 +294,10 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff) + struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff); + int err = -ENOSYS; + +- if (skb->encapsulation) ++ if (skb->encapsulation) { ++ skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IPV6)); + skb_set_inner_network_header(skb, nhoff); ++ } + + iph->payload_len = htons(skb->len - nhoff - sizeof(*iph)); + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 7cebee58e55b..d57f4ee5ec29 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -767,13 +767,14 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, + * Fragment the datagram. + */ + +- *prevhdr = NEXTHDR_FRAGMENT; + troom = rt->dst.dev->needed_tailroom; + + /* + * Keep copying data until we run out. + */ + while (left > 0) { ++ u8 *fragnexthdr_offset; ++ + len = left; + /* IF: it doesn't fit, use 'mtu' - the data space left */ + if (len > mtu) +@@ -818,6 +819,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, + */ + skb_copy_from_linear_data(skb, skb_network_header(frag), hlen); + ++ fragnexthdr_offset = skb_network_header(frag); ++ fragnexthdr_offset += prevhdr - skb_network_header(skb); ++ *fragnexthdr_offset = NEXTHDR_FRAGMENT; ++ + /* + * Build fragment header. + */ +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index d82042c8d8fd..733c63ef4b8a 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -692,6 +692,10 @@ vti6_parm_to_user(struct ip6_tnl_parm2 *u, const struct __ip6_tnl_parm *p) + u->link = p->link; + u->i_key = p->i_key; + u->o_key = p->o_key; ++ if (u->i_key) ++ u->i_flags |= GRE_KEY; ++ if (u->o_key) ++ u->o_flags |= GRE_KEY; + u->proto = p->proto; + + memcpy(u->name, p->name, sizeof(u->name)); +diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c +index 9948b5ce52da..986d4ca38832 100644 +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -589,6 +589,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) + hdr = ipv6_hdr(skb); + fhdr = (struct frag_hdr *)skb_transport_header(skb); + ++ skb_orphan(skb); + fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr, + skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); + if (fq == NULL) { +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 4c60c6f71cd3..cfc232714139 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -382,10 +382,12 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + np = inet6_sk(sk); + + if (type == NDISC_REDIRECT) { +- struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); ++ if (!sock_owned_by_user(sk)) { ++ struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); + +- if (dst) +- dst->ops->redirect(dst, sk, skb); ++ if (dst) ++ dst->ops->redirect(dst, sk, skb); ++ } + goto out; + } + +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index 28c21546d5b6..3ed30153a6f5 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -381,7 +381,7 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) + drop: + IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); + kfree_skb(skb); +- return -1; ++ return 0; + } + + /* Userspace will call sendmsg() on the tunnel socket to send L2TP +diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c +index 5b77377e5a15..1309e2c34764 100644 +--- a/net/mpls/af_mpls.c ++++ b/net/mpls/af_mpls.c +@@ -956,7 +956,8 @@ static void mpls_ifdown(struct net_device *dev, int event) + /* fall through */ + case NETDEV_CHANGE: + nh->nh_flags |= RTNH_F_LINKDOWN; +- ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; ++ if (event != NETDEV_UNREGISTER) ++ ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; + break; + } + if (event == NETDEV_UNREGISTER) +@@ -1696,6 +1697,7 @@ static void mpls_net_exit(struct net *net) + for (index = 0; index < platform_labels; index++) { + struct mpls_route *rt = rtnl_dereference(platform_label[index]); + RCU_INIT_POINTER(platform_label[index], NULL); ++ mpls_notify_route(net, index, rt, NULL, NULL); + mpls_rt_free(rt); + } + rtnl_unlock(); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index 54253ea5976e..919d66e083d1 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -367,7 +367,6 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, + } else if (key->eth.type == htons(ETH_P_IPV6)) { + enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone; + +- skb_orphan(skb); + memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); + err = nf_ct_frag6_gather(net, skb, user); + if (err) { +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 70f5b6a4683c..c59fcc79ba32 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3082,7 +3082,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + int addr_len) + { + struct sock *sk = sock->sk; +- char name[15]; ++ char name[sizeof(uaddr->sa_data) + 1]; + + /* + * Check legality +@@ -3090,7 +3090,11 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + + if (addr_len != sizeof(struct sockaddr)) + return -EINVAL; +- strlcpy(name, uaddr->sa_data, sizeof(name)); ++ /* uaddr->sa_data comes from the userspace, it's not guaranteed to be ++ * zero-terminated. ++ */ ++ memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); ++ name[sizeof(uaddr->sa_data)] = 0; + + return packet_do_bind(sk, name, 0, pkt_sk(sk)->num); + } +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index e10456ef6f7a..9b29b6115384 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -817,10 +817,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, + goto out_module_put; + + err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops); +- if (err < 0) ++ if (err <= 0) + goto out_module_put; +- if (err == 0) +- goto noflush_out; + + nla_nest_end(skb, nest); + +@@ -837,7 +835,6 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, + out_module_put: + module_put(ops->owner); + err_out: +-noflush_out: + kfree_skb(skb); + return err; + } +diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c +index ab8062909962..f9bb43c25697 100644 +--- a/net/sched/act_connmark.c ++++ b/net/sched/act_connmark.c +@@ -113,6 +113,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, + if (ret < 0) + return ret; + ++ if (!tb[TCA_CONNMARK_PARMS]) ++ return -EINVAL; ++ + parm = nla_data(tb[TCA_CONNMARK_PARMS]); + + if (!tcf_hash_check(tn, parm->index, a, bind)) { +diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c +index 3b7074e23024..c736627f8f4a 100644 +--- a/net/sched/act_skbmod.c ++++ b/net/sched/act_skbmod.c +@@ -228,7 +228,6 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, + + return skb->len; + nla_put_failure: +- rcu_read_unlock(); + nlmsg_trim(skb, b); + return -1; + } +diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c +index 616a9428e0c4..4ee4a33e34dc 100644 +--- a/net/sctp/protocol.c ++++ b/net/sctp/protocol.c +@@ -199,6 +199,7 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp, + sctp_scope_t scope, gfp_t gfp, int copy_flags) + { + struct sctp_sockaddr_entry *addr; ++ union sctp_addr laddr; + int error = 0; + + rcu_read_lock(); +@@ -220,7 +221,10 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp, + !(copy_flags & SCTP_ADDR6_PEERSUPP))) + continue; + +- if (sctp_bind_addr_state(bp, &addr->a) != -1) ++ laddr = addr->a; ++ /* also works for setting ipv6 address port */ ++ laddr.v4.sin_port = htons(bp->port); ++ if (sctp_bind_addr_state(bp, &laddr) != -1) + continue; + + error = sctp_add_bind_addr(bp, &addr->a, sizeof(addr->a), +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 1b5d669e3029..d04a8b66098c 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -4734,6 +4734,12 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) + if (!asoc) + return -EINVAL; + ++ /* If there is a thread waiting on more sndbuf space for ++ * sending on this asoc, it cannot be peeled. ++ */ ++ if (waitqueue_active(&asoc->wait)) ++ return -EBUSY; ++ + /* An association cannot be branched off from an already peeled-off + * socket, nor is this supported for tcp style sockets. + */ +@@ -7426,8 +7432,6 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, + */ + release_sock(sk); + current_timeo = schedule_timeout(current_timeo); +- if (sk != asoc->base.sk) +- goto do_error; + lock_sock(sk); + + *timeo_p = current_timeo; +diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c +index 41adf362936d..b5c279b22680 100644 +--- a/net/strparser/strparser.c ++++ b/net/strparser/strparser.c +@@ -504,6 +504,7 @@ static int __init strp_mod_init(void) + + static void __exit strp_mod_exit(void) + { ++ destroy_workqueue(strp_wq); + } + module_init(strp_mod_init); + module_exit(strp_mod_exit); |