diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/arc/include/asm/entry-arcv2.h linux-libre-4.4.66-gnu/arch/arc/include/asm/entry-arcv2.h
--- linux-libre-4.4.65-gnu/arch/arc/include/asm/entry-arcv2.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/arc/include/asm/entry-arcv2.h	2017-05-03 00:20:09.000000000 -0400
@@ -16,6 +16,7 @@
 	;
 	; Now manually save: r12, sp, fp, gp, r25
 
+	PUSH	r30
 	PUSH	r12
 
 	; Saving pt_regs->sp correctly requires some extra work due to the way
@@ -72,6 +73,7 @@
 	POPAX	AUX_USER_SP
 1:
 	POP	r12
+	POP	r30
 
 .endm
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/arc/include/asm/ptrace.h linux-libre-4.4.66-gnu/arch/arc/include/asm/ptrace.h
--- linux-libre-4.4.65-gnu/arch/arc/include/asm/ptrace.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/arc/include/asm/ptrace.h	2017-05-03 00:20:09.000000000 -0400
@@ -84,7 +84,7 @@ struct pt_regs {
 	unsigned long fp;
 	unsigned long sp;	/* user/kernel sp depending on where we came from  */
 
-	unsigned long r12;
+	unsigned long r12, r30;
 
 	/*------- Below list auto saved by h/w -----------*/
 	unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/arm/mach-omap2/timer.c linux-libre-4.4.66-gnu/arch/arm/mach-omap2/timer.c
--- linux-libre-4.4.65-gnu/arch/arm/mach-omap2/timer.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/arm/mach-omap2/timer.c	2017-05-03 00:20:09.000000000 -0400
@@ -496,8 +496,7 @@ void __init omap_init_time(void)
 	__omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
 			2, "timer_sys_ck", NULL, false);
 
-	if (of_have_populated_dt())
-		clocksource_probe();
+	clocksource_probe();
 }
 
 #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
