diff -druNp --no-dereference linux-libre-4.10.4-gnu/arch/arm64/Kconfig linux-libre-4.10.5-gnu/arch/arm64/Kconfig
--- linux-libre-4.10.4-gnu/arch/arm64/Kconfig	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/arm64/Kconfig	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/arm64/kvm/hyp/tlb.c linux-libre-4.10.5-gnu/arch/arm64/kvm/hyp/tlb.c
--- linux-libre-4.10.4-gnu/arch/arm64/kvm/hyp/tlb.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/arm64/kvm/hyp/tlb.c	2017-03-22 08:38:58.000000000 -0400
@@ -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
 	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(str
 
 	/* 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_vm
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/powerpc/crypto/crc32c-vpmsum_glue.c linux-libre-4.10.5-gnu/arch/powerpc/crypto/crc32c-vpmsum_glue.c
--- linux-libre-4.10.4-gnu/arch/powerpc/crypto/crc32c-vpmsum_glue.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/powerpc/crypto/crc32c-vpmsum_glue.c	2017-03-22 08:38:58.000000000 -0400
@@ -52,7 +52,7 @@ static int crc32c_vpmsum_cra_init(struct
 {
 	u32 *key = crypto_tfm_ctx(tfm);
 
-	*key = 0;
+	*key = ~0;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.10.4-gnu/arch/x86/events/core.c linux-libre-4.10.5-gnu/arch/x86/events/core.c
--- linux-libre-4.10.4-gnu/arch/x86/events/core.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/x86/events/core.c	2017-03-22 08:38:58.000000000 -0400
@@ -2100,8 +2100,8 @@ static int x86_pmu_event_init(struct per
 
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c linux-libre-4.10.5-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
--- linux-libre-4.10.4-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c	2017-03-22 08:38:58.000000000 -0400
@@ -727,7 +727,7 @@ void rdtgroup_kn_unlock(struct kernfs_no
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/x86/kernel/head64.c linux-libre-4.10.5-gnu/arch/x86/kernel/head64.c
--- linux-libre-4.10.4-gnu/arch/x86/kernel/head64.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/x86/kernel/head64.c	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/x86/kernel/tsc.c linux-libre-4.10.5-gnu/arch/x86/kernel/tsc.c
--- linux-libre-4.10.4-gnu/arch/x86/kernel/tsc.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/x86/kernel/tsc.c	2017-03-22 08:38:58.000000000 -0400
@@ -1310,6 +1310,8 @@ static int __init init_tsc_clocksource(v
 	 * 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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/x86/kernel/unwind_frame.c linux-libre-4.10.5-gnu/arch/x86/kernel/unwind_frame.c
--- linux-libre-4.10.4-gnu/arch/x86/kernel/unwind_frame.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/x86/kernel/unwind_frame.c	2017-03-22 08:38:58.000000000 -0400
@@ -80,19 +80,43 @@ static size_t regs_size(struct pt_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 -druNp --no-dereference linux-libre-4.10.4-gnu/arch/x86/mm/kasan_init_64.c linux-libre-4.10.5-gnu/arch/x86/mm/kasan_init_64.c
--- linux-libre-4.10.4-gnu/arch/x86/mm/kasan_init_64.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/arch/x86/mm/kasan_init_64.c	2017-03-22 08:38:58.000000000 -0400
@@ -1,3 +1,4 @@
+#define DISABLE_BRANCH_PROFILING
 #define pr_fmt(fmt) "kasan: " fmt
 #include <linux/bootmem.h>
 #include <linux/kasan.h>
diff -druNp --no-dereference linux-libre-4.10.4-gnu/Documentation/arm64/silicon-errata.txt linux-libre-4.10.5-gnu/Documentation/arm64/silicon-errata.txt
--- linux-libre-4.10.4-gnu/Documentation/arm64/silicon-errata.txt	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/Documentation/arm64/silicon-errata.txt	2017-03-22 08:38:58.000000000 -0400
@@ -42,24 +42,26 @@ file acts as a registry of software work
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/crypto/s5p-sss.c linux-libre-4.10.5-gnu/drivers/crypto/s5p-sss.c
--- linux-libre-4.10.4-gnu/drivers/crypto/s5p-sss.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/crypto/s5p-sss.c	2017-03-22 08:38:58.000000000 -0400
@@ -270,7 +270,7 @@ static void s5p_sg_copy_buf(void *buf, s
 	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_
 	}
 	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 @@ exit:
 }
 
 /*
- * 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
 {
 	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 @@ outdata_error:
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/i915_drv.c linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/i915_drv.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/i915_drv.c	2017-03-22 08:38:58.000000000 -0400
@@ -1573,18 +1573,21 @@ static int i915_drm_resume(struct drm_de
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/i915_irq.c linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/i915_irq.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/i915_irq.c	2017-03-22 08:38:58.000000000 -0400
@@ -3089,19 +3089,16 @@ static void ibx_hpd_irq_setup(struct drm
 	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_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
 	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
 	 * 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_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 d
 
 	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(stru
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/intel_dp.c linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/intel_dp.c
--- linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/intel_dp.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/intel_dp.c	2017-03-22 08:38:58.000000000 -0400
@@ -4289,8 +4289,8 @@ static bool bxt_digital_port_connected(s
  *
  * 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/intel_drv.h linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/intel_drv.h
--- linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/intel_drv.h	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/intel_drv.h	2017-03-22 08:38:58.000000000 -0400
@@ -1451,6 +1451,8 @@ bool intel_dp_read_dpcd(struct 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/intel_lspcon.c linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/intel_lspcon.c
--- linux-libre-4.10.4-gnu/drivers/gpu/drm/i915/intel_lspcon.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/gpu/drm/i915/intel_lspcon.c	2017-03-22 08:38:58.000000000 -0400
@@ -100,6 +100,8 @@ static bool lspcon_probe(struct intel_ls
 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(str
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/irqchip/irq-gic-v3-its.c linux-libre-4.10.5-gnu/drivers/irqchip/irq-gic-v3-its.c
--- linux-libre-4.10.4-gnu/drivers/irqchip/irq-gic-v3-its.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/irqchip/irq-gic-v3-its.c	2017-03-22 08:38:58.000000000 -0400
@@ -1597,6 +1597,14 @@ static void __maybe_unused its_enable_qu
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/bonding/bond_main.c linux-libre-4.10.5-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-4.10.4-gnu/drivers/net/bonding/bond_main.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/bonding/bond_main.c	2017-03-22 08:38:58.000000000 -0400
@@ -4185,6 +4185,7 @@ void bond_setup(struct net_device *bond_
 
 	/* 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/amd/xgbe/xgbe-dev.c linux-libre-4.10.5-gnu/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/amd/xgbe/xgbe-dev.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/amd/xgbe/xgbe-dev.c	2017-03-22 08:38:58.000000000 -0400
@@ -1323,7 +1323,7 @@ static int xgbe_read_ext_mii_regs(struct
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/amd/xgbe/xgbe-drv.c linux-libre-4.10.5-gnu/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/amd/xgbe/xgbe-drv.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/amd/xgbe/xgbe-drv.c	2017-03-22 08:38:58.000000000 -0400
@@ -1131,12 +1131,12 @@ static void xgbe_stop(struct xgbe_prv_da
 	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_str
 	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_str
 	} 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c linux-libre-4.10.5-gnu/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c	2017-03-22 08:38:58.000000000 -0400
@@ -716,6 +716,8 @@ static void xgbe_phy_sfp_phy_settings(st
 		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(stru
 	    !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_pr
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c	2017-03-22 08:38:58.000000000 -0400
@@ -1477,6 +1477,7 @@ static int set_pflag_rx_cqe_compress(str
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h	2017-03-22 08:38:58.000000000 -0400
@@ -803,6 +803,7 @@ int mlx5e_get_max_linkspeed(struct mlx5_
 
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2017-03-22 08:38:58.000000000 -0400
@@ -78,9 +78,10 @@ static bool mlx5e_check_fragmented_strid
 		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(str
 		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(
 			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(
 	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(str
 	}
 }
 
+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
 		return err;
 	}
 
+	mlx5e_register_vport_rep(mdev);
 	return 0;
 }
 
@@ -3997,6 +4012,7 @@ static void mlx5e_detach(struct mlx5_cor
 	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_
 	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_co
 
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c	2017-03-22 08:38:58.000000000 -0400
@@ -92,19 +92,18 @@ static inline void mlx5e_cqes_update_own
 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(str
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
--- linux-libre-4.10.4-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/geneve.c linux-libre-4.10.5-gnu/drivers/net/geneve.c
--- linux-libre-4.10.4-gnu/drivers/net/geneve.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/geneve.c	2017-03-22 08:38:58.000000000 -0400
@@ -881,12 +881,14 @@ static netdev_tx_t geneve_xmit(struct sk
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/team/team.c linux-libre-4.10.5-gnu/drivers/net/team/team.c
--- linux-libre-4.10.4-gnu/drivers/net/team/team.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/team/team.c	2017-03-22 08:38:58.000000000 -0400
@@ -2075,6 +2075,7 @@ static int team_dev_type_check_change(st
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/tun.c linux-libre-4.10.5-gnu/drivers/net/tun.c
--- linux-libre-4.10.4-gnu/drivers/net/tun.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/tun.c	2017-03-22 08:38:58.000000000 -0400
@@ -819,7 +819,18 @@ static void tun_net_uninit(struct net_de
 /* 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
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/vrf.c linux-libre-4.10.5-gnu/drivers/net/vrf.c
--- linux-libre-4.10.4-gnu/drivers/net/vrf.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/vrf.c	2017-03-22 08:38:58.000000000 -0400
@@ -341,6 +341,7 @@ static netdev_tx_t is_ip_tx_frame(struct
 
 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_bu
 
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/drivers/net/vxlan.c linux-libre-4.10.5-gnu/drivers/net/vxlan.c
--- linux-libre-4.10.4-gnu/drivers/net/vxlan.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/drivers/net/vxlan.c	2017-03-22 08:38:58.000000000 -0400
@@ -1992,7 +1992,6 @@ static void vxlan_xmit_one(struct sk_buf
 	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_buf
 
 		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_buf
 		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_buf
 	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_buf
 		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_buf
 						    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_buf
 		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_buf
 		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_buf
 						    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_buf
 			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 @@ drop:
 	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
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/include/linux/dccp.h linux-libre-4.10.5-gnu/include/linux/dccp.h
--- linux-libre-4.10.4-gnu/include/linux/dccp.h	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/include/linux/dccp.h	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/include/uapi/linux/packet_diag.h linux-libre-4.10.5-gnu/include/uapi/linux/packet_diag.h
--- linux-libre-4.10.4-gnu/include/uapi/linux/packet_diag.h	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/include/uapi/linux/packet_diag.h	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/kernel/futex.c linux-libre-4.10.5-gnu/kernel/futex.c
--- linux-libre-4.10.4-gnu/kernel/futex.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/kernel/futex.c	2017-03-22 08:38:58.000000000 -0400
@@ -2813,7 +2813,6 @@ static int futex_wait_requeue_pi(u32 __u
 {
 	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 __u
 		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 __u
 			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 __u
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/kernel/locking/rwsem-spinlock.c linux-libre-4.10.5-gnu/kernel/locking/rwsem-spinlock.c
--- linux-libre-4.10.4-gnu/kernel/locking/rwsem-spinlock.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/kernel/locking/rwsem-spinlock.c	2017-03-22 08:38:58.000000000 -0400
@@ -216,10 +216,8 @@ int __sched __down_write_common(struct r
 		 */
 		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 r
 	}
 	/* 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 -druNp --no-dereference linux-libre-4.10.4-gnu/Makefile linux-libre-4.10.5-gnu/Makefile
--- linux-libre-4.10.4-gnu/Makefile	2017-03-18 10:36:04.000000000 -0400
+++ linux-libre-4.10.5-gnu/Makefile	2017-03-22 11:37:28.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 10
-SUBLEVEL = 4
+SUBLEVEL = 5
 EXTRAVERSION = -gnu
 NAME = Fearless Coyote
 
diff -druNp --no-dereference linux-libre-4.10.4-gnu/net/bridge/br_forward.c linux-libre-4.10.5-gnu/net/bridge/br_forward.c
--- linux-libre-4.10.4-gnu/net/bridge/br_forward.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/bridge/br_forward.c	2017-03-22 08:38:58.000000000 -0400
@@ -186,8 +186,9 @@ void br_flood(struct net_bridge *br, str
 		/* 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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/bridge/br_input.c linux-libre-4.10.5-gnu/net/bridge/br_input.c
--- linux-libre-4.10.4-gnu/net/bridge/br_input.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/bridge/br_input.c	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/bridge/br_netfilter_hooks.c linux-libre-4.10.5-gnu/net/bridge/br_netfilter_hooks.c
--- linux-libre-4.10.4-gnu/net/bridge/br_netfilter_hooks.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/bridge/br_netfilter_hooks.c	2017-03-22 08:38:58.000000000 -0400
@@ -521,21 +521,6 @@ static unsigned int br_nf_pre_routing(vo
 }
 
 
-/* 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[] __
 		.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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/core/dev.c linux-libre-4.10.5-gnu/net/core/dev.c
--- linux-libre-4.10.4-gnu/net/core/dev.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/core/dev.c	2017-03-22 08:38:58.000000000 -0400
@@ -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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/core/net-sysfs.c linux-libre-4.10.5-gnu/net/core/net-sysfs.c
--- linux-libre-4.10.4-gnu/net/core/net-sysfs.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/core/net-sysfs.c	2017-03-22 08:38:58.000000000 -0400
@@ -952,7 +952,7 @@ net_rx_queue_update_kobjects(struct net_
 	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_
 	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 ne
 {
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/core/skbuff.c linux-libre-4.10.5-gnu/net/core/skbuff.c
--- linux-libre-4.10.4-gnu/net/core/skbuff.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/core/skbuff.c	2017-03-22 08:38:58.000000000 -0400
@@ -3824,13 +3824,14 @@ void skb_complete_tx_timestamp(struct sk
 	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_buf
 {
 	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_buf
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/dccp/ccids/ccid2.c linux-libre-4.10.5-gnu/net/dccp/ccids/ccid2.c
--- linux-libre-4.10.4-gnu/net/dccp/ccids/ccid2.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/dccp/ccids/ccid2.c	2017-03-22 08:38:58.000000000 -0400
@@ -749,6 +749,7 @@ static void ccid2_hc_tx_exit(struct sock
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/dccp/input.c linux-libre-4.10.5-gnu/net/dccp/input.c
--- linux-libre-4.10.4-gnu/net/dccp/input.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/dccp/input.c	2017-03-22 08:38:58.000000000 -0400
@@ -577,6 +577,7 @@ int dccp_rcv_state_process(struct sock *
 	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 *
 	 */
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/dccp/ipv4.c linux-libre-4.10.5-gnu/net/dccp/ipv4.c
--- linux-libre-4.10.4-gnu/net/dccp/ipv4.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/dccp/ipv4.c	2017-03-22 08:38:58.000000000 -0400
@@ -289,7 +289,8 @@ static void dccp_v4_err(struct sk_buff *
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/dccp/ipv6.c linux-libre-4.10.5-gnu/net/dccp/ipv6.c
--- linux-libre-4.10.4-gnu/net/dccp/ipv6.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/dccp/ipv6.c	2017-03-22 08:38:58.000000000 -0400
@@ -122,10 +122,12 @@ static void dccp_v6_err(struct sk_buff *
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/dccp/minisocks.c linux-libre-4.10.5-gnu/net/dccp/minisocks.c
--- linux-libre-4.10.4-gnu/net/dccp/minisocks.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/dccp/minisocks.c	2017-03-22 08:38:58.000000000 -0400
@@ -122,6 +122,7 @@ struct sock *dccp_create_openreq_child(c
 			/* 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
 	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
 			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
 
 	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
 {
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv4/af_inet.c linux-libre-4.10.5-gnu/net/ipv4/af_inet.c
--- linux-libre-4.10.4-gnu/net/ipv4/af_inet.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv4/af_inet.c	2017-03-22 08:38:58.000000000 -0400
@@ -1470,8 +1470,10 @@ int inet_gro_complete(struct sk_buff *sk
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv4/fib_frontend.c linux-libre-4.10.5-gnu/net/ipv4/fib_frontend.c
--- linux-libre-4.10.4-gnu/net/ipv4/fib_frontend.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv4/fib_frontend.c	2017-03-22 08:38:58.000000000 -0400
@@ -319,7 +319,7 @@ static int __fib_validate_source(struct
 	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
 	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
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv4/route.c linux-libre-4.10.5-gnu/net/ipv4/route.c
--- linux-libre-4.10.4-gnu/net/ipv4/route.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv4/route.c	2017-03-22 08:38:58.000000000 -0400
@@ -1858,6 +1858,7 @@ static int ip_route_input_slow(struct sk
 	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
 {
 	int res;
 
+	tos &= IPTOS_RT_MASK;
 	rcu_read_lock();
 
 	/* Multicast recognition logic is moved from route cache to here.
diff -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv4/tcp_input.c linux-libre-4.10.5-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.10.4-gnu/net/ipv4/tcp_input.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv4/tcp_input.c	2017-03-22 08:38:58.000000000 -0400
@@ -5916,9 +5916,15 @@ int tcp_rcv_state_process(struct sock *s
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv4/tcp_ipv4.c linux-libre-4.10.5-gnu/net/ipv4/tcp_ipv4.c
--- linux-libre-4.10.4-gnu/net/ipv4/tcp_ipv4.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv4/tcp_ipv4.c	2017-03-22 08:38:58.000000000 -0400
@@ -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
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv4/tcp_timer.c linux-libre-4.10.5-gnu/net/ipv4/tcp_timer.c
--- linux-libre-4.10.4-gnu/net/ipv4/tcp_timer.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv4/tcp_timer.c	2017-03-22 08:38:58.000000000 -0400
@@ -249,7 +249,8 @@ void tcp_delack_timer_handler(struct soc
 
 	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
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv6/ip6_fib.c linux-libre-4.10.5-gnu/net/ipv6/ip6_fib.c
--- linux-libre-4.10.4-gnu/net/ipv6/ip6_fib.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv6/ip6_fib.c	2017-03-22 08:38:58.000000000 -0400
@@ -908,6 +908,8 @@ add:
 			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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv6/ip6_offload.c linux-libre-4.10.5-gnu/net/ipv6/ip6_offload.c
--- linux-libre-4.10.4-gnu/net/ipv6/ip6_offload.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv6/ip6_offload.c	2017-03-22 08:38:58.000000000 -0400
@@ -294,8 +294,10 @@ static int ipv6_gro_complete(struct sk_b
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv6/ip6_output.c linux-libre-4.10.5-gnu/net/ipv6/ip6_output.c
--- linux-libre-4.10.4-gnu/net/ipv6/ip6_output.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv6/ip6_output.c	2017-03-22 08:38:58.000000000 -0400
@@ -767,13 +767,14 @@ slow_path:
 	 *	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 @@ slow_path:
 		 */
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv6/ip6_vti.c linux-libre-4.10.5-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.10.4-gnu/net/ipv6/ip6_vti.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv6/ip6_vti.c	2017-03-22 08:38:58.000000000 -0400
@@ -692,6 +692,10 @@ vti6_parm_to_user(struct ip6_tnl_parm2 *
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c linux-libre-4.10.5-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c
--- linux-libre-4.10.4-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c	2017-03-22 08:38:58.000000000 -0400
@@ -589,6 +589,7 @@ int nf_ct_frag6_gather(struct net *net,
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/ipv6/tcp_ipv6.c linux-libre-4.10.5-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-4.10.4-gnu/net/ipv6/tcp_ipv6.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/ipv6/tcp_ipv6.c	2017-03-22 08:38:58.000000000 -0400
@@ -382,10 +382,12 @@ static void tcp_v6_err(struct sk_buff *s
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/l2tp/l2tp_ip.c linux-libre-4.10.5-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-4.10.4-gnu/net/l2tp/l2tp_ip.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/l2tp/l2tp_ip.c	2017-03-22 08:38:58.000000000 -0400
@@ -381,7 +381,7 @@ static int l2tp_ip_backlog_recv(struct s
 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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/mpls/af_mpls.c linux-libre-4.10.5-gnu/net/mpls/af_mpls.c
--- linux-libre-4.10.4-gnu/net/mpls/af_mpls.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/mpls/af_mpls.c	2017-03-22 08:38:58.000000000 -0400
@@ -956,7 +956,8 @@ static void mpls_ifdown(struct net_devic
 				/* 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 *ne
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/openvswitch/conntrack.c linux-libre-4.10.5-gnu/net/openvswitch/conntrack.c
--- linux-libre-4.10.4-gnu/net/openvswitch/conntrack.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/openvswitch/conntrack.c	2017-03-22 08:38:58.000000000 -0400
@@ -367,7 +367,6 @@ static int handle_fragments(struct net *
 	} 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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/packet/af_packet.c linux-libre-4.10.5-gnu/net/packet/af_packet.c
--- linux-libre-4.10.4-gnu/net/packet/af_packet.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/packet/af_packet.c	2017-03-22 08:38:58.000000000 -0400
@@ -3082,7 +3082,7 @@ static int packet_bind_spkt(struct socke
 			    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 socke
 
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/sched/act_api.c linux-libre-4.10.5-gnu/net/sched/act_api.c
--- linux-libre-4.10.4-gnu/net/sched/act_api.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/sched/act_api.c	2017-03-22 08:38:58.000000000 -0400
@@ -817,10 +817,8 @@ static int tca_action_flush(struct net *
 		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 *
 out_module_put:
 	module_put(ops->owner);
 err_out:
-noflush_out:
 	kfree_skb(skb);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.10.4-gnu/net/sched/act_connmark.c linux-libre-4.10.5-gnu/net/sched/act_connmark.c
--- linux-libre-4.10.4-gnu/net/sched/act_connmark.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/sched/act_connmark.c	2017-03-22 08:38:58.000000000 -0400
@@ -113,6 +113,9 @@ static int tcf_connmark_init(struct net
 	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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/sched/act_skbmod.c linux-libre-4.10.5-gnu/net/sched/act_skbmod.c
--- linux-libre-4.10.4-gnu/net/sched/act_skbmod.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/sched/act_skbmod.c	2017-03-22 08:38:58.000000000 -0400
@@ -228,7 +228,6 @@ static int tcf_skbmod_dump(struct sk_buf
 
 	return skb->len;
 nla_put_failure:
-	rcu_read_unlock();
 	nlmsg_trim(skb, b);
 	return -1;
 }
diff -druNp --no-dereference linux-libre-4.10.4-gnu/net/sctp/protocol.c linux-libre-4.10.5-gnu/net/sctp/protocol.c
--- linux-libre-4.10.4-gnu/net/sctp/protocol.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/sctp/protocol.c	2017-03-22 08:38:58.000000000 -0400
@@ -199,6 +199,7 @@ int sctp_copy_local_addr_list(struct net
 			      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
 		     !(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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/sctp/socket.c linux-libre-4.10.5-gnu/net/sctp/socket.c
--- linux-libre-4.10.4-gnu/net/sctp/socket.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/sctp/socket.c	2017-03-22 08:38:58.000000000 -0400
@@ -4734,6 +4734,12 @@ int sctp_do_peeloff(struct sock *sk, sct
 	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 s
 		 */
 		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 -druNp --no-dereference linux-libre-4.10.4-gnu/net/strparser/strparser.c linux-libre-4.10.5-gnu/net/strparser/strparser.c
--- linux-libre-4.10.4-gnu/net/strparser/strparser.c	2017-03-18 07:19:00.000000000 -0400
+++ linux-libre-4.10.5-gnu/net/strparser/strparser.c	2017-03-22 08:38:58.000000000 -0400
@@ -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);