@@ -505,6 +504,8 @@ void __init omap3_secure_sync32k_timer_i
 {
 	__omap_sync32k_timer_init(12, "secure_32k_fck", "ti,timer-secure",
 			2, "timer_sys_ck", NULL, false);
+
+	clocksource_probe();
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
@@ -513,6 +514,8 @@ void __init omap3_gptimer_timer_init(voi
 {
 	__omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
 			1, "timer_sys_ck", "ti,timer-alwon", true);
+
+	clocksource_probe();
 }
 #endif
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/mips/kernel/crash.c linux-libre-4.4.66-gnu/arch/mips/kernel/crash.c
--- linux-libre-4.4.65-gnu/arch/mips/kernel/crash.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/mips/kernel/crash.c	2017-05-03 00:20:09.000000000 -0400
@@ -14,12 +14,22 @@ static int crashing_cpu = -1;
 static cpumask_t cpus_in_crash = CPU_MASK_NONE;
 
 #ifdef CONFIG_SMP
-static void crash_shutdown_secondary(void *ignore)
+static void crash_shutdown_secondary(void *passed_regs)
 {
-	struct pt_regs *regs;
+	struct pt_regs *regs = passed_regs;
 	int cpu = smp_processor_id();
 
-	regs = task_pt_regs(current);
+	/*
+	 * If we are passed registers, use those.  Otherwise get the
+	 * regs from the last interrupt, which should be correct, as
+	 * we are in an interrupt.  But if the regs are not there,
+	 * pull them from the top of the stack.  They are probably
+	 * wrong, but we need something to keep from crashing again.
+	 */
+	if (!regs)
+		regs = get_irq_regs();
+	if (!regs)
+		regs = task_pt_regs(current);
 
 	if (!cpu_online(cpu))
 		return;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/mips/kernel/elf.c linux-libre-4.4.66-gnu/arch/mips/kernel/elf.c
--- linux-libre-4.4.65-gnu/arch/mips/kernel/elf.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/mips/kernel/elf.c	2017-05-03 00:20:09.000000000 -0400
@@ -206,7 +206,7 @@ int arch_check_elf(void *_ehdr, bool has
 	else if ((prog_req.fr1 && prog_req.frdefault) ||
 		 (prog_req.single && !prog_req.frdefault))
 		/* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */
-		state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
+		state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
 					  cpu_has_mips_r2_r6) ?
 					  FP_FR1 : FP_FR0;
 	else if (prog_req.fr1)
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/mips/kernel/kgdb.c linux-libre-4.4.66-gnu/arch/mips/kernel/kgdb.c
--- linux-libre-4.4.65-gnu/arch/mips/kernel/kgdb.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/mips/kernel/kgdb.c	2017-05-03 00:20:09.000000000 -0400
@@ -244,9 +244,6 @@ static int compute_signal(int tt)
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
 	int reg;
-	struct thread_info *ti = task_thread_info(p);
-	unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
-	struct pt_regs *regs = (struct pt_regs *)ksp - 1;
 #if (KGDB_GDB_REG_SIZE == 32)
 	u32 *ptr = (u32 *)gdb_regs;
 #else
@@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigne
 #endif
 
 	for (reg = 0; reg < 16; reg++)
-		*(ptr++) = regs->regs[reg];
+		*(ptr++) = 0;
 
 	/* S0 - S7 */
-	for (reg = 16; reg < 24; reg++)
-		*(ptr++) = regs->regs[reg];
+	*(ptr++) = p->thread.reg16;
+	*(ptr++) = p->thread.reg17;
+	*(ptr++) = p->thread.reg18;
+	*(ptr++) = p->thread.reg19;
+	*(ptr++) = p->thread.reg20;
+	*(ptr++) = p->thread.reg21;
+	*(ptr++) = p->thread.reg22;
+	*(ptr++) = p->thread.reg23;
 
 	for (reg = 24; reg < 28; reg++)
 		*(ptr++) = 0;
 
 	/* GP, SP, FP, RA */
-	for (reg = 28; reg < 32; reg++)
-		*(ptr++) = regs->regs[reg];
+	*(ptr++) = (long)p;
+	*(ptr++) = p->thread.reg29;
+	*(ptr++) = p->thread.reg30;
+	*(ptr++) = p->thread.reg31;
 
-	*(ptr++) = regs->cp0_status;
-	*(ptr++) = regs->lo;
-	*(ptr++) = regs->hi;
-	*(ptr++) = regs->cp0_badvaddr;
-	*(ptr++) = regs->cp0_cause;
-	*(ptr++) = regs->cp0_epc;
+	*(ptr++) = p->thread.cp0_status;
+
+	/* lo, hi */
+	*(ptr++) = 0;
+	*(ptr++) = 0;
+
+	/*
+	 * BadVAddr, Cause
+	 * Ideally these would come from the last exception frame up the stack
+	 * but that requires unwinding, otherwise we can't know much for sure.
+	 */
+	*(ptr++) = 0;
+	*(ptr++) = 0;
+
+	/*
+	 * PC
+	 * use return address (RA), i.e. the moment after return from resume()
+	 */
+	*(ptr++) = p->thread.reg31;
 }
 
 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/sparc/include/asm/pgtable_64.h linux-libre-4.4.66-gnu/arch/sparc/include/asm/pgtable_64.h
--- linux-libre-4.4.65-gnu/arch/sparc/include/asm/pgtable_64.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/sparc/include/asm/pgtable_64.h	2017-05-03 00:20:09.000000000 -0400
@@ -668,26 +668,27 @@ static inline unsigned long pmd_pfn(pmd_
 	return pte_pfn(pte);
 }
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-static inline unsigned long pmd_dirty(pmd_t pmd)
+#define __HAVE_ARCH_PMD_WRITE
+static inline unsigned long pmd_write(pmd_t pmd)
 {
 	pte_t pte = __pte(pmd_val(pmd));
 
-	return pte_dirty(pte);
+	return pte_write(pte);
 }
 
-static inline unsigned long pmd_young(pmd_t pmd)
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static inline unsigned long pmd_dirty(pmd_t pmd)
 {
 	pte_t pte = __pte(pmd_val(pmd));
 
-	return pte_young(pte);
+	return pte_dirty(pte);
 }
 
-static inline unsigned long pmd_write(pmd_t pmd)
+static inline unsigned long pmd_young(pmd_t pmd)
 {
 	pte_t pte = __pte(pmd_val(pmd));
 
-	return pte_write(pte);
+	return pte_young(pte);
 }
 
 static inline unsigned long pmd_trans_huge(pmd_t pmd)
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/sparc/mm/init_64.c linux-libre-4.4.66-gnu/arch/sparc/mm/init_64.c
--- linux-libre-4.4.65-gnu/arch/sparc/mm/init_64.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/sparc/mm/init_64.c	2017-05-03 00:20:09.000000000 -0400
@@ -1493,7 +1493,7 @@ bool kern_addr_valid(unsigned long addr)
 	if ((long)addr < 0L) {
 		unsigned long pa = __pa(addr);
 
-		if ((addr >> max_phys_bits) != 0UL)
+		if ((pa >> max_phys_bits) != 0UL)
 			return false;
 
 		return pfn_valid(pa >> PAGE_SHIFT);
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/x86/kernel/ftrace.c linux-libre-4.4.66-gnu/arch/x86/kernel/ftrace.c
--- linux-libre-4.4.65-gnu/arch/x86/kernel/ftrace.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/x86/kernel/ftrace.c	2017-05-03 00:20:09.000000000 -0400
@@ -977,6 +977,18 @@ void prepare_ftrace_return(unsigned long
 	unsigned long return_hooker = (unsigned long)
 				&return_to_handler;
 
+	/*
+	 * When resuming from suspend-to-ram, this function can be indirectly
+	 * called from early CPU startup code while the CPU is in real mode,
+	 * which would fail miserably.  Make sure the stack pointer is a
+	 * virtual address.
+	 *
+	 * This check isn't as accurate as virt_addr_valid(), but it should be
+	 * good enough for this purpose, and it's fast.
+	 */
+	if (unlikely((long)__builtin_frame_address(0) >= 0))
+		return;
+
 	if (unlikely(ftrace_graph_is_dead()))
 		return;
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/arch/x86/xen/time.c linux-libre-4.4.66-gnu/arch/x86/xen/time.c
--- linux-libre-4.4.65-gnu/arch/x86/xen/time.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/arch/x86/xen/time.c	2017-05-03 00:20:09.000000000 -0400
@@ -343,11 +343,11 @@ static int xen_vcpuop_set_next_event(uns
 	WARN_ON(!clockevent_state_oneshot(evt));
 
 	single.timeout_abs_ns = get_abs_timeout(delta);
-	single.flags = VCPU_SSHOTTMR_future;
+	/* Get an event anyway, even if the timeout is already expired */
+	single.flags = 0;
 
 	ret = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &single);
-
-	BUG_ON(ret != 0 && ret != -ETIME);
+	BUG_ON(ret != 0);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.4.65-gnu/crypto/testmgr.c linux-libre-4.4.66-gnu/crypto/testmgr.c
--- linux-libre-4.4.65-gnu/crypto/testmgr.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/crypto/testmgr.c	2017-05-03 00:20:09.000000000 -0400
@@ -488,6 +488,8 @@ static int __test_aead(struct crypto_aea
 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				  tcrypt_complete, &result);
 
+	iv_len = crypto_aead_ivsize(tfm);
+
 	for (i = 0, j = 0; i < tcount; i++) {
 		if (template[i].np)
 			continue;
@@ -508,7 +510,6 @@ static int __test_aead(struct crypto_aea
 
 		memcpy(input, template[i].input, template[i].ilen);
 		memcpy(assoc, template[i].assoc, template[i].alen);
-		iv_len = crypto_aead_ivsize(tfm);
 		if (template[i].iv)
 			memcpy(iv, template[i].iv, iv_len);
 		else
@@ -617,7 +618,7 @@ static int __test_aead(struct crypto_aea
 		j++;
 
 		if (template[i].iv)
-			memcpy(iv, template[i].iv, MAX_IVLEN);
+			memcpy(iv, template[i].iv, iv_len);
 		else
 			memset(iv, 0, MAX_IVLEN);
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/Documentation/devicetree/bindings/clock/sunxi.txt linux-libre-4.4.66-gnu/Documentation/devicetree/bindings/clock/sunxi.txt
--- linux-libre-4.4.65-gnu/Documentation/devicetree/bindings/clock/sunxi.txt	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/Documentation/devicetree/bindings/clock/sunxi.txt	2017-05-03 00:20:09.000000000 -0400
@@ -18,6 +18,7 @@ Required properties:
 	"allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock
 	"allwinner,sun4i-a10-axi-clk" - for the AXI clock
 	"allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23
+	"allwinner,sun4i-a10-gates-clk" - for generic gates on all compatible SoCs
 	"allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates
 	"allwinner,sun4i-a10-ahb-clk" - for the AHB clock
 	"allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
@@ -43,6 +44,7 @@ Required properties:
 	"allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31
 	"allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
 	"allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23
+	"allwinner,sun8i-h3-apb0-gates-clk" - for the APB0 gates on H3
 	"allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80
 	"allwinner,sun4i-a10-apb1-clk" - for the APB1 clock
 	"allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/clk/sunxi/clk-simple-gates.c linux-libre-4.4.66-gnu/drivers/clk/sunxi/clk-simple-gates.c
--- linux-libre-4.4.65-gnu/drivers/clk/sunxi/clk-simple-gates.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/clk/sunxi/clk-simple-gates.c	2017-05-03 00:20:09.000000000 -0400
@@ -98,6 +98,8 @@ static void __init sunxi_simple_gates_in
 	sunxi_simple_gates_setup(node, NULL, 0);
 }
 
+CLK_OF_DECLARE(sun4i_a10_gates, "allwinner,sun4i-a10-gates-clk",
+	       sunxi_simple_gates_init);
 CLK_OF_DECLARE(sun4i_a10_apb0, "allwinner,sun4i-a10-apb0-gates-clk",
 	       sunxi_simple_gates_init);
 CLK_OF_DECLARE(sun4i_a10_apb1, "allwinner,sun4i-a10-apb1-gates-clk",
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/gpu/drm/amd/amdgpu/kv_dpm.c linux-libre-4.4.66-gnu/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
--- linux-libre-4.4.65-gnu/drivers/gpu/drm/amd/amdgpu/kv_dpm.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/gpu/drm/amd/amdgpu/kv_dpm.c	2017-05-03 00:20:09.000000000 -0400
@@ -2258,7 +2258,7 @@ static void kv_apply_state_adjust_rules(
 	if (pi->caps_stable_p_state) {
 		stable_p_state_sclk = (max_limits->sclk * 75) / 100;
 
-		for (i = table->count - 1; i >= 0; i++) {
+		for (i = table->count - 1; i >= 0; i--) {
 			if (stable_p_state_sclk >= table->entries[i].clk) {
 				stable_p_state_sclk = table->entries[i].clk;
 				break;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/input/serio/i8042-x86ia64io.h linux-libre-4.4.66-gnu/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-4.4.65-gnu/drivers/input/serio/i8042-x86ia64io.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/input/serio/i8042-x86ia64io.h	2017-05-03 00:20:09.000000000 -0400
@@ -685,6 +685,13 @@ static const struct dmi_system_id __init
 			DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
 		},
 	},
+	{
+		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
+		},
+	},
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/md/raid1.c linux-libre-4.4.66-gnu/drivers/md/raid1.c
--- linux-libre-4.4.65-gnu/drivers/md/raid1.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/md/raid1.c	2017-05-03 00:20:09.000000000 -0400
@@ -570,7 +570,7 @@ static int read_balance(struct r1conf *c
 			if (best_dist_disk < 0) {
 				if (is_badblock(rdev, this_sector, sectors,
 						&first_bad, &bad_sectors)) {
-					if (first_bad < this_sector)
+					if (first_bad <= this_sector)
 						/* Cannot use this */
 						continue;
 					best_good_sectors = first_bad - this_sector;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/media/tuners/tuner-xc2028.c linux-libre-4.4.66-gnu/drivers/media/tuners/tuner-xc2028.c
--- linux-libre-4.4.65-gnu/drivers/media/tuners/tuner-xc2028.c	2017-04-30 00:58:21.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/media/tuners/tuner-xc2028.c	2017-05-03 23:09:33.000000000 -0400
@@ -1407,8 +1407,10 @@ static int xc2028_set_config(struct dvb_
 	memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
 	if (p->fname) {
 		priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
-		if (priv->ctrl.fname == NULL)
-			return -ENOMEM;
+		if (priv->ctrl.fname == NULL) {
+			rc = -ENOMEM;
+			goto unlock;
+		}
 	}
 
 	/*
@@ -1440,6 +1442,7 @@ static int xc2028_set_config(struct dvb_
 		} else
 			priv->state = XC2028_WAITING_FIRMWARE;
 	}
+unlock:
 	mutex_unlock(&priv->lock);
 
 	return rc;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/net/ethernet/cavium/liquidio/lio_main.c linux-libre-4.4.66-gnu/drivers/net/ethernet/cavium/liquidio/lio_main.c
--- linux-libre-4.4.65-gnu/drivers/net/ethernet/cavium/liquidio/lio_main.c	2017-04-30 01:09:12.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/net/ethernet/cavium/liquidio/lio_main.c	2017-05-03 23:19:30.000000000 -0400
@@ -2821,7 +2821,7 @@ static int liquidio_xmit(struct sk_buff
 		if (!g) {
 			netif_info(lio, tx_err, lio->netdev,
 				   "Transmit scatter gather: glist null!\n");
-			goto lio_xmit_failed;
+			goto lio_xmit_dma_failed;
 		}
 
 		cmdsetup.s.gather = 1;
@@ -2892,7 +2892,7 @@ static int liquidio_xmit(struct sk_buff
 	else
 		status = octnet_send_nic_data_pkt(oct, &ndata, xmit_more);
 	if (status == IQ_SEND_FAILED)
-		goto lio_xmit_failed;
+		goto lio_xmit_dma_failed;
 
 	netif_info(lio, tx_queued, lio->netdev, "Transmit queued successfully\n");
 
@@ -2906,12 +2906,13 @@ static int liquidio_xmit(struct sk_buff
 
 	return NETDEV_TX_OK;
 
+lio_xmit_dma_failed:
+	dma_unmap_single(&oct->pci_dev->dev, ndata.cmd.dptr,
+			 ndata.datasize, DMA_TO_DEVICE);
 lio_xmit_failed:
 	stats->tx_dropped++;
 	netif_info(lio, tx_err, lio->netdev, "IQ%d Transmit dropped:%llu\n",
 		   iq_no, stats->tx_dropped);
-	dma_unmap_single(&oct->pci_dev->dev, ndata.cmd.dptr,
-			 ndata.datasize, DMA_TO_DEVICE);
 	recv_buffer_free(skb);
 	return NETDEV_TX_OK;
 }
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/net/macvlan.c linux-libre-4.4.66-gnu/drivers/net/macvlan.c
--- linux-libre-4.4.65-gnu/drivers/net/macvlan.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/net/macvlan.c	2017-05-03 00:20:09.000000000 -0400
@@ -1110,6 +1110,7 @@ static int macvlan_port_create(struct ne
 static void macvlan_port_destroy(struct net_device *dev)
 {
 	struct macvlan_port *port = macvlan_port_get_rtnl(dev);
+	struct sk_buff *skb;
 
 	dev->priv_flags &= ~IFF_MACVLAN_PORT;
 	netdev_rx_handler_unregister(dev);
@@ -1118,7 +1119,15 @@ static void macvlan_port_destroy(struct
 	 * but we need to cancel it and purge left skbs if any.
 	 */
 	cancel_work_sync(&port->bc_work);
-	__skb_queue_purge(&port->bc_queue);
+
+	while ((skb = __skb_dequeue(&port->bc_queue))) {
+		const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
+
+		if (src)
+			dev_put(src->dev);
+
+		kfree_skb(skb);
+	}
 
 	kfree_rcu(port, rcu);
 }
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/net/phy/dp83640.c linux-libre-4.4.66-gnu/drivers/net/phy/dp83640.c
--- linux-libre-4.4.65-gnu/drivers/net/phy/dp83640.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/net/phy/dp83640.c	2017-05-03 00:20:09.000000000 -0400
@@ -1436,8 +1436,6 @@ static bool dp83640_rxtstamp(struct phy_
 		skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT;
 		skb_queue_tail(&dp83640->rx_queue, skb);
 		schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
-	} else {
-		netif_rx_ni(skb);
 	}
 
 	return true;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/net/phy/phy.c linux-libre-4.4.66-gnu/drivers/net/phy/phy.c
--- linux-libre-4.4.65-gnu/drivers/net/phy/phy.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/net/phy/phy.c	2017-05-03 00:20:09.000000000 -0400
@@ -538,7 +538,7 @@ void phy_stop_machine(struct phy_device
 	cancel_delayed_work_sync(&phydev->state_queue);
 
 	mutex_lock(&phydev->lock);
-	if (phydev->state > PHY_UP)
+	if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
 		phydev->state = PHY_UP;
 	mutex_unlock(&phydev->lock);
 }
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/regulator/core.c linux-libre-4.4.66-gnu/drivers/regulator/core.c
--- linux-libre-4.4.65-gnu/drivers/regulator/core.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/regulator/core.c	2017-05-03 00:20:09.000000000 -0400
@@ -1519,6 +1519,7 @@ static int regulator_resolve_supply(stru
 		ret = regulator_enable(rdev->supply);
 		if (ret < 0) {
 			_regulator_put(rdev->supply);
+			rdev->supply = NULL;
 			return ret;
 		}
 	}
diff -druNp --no-dereference linux-libre-4.4.65-gnu/drivers/usb/gadget/function/f_midi.c linux-libre-4.4.66-gnu/drivers/usb/gadget/function/f_midi.c
--- linux-libre-4.4.65-gnu/drivers/usb/gadget/function/f_midi.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/drivers/usb/gadget/function/f_midi.c	2017-05-03 00:20:09.000000000 -0400
@@ -361,7 +361,9 @@ static int f_midi_set_alt(struct usb_fun
 	/* allocate a bunch of read buffers and queue them all at once. */
 	for (i = 0; i < midi->qlen && err == 0; i++) {
 		struct usb_request *req =
-			midi_alloc_ep_req(midi->out_ep, midi->buflen);
+			midi_alloc_ep_req(midi->out_ep,
+				max_t(unsigned, midi->buflen,
+					bulk_out_desc.wMaxPacketSize));
 		if (req == NULL)
 			return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/fs/ext4/xattr.c linux-libre-4.4.66-gnu/fs/ext4/xattr.c
--- linux-libre-4.4.65-gnu/fs/ext4/xattr.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/fs/ext4/xattr.c	2017-05-03 00:20:09.000000000 -0400
@@ -233,6 +233,27 @@ ext4_xattr_check_block(struct inode *ino
 	return error;
 }
 
+static int
+__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
+			 void *end, const char *function, unsigned int line)
+{
+	struct ext4_xattr_entry *entry = IFIRST(header);
+	int error = -EFSCORRUPTED;
+
+	if (((void *) header >= end) ||
+	    (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC)))
+		goto errout;
+	error = ext4_xattr_check_names(entry, end, entry);
+errout:
+	if (error)
+		__ext4_error_inode(inode, function, line, 0,
+				   "corrupted in-inode xattr");
+	return error;
+}
+
+#define xattr_check_inode(inode, header, end) \
+	__xattr_check_inode((inode), (header), (end), __func__, __LINE__)
+
 static inline int
 ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
 {
@@ -344,7 +365,7 @@ ext4_xattr_ibody_get(struct inode *inode
 	header = IHDR(inode, raw_inode);
 	entry = IFIRST(header);
 	end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
-	error = ext4_xattr_check_names(entry, end, entry);
+	error = xattr_check_inode(inode, header, end);
 	if (error)
 		goto cleanup;
 	error = ext4_xattr_find_entry(&entry, name_index, name,
@@ -475,7 +496,7 @@ ext4_xattr_ibody_list(struct dentry *den
 	raw_inode = ext4_raw_inode(&iloc);
 	header = IHDR(inode, raw_inode);
 	end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
-	error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header));
+	error = xattr_check_inode(inode, header, end);
 	if (error)
 		goto cleanup;
 	error = ext4_xattr_list_entries(dentry, IFIRST(header),
@@ -991,8 +1012,7 @@ int ext4_xattr_ibody_find(struct inode *
 	is->s.here = is->s.first;
 	is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
 	if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
-		error = ext4_xattr_check_names(IFIRST(header), is->s.end,
-					       IFIRST(header));
+		error = xattr_check_inode(inode, header, is->s.end);
 		if (error)
 			return error;
 		/* Find the named attribute. */
@@ -1293,6 +1313,10 @@ retry:
 	last = entry;
 	total_ino = sizeof(struct ext4_xattr_ibody_header);
 
+	error = xattr_check_inode(inode, header, end);
+	if (error)
+		goto cleanup;
+
 	free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
 	if (free >= isize_diff) {
 		entry = IFIRST(header);
diff -druNp --no-dereference linux-libre-4.4.65-gnu/fs/f2fs/super.c linux-libre-4.4.66-gnu/fs/f2fs/super.c
--- linux-libre-4.4.65-gnu/fs/f2fs/super.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/fs/f2fs/super.c	2017-05-03 00:20:09.000000000 -0400
@@ -918,6 +918,79 @@ static loff_t max_file_size(unsigned bit
 	return result;
 }
 
+static inline bool sanity_check_area_boundary(struct super_block *sb,
+					struct f2fs_super_block *raw_super)
+{
+	u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
+	u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr);
+	u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr);
+	u32 nat_blkaddr = le32_to_cpu(raw_super->nat_blkaddr);
+	u32 ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
+	u32 main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
+	u32 segment_count_ckpt = le32_to_cpu(raw_super->segment_count_ckpt);
+	u32 segment_count_sit = le32_to_cpu(raw_super->segment_count_sit);
+	u32 segment_count_nat = le32_to_cpu(raw_super->segment_count_nat);
+	u32 segment_count_ssa = le32_to_cpu(raw_super->segment_count_ssa);
+	u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main);
+	u32 segment_count = le32_to_cpu(raw_super->segment_count);
+	u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
+
+	if (segment0_blkaddr != cp_blkaddr) {
+		f2fs_msg(sb, KERN_INFO,
+			"Mismatch start address, segment0(%u) cp_blkaddr(%u)",
+			segment0_blkaddr, cp_blkaddr);
+		return true;
+	}
+
+	if (cp_blkaddr + (segment_count_ckpt << log_blocks_per_seg) !=
+							sit_blkaddr) {
+		f2fs_msg(sb, KERN_INFO,
+			"Wrong CP boundary, start(%u) end(%u) blocks(%u)",
+			cp_blkaddr, sit_blkaddr,
+			segment_count_ckpt << log_blocks_per_seg);
+		return true;
+	}
+
+	if (sit_blkaddr + (segment_count_sit << log_blocks_per_seg) !=
+							nat_blkaddr) {
+		f2fs_msg(sb, KERN_INFO,
+			"Wrong SIT boundary, start(%u) end(%u) blocks(%u)",
+			sit_blkaddr, nat_blkaddr,
+			segment_count_sit << log_blocks_per_seg);
+		return true;
+	}
+
+	if (nat_blkaddr + (segment_count_nat << log_blocks_per_seg) !=
+							ssa_blkaddr) {
+		f2fs_msg(sb, KERN_INFO,
+			"Wrong NAT boundary, start(%u) end(%u) blocks(%u)",
+			nat_blkaddr, ssa_blkaddr,
+			segment_count_nat << log_blocks_per_seg);
+		return true;
+	}
+
+	if (ssa_blkaddr + (segment_count_ssa << log_blocks_per_seg) !=
+							main_blkaddr) {
+		f2fs_msg(sb, KERN_INFO,
+			"Wrong SSA boundary, start(%u) end(%u) blocks(%u)",
+			ssa_blkaddr, main_blkaddr,
+			segment_count_ssa << log_blocks_per_seg);
+		return true;
+	}
+
+	if (main_blkaddr + (segment_count_main << log_blocks_per_seg) !=
+		segment0_blkaddr + (segment_count << log_blocks_per_seg)) {
+		f2fs_msg(sb, KERN_INFO,
+			"Wrong MAIN_AREA boundary, start(%u) end(%u) blocks(%u)",
+			main_blkaddr,
+			segment0_blkaddr + (segment_count << log_blocks_per_seg),
+			segment_count_main << log_blocks_per_seg);
+		return true;
+	}
+
+	return false;
+}
+
 static int sanity_check_raw_super(struct super_block *sb,
 			struct f2fs_super_block *raw_super)
 {
@@ -947,6 +1020,14 @@ static int sanity_check_raw_super(struct
 		return 1;
 	}
 
+	/* check log blocks per segment */
+	if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) {
+		f2fs_msg(sb, KERN_INFO,
+			"Invalid log blocks per segment (%u)\n",
+			le32_to_cpu(raw_super->log_blocks_per_seg));
+		return 1;
+	}
+
 	/* Currently, support 512/1024/2048/4096 bytes sector size */
 	if (le32_to_cpu(raw_super->log_sectorsize) >
 				F2FS_MAX_LOG_SECTOR_SIZE ||
@@ -965,6 +1046,23 @@ static int sanity_check_raw_super(struct
 			le32_to_cpu(raw_super->log_sectorsize));
 		return 1;
 	}
+
+	/* check reserved ino info */
+	if (le32_to_cpu(raw_super->node_ino) != 1 ||
+		le32_to_cpu(raw_super->meta_ino) != 2 ||
+		le32_to_cpu(raw_super->root_ino) != 3) {
+		f2fs_msg(sb, KERN_INFO,
+			"Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)",
+			le32_to_cpu(raw_super->node_ino),
+			le32_to_cpu(raw_super->meta_ino),
+			le32_to_cpu(raw_super->root_ino));
+		return 1;
+	}
+
+	/* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
+	if (sanity_check_area_boundary(sb, raw_super))
+		return 1;
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/fs/nfsd/nfssvc.c linux-libre-4.4.66-gnu/fs/nfsd/nfssvc.c
--- linux-libre-4.4.65-gnu/fs/nfsd/nfssvc.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/fs/nfsd/nfssvc.c	2017-05-03 00:20:09.000000000 -0400
@@ -656,6 +656,37 @@ static __be32 map_new_errors(u32 vers, _
 	return nfserr;
 }
 
+/*
+ * A write procedure can have a large argument, and a read procedure can
+ * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
+ * reply that can both be larger than a page.  The xdr code has taken
+ * advantage of this assumption to be a sloppy about bounds checking in
+ * some cases.  Pending a rewrite of the NFSv2/v3 xdr code to fix that
+ * problem, we enforce these assumptions here:
+ */
+static bool nfs_request_too_big(struct svc_rqst *rqstp,
+				struct svc_procedure *proc)
+{
+	/*
+	 * The ACL code has more careful bounds-checking and is not
+	 * susceptible to this problem:
+	 */
+	if (rqstp->rq_prog != NFS_PROGRAM)
+		return false;
+	/*
+	 * Ditto NFSv4 (which can in theory have argument and reply both
+	 * more than a page):
+	 */
+	if (rqstp->rq_vers >= 4)
+		return false;
+	/* The reply will be small, we're OK: */
+	if (proc->pc_xdrressize > 0 &&
+	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
+		return false;
+
+	return rqstp->rq_arg.len > PAGE_SIZE;
+}
+
 int
 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 {
@@ -668,6 +699,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __
 				rqstp->rq_vers, rqstp->rq_proc);
 	proc = rqstp->rq_procinfo;
 
+	if (nfs_request_too_big(rqstp, proc)) {
+		dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
+		*statp = rpc_garbage_args;
+		return 1;
+	}
 	/*
 	 * Give the xdr decoder a chance to change this if it wants
 	 * (necessary in the NFSv4.0 compound case)
diff -druNp --no-dereference linux-libre-4.4.65-gnu/include/uapi/linux/ipv6_route.h linux-libre-4.4.66-gnu/include/uapi/linux/ipv6_route.h
--- linux-libre-4.4.65-gnu/include/uapi/linux/ipv6_route.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/include/uapi/linux/ipv6_route.h	2017-05-03 00:20:09.000000000 -0400
@@ -34,7 +34,7 @@
 #define RTF_PREF(pref)	((pref) << 27)
 #define RTF_PREF_MASK	0x18000000
 
-#define RTF_PCPU	0x40000000
+#define RTF_PCPU	0x40000000	/* read-only: can not be set by user */
 #define RTF_LOCAL	0x80000000
 
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/Makefile linux-libre-4.4.66-gnu/Makefile
--- linux-libre-4.4.65-gnu/Makefile	2017-04-30 00:51:45.000000000 -0400
+++ linux-libre-4.4.66-gnu/Makefile	2017-05-03 23:03:05.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 65
+SUBLEVEL = 66
 EXTRAVERSION = -gnu
 NAME = Blurry Fish Butt
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/9p/client.c linux-libre-4.4.66-gnu/net/9p/client.c
--- linux-libre-4.4.65-gnu/net/9p/client.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/9p/client.c	2017-05-03 00:20:09.000000000 -0400
@@ -2101,6 +2101,10 @@ int p9_client_readdir(struct p9_fid *fid
 		trace_9p_protocol_dump(clnt, req->rc);
 		goto free_and_error;
 	}
+	if (rsize < count) {
+		pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
+		count = rsize;
+	}
 
 	p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/core/neighbour.c linux-libre-4.4.66-gnu/net/core/neighbour.c
--- linux-libre-4.4.65-gnu/net/core/neighbour.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/core/neighbour.c	2017-05-03 00:20:09.000000000 -0400
@@ -859,7 +859,8 @@ static void neigh_probe(struct neighbour
 	if (skb)
 		skb = skb_clone(skb, GFP_ATOMIC);
 	write_unlock(&neigh->lock);
-	neigh->ops->solicit(neigh, skb);
+	if (neigh->ops->solicit)
+		neigh->ops->solicit(neigh, skb);
 	atomic_inc(&neigh->probes);
 	kfree_skb(skb);
 }
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/core/netpoll.c linux-libre-4.4.66-gnu/net/core/netpoll.c
--- linux-libre-4.4.65-gnu/net/core/netpoll.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/core/netpoll.c	2017-05-03 00:20:09.000000000 -0400
@@ -105,15 +105,21 @@ static void queue_process(struct work_st
 	while ((skb = skb_dequeue(&npinfo->txq))) {
 		struct net_device *dev = skb->dev;
 		struct netdev_queue *txq;
+		unsigned int q_index;
 
 		if (!netif_device_present(dev) || !netif_running(dev)) {
 			kfree_skb(skb);
 			continue;
 		}
 
-		txq = skb_get_tx_queue(dev, skb);
-
 		local_irq_save(flags);
+		/* check if skb->queue_mapping is still valid */
+		q_index = skb_get_queue_mapping(skb);
+		if (unlikely(q_index >= dev->real_num_tx_queues)) {
+			q_index = q_index % dev->real_num_tx_queues;
+			skb_set_queue_mapping(skb, q_index);
+		}
+		txq = netdev_get_tx_queue(dev, q_index);
 		HARD_TX_LOCK(dev, txq, smp_processor_id());
 		if (netif_xmit_frozen_or_stopped(txq) ||
 		    netpoll_start_xmit(skb, dev, txq) != NETDEV_TX_OK) {
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/ipv4/route.c linux-libre-4.4.66-gnu/net/ipv4/route.c
--- linux-libre-4.4.65-gnu/net/ipv4/route.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/ipv4/route.c	2017-05-03 00:20:09.000000000 -0400
@@ -2559,7 +2559,7 @@ static int inet_rtm_getroute(struct sk_b
 	skb_reset_network_header(skb);
 
 	/* Bugfix: need to give ip_route_input enough of an IP header to not gag. */
-	ip_hdr(skb)->protocol = IPPROTO_ICMP;
+	ip_hdr(skb)->protocol = IPPROTO_UDP;
 	skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
 
 	src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/ipv4/tcp.c linux-libre-4.4.66-gnu/net/ipv4/tcp.c
--- linux-libre-4.4.65-gnu/net/ipv4/tcp.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/ipv4/tcp.c	2017-05-03 00:20:09.000000000 -0400
@@ -2260,6 +2260,7 @@ int tcp_disconnect(struct sock *sk, int
 	tcp_init_send_head(sk);
 	memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
 	__sk_dst_reset(sk);
+	tcp_saved_syn_free(tp);
 
 	WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/ipv6/ip6mr.c linux-libre-4.4.66-gnu/net/ipv6/ip6mr.c
--- linux-libre-4.4.65-gnu/net/ipv6/ip6mr.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/ipv6/ip6mr.c	2017-05-03 00:20:09.000000000 -0400
@@ -774,7 +774,8 @@ failure:
  *	Delete a VIF entry
  */
 
-static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
+static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
+		       struct list_head *head)
 {
 	struct mif_device *v;
 	struct net_device *dev;
@@ -820,7 +821,7 @@ static int mif6_delete(struct mr6_table
 					     dev->ifindex, &in6_dev->cnf);
 	}
 
-	if (v->flags & MIFF_REGISTER)
+	if ((v->flags & MIFF_REGISTER) && !notify)
 		unregister_netdevice_queue(dev, head);
 
 	dev_put(dev);
@@ -1330,7 +1331,6 @@ static int ip6mr_device_event(struct not
 	struct mr6_table *mrt;
 	struct mif_device *v;
 	int ct;
-	LIST_HEAD(list);
 
 	if (event != NETDEV_UNREGISTER)
 		return NOTIFY_DONE;
@@ -1339,10 +1339,9 @@ static int ip6mr_device_event(struct not
 		v = &mrt->vif6_table[0];
 		for (ct = 0; ct < mrt->maxvif; ct++, v++) {
 			if (v->dev == dev)
-				mif6_delete(mrt, ct, &list);
+				mif6_delete(mrt, ct, 1, NULL);
 		}
 	}
-	unregister_netdevice_many(&list);
 
 	return NOTIFY_DONE;
 }
@@ -1551,7 +1550,7 @@ static void mroute_clean_tables(struct m
 	for (i = 0; i < mrt->maxvif; i++) {
 		if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
 			continue;
-		mif6_delete(mrt, i, &list);
+		mif6_delete(mrt, i, 0, &list);
 	}
 	unregister_netdevice_many(&list);
 
@@ -1704,7 +1703,7 @@ int ip6_mroute_setsockopt(struct sock *s
 		if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
 			return -EFAULT;
 		rtnl_lock();
-		ret = mif6_delete(mrt, mifi, NULL);
+		ret = mif6_delete(mrt, mifi, 0, NULL);
 		rtnl_unlock();
 		return ret;
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/ipv6/ip6_tunnel.c linux-libre-4.4.66-gnu/net/ipv6/ip6_tunnel.c
--- linux-libre-4.4.65-gnu/net/ipv6/ip6_tunnel.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/ipv6/ip6_tunnel.c	2017-05-03 00:20:09.000000000 -0400
@@ -1049,7 +1049,7 @@ static int ip6_tnl_xmit2(struct sk_buff
 	struct ip6_tnl *t = netdev_priv(dev);
 	struct net *net = t->net;
 	struct net_device_stats *stats = &t->dev->stats;
-	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+	struct ipv6hdr *ipv6h;
 	struct ipv6_tel_txoption opt;
 	struct dst_entry *dst = NULL, *ndst = NULL;
 	struct net_device *tdev;
@@ -1061,26 +1061,28 @@ static int ip6_tnl_xmit2(struct sk_buff
 
 	/* NBMA tunnel */
 	if (ipv6_addr_any(&t->parms.raddr)) {
-		struct in6_addr *addr6;
-		struct neighbour *neigh;
-		int addr_type;
+		if (skb->protocol == htons(ETH_P_IPV6)) {
+			struct in6_addr *addr6;
+			struct neighbour *neigh;
+			int addr_type;
 
-		if (!skb_dst(skb))
-			goto tx_err_link_failure;
+			if (!skb_dst(skb))
+				goto tx_err_link_failure;
 
-		neigh = dst_neigh_lookup(skb_dst(skb),
-					 &ipv6_hdr(skb)->daddr);
-		if (!neigh)
-			goto tx_err_link_failure;
+			neigh = dst_neigh_lookup(skb_dst(skb),
+						 &ipv6_hdr(skb)->daddr);
+			if (!neigh)
+				goto tx_err_link_failure;
 
-		addr6 = (struct in6_addr *)&neigh->primary_key;
-		addr_type = ipv6_addr_type(addr6);
+			addr6 = (struct in6_addr *)&neigh->primary_key;
+			addr_type = ipv6_addr_type(addr6);
 
-		if (addr_type == IPV6_ADDR_ANY)
-			addr6 = &ipv6_hdr(skb)->daddr;
+			if (addr_type == IPV6_ADDR_ANY)
+				addr6 = &ipv6_hdr(skb)->daddr;
 
-		memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
-		neigh_release(neigh);
+			memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
+			neigh_release(neigh);
+		}
 	} else if (!(t->parms.flags &
 		     (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) {
 		/* enable the cache only only if the routing decision does
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/ipv6/raw.c linux-libre-4.4.66-gnu/net/ipv6/raw.c
--- linux-libre-4.4.65-gnu/net/ipv6/raw.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/ipv6/raw.c	2017-05-03 00:20:09.000000000 -0400
@@ -1144,8 +1144,7 @@ static int rawv6_ioctl(struct sock *sk,
 		spin_lock_bh(&sk->sk_receive_queue.lock);
 		skb = skb_peek(&sk->sk_receive_queue);
 		if (skb)
-			amount = skb_tail_pointer(skb) -
-				skb_transport_header(skb);
+			amount = skb->len;
 		spin_unlock_bh(&sk->sk_receive_queue.lock);
 		return put_user(amount, (int __user *)arg);
 	}
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/ipv6/route.c linux-libre-4.4.66-gnu/net/ipv6/route.c
--- linux-libre-4.4.65-gnu/net/ipv6/route.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/ipv6/route.c	2017-05-03 00:20:09.000000000 -0400
@@ -1758,6 +1758,10 @@ static struct rt6_info *ip6_route_info_c
 	int addr_type;
 	int err = -EINVAL;
 
+	/* RTF_PCPU is an internal flag; can not be set by userspace */
+	if (cfg->fc_flags & RTF_PCPU)
+		goto out;
+
 	if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128)
 		goto out;
 #ifndef CONFIG_IPV6_SUBTREES
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/l2tp/l2tp_core.c linux-libre-4.4.66-gnu/net/l2tp/l2tp_core.c
--- linux-libre-4.4.65-gnu/net/l2tp/l2tp_core.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/l2tp/l2tp_core.c	2017-05-03 00:20:09.000000000 -0400
@@ -278,7 +278,8 @@ struct l2tp_session *l2tp_session_find(s
 }
 EXPORT_SYMBOL_GPL(l2tp_session_find);
 
-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
+struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
+					  bool do_ref)
 {
 	int hash;
 	struct l2tp_session *session;
@@ -288,6 +289,9 @@ struct l2tp_session *l2tp_session_find_n
 	for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
 		hlist_for_each_entry(session, &tunnel->session_hlist[hash], hlist) {
 			if (++count > nth) {
+				l2tp_session_inc_refcount(session);
+				if (do_ref && session->ref)
+					session->ref(session);
 				read_unlock_bh(&tunnel->hlist_lock);
 				return session;
 			}
@@ -298,7 +302,7 @@ struct l2tp_session *l2tp_session_find_n
 
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(l2tp_session_find_nth);
+EXPORT_SYMBOL_GPL(l2tp_session_get_nth);
 
 /* Lookup a session by interface name.
  * This is very inefficient but is only used by management interfaces.
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/l2tp/l2tp_core.h linux-libre-4.4.66-gnu/net/l2tp/l2tp_core.h
--- linux-libre-4.4.65-gnu/net/l2tp/l2tp_core.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/l2tp/l2tp_core.h	2017-05-03 00:20:09.000000000 -0400
@@ -243,7 +243,8 @@ out:
 struct l2tp_session *l2tp_session_find(struct net *net,
 				       struct l2tp_tunnel *tunnel,
 				       u32 session_id);
-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
+struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
+					  bool do_ref);
 struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);
 struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
 struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/l2tp/l2tp_debugfs.c linux-libre-4.4.66-gnu/net/l2tp/l2tp_debugfs.c
--- linux-libre-4.4.65-gnu/net/l2tp/l2tp_debugfs.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/l2tp/l2tp_debugfs.c	2017-05-03 00:20:09.000000000 -0400
@@ -53,7 +53,7 @@ static void l2tp_dfs_next_tunnel(struct
 
 static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd)
 {
-	pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx);
+	pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true);
 	pd->session_idx++;
 
 	if (pd->session == NULL) {
@@ -238,10 +238,14 @@ static int l2tp_dfs_seq_show(struct seq_
 	}
 
 	/* Show the tunnel or session context */
-	if (pd->session == NULL)
+	if (!pd->session) {
 		l2tp_dfs_seq_tunnel_show(m, pd->tunnel);
-	else
+	} else {
 		l2tp_dfs_seq_session_show(m, pd->session);
+		if (pd->session->deref)
+			pd->session->deref(pd->session);
+		l2tp_session_dec_refcount(pd->session);
+	}
 
 out:
 	return 0;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/l2tp/l2tp_netlink.c linux-libre-4.4.66-gnu/net/l2tp/l2tp_netlink.c
--- linux-libre-4.4.65-gnu/net/l2tp/l2tp_netlink.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/l2tp/l2tp_netlink.c	2017-05-03 00:20:09.000000000 -0400
@@ -827,7 +827,7 @@ static int l2tp_nl_cmd_session_dump(stru
 				goto out;
 		}
 
-		session = l2tp_session_find_nth(tunnel, si);
+		session = l2tp_session_get_nth(tunnel, si, false);
 		if (session == NULL) {
 			ti++;
 			tunnel = NULL;
@@ -837,8 +837,11 @@ static int l2tp_nl_cmd_session_dump(stru
 
 		if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid,
 					 cb->nlh->nlmsg_seq, NLM_F_MULTI,
-					 session, L2TP_CMD_SESSION_GET) < 0)
+					 session, L2TP_CMD_SESSION_GET) < 0) {
+			l2tp_session_dec_refcount(session);
 			break;
+		}
+		l2tp_session_dec_refcount(session);
 
 		si++;
 	}
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/l2tp/l2tp_ppp.c linux-libre-4.4.66-gnu/net/l2tp/l2tp_ppp.c
--- linux-libre-4.4.65-gnu/net/l2tp/l2tp_ppp.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/l2tp/l2tp_ppp.c	2017-05-03 00:20:09.000000000 -0400
@@ -467,6 +467,10 @@ static void pppol2tp_session_close(struc
 static void pppol2tp_session_destruct(struct sock *sk)
 {
 	struct l2tp_session *session = sk->sk_user_data;
+
+	skb_queue_purge(&sk->sk_receive_queue);
+	skb_queue_purge(&sk->sk_write_queue);
+
 	if (session) {
 		sk->sk_user_data = NULL;
 		BUG_ON(session->magic != L2TP_SESSION_MAGIC);
@@ -505,9 +509,6 @@ static int pppol2tp_release(struct socke
 		l2tp_session_queue_purge(session);
 		sock_put(sk);
 	}
-	skb_queue_purge(&sk->sk_receive_queue);
-	skb_queue_purge(&sk->sk_write_queue);
-
 	release_sock(sk);
 
 	/* This will delete the session context via
@@ -1574,7 +1575,7 @@ static void pppol2tp_next_tunnel(struct
 
 static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd)
 {
-	pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx);
+	pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true);
 	pd->session_idx++;
 
 	if (pd->session == NULL) {
@@ -1701,10 +1702,14 @@ static int pppol2tp_seq_show(struct seq_
 
 	/* Show the tunnel or session context.
 	 */
-	if (pd->session == NULL)
+	if (!pd->session) {
 		pppol2tp_seq_tunnel_show(m, pd->tunnel);
-	else
+	} else {
 		pppol2tp_seq_session_show(m, pd->session);
+		if (pd->session->deref)
+			pd->session->deref(pd->session);
+		l2tp_session_dec_refcount(pd->session);
+	}
 
 out:
 	return 0;
@@ -1863,4 +1868,4 @@ MODULE_DESCRIPTION("PPP over L2TP over U
 MODULE_LICENSE("GPL");
 MODULE_VERSION(PPPOL2TP_DRV_VERSION);
 MODULE_ALIAS("pppox-proto-" __stringify(PX_PROTO_OL2TP));
-MODULE_ALIAS_L2TP_PWTYPE(11);
+MODULE_ALIAS_L2TP_PWTYPE(7);
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/packet/af_packet.c linux-libre-4.4.66-gnu/net/packet/af_packet.c
--- linux-libre-4.4.65-gnu/net/packet/af_packet.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/packet/af_packet.c	2017-05-03 00:20:09.000000000 -0400
@@ -3626,6 +3626,8 @@ packet_setsockopt(struct socket *sock, i
 			return -EBUSY;
 		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
+		if (val > INT_MAX)
+			return -EINVAL;
 		po->tp_reserve = val;
 		return 0;
 	}
@@ -4150,6 +4152,8 @@ static int packet_set_ring(struct sock *
 		rb->frames_per_block = req->tp_block_size / req->tp_frame_size;
 		if (unlikely(rb->frames_per_block == 0))
 			goto out;
+		if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr))
+			goto out;
 		if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
 					req->tp_frame_nr))
 			goto out;
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/rds/cong.c linux-libre-4.4.66-gnu/net/rds/cong.c
--- linux-libre-4.4.65-gnu/net/rds/cong.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/rds/cong.c	2017-05-03 00:20:09.000000000 -0400
@@ -299,7 +299,7 @@ void rds_cong_set_bit(struct rds_cong_ma
 	i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
 	off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
 
-	__set_bit_le(off, (void *)map->m_page_addrs[i]);
+	set_bit_le(off, (void *)map->m_page_addrs[i]);
 }
 
 void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port)
@@ -313,7 +313,7 @@ void rds_cong_clear_bit(struct rds_cong_
 	i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
 	off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
 
-	__clear_bit_le(off, (void *)map->m_page_addrs[i]);
+	clear_bit_le(off, (void *)map->m_page_addrs[i]);
 }
 
 static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port)
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/sched/act_mirred.c linux-libre-4.4.66-gnu/net/sched/act_mirred.c
--- linux-libre-4.4.65-gnu/net/sched/act_mirred.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/sched/act_mirred.c	2017-05-03 00:20:09.000000000 -0400
@@ -36,14 +36,15 @@ static DEFINE_SPINLOCK(mirred_list_lock)
 static void tcf_mirred_release(struct tc_action *a, int bind)
 {
 	struct tcf_mirred *m = to_mirred(a);
-	struct net_device *dev = rcu_dereference_protected(m->tcfm_dev, 1);
+	struct net_device *dev;
 
 	/* We could be called either in a RCU callback or with RTNL lock held. */
 	spin_lock_bh(&mirred_list_lock);
 	list_del(&m->tcfm_list);
-	spin_unlock_bh(&mirred_list_lock);
+	dev = rcu_dereference_protected(m->tcfm_dev, 1);
 	if (dev)
 		dev_put(dev);
+	spin_unlock_bh(&mirred_list_lock);
 }
 
 static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
diff -druNp --no-dereference linux-libre-4.4.65-gnu/net/sctp/socket.c linux-libre-4.4.66-gnu/net/sctp/socket.c
--- linux-libre-4.4.65-gnu/net/sctp/socket.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/net/sctp/socket.c	2017-05-03 00:20:09.000000000 -0400
@@ -6394,6 +6394,9 @@ int sctp_inet_listen(struct socket *sock
 	if (sock->state != SS_UNCONNECTED)
 		goto out;
 
+	if (!sctp_sstate(sk, LISTENING) && !sctp_sstate(sk, CLOSED))
+		goto out;
+
 	/* If backlog is zero, disable listening. */
 	if (!backlog) {
 		if (sctp_sstate(sk, CLOSED))
diff -druNp --no-dereference linux-libre-4.4.65-gnu/sound/core/seq/seq_lock.c linux-libre-4.4.66-gnu/sound/core/seq/seq_lock.c
--- linux-libre-4.4.65-gnu/sound/core/seq/seq_lock.c	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/sound/core/seq/seq_lock.c	2017-05-03 00:20:09.000000000 -0400
@@ -28,19 +28,16 @@
 /* wait until all locks are released */
 void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
 {
-	int max_count = 5 * HZ;
+	int warn_count = 5 * HZ;
 
 	if (atomic_read(lockp) < 0) {
 		pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
 		return;
 	}
 	while (atomic_read(lockp) > 0) {
-		if (max_count == 0) {
-			pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
-			break;
-		}
+		if (warn_count-- == 0)
+			pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line);
 		schedule_timeout_uninterruptible(1);
-		max_count--;
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.4.65-gnu/sound/firewire/lib.h linux-libre-4.4.66-gnu/sound/firewire/lib.h
--- linux-libre-4.4.65-gnu/sound/firewire/lib.h	2017-04-29 23:50:11.000000000 -0400
+++ linux-libre-4.4.66-gnu/sound/firewire/lib.h	2017-05-03 00:20:09.000000000 -0400
@@ -42,7 +42,7 @@ struct snd_fw_async_midi_port {
 
 	struct snd_rawmidi_substream *substream;
 	snd_fw_async_midi_port_fill fill;
-	unsigned int consume_bytes;
+	int consume_bytes;
 };
 
 int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
