diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/arm/crypto/aes-ce-glue.c linux-libre-4.8-rc8-gnu/arch/arm/crypto/aes-ce-glue.c
--- linux-libre-4.8-rc7-gnu/arch/arm/crypto/aes-ce-glue.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/arm/crypto/aes-ce-glue.c	2016-09-25 21:47:13.000000000 -0400
@@ -284,7 +284,7 @@ static int ctr_encrypt(struct blkcipher_
 		err = blkcipher_walk_done(desc, &walk,
 					  walk.nbytes % AES_BLOCK_SIZE);
 	}
-	if (nbytes) {
+	if (walk.nbytes % AES_BLOCK_SIZE) {
 		u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 __aligned(8) tail[AES_BLOCK_SIZE];
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/arm64/crypto/aes-glue.c linux-libre-4.8-rc8-gnu/arch/arm64/crypto/aes-glue.c
--- linux-libre-4.8-rc7-gnu/arch/arm64/crypto/aes-glue.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/arm64/crypto/aes-glue.c	2016-09-25 21:47:13.000000000 -0400
@@ -216,7 +216,7 @@ static int ctr_encrypt(struct blkcipher_
 		err = blkcipher_walk_done(desc, &walk,
 					  walk.nbytes % AES_BLOCK_SIZE);
 	}
-	if (nbytes) {
+	if (walk.nbytes % AES_BLOCK_SIZE) {
 		u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 __aligned(8) tail[AES_BLOCK_SIZE];
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/arm64/include/asm/debug-monitors.h linux-libre-4.8-rc8-gnu/arch/arm64/include/asm/debug-monitors.h
--- linux-libre-4.8-rc7-gnu/arch/arm64/include/asm/debug-monitors.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/arm64/include/asm/debug-monitors.h	2016-09-25 21:47:13.000000000 -0400
@@ -61,8 +61,6 @@
 
 #define AARCH64_BREAK_KGDB_DYN_DBG	\
 	(AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5))
-#define KGDB_DYN_BRK_INS_BYTE(x)	\
-	((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff)
 
 #define CACHE_FLUSH_IS_SAFE		1
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/arm64/kernel/kgdb.c linux-libre-4.8-rc8-gnu/arch/arm64/kernel/kgdb.c
--- linux-libre-4.8-rc7-gnu/arch/arm64/kernel/kgdb.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/arm64/kernel/kgdb.c	2016-09-25 21:47:13.000000000 -0400
@@ -19,10 +19,13 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/bug.h>
 #include <linux/irq.h>
 #include <linux/kdebug.h>
 #include <linux/kgdb.h>
 #include <linux/kprobes.h>
+#include <asm/debug-monitors.h>
+#include <asm/insn.h>
 #include <asm/traps.h>
 
 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
@@ -338,15 +341,24 @@ void kgdb_arch_exit(void)
 	unregister_die_notifier(&kgdb_notifier);
 }
 
-/*
- * ARM instructions are always in LE.
- * Break instruction is encoded in LE format
- */
-struct kgdb_arch arch_kgdb_ops = {
-	.gdb_bpt_instr = {
-		KGDB_DYN_BRK_INS_BYTE(0),
-		KGDB_DYN_BRK_INS_BYTE(1),
-		KGDB_DYN_BRK_INS_BYTE(2),
-		KGDB_DYN_BRK_INS_BYTE(3),
-	}
-};
+struct kgdb_arch arch_kgdb_ops;
+
+int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
+{
+	int err;
+
+	BUILD_BUG_ON(AARCH64_INSN_SIZE != BREAK_INSTR_SIZE);
+
+	err = aarch64_insn_read((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr);
+	if (err)
+		return err;
+
+	return aarch64_insn_write((void *)bpt->bpt_addr,
+			(u32)AARCH64_BREAK_KGDB_DYN_DBG);
+}
+
+int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
+{
+	return aarch64_insn_write((void *)bpt->bpt_addr,
+			*(u32 *)bpt->saved_instr);
+}
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/arm64/kernel/smp.c linux-libre-4.8-rc8-gnu/arch/arm64/kernel/smp.c
--- linux-libre-4.8-rc7-gnu/arch/arm64/kernel/smp.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/arm64/kernel/smp.c	2016-09-25 21:47:13.000000000 -0400
@@ -201,12 +201,6 @@ int __cpu_up(unsigned int cpu, struct ta
 	return ret;
 }
 
-static void smp_store_cpu_info(unsigned int cpuid)
-{
-	store_cpu_topology(cpuid);
-	numa_store_cpu_info(cpuid);
-}
-
 /*
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
@@ -254,7 +248,7 @@ asmlinkage void secondary_start_kernel(v
 	 */
 	notify_cpu_starting(cpu);
 
-	smp_store_cpu_info(cpu);
+	store_cpu_topology(cpu);
 
 	/*
 	 * OK, now it's safe to let the boot CPU continue.  Wait for
@@ -689,10 +683,13 @@ void __init smp_prepare_cpus(unsigned in
 {
 	int err;
 	unsigned int cpu;
+	unsigned int this_cpu;
 
 	init_cpu_topology();
 
-	smp_store_cpu_info(smp_processor_id());
+	this_cpu = smp_processor_id();
+	store_cpu_topology(this_cpu);
+	numa_store_cpu_info(this_cpu);
 
 	/*
 	 * If UP is mandated by "nosmp" (which implies "maxcpus=0"), don't set
@@ -719,6 +716,7 @@ void __init smp_prepare_cpus(unsigned in
 			continue;
 
 		set_cpu_present(cpu, true);
+		numa_store_cpu_info(cpu);
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/ath79/clock.c linux-libre-4.8-rc8-gnu/arch/mips/ath79/clock.c
--- linux-libre-4.8-rc7-gnu/arch/mips/ath79/clock.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/ath79/clock.c	2016-09-25 21:47:13.000000000 -0400
@@ -96,7 +96,7 @@ static struct clk * __init ath79_reg_ffc
 	struct clk *clk;
 
 	clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
-	if (!clk)
+	if (IS_ERR(clk))
 		panic("failed to allocate %s clock structure", name);
 
 	return clk;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/cavium-octeon/octeon-platform.c linux-libre-4.8-rc8-gnu/arch/mips/cavium-octeon/octeon-platform.c
--- linux-libre-4.8-rc7-gnu/arch/mips/cavium-octeon/octeon-platform.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/cavium-octeon/octeon-platform.c	2016-09-25 21:47:13.000000000 -0400
@@ -1059,7 +1059,7 @@ static int __init octeon_publish_devices
 {
 	return of_platform_bus_probe(NULL, octeon_ids, NULL);
 }
-device_initcall(octeon_publish_devices);
+arch_initcall(octeon_publish_devices);
 
 MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/include/asm/asmmacro.h linux-libre-4.8-rc8-gnu/arch/mips/include/asm/asmmacro.h
--- linux-libre-4.8-rc7-gnu/arch/mips/include/asm/asmmacro.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/include/asm/asmmacro.h	2016-09-25 21:47:13.000000000 -0400
@@ -157,6 +157,7 @@
 	ldc1	$f28, THREAD_FPR28(\thread)
 	ldc1	$f30, THREAD_FPR30(\thread)
 	ctc1	\tmp, fcr31
+	.set	pop
 	.endm
 
 	.macro	fpu_restore_16odd thread
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h linux-libre-4.8-rc8-gnu/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h
--- linux-libre-4.8-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h	2016-09-25 21:47:13.000000000 -0400
@@ -15,8 +15,8 @@
 static inline bool __should_swizzle_bits(volatile void *a)
 {
 	extern const bool octeon_should_swizzle_table[];
+	u64 did = ((u64)(uintptr_t)a >> 40) & 0xff;
 
-	unsigned long did = ((unsigned long)a >> 40) & 0xff;
 	return octeon_should_swizzle_table[did];
 }
 
@@ -29,7 +29,7 @@ static inline bool __should_swizzle_bits
 
 #define __should_swizzle_bits(a)	false
 
-static inline bool __should_swizzle_addr(unsigned long p)
+static inline bool __should_swizzle_addr(u64 p)
 {
 	/* boot bus? */
 	return ((p >> 40) & 0xff) == 0;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h linux-libre-4.8-rc8-gnu/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
--- linux-libre-4.8-rc7-gnu/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h	2016-09-25 21:47:13.000000000 -0400
@@ -11,11 +11,13 @@
 #define CP0_EBASE $15, 1
 
 	.macro  kernel_entry_setup
+#ifdef CONFIG_SMP
 	mfc0	t0, CP0_EBASE
 	andi	t0, t0, 0x3ff		# CPUNum
 	beqz	t0, 1f
 	# CPUs other than zero goto smp_bootstrap
 	j	smp_bootstrap
+#endif /* CONFIG_SMP */
 
 1:
 	.endm
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/Kconfig linux-libre-4.8-rc8-gnu/arch/mips/Kconfig
--- linux-libre-4.8-rc7-gnu/arch/mips/Kconfig	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/Kconfig	2016-09-25 21:47:13.000000000 -0400
@@ -65,6 +65,7 @@ config MIPS
 	select ARCH_CLOCKSOURCE_DATA
 	select HANDLE_DOMAIN_IRQ
 	select HAVE_EXIT_THREAD
+	select HAVE_REGS_AND_STACK_ACCESS_API
 
 menu "Machine selection"
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/Kconfig.debug linux-libre-4.8-rc8-gnu/arch/mips/Kconfig.debug
--- linux-libre-4.8-rc7-gnu/arch/mips/Kconfig.debug	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/Kconfig.debug	2016-09-25 21:47:13.000000000 -0400
@@ -113,42 +113,6 @@ config SPINLOCK_TEST
 	help
 	  Add several files to the debugfs to test spinlock speed.
 
-if CPU_MIPSR6
-
-choice
-	prompt "Compact branch policy"
-	default MIPS_COMPACT_BRANCHES_OPTIMAL
-
-config MIPS_COMPACT_BRANCHES_NEVER
-	bool "Never (force delay slot branches)"
-	help
-	  Pass the -mcompact-branches=never flag to the compiler in order to
-	  force it to always emit branches with delay slots, and make no use
-	  of the compact branch instructions introduced by MIPSr6. This is
-	  useful if you suspect there may be an issue with compact branches in
-	  either the compiler or the CPU.
-
-config MIPS_COMPACT_BRANCHES_OPTIMAL
-	bool "Optimal (use where beneficial)"
-	help
-	  Pass the -mcompact-branches=optimal flag to the compiler in order for
-	  it to make use of compact branch instructions where it deems them
-	  beneficial, and use branches with delay slots elsewhere. This is the
-	  default compiler behaviour, and should be used unless you have a
-	  reason to choose otherwise.
-
-config MIPS_COMPACT_BRANCHES_ALWAYS
-	bool "Always (force compact branches)"
-	help
-	  Pass the -mcompact-branches=always flag to the compiler in order to
-	  force it to always emit compact branches, making no use of branch
-	  instructions with delay slots. This can result in more compact code
-	  which may be beneficial in some scenarios.
-
-endchoice
-
-endif # CPU_MIPSR6
-
 config SCACHE_DEBUGFS
 	bool "L2 cache debugfs entries"
 	depends on DEBUG_FS
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c linux-libre-4.8-rc8-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c
--- linux-libre-4.8-rc7-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c	2016-09-25 21:47:13.000000000 -0400
@@ -1164,7 +1164,9 @@ fpu_emul:
 		regs->regs[31] = r31;
 		regs->cp0_epc = epc;
 		if (!used_math()) {     /* First time FPU user.  */
+			preempt_disable();
 			err = init_fpu();
+			preempt_enable();
 			set_used_math();
 		}
 		lose_fpu(1);    /* Save FPU state for the emulator. */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/kernel/process.c linux-libre-4.8-rc8-gnu/arch/mips/kernel/process.c
--- linux-libre-4.8-rc7-gnu/arch/mips/kernel/process.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/kernel/process.c	2016-09-25 21:47:13.000000000 -0400
@@ -605,14 +605,14 @@ int mips_set_process_fp_mode(struct task
 		return -EOPNOTSUPP;
 
 	/* Avoid inadvertently triggering emulation */
-	if ((value & PR_FP_MODE_FR) && cpu_has_fpu &&
-	    !(current_cpu_data.fpu_id & MIPS_FPIR_F64))
+	if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
+	    !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
 		return -EOPNOTSUPP;
-	if ((value & PR_FP_MODE_FRE) && cpu_has_fpu && !cpu_has_fre)
+	if ((value & PR_FP_MODE_FRE) && raw_cpu_has_fpu && !cpu_has_fre)
 		return -EOPNOTSUPP;
 
 	/* FR = 0 not supported in MIPS R6 */
-	if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
+	if (!(value & PR_FP_MODE_FR) && raw_cpu_has_fpu && cpu_has_mips_r6)
 		return -EOPNOTSUPP;
 
 	/* Proceed with the mode switch */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/kernel/setup.c linux-libre-4.8-rc8-gnu/arch/mips/kernel/setup.c
--- linux-libre-4.8-rc7-gnu/arch/mips/kernel/setup.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/kernel/setup.c	2016-09-25 21:47:13.000000000 -0400
@@ -87,6 +87,13 @@ void __init add_memory_region(phys_addr_
 	int x = boot_mem_map.nr_map;
 	int i;
 
+	/*
+	 * If the region reaches the top of the physical address space, adjust
+	 * the size slightly so that (start + size) doesn't overflow
+	 */
+	if (start + size - 1 == (phys_addr_t)ULLONG_MAX)
+		--size;
+
 	/* Sanity check */
 	if (start + size < start) {
 		pr_warn("Trying to add an invalid memory region, skipped\n");
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/kernel/smp.c linux-libre-4.8-rc8-gnu/arch/mips/kernel/smp.c
--- linux-libre-4.8-rc7-gnu/arch/mips/kernel/smp.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/kernel/smp.c	2016-09-25 21:47:13.000000000 -0400
@@ -322,6 +322,9 @@ asmlinkage void start_secondary(void)
 	cpumask_set_cpu(cpu, &cpu_coherent_mask);
 	notify_cpu_starting(cpu);
 
+	cpumask_set_cpu(cpu, &cpu_callin_map);
+	synchronise_count_slave(cpu);
+
 	set_cpu_online(cpu, true);
 
 	set_cpu_sibling_map(cpu);
@@ -329,10 +332,6 @@ asmlinkage void start_secondary(void)
 
 	calculate_cpu_foreign_map();
 
-	cpumask_set_cpu(cpu, &cpu_callin_map);
-
-	synchronise_count_slave(cpu);
-
 	/*
 	 * irq will be enabled in ->smp_finish(), enabling it too early
 	 * is dangerous.
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/kernel/uprobes.c linux-libre-4.8-rc8-gnu/arch/mips/kernel/uprobes.c
--- linux-libre-4.8-rc7-gnu/arch/mips/kernel/uprobes.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/kernel/uprobes.c	2016-09-25 21:47:13.000000000 -0400
@@ -222,7 +222,7 @@ int arch_uprobe_exception_notify(struct
 		return NOTIFY_DONE;
 
 	switch (val) {
-	case DIE_BREAK:
+	case DIE_UPROBE:
 		if (uprobe_pre_sstep_notifier(regs))
 			return NOTIFY_STOP;
 		break;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/kernel/vdso.c linux-libre-4.8-rc8-gnu/arch/mips/kernel/vdso.c
--- linux-libre-4.8-rc7-gnu/arch/mips/kernel/vdso.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/kernel/vdso.c	2016-09-25 21:47:13.000000000 -0400
@@ -39,16 +39,16 @@ static struct vm_special_mapping vdso_vv
 static void __init init_vdso_image(struct mips_vdso_image *image)
 {
 	unsigned long num_pages, i;
+	unsigned long data_pfn;
 
 	BUG_ON(!PAGE_ALIGNED(image->data));
 	BUG_ON(!PAGE_ALIGNED(image->size));
 
 	num_pages = image->size / PAGE_SIZE;
 
-	for (i = 0; i < num_pages; i++) {
-		image->mapping.pages[i] =
-			virt_to_page(image->data + (i * PAGE_SIZE));
-	}
+	data_pfn = __phys_to_pfn(__pa_symbol(image->data));
+	for (i = 0; i < num_pages; i++)
+		image->mapping.pages[i] = pfn_to_page(data_pfn + i);
 }
 
 static int __init init_vdso(void)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/Makefile linux-libre-4.8-rc8-gnu/arch/mips/Makefile
--- linux-libre-4.8-rc7-gnu/arch/mips/Makefile	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/Makefile	2016-09-25 21:47:13.000000000 -0400
@@ -203,10 +203,6 @@ endif
 toolchain-virt				:= $(call cc-option-yn,$(mips-cflags) -mvirt)
 cflags-$(toolchain-virt)		+= -DTOOLCHAIN_SUPPORTS_VIRT
 
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER)	+= -mcompact-branches=never
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL)	+= -mcompact-branches=optimal
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS)	+= -mcompact-branches=always
-
 #
 # Firmware support
 #
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/math-emu/dsemul.c linux-libre-4.8-rc8-gnu/arch/mips/math-emu/dsemul.c
--- linux-libre-4.8-rc7-gnu/arch/mips/math-emu/dsemul.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/math-emu/dsemul.c	2016-09-25 21:47:13.000000000 -0400
@@ -298,5 +298,6 @@ bool do_dsemulret(struct pt_regs *xcp)
 	/* Set EPC to return to post-branch instruction */
 	xcp->cp0_epc = current->thread.bd_emu_cont_pc;
 	pr_debug("dsemulret to 0x%08lx\n", xcp->cp0_epc);
+	MIPS_FPU_EMU_INC_STATS(ds_emul);
 	return true;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/mm/c-r4k.c linux-libre-4.8-rc8-gnu/arch/mips/mm/c-r4k.c
--- linux-libre-4.8-rc7-gnu/arch/mips/mm/c-r4k.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/mm/c-r4k.c	2016-09-25 21:47:13.000000000 -0400
@@ -800,7 +800,7 @@ static void r4k_flush_icache_range(unsig
 		 * If address-based cache ops don't require an SMP call, then
 		 * use them exclusively for small flushes.
 		 */
-		size = start - end;
+		size = end - start;
 		cache_size = icache_size;
 		if (!cpu_has_ic_fills_f_dc) {
 			size *= 2;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/mips/mm/init.c linux-libre-4.8-rc8-gnu/arch/mips/mm/init.c
--- linux-libre-4.8-rc7-gnu/arch/mips/mm/init.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/mips/mm/init.c	2016-09-25 21:47:13.000000000 -0400
@@ -261,7 +261,6 @@ unsigned __weak platform_maar_init(unsig
 {
 	struct maar_config cfg[BOOT_MEM_MAP_MAX];
 	unsigned i, num_configured, num_cfg = 0;
-	phys_addr_t skip;
 
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
 		switch (boot_mem_map.map[i].type) {
@@ -272,14 +271,14 @@ unsigned __weak platform_maar_init(unsig
 			continue;
 		}
 
-		skip = 0x10000 - (boot_mem_map.map[i].addr & 0xffff);
-
+		/* Round lower up */
 		cfg[num_cfg].lower = boot_mem_map.map[i].addr;
-		cfg[num_cfg].lower += skip;
+		cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
 
-		cfg[num_cfg].upper = cfg[num_cfg].lower;
-		cfg[num_cfg].upper += boot_mem_map.map[i].size - 1;
-		cfg[num_cfg].upper -= skip;
+		/* Round upper down */
+		cfg[num_cfg].upper = boot_mem_map.map[i].addr +
+					boot_mem_map.map[i].size;
+		cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
 
 		cfg[num_cfg].attrs = MIPS_MAAR_S;
 		num_cfg++;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/powerpc/platforms/powernv/pci-ioda.c linux-libre-4.8-rc8-gnu/arch/powerpc/platforms/powernv/pci-ioda.c
--- linux-libre-4.8-rc7-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2016-09-25 21:47:13.000000000 -0400
@@ -124,6 +124,13 @@ static inline bool pnv_pci_is_m64(struct
 		r->start < (phb->ioda.m64_base + phb->ioda.m64_size));
 }
 
+static inline bool pnv_pci_is_m64_flags(unsigned long resource_flags)
+{
+	unsigned long flags = (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH);
+
+	return (resource_flags & flags) == flags;
+}
+
 static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb *phb, int pe_no)
 {
 	phb->ioda.pe_array[pe_no].phb = phb;
@@ -2871,7 +2878,7 @@ static void pnv_pci_ioda_fixup_iov_resou
 		res = &pdev->resource[i + PCI_IOV_RESOURCES];
 		if (!res->flags || res->parent)
 			continue;
-		if (!pnv_pci_is_m64(phb, res)) {
+		if (!pnv_pci_is_m64_flags(res->flags)) {
 			dev_warn(&pdev->dev, "Don't support SR-IOV with"
 					" non M64 VF BAR%d: %pR. \n",
 				 i, res);
@@ -3096,7 +3103,7 @@ static resource_size_t pnv_pci_window_al
 	 * alignment for any 64-bit resource, PCIe doesn't care and
 	 * bridges only do 64-bit prefetchable anyway.
 	 */
-	if (phb->ioda.m64_segsize && (type & IORESOURCE_MEM_64))
+	if (phb->ioda.m64_segsize && pnv_pci_is_m64_flags(type))
 		return phb->ioda.m64_segsize;
 	if (type & IORESOURCE_MEM)
 		return phb->ioda.m32_segsize;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/sh/include/asm/atomic-llsc.h linux-libre-4.8-rc8-gnu/arch/sh/include/asm/atomic-llsc.h
--- linux-libre-4.8-rc7-gnu/arch/sh/include/asm/atomic-llsc.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/sh/include/asm/atomic-llsc.h	2016-09-25 21:47:13.000000000 -0400
@@ -60,7 +60,7 @@ static inline int atomic_fetch_##op(int
 "	movco.l	%0, @%3					\n"		\
 "	bf	1b					\n"		\
 "	synco						\n"		\
-	: "=&z" (temp), "=&z" (res)					\
+	: "=&z" (temp), "=&r" (res)					\
 	: "r" (i), "r" (&v->counter)					\
 	: "t");								\
 									\
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/x86/events/intel/bts.c linux-libre-4.8-rc8-gnu/arch/x86/events/intel/bts.c
--- linux-libre-4.8-rc7-gnu/arch/x86/events/intel/bts.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/x86/events/intel/bts.c	2016-09-25 21:47:13.000000000 -0400
@@ -455,7 +455,7 @@ int intel_bts_interrupt(void)
 	 * The only surefire way of knowing if this NMI is ours is by checking
 	 * the write ptr against the PMI threshold.
 	 */
-	if (ds->bts_index >= ds->bts_interrupt_threshold)
+	if (ds && (ds->bts_index >= ds->bts_interrupt_threshold))
 		handled = 1;
 
 	/*
@@ -584,7 +584,8 @@ static __init int bts_init(void)
 	if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts)
 		return -ENODEV;
 
-	bts_pmu.capabilities	= PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE;
+	bts_pmu.capabilities	= PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE |
+				  PERF_PMU_CAP_EXCLUSIVE;
 	bts_pmu.task_ctx_nr	= perf_sw_context;
 	bts_pmu.event_init	= bts_event_init;
 	bts_pmu.add		= bts_event_add;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/x86/mm/pageattr.c linux-libre-4.8-rc8-gnu/arch/x86/mm/pageattr.c
--- linux-libre-4.8-rc7-gnu/arch/x86/mm/pageattr.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/x86/mm/pageattr.c	2016-09-25 21:47:13.000000000 -0400
@@ -917,11 +917,11 @@ static void populate_pte(struct cpa_data
 	}
 }
 
-static int populate_pmd(struct cpa_data *cpa,
-			unsigned long start, unsigned long end,
-			unsigned num_pages, pud_t *pud, pgprot_t pgprot)
+static long populate_pmd(struct cpa_data *cpa,
+			 unsigned long start, unsigned long end,
+			 unsigned num_pages, pud_t *pud, pgprot_t pgprot)
 {
-	unsigned int cur_pages = 0;
+	long cur_pages = 0;
 	pmd_t *pmd;
 	pgprot_t pmd_pgprot;
 
@@ -991,12 +991,12 @@ static int populate_pmd(struct cpa_data
 	return num_pages;
 }
 
-static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd,
-			pgprot_t pgprot)
+static long populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd,
+			 pgprot_t pgprot)
 {
 	pud_t *pud;
 	unsigned long end;
-	int cur_pages = 0;
+	long cur_pages = 0;
 	pgprot_t pud_pgprot;
 
 	end = start + (cpa->numpages << PAGE_SHIFT);
@@ -1052,7 +1052,7 @@ static int populate_pud(struct cpa_data
 
 	/* Map trailing leftover */
 	if (start < end) {
-		int tmp;
+		long tmp;
 
 		pud = pud_offset(pgd, start);
 		if (pud_none(*pud))
@@ -1078,7 +1078,7 @@ static int populate_pgd(struct cpa_data
 	pgprot_t pgprot = __pgprot(_KERNPG_TABLE);
 	pud_t *pud = NULL;	/* shut up gcc */
 	pgd_t *pgd_entry;
-	int ret;
+	long ret;
 
 	pgd_entry = cpa->pgd + pgd_index(addr);
 
@@ -1327,7 +1327,8 @@ static int cpa_process_alias(struct cpa_
 
 static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
 {
-	int ret, numpages = cpa->numpages;
+	unsigned long numpages = cpa->numpages;
+	int ret;
 
 	while (numpages) {
 		/*
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/arch/x86/platform/efi/efi_64.c linux-libre-4.8-rc8-gnu/arch/x86/platform/efi/efi_64.c
--- linux-libre-4.8-rc7-gnu/arch/x86/platform/efi/efi_64.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/arch/x86/platform/efi/efi_64.c	2016-09-25 21:47:13.000000000 -0400
@@ -245,7 +245,7 @@ int __init efi_setup_page_tables(unsigne
 	 * text and allocate a new stack because we can't rely on the
 	 * stack pointer being < 4GB.
 	 */
-	if (!IS_ENABLED(CONFIG_EFI_MIXED))
+	if (!IS_ENABLED(CONFIG_EFI_MIXED) || efi_is_native())
 		return 0;
 
 	/*
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/block/blk-mq.c linux-libre-4.8-rc8-gnu/block/blk-mq.c
--- linux-libre-4.8-rc7-gnu/block/blk-mq.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/block/blk-mq.c	2016-09-25 21:47:13.000000000 -0400
@@ -296,17 +296,29 @@ struct request *blk_mq_alloc_request_hct
 	if (ret)
 		return ERR_PTR(ret);
 
+	/*
+	 * Check if the hardware context is actually mapped to anything.
+	 * If not tell the caller that it should skip this queue.
+	 */
 	hctx = q->queue_hw_ctx[hctx_idx];
+	if (!blk_mq_hw_queue_mapped(hctx)) {
+		ret = -EXDEV;
+		goto out_queue_exit;
+	}
 	ctx = __blk_mq_get_ctx(q, cpumask_first(hctx->cpumask));
 
 	blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
 	rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
 	if (!rq) {
-		blk_queue_exit(q);
-		return ERR_PTR(-EWOULDBLOCK);
+		ret = -EWOULDBLOCK;
+		goto out_queue_exit;
 	}
 
 	return rq;
+
+out_queue_exit:
+	blk_queue_exit(q);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/block/blk-throttle.c linux-libre-4.8-rc8-gnu/block/blk-throttle.c
--- linux-libre-4.8-rc7-gnu/block/blk-throttle.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/block/blk-throttle.c	2016-09-25 21:47:13.000000000 -0400
@@ -780,9 +780,11 @@ static bool tg_may_dispatch(struct throt
 	/*
 	 * If previous slice expired, start a new one otherwise renew/extend
 	 * existing slice to make sure it is at least throtl_slice interval
-	 * long since now.
+	 * long since now. New slice is started only for empty throttle group.
+	 * If there is queued bio, that means there should be an active
+	 * slice and it should be extended instead.
 	 */
-	if (throtl_slice_used(tg, rw))
+	if (throtl_slice_used(tg, rw) && !(tg->service_queue.nr_queued[rw]))
 		throtl_start_new_slice(tg, rw);
 	else {
 		if (time_before(tg->slice_end[rw], jiffies + throtl_slice))
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/crypto/blkcipher.c linux-libre-4.8-rc8-gnu/crypto/blkcipher.c
--- linux-libre-4.8-rc7-gnu/crypto/blkcipher.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/crypto/blkcipher.c	2016-09-25 21:47:13.000000000 -0400
@@ -233,6 +233,8 @@ static int blkcipher_walk_next(struct bl
 		return blkcipher_walk_done(desc, walk, -EINVAL);
 	}
 
+	bsize = min(walk->walk_blocksize, n);
+
 	walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
 			 BLKCIPHER_WALK_DIFF);
 	if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
@@ -245,7 +247,6 @@ static int blkcipher_walk_next(struct bl
 		}
 	}
 
-	bsize = min(walk->walk_blocksize, n);
 	n = scatterwalk_clamp(&walk->in, n);
 	n = scatterwalk_clamp(&walk->out, n);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/crypto/echainiv.c linux-libre-4.8-rc8-gnu/crypto/echainiv.c
--- linux-libre-4.8-rc7-gnu/crypto/echainiv.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/crypto/echainiv.c	2016-09-25 21:47:13.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * echainiv: Encrypted Chain IV Generator
  *
- * This generator generates an IV based on a sequence number by xoring it
- * with a salt and then encrypting it with the same key as used to encrypt
+ * This generator generates an IV based on a sequence number by multiplying
+ * it with a salt and then encrypting it with the same key as used to encrypt
  * the plain text.  This algorithm requires that the block size be equal
  * to the IV size.  It is mainly useful for CBC.
  *
@@ -24,81 +24,17 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/percpu.h>
-#include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
-#define MAX_IV_SIZE 16
-
-static DEFINE_PER_CPU(u32 [MAX_IV_SIZE / sizeof(u32)], echainiv_iv);
-
-/* We don't care if we get preempted and read/write IVs from the next CPU. */
-static void echainiv_read_iv(u8 *dst, unsigned size)
-{
-	u32 *a = (u32 *)dst;
-	u32 __percpu *b = echainiv_iv;
-
-	for (; size >= 4; size -= 4) {
-		*a++ = this_cpu_read(*b);
-		b++;
-	}
-}
-
-static void echainiv_write_iv(const u8 *src, unsigned size)
-{
-	const u32 *a = (const u32 *)src;
-	u32 __percpu *b = echainiv_iv;
-
-	for (; size >= 4; size -= 4) {
-		this_cpu_write(*b, *a);
-		a++;
-		b++;
-	}
-}
-
-static void echainiv_encrypt_complete2(struct aead_request *req, int err)
-{
-	struct aead_request *subreq = aead_request_ctx(req);
-	struct crypto_aead *geniv;
-	unsigned int ivsize;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	if (err)
-		goto out;
-
-	geniv = crypto_aead_reqtfm(req);
-	ivsize = crypto_aead_ivsize(geniv);
-
-	echainiv_write_iv(subreq->iv, ivsize);
-
-	if (req->iv != subreq->iv)
-		memcpy(req->iv, subreq->iv, ivsize);
-
-out:
-	if (req->iv != subreq->iv)
-		kzfree(subreq->iv);
-}
-
-static void echainiv_encrypt_complete(struct crypto_async_request *base,
-					 int err)
-{
-	struct aead_request *req = base->data;
-
-	echainiv_encrypt_complete2(req, err);
-	aead_request_complete(req, err);
-}
-
 static int echainiv_encrypt(struct aead_request *req)
 {
 	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
 	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
 	struct aead_request *subreq = aead_request_ctx(req);
-	crypto_completion_t compl;
-	void *data;
+	__be64 nseqno;
+	u64 seqno;
 	u8 *info;
 	unsigned int ivsize = crypto_aead_ivsize(geniv);
 	int err;
@@ -108,8 +44,6 @@ static int echainiv_encrypt(struct aead_
 
 	aead_request_set_tfm(subreq, ctx->child);
 
-	compl = echainiv_encrypt_complete;
-	data = req;
 	info = req->iv;
 
 	if (req->src != req->dst) {
@@ -127,29 +61,30 @@ static int echainiv_encrypt(struct aead_
 			return err;
 	}
 
-	if (unlikely(!IS_ALIGNED((unsigned long)info,
-				 crypto_aead_alignmask(geniv) + 1))) {
-		info = kmalloc(ivsize, req->base.flags &
-				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
-								  GFP_ATOMIC);
-		if (!info)
-			return -ENOMEM;
-
-		memcpy(info, req->iv, ivsize);
-	}
-
-	aead_request_set_callback(subreq, req->base.flags, compl, data);
+	aead_request_set_callback(subreq, req->base.flags,
+				  req->base.complete, req->base.data);
 	aead_request_set_crypt(subreq, req->dst, req->dst,
 			       req->cryptlen, info);
 	aead_request_set_ad(subreq, req->assoclen);
 
-	crypto_xor(info, ctx->salt, ivsize);
+	memcpy(&nseqno, info + ivsize - 8, 8);
+	seqno = be64_to_cpu(nseqno);
+	memset(info, 0, ivsize);
+
 	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);
-	echainiv_read_iv(info, ivsize);
 
-	err = crypto_aead_encrypt(subreq);
-	echainiv_encrypt_complete2(req, err);
-	return err;
+	do {
+		u64 a;
+
+		memcpy(&a, ctx->salt + ivsize - 8, 8);
+
+		a |= 1;
+		a *= seqno;
+
+		memcpy(info + ivsize - 8, &a, 8);
+	} while ((ivsize -= 8));
+
+	return crypto_aead_encrypt(subreq);
 }
 
 static int echainiv_decrypt(struct aead_request *req)
@@ -196,8 +131,7 @@ static int echainiv_aead_create(struct c
 	alg = crypto_spawn_aead_alg(spawn);
 
 	err = -EINVAL;
-	if (inst->alg.ivsize & (sizeof(u32) - 1) ||
-	    inst->alg.ivsize > MAX_IV_SIZE)
+	if (inst->alg.ivsize & (sizeof(u64) - 1) || !inst->alg.ivsize)
 		goto free_inst;
 
 	inst->alg.encrypt = echainiv_encrypt;
@@ -206,7 +140,6 @@ static int echainiv_aead_create(struct c
 	inst->alg.init = aead_init_geniv;
 	inst->alg.exit = aead_exit_geniv;
 
-	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
 	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
 	inst->alg.base.cra_ctxsize += inst->alg.ivsize;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/crypto/rsa-pkcs1pad.c linux-libre-4.8-rc8-gnu/crypto/rsa-pkcs1pad.c
--- linux-libre-4.8-rc7-gnu/crypto/rsa-pkcs1pad.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/crypto/rsa-pkcs1pad.c	2016-09-25 21:47:13.000000000 -0400
@@ -298,41 +298,48 @@ static int pkcs1pad_decrypt_complete(str
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
 	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	unsigned int dst_len;
 	unsigned int pos;
-
-	if (err == -EOVERFLOW)
-		/* Decrypted value had no leading 0 byte */
-		err = -EINVAL;
+	u8 *out_buf;
 
 	if (err)
 		goto done;
 
-	if (req_ctx->child_req.dst_len != ctx->key_size - 1) {
-		err = -EINVAL;
+	err = -EINVAL;
+	dst_len = req_ctx->child_req.dst_len;
+	if (dst_len < ctx->key_size - 1)
 		goto done;
+
+	out_buf = req_ctx->out_buf;
+	if (dst_len == ctx->key_size) {
+		if (out_buf[0] != 0x00)
+			/* Decrypted value had no leading 0 byte */
+			goto done;
+
+		dst_len--;
+		out_buf++;
 	}
 
-	if (req_ctx->out_buf[0] != 0x02) {
-		err = -EINVAL;
+	if (out_buf[0] != 0x02)
 		goto done;
-	}
-	for (pos = 1; pos < req_ctx->child_req.dst_len; pos++)
-		if (req_ctx->out_buf[pos] == 0x00)
+
+	for (pos = 1; pos < dst_len; pos++)
+		if (out_buf[pos] == 0x00)
 			break;
-	if (pos < 9 || pos == req_ctx->child_req.dst_len) {
-		err = -EINVAL;
+	if (pos < 9 || pos == dst_len)
 		goto done;
-	}
 	pos++;
 
-	if (req->dst_len < req_ctx->child_req.dst_len - pos)
+	err = 0;
+
+	if (req->dst_len < dst_len - pos)
 		err = -EOVERFLOW;
-	req->dst_len = req_ctx->child_req.dst_len - pos;
+	req->dst_len = dst_len - pos;
 
 	if (!err)
 		sg_copy_from_buffer(req->dst,
 				sg_nents_for_len(req->dst, req->dst_len),
-				req_ctx->out_buf + pos, req->dst_len);
+				out_buf + pos, req->dst_len);
 
 done:
 	kzfree(req_ctx->out_buf);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt linux-libre-4.8-rc8-gnu/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
--- linux-libre-4.8-rc7-gnu/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt	2016-09-25 21:47:13.000000000 -0400
@@ -13,6 +13,7 @@ Required properties:
 - touchscreen-size-y	  : See touchscreen.txt
 
 Optional properties:
+- firmware-name		  : File basename (string) for board specific firmware
 - touchscreen-inverted-x  : See touchscreen.txt
 - touchscreen-inverted-y  : See touchscreen.txt
 - touchscreen-swapped-x-y : See touchscreen.txt
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst linux-libre-4.8-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst
--- linux-libre-4.8-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst	2016-09-25 21:47:13.000000000 -0400
@@ -144,7 +144,7 @@ logical address types are already define
 
        -  ``flags``
 
-       -  Flags. No flags are defined yet, so set this to 0.
+       -  Flags. See :ref:`cec-log-addrs-flags` for a list of available flags.
 
     -  .. row 7
 
@@ -201,6 +201,25 @@ logical address types are already define
           give the CEC framework more information about the device type, even
           though the framework won't use it directly in the CEC message.
 
+.. _cec-log-addrs-flags:
+
+.. flat-table:: Flags for struct cec_log_addrs
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+
+    -  .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`:
+
+       -  ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK``
+
+       -  1
+
+       -  By default if no logical address of the requested type can be claimed, then
+	  it will go back to the unconfigured state. If this flag is set, then it will
+	  fallback to the Unregistered logical address. Note that if the Unregistered
+	  logical address was explicitly requested, then this flag has no effect.
+
 .. _cec-versions:
 
 .. flat-table:: CEC Versions
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst linux-libre-4.8-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
--- linux-libre-4.8-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst	2016-09-25 21:47:13.000000000 -0400
@@ -64,7 +64,8 @@ it is guaranteed that the state did chan
 
        -  ``phys_addr``
 
-       -  The current physical address.
+       -  The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no
+          valid physical address is set.
 
     -  .. row 2
 
@@ -72,7 +73,10 @@ it is guaranteed that the state did chan
 
        -  ``log_addr_mask``
 
-       -  The current set of claimed logical addresses.
+       -  The current set of claimed logical addresses. This is 0 if no logical
+          addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``.
+	  If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device
+	  has the unregistered logical address. In that case all other bits are 0.
 
 
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/base/regmap/regmap.c linux-libre-4.8-rc8-gnu/drivers/base/regmap/regmap.c
--- linux-libre-4.8-rc7-gnu/drivers/base/regmap/regmap.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/base/regmap/regmap.c	2016-09-25 21:47:13.000000000 -0400
@@ -1475,7 +1475,11 @@ int _regmap_raw_write(struct regmap *map
 
 		kfree(buf);
 	} else if (ret != 0 && !map->cache_bypass && map->format.parse_val) {
-		regcache_drop_region(map, reg, reg + 1);
+		/* regcache_drop_region() takes lock that we already have,
+		 * thus call map->cache_ops->drop() directly
+		 */
+		if (map->cache_ops && map->cache_ops->drop)
+			map->cache_ops->drop(map, reg, reg + 1);
 	}
 
 	trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/gpu/drm/drm_ioc32.c linux-libre-4.8-rc8-gnu/drivers/gpu/drm/drm_ioc32.c
--- linux-libre-4.8-rc7-gnu/drivers/gpu/drm/drm_ioc32.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/gpu/drm/drm_ioc32.c	2016-09-25 21:47:13.000000000 -0400
@@ -1015,6 +1015,7 @@ static int compat_drm_wait_vblank(struct
 	return 0;
 }
 
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 typedef struct drm_mode_fb_cmd232 {
 	u32 fb_id;
 	u32 width;
@@ -1071,6 +1072,7 @@ static int compat_drm_mode_addfb2(struct
 
 	return 0;
 }
+#endif
 
 static drm_ioctl_compat_t *drm_compat_ioctls[] = {
 	[DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
@@ -1104,7 +1106,9 @@ static drm_ioctl_compat_t *drm_compat_io
 	[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
 #endif
 	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 	[DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB232)] = compat_drm_mode_addfb2,
+#endif
 };
 
 /**
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c
--- linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c	2016-09-25 21:47:13.000000000 -0400
@@ -55,11 +55,11 @@ static int check_fb_gem_memory_type(stru
 	flags = exynos_gem->flags;
 
 	/*
-	 * without iommu support, not support physically non-continuous memory
-	 * for framebuffer.
+	 * Physically non-contiguous memory type for framebuffer is not
+	 * supported without IOMMU.
 	 */
 	if (IS_NONCONTIG_BUFFER(flags)) {
-		DRM_ERROR("cannot use this gem memory type for fb.\n");
+		DRM_ERROR("Non-contiguous GEM memory is not supported.\n");
 		return -EINVAL;
 	}
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c
--- linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c	2016-09-25 21:47:13.000000000 -0400
@@ -1753,32 +1753,6 @@ static int fimc_clk_ctrl(struct fimc_con
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int fimc_suspend(struct device *dev)
-{
-	struct fimc_context *ctx = get_fimc_context(dev);
-
-	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
-
-	if (pm_runtime_suspended(dev))
-		return 0;
-
-	return fimc_clk_ctrl(ctx, false);
-}
-
-static int fimc_resume(struct device *dev)
-{
-	struct fimc_context *ctx = get_fimc_context(dev);
-
-	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
-
-	if (!pm_runtime_suspended(dev))
-		return fimc_clk_ctrl(ctx, true);
-
-	return 0;
-}
-#endif
-
 static int fimc_runtime_suspend(struct device *dev)
 {
 	struct fimc_context *ctx = get_fimc_context(dev);
@@ -1799,7 +1773,8 @@ static int fimc_runtime_resume(struct de
 #endif
 
 static const struct dev_pm_ops fimc_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)
 };
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c
--- linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c	2016-09-25 21:47:13.000000000 -0400
@@ -1475,8 +1475,8 @@ static int g2d_remove(struct platform_de
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int g2d_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int g2d_runtime_suspend(struct device *dev)
 {
 	struct g2d_data *g2d = dev_get_drvdata(dev);
 
@@ -1490,25 +1490,6 @@ static int g2d_suspend(struct device *de
 
 	flush_work(&g2d->runqueue_work);
 
-	return 0;
-}
-
-static int g2d_resume(struct device *dev)
-{
-	struct g2d_data *g2d = dev_get_drvdata(dev);
-
-	g2d->suspended = false;
-	g2d_exec_runqueue(g2d);
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_PM
-static int g2d_runtime_suspend(struct device *dev)
-{
-	struct g2d_data *g2d = dev_get_drvdata(dev);
-
 	clk_disable_unprepare(g2d->gate_clk);
 
 	return 0;
@@ -1523,12 +1504,16 @@ static int g2d_runtime_resume(struct dev
 	if (ret < 0)
 		dev_warn(dev, "failed to enable clock.\n");
 
+	g2d->suspended = false;
+	g2d_exec_runqueue(g2d);
+
 	return ret;
 }
 #endif
 
 static const struct dev_pm_ops g2d_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL)
 };
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c
--- linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c	2016-09-25 21:47:13.000000000 -0400
@@ -1760,34 +1760,7 @@ static int gsc_remove(struct platform_de
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int gsc_suspend(struct device *dev)
-{
-	struct gsc_context *ctx = get_gsc_context(dev);
-
-	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
-
-	if (pm_runtime_suspended(dev))
-		return 0;
-
-	return gsc_clk_ctrl(ctx, false);
-}
-
-static int gsc_resume(struct device *dev)
-{
-	struct gsc_context *ctx = get_gsc_context(dev);
-
-	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
-
-	if (!pm_runtime_suspended(dev))
-		return gsc_clk_ctrl(ctx, true);
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_PM
-static int gsc_runtime_suspend(struct device *dev)
+static int __maybe_unused gsc_runtime_suspend(struct device *dev)
 {
 	struct gsc_context *ctx = get_gsc_context(dev);
 
@@ -1796,7 +1769,7 @@ static int gsc_runtime_suspend(struct de
 	return  gsc_clk_ctrl(ctx, false);
 }
 
-static int gsc_runtime_resume(struct device *dev)
+static int __maybe_unused gsc_runtime_resume(struct device *dev)
 {
 	struct gsc_context *ctx = get_gsc_context(dev);
 
@@ -1804,10 +1777,10 @@ static int gsc_runtime_resume(struct dev
 
 	return  gsc_clk_ctrl(ctx, true);
 }
-#endif
 
 static const struct dev_pm_ops gsc_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(gsc_suspend, gsc_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
 };
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c
--- linux-libre-4.8-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c	2016-09-25 21:47:13.000000000 -0400
@@ -794,29 +794,6 @@ static int rotator_clk_crtl(struct rot_c
 	return 0;
 }
 
-
-#ifdef CONFIG_PM_SLEEP
-static int rotator_suspend(struct device *dev)
-{
-	struct rot_context *rot = dev_get_drvdata(dev);
-
-	if (pm_runtime_suspended(dev))
-		return 0;
-
-	return rotator_clk_crtl(rot, false);
-}
-
-static int rotator_resume(struct device *dev)
-{
-	struct rot_context *rot = dev_get_drvdata(dev);
-
-	if (!pm_runtime_suspended(dev))
-		return rotator_clk_crtl(rot, true);
-
-	return 0;
-}
-#endif
-
 static int rotator_runtime_suspend(struct device *dev)
 {
 	struct rot_context *rot = dev_get_drvdata(dev);
@@ -833,7 +810,8 @@ static int rotator_runtime_resume(struct
 #endif
 
 static const struct dev_pm_ops rotator_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(rotator_suspend, rotator_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(rotator_runtime_suspend, rotator_runtime_resume,
 									NULL)
 };
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/i2c/busses/i2c-eg20t.c linux-libre-4.8-rc8-gnu/drivers/i2c/busses/i2c-eg20t.c
--- linux-libre-4.8-rc7-gnu/drivers/i2c/busses/i2c-eg20t.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/i2c/busses/i2c-eg20t.c	2016-09-25 21:47:13.000000000 -0400
@@ -773,13 +773,6 @@ static int pch_i2c_probe(struct pci_dev
 	/* Set the number of I2C channel instance */
 	adap_info->ch_num = id->driver_data;
 
-	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, adap_info);
-	if (ret) {
-		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
-	}
-
 	for (i = 0; i < adap_info->ch_num; i++) {
 		pch_adap = &adap_info->pch_data[i].pch_adapter;
 		adap_info->pch_i2c_suspended = false;
@@ -797,6 +790,17 @@ static int pch_i2c_probe(struct pci_dev
 
 		pch_adap->dev.of_node = pdev->dev.of_node;
 		pch_adap->dev.parent = &pdev->dev;
+	}
+
+	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
+		  KBUILD_MODNAME, adap_info);
+	if (ret) {
+		pch_pci_err(pdev, "request_irq FAILED\n");
+		goto err_request_irq;
+	}
+
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
 
 		pch_i2c_init(&adap_info->pch_data[i]);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/i2c/busses/i2c-qup.c linux-libre-4.8-rc8-gnu/drivers/i2c/busses/i2c-qup.c
--- linux-libre-4.8-rc7-gnu/drivers/i2c/busses/i2c-qup.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/i2c/busses/i2c-qup.c	2016-09-25 21:47:13.000000000 -0400
@@ -1599,7 +1599,8 @@ static int qup_i2c_pm_resume_runtime(str
 #ifdef CONFIG_PM_SLEEP
 static int qup_i2c_suspend(struct device *device)
 {
-	qup_i2c_pm_suspend_runtime(device);
+	if (!pm_runtime_suspended(device))
+		return qup_i2c_pm_suspend_runtime(device);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/i2c/muxes/i2c-mux-pca954x.c linux-libre-4.8-rc8-gnu/drivers/i2c/muxes/i2c-mux-pca954x.c
--- linux-libre-4.8-rc7-gnu/drivers/i2c/muxes/i2c-mux-pca954x.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/i2c/muxes/i2c-mux-pca954x.c	2016-09-25 21:47:13.000000000 -0400
@@ -164,7 +164,7 @@ static int pca954x_select_chan(struct i2
 	/* Only select the channel if its different from the last channel */
 	if (data->last_chan != regval) {
 		ret = pca954x_reg_write(muxc->parent, client, regval);
-		data->last_chan = regval;
+		data->last_chan = ret ? 0 : regval;
 	}
 
 	return ret;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/input/touchscreen/silead.c linux-libre-4.8-rc8-gnu/drivers/input/touchscreen/silead.c
--- linux-libre-4.8-rc7-gnu/drivers/input/touchscreen/silead.c	2016-09-22 01:15:10.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/input/touchscreen/silead.c	2016-09-26 00:38:38.000000000 -0400
@@ -390,7 +390,7 @@ static void silead_ts_read_props(struct
 		data->max_fingers = 5; /* Most devices handle up-to 5 fingers */
 	}
 
-	error = device_property_read_string(dev, "touchscreen-fw-name", &str);
+	error = device_property_read_string(dev, "firmware-name", &str);
 	if (!error)
 		/*(DEBLOBBED)*/;
 	else
@@ -410,14 +410,14 @@ static int silead_ts_set_default_fw_name
 		if (!acpi_id)
 			return -ENODEV;
 
-		snprintf(data->fw_name, sizeof(data->fw_name), "/*(DEBLOBBED)*/",
-			acpi_id->id);
+		snprintf(data->fw_name, sizeof(data->fw_name),
+			 "/*(DEBLOBBED)*/", acpi_id->id);
 
 		for (i = 0; i < strlen(data->fw_name); i++)
 			data->fw_name[i] = tolower(data->fw_name[i]);
 	} else {
-		snprintf(data->fw_name, sizeof(data->fw_name), "/*(DEBLOBBED)*/",
-			id->name);
+		snprintf(data->fw_name, sizeof(data->fw_name),
+			 "/*(DEBLOBBED)*/", id->name);
 	}
 
 	return 0;
@@ -426,7 +426,8 @@ static int silead_ts_set_default_fw_name
 static int silead_ts_set_default_fw_name(struct silead_ts_data *data,
 					 const struct i2c_device_id *id)
 {
-	snprintf(data->fw_name, sizeof(data->fw_name), "/*(DEBLOBBED)*/", id->name);
+	snprintf(data->fw_name, sizeof(data->fw_name),
+		 "/*(DEBLOBBED)*/", id->name);
 	return 0;
 }
 #endif
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/irqchip/irq-gic-v3.c linux-libre-4.8-rc8-gnu/drivers/irqchip/irq-gic-v3.c
--- linux-libre-4.8-rc7-gnu/drivers/irqchip/irq-gic-v3.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/irqchip/irq-gic-v3.c	2016-09-25 21:47:13.000000000 -0400
@@ -548,7 +548,7 @@ static int gic_starting_cpu(unsigned int
 static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
 				   unsigned long cluster_id)
 {
-	int cpu = *base_cpu;
+	int next_cpu, cpu = *base_cpu;
 	unsigned long mpidr = cpu_logical_map(cpu);
 	u16 tlist = 0;
 
@@ -562,9 +562,10 @@ static u16 gic_compute_target_list(int *
 
 		tlist |= 1 << (mpidr & 0xf);
 
-		cpu = cpumask_next(cpu, mask);
-		if (cpu >= nr_cpu_ids)
+		next_cpu = cpumask_next(cpu, mask);
+		if (next_cpu >= nr_cpu_ids)
 			goto out;
+		cpu = next_cpu;
 
 		mpidr = cpu_logical_map(cpu);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/irqchip/irq-mips-gic.c linux-libre-4.8-rc8-gnu/drivers/irqchip/irq-mips-gic.c
--- linux-libre-4.8-rc7-gnu/drivers/irqchip/irq-mips-gic.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/irqchip/irq-mips-gic.c	2016-09-25 21:47:13.000000000 -0400
@@ -638,27 +638,6 @@ static int gic_local_irq_domain_map(stru
 	if (!gic_local_irq_is_routable(intr))
 		return -EPERM;
 
-	/*
-	 * HACK: These are all really percpu interrupts, but the rest
-	 * of the MIPS kernel code does not use the percpu IRQ API for
-	 * the CP0 timer and performance counter interrupts.
-	 */
-	switch (intr) {
-	case GIC_LOCAL_INT_TIMER:
-	case GIC_LOCAL_INT_PERFCTR:
-	case GIC_LOCAL_INT_FDC:
-		irq_set_chip_and_handler(virq,
-					 &gic_all_vpes_local_irq_controller,
-					 handle_percpu_irq);
-		break;
-	default:
-		irq_set_chip_and_handler(virq,
-					 &gic_local_irq_controller,
-					 handle_percpu_devid_irq);
-		irq_set_percpu_devid(virq);
-		break;
-	}
-
 	spin_lock_irqsave(&gic_lock, flags);
 	for (i = 0; i < gic_vpes; i++) {
 		u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin;
@@ -724,16 +703,42 @@ static int gic_shared_irq_domain_map(str
 	return 0;
 }
 
-static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
-			      irq_hw_number_t hw)
+static int gic_setup_dev_chip(struct irq_domain *d, unsigned int virq,
+			      unsigned int hwirq)
 {
-	if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS)
-		return gic_local_irq_domain_map(d, virq, hw);
+	struct irq_chip *chip;
+	int err;
 
-	irq_set_chip_and_handler(virq, &gic_level_irq_controller,
-				 handle_level_irq);
+	if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
+		err = irq_domain_set_hwirq_and_chip(d, virq, hwirq,
+						    &gic_level_irq_controller,
+						    NULL);
+	} else {
+		switch (GIC_HWIRQ_TO_LOCAL(hwirq)) {
+		case GIC_LOCAL_INT_TIMER:
+		case GIC_LOCAL_INT_PERFCTR:
+		case GIC_LOCAL_INT_FDC:
+			/*
+			 * HACK: These are all really percpu interrupts, but
+			 * the rest of the MIPS kernel code does not use the
+			 * percpu IRQ API for them.
+			 */
+			chip = &gic_all_vpes_local_irq_controller;
+			irq_set_handler(virq, handle_percpu_irq);
+			break;
 
-	return gic_shared_irq_domain_map(d, virq, hw, 0);
+		default:
+			chip = &gic_local_irq_controller;
+			irq_set_handler(virq, handle_percpu_devid_irq);
+			irq_set_percpu_devid(virq);
+			break;
+		}
+
+		err = irq_domain_set_hwirq_and_chip(d, virq, hwirq,
+						    chip, NULL);
+	}
+
+	return err;
 }
 
 static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
@@ -744,15 +749,12 @@ static int gic_irq_domain_alloc(struct i
 	int cpu, ret, i;
 
 	if (spec->type == GIC_DEVICE) {
-		/* verify that it doesn't conflict with an IPI irq */
-		if (test_bit(spec->hwirq, ipi_resrv))
+		/* verify that shared irqs don't conflict with an IPI irq */
+		if ((spec->hwirq >= GIC_SHARED_HWIRQ_BASE) &&
+		    test_bit(GIC_HWIRQ_TO_SHARED(spec->hwirq), ipi_resrv))
 			return -EBUSY;
 
-		hwirq = GIC_SHARED_TO_HWIRQ(spec->hwirq);
-
-		return irq_domain_set_hwirq_and_chip(d, virq, hwirq,
-						     &gic_level_irq_controller,
-						     NULL);
+		return gic_setup_dev_chip(d, virq, spec->hwirq);
 	} else {
 		base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs);
 		if (base_hwirq == gic_shared_intrs) {
@@ -821,7 +823,6 @@ int gic_irq_domain_match(struct irq_doma
 }
 
 static const struct irq_domain_ops gic_irq_domain_ops = {
-	.map = gic_irq_domain_map,
 	.alloc = gic_irq_domain_alloc,
 	.free = gic_irq_domain_free,
 	.match = gic_irq_domain_match,
@@ -852,29 +853,20 @@ static int gic_dev_domain_alloc(struct i
 	struct irq_fwspec *fwspec = arg;
 	struct gic_irq_spec spec = {
 		.type = GIC_DEVICE,
-		.hwirq = fwspec->param[1],
 	};
 	int i, ret;
-	bool is_shared = fwspec->param[0] == GIC_SHARED;
-
-	if (is_shared) {
-		ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec);
-		if (ret)
-			return ret;
-	}
 
-	for (i = 0; i < nr_irqs; i++) {
-		irq_hw_number_t hwirq;
+	if (fwspec->param[0] == GIC_SHARED)
+		spec.hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]);
+	else
+		spec.hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]);
 
-		if (is_shared)
-			hwirq = GIC_SHARED_TO_HWIRQ(spec.hwirq + i);
-		else
-			hwirq = GIC_LOCAL_TO_HWIRQ(spec.hwirq + i);
+	ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec);
+	if (ret)
+		return ret;
 
-		ret = irq_domain_set_hwirq_and_chip(d, virq + i,
-						    hwirq,
-						    &gic_level_irq_controller,
-						    NULL);
+	for (i = 0; i < nr_irqs; i++) {
+		ret = gic_setup_dev_chip(d, virq + i, spec.hwirq + i);
 		if (ret)
 			goto error;
 	}
@@ -896,7 +888,10 @@ void gic_dev_domain_free(struct irq_doma
 static void gic_dev_domain_activate(struct irq_domain *domain,
 				    struct irq_data *d)
 {
-	gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0);
+	if (GIC_HWIRQ_TO_LOCAL(d->hwirq) < GIC_NUM_LOCAL_INTRS)
+		gic_local_irq_domain_map(domain, d->irq, d->hwirq);
+	else
+		gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0);
 }
 
 static struct irq_domain_ops gic_dev_domain_ops = {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/cec-edid.c linux-libre-4.8-rc8-gnu/drivers/media/cec-edid.c
--- linux-libre-4.8-rc7-gnu/drivers/media/cec-edid.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/cec-edid.c	2016-09-25 21:47:13.000000000 -0400
@@ -70,7 +70,10 @@ static unsigned int cec_get_edid_spa_loc
 				u8 tag = edid[i] >> 5;
 				u8 len = edid[i] & 0x1f;
 
-				if (tag == 3 && len >= 5 && i + len <= end)
+				if (tag == 3 && len >= 5 && i + len <= end &&
+				    edid[i + 1] == 0x03 &&
+				    edid[i + 2] == 0x0c &&
+				    edid[i + 3] == 0x00)
 					return i + 4;
 				i += len + 1;
 			} while (i < end);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/pci/cx23885/cx23885-417.c linux-libre-4.8-rc8-gnu/drivers/media/pci/cx23885/cx23885-417.c
--- linux-libre-4.8-rc7-gnu/drivers/media/pci/cx23885/cx23885-417.c	2016-09-22 01:04:04.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/pci/cx23885/cx23885-417.c	2016-09-26 00:26:31.000000000 -0400
@@ -1552,6 +1552,7 @@ int cx23885_417_register(struct cx23885_
 	q->mem_ops = &vb2_dma_sg_memops;
 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 	q->lock = &dev->lock;
+	q->dev = &dev->pci->dev;
 
 	err = vb2_queue_init(q);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/pci/saa7134/saa7134-dvb.c linux-libre-4.8-rc8-gnu/drivers/media/pci/saa7134/saa7134-dvb.c
--- linux-libre-4.8-rc7-gnu/drivers/media/pci/saa7134/saa7134-dvb.c	2016-09-22 01:04:37.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/pci/saa7134/saa7134-dvb.c	2016-09-26 00:27:07.000000000 -0400
@@ -1238,6 +1238,7 @@ static int dvb_init(struct saa7134_dev *
 	q->buf_struct_size = sizeof(struct saa7134_buf);
 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 	q->lock = &dev->lock;
+	q->dev = &dev->pci->dev;
 	ret = vb2_queue_init(q);
 	if (ret) {
 		vb2_dvb_dealloc_frontends(&dev->frontends);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/pci/saa7134/saa7134-empress.c linux-libre-4.8-rc8-gnu/drivers/media/pci/saa7134/saa7134-empress.c
--- linux-libre-4.8-rc7-gnu/drivers/media/pci/saa7134/saa7134-empress.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/pci/saa7134/saa7134-empress.c	2016-09-25 21:47:13.000000000 -0400
@@ -295,6 +295,7 @@ static int empress_init(struct saa7134_d
 	q->buf_struct_size = sizeof(struct saa7134_buf);
 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 	q->lock = &dev->lock;
+	q->dev = &dev->pci->dev;
 	err = vb2_queue_init(q);
 	if (err)
 		return err;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/Kconfig linux-libre-4.8-rc8-gnu/drivers/media/platform/Kconfig
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/Kconfig	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/Kconfig	2016-09-25 21:47:13.000000000 -0400
@@ -169,7 +169,7 @@ config VIDEO_MEDIATEK_VPU
 config VIDEO_MEDIATEK_VCODEC
 	tristate "Mediatek Video Codec driver"
 	depends on MTK_IOMMU || COMPILE_TEST
-	depends on VIDEO_DEV && VIDEO_V4L2
+	depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h	2016-09-25 21:47:13.000000000 -0400
@@ -23,7 +23,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-core.h>
 
-#include "mtk_vcodec_util.h"
 
 #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
 #define MTK_VCODEC_ENC_NAME	"mtk-vcodec-enc"
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c	2016-09-25 21:47:13.000000000 -0400
@@ -487,7 +487,6 @@ static int vidioc_venc_s_fmt_out(struct
 	struct mtk_q_data *q_data;
 	int ret, i;
 	struct mtk_video_fmt *fmt;
-	unsigned int pitch_w_div16;
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 
 	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
@@ -530,15 +529,6 @@ static int vidioc_venc_s_fmt_out(struct
 	q_data->coded_width = f->fmt.pix_mp.width;
 	q_data->coded_height = f->fmt.pix_mp.height;
 
-	pitch_w_div16 = DIV_ROUND_UP(q_data->visible_width, 16);
-	if (pitch_w_div16 % 8 != 0) {
-		/* Adjust returned width/height, so application could correctly
-		 * allocate hw required memory
-		 */
-		q_data->visible_height += 32;
-		vidioc_try_fmt(f, q_data->fmt);
-	}
-
 	q_data->field = f->fmt.pix_mp.field;
 	ctx->colorspace = f->fmt.pix_mp.colorspace;
 	ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
@@ -878,7 +868,8 @@ static int mtk_venc_encode_header(void *
 {
 	struct mtk_vcodec_ctx *ctx = priv;
 	int ret;
-	struct vb2_buffer *dst_buf;
+	struct vb2_buffer *src_buf, *dst_buf;
+	struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2;
 	struct mtk_vcodec_mem bs_buf;
 	struct venc_done_result enc_result;
 
@@ -911,6 +902,15 @@ static int mtk_venc_encode_header(void *
 		mtk_v4l2_err("venc_if_encode failed=%d", ret);
 		return -EINVAL;
 	}
+	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	if (src_buf) {
+		src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf);
+		dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf);
+		dst_buf->timestamp = src_buf->timestamp;
+		dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode;
+	} else {
+		mtk_v4l2_err("No timestamp for the header buffer.");
+	}
 
 	ctx->state = MTK_STATE_HEADER;
 	dst_buf->planes[0].bytesused = enc_result.bs_size;
@@ -1003,7 +1003,7 @@ static void mtk_venc_worker(struct work_
 	struct mtk_vcodec_mem bs_buf;
 	struct venc_done_result enc_result;
 	int ret, i;
-	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2;
 
 	/* check dst_buf, dst_buf may be removed in device_run
 	 * to stored encdoe header so we need check dst_buf and
@@ -1043,9 +1043,14 @@ static void mtk_venc_worker(struct work_
 	ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME,
 			     &frm_buf, &bs_buf, &enc_result);
 
-	vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
+	src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf);
+	dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf);
+
+	dst_buf->timestamp = src_buf->timestamp;
+	dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode;
+
 	if (enc_result.is_key_frm)
-		vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME;
+		dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME;
 
 	if (ret) {
 		v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf),
@@ -1217,7 +1222,7 @@ int mtk_vcodec_enc_ctrls_setup(struct mt
 			0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE);
 	v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE,
 			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
-			0, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN);
+			0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
 	v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL,
 			V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
 			0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
@@ -1288,5 +1293,10 @@ int mtk_venc_lock(struct mtk_vcodec_ctx
 
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
 {
-	venc_if_deinit(ctx);
+	int ret = venc_if_deinit(ctx);
+
+	if (ret)
+		mtk_v4l2_err("venc_if_deinit failed=%d", ret);
+
+	ctx->state = MTK_STATE_FREE;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c	2016-09-25 21:47:13.000000000 -0400
@@ -218,11 +218,15 @@ static int fops_vcodec_release(struct fi
 	mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
 	mutex_lock(&dev->dev_mutex);
 
+	/*
+	 * Call v4l2_m2m_ctx_release to make sure the worker thread is not
+	 * running after venc_if_deinit.
+	 */
+	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_enc_release(ctx);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
-	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 
 	list_del_init(&ctx->list);
 	dev->num_instances--;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h	2016-09-25 21:47:13.000000000 -0400
@@ -16,7 +16,6 @@
 #define _MTK_VCODEC_INTR_H_
 
 #define MTK_INST_IRQ_RECEIVED		0x1
-#define MTK_INST_WORK_THREAD_ABORT_DONE	0x2
 
 struct mtk_vcodec_ctx;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c	2016-09-25 21:47:13.000000000 -0400
@@ -61,6 +61,8 @@ enum venc_h264_bs_mode {
 
 /*
  * struct venc_h264_vpu_config - Structure for h264 encoder configuration
+ *                               AP-W/R : AP is writer/reader on this item
+ *                               VPU-W/R: VPU is write/reader on this item
  * @input_fourcc: input fourcc
  * @bitrate: target bitrate (in bps)
  * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
@@ -94,13 +96,13 @@ struct venc_h264_vpu_config {
 
 /*
  * struct venc_h264_vpu_buf - Structure for buffer information
- * @align: buffer alignment (in bytes)
+ *                            AP-W/R : AP is writer/reader on this item
+ *                            VPU-W/R: VPU is write/reader on this item
  * @iova: IO virtual address
  * @vpua: VPU side memory addr which is used by RC_CODE
  * @size: buffer size (in bytes)
  */
 struct venc_h264_vpu_buf {
-	u32 align;
 	u32 iova;
 	u32 vpua;
 	u32 size;
@@ -108,6 +110,8 @@ struct venc_h264_vpu_buf {
 
 /*
  * struct venc_h264_vsi - Structure for VPU driver control and info share
+ *                        AP-W/R : AP is writer/reader on this item
+ *                        VPU-W/R: VPU is write/reader on this item
  * This structure is allocated in VPU side and shared to AP side.
  * @config: h264 encoder configuration
  * @work_bufs: working buffer information in VPU side
@@ -150,12 +154,6 @@ struct venc_h264_inst {
 	struct mtk_vcodec_ctx *ctx;
 };
 
-static inline void h264_write_reg(struct venc_h264_inst *inst, u32 addr,
-				  u32 val)
-{
-	writel(val, inst->hw_base + addr);
-}
-
 static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr)
 {
 	return readl(inst->hw_base + addr);
@@ -214,6 +212,8 @@ static unsigned int h264_get_level(struc
 		return 40;
 	case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
 		return 41;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
+		return 42;
 	default:
 		mtk_vcodec_debug(inst, "unsupported level %d", level);
 		return 31;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c	2016-09-25 21:47:13.000000000 -0400
@@ -56,6 +56,8 @@ enum venc_vp8_vpu_work_buf {
 
 /*
  * struct venc_vp8_vpu_config - Structure for vp8 encoder configuration
+ *                              AP-W/R : AP is writer/reader on this item
+ *                              VPU-W/R: VPU is write/reader on this item
  * @input_fourcc: input fourcc
  * @bitrate: target bitrate (in bps)
  * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
@@ -83,14 +85,14 @@ struct venc_vp8_vpu_config {
 };
 
 /*
- * struct venc_vp8_vpu_buf -Structure for buffer information
- * @align: buffer alignment (in bytes)
+ * struct venc_vp8_vpu_buf - Structure for buffer information
+ *                           AP-W/R : AP is writer/reader on this item
+ *                           VPU-W/R: VPU is write/reader on this item
  * @iova: IO virtual address
  * @vpua: VPU side memory addr which is used by RC_CODE
  * @size: buffer size (in bytes)
  */
 struct venc_vp8_vpu_buf {
-	u32 align;
 	u32 iova;
 	u32 vpua;
 	u32 size;
@@ -98,6 +100,8 @@ struct venc_vp8_vpu_buf {
 
 /*
  * struct venc_vp8_vsi - Structure for VPU driver control and info share
+ *                       AP-W/R : AP is writer/reader on this item
+ *                       VPU-W/R: VPU is write/reader on this item
  * This structure is allocated in VPU side and shared to AP side.
  * @config: vp8 encoder configuration
  * @work_bufs: working buffer information in VPU side
@@ -138,12 +142,6 @@ struct venc_vp8_inst {
 	struct mtk_vcodec_ctx *ctx;
 };
 
-static inline void vp8_enc_write_reg(struct venc_vp8_inst *inst, u32 addr,
-				     u32 val)
-{
-	writel(val, inst->hw_base + addr);
-}
-
 static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr)
 {
 	return readl(inst->hw_base + addr);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/media/platform/rcar-fcp.c linux-libre-4.8-rc8-gnu/drivers/media/platform/rcar-fcp.c
--- linux-libre-4.8-rc7-gnu/drivers/media/platform/rcar-fcp.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/media/platform/rcar-fcp.c	2016-09-25 21:47:13.000000000 -0400
@@ -99,10 +99,16 @@ EXPORT_SYMBOL_GPL(rcar_fcp_put);
  */
 int rcar_fcp_enable(struct rcar_fcp_device *fcp)
 {
+	int error;
+
 	if (!fcp)
 		return 0;
 
-	return pm_runtime_get_sync(fcp->dev);
+	error = pm_runtime_get_sync(fcp->dev);
+	if (error < 0)
+		return error;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(rcar_fcp_enable);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/mmc/host/dw_mmc.c linux-libre-4.8-rc8-gnu/drivers/mmc/host/dw_mmc.c
--- linux-libre-4.8-rc7-gnu/drivers/mmc/host/dw_mmc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/mmc/host/dw_mmc.c	2016-09-25 21:47:13.000000000 -0400
@@ -1112,11 +1112,12 @@ static void dw_mci_setup_bus(struct dw_m
 
 		div = (host->bus_hz != clock) ? DIV_ROUND_UP(div, 2) : 0;
 
-		dev_info(&slot->mmc->class_dev,
-			 "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n",
-			 slot->id, host->bus_hz, clock,
-			 div ? ((host->bus_hz / div) >> 1) :
-			 host->bus_hz, div);
+		if (clock != slot->__clk_old || force_clkinit)
+			dev_info(&slot->mmc->class_dev,
+				 "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n",
+				 slot->id, host->bus_hz, clock,
+				 div ? ((host->bus_hz / div) >> 1) :
+				 host->bus_hz, div);
 
 		/* disable clock */
 		mci_writel(host, CLKENA, 0);
@@ -1139,6 +1140,9 @@ static void dw_mci_setup_bus(struct dw_m
 
 		/* inform CIU */
 		mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+
+		/* keep the last clock value that was requested from core */
+		slot->__clk_old = clock;
 	}
 
 	host->current_speed = clock;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/mmc/host/dw_mmc.h linux-libre-4.8-rc8-gnu/drivers/mmc/host/dw_mmc.h
--- linux-libre-4.8-rc7-gnu/drivers/mmc/host/dw_mmc.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/mmc/host/dw_mmc.h	2016-09-25 21:47:13.000000000 -0400
@@ -249,6 +249,8 @@ extern int dw_mci_resume(struct dw_mci *
  * @queue_node: List node for placing this node in the @queue list of
  *	&struct dw_mci.
  * @clock: Clock rate configured by set_ios(). Protected by host->lock.
+ * @__clk_old: The last clock value that was requested from core.
+ *	Keeping track of this helps us to avoid spamming the console.
  * @flags: Random state bits associated with the slot.
  * @id: Number of this slot.
  * @sdio_id: Number of this slot in the SDIO interrupt registers.
@@ -263,6 +265,7 @@ struct dw_mci_slot {
 	struct list_head	queue_node;
 
 	unsigned int		clock;
+	unsigned int		__clk_old;
 
 	unsigned long		flags;
 #define DW_MMC_CARD_PRESENT	0
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/mtd/nand/mtk_ecc.c linux-libre-4.8-rc8-gnu/drivers/mtd/nand/mtk_ecc.c
--- linux-libre-4.8-rc7-gnu/drivers/mtd/nand/mtk_ecc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/mtd/nand/mtk_ecc.c	2016-09-25 21:47:13.000000000 -0400
@@ -366,7 +366,8 @@ int mtk_ecc_encode(struct mtk_ecc *ecc,
 		   u8 *data, u32 bytes)
 {
 	dma_addr_t addr;
-	u32 *p, len, i;
+	u8 *p;
+	u32 len, i, val;
 	int ret = 0;
 
 	addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
@@ -392,11 +393,14 @@ int mtk_ecc_encode(struct mtk_ecc *ecc,
 
 	/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
 	len = (config->strength * ECC_PARITY_BITS + 7) >> 3;
-	p = (u32 *)(data + bytes);
+	p = data + bytes;
 
 	/* write the parity bytes generated by the ECC back to the OOB region */
-	for (i = 0; i < len; i++)
-		p[i] = readl(ecc->regs + ECC_ENCPAR(i));
+	for (i = 0; i < len; i++) {
+		if ((i % 4) == 0)
+			val = readl(ecc->regs + ECC_ENCPAR(i / 4));
+		p[i] = (val >> ((i % 4) * 8)) & 0xff;
+	}
 timeout:
 
 	dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/mtd/nand/mtk_nand.c linux-libre-4.8-rc8-gnu/drivers/mtd/nand/mtk_nand.c
--- linux-libre-4.8-rc7-gnu/drivers/mtd/nand/mtk_nand.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/mtd/nand/mtk_nand.c	2016-09-25 21:47:13.000000000 -0400
@@ -93,6 +93,9 @@
 #define		NFI_FSM_MASK		(0xf << 16)
 #define NFI_ADDRCNTR		(0x70)
 #define		CNTR_MASK		GENMASK(16, 12)
+#define		ADDRCNTR_SEC_SHIFT	(12)
+#define		ADDRCNTR_SEC(val) \
+		(((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT)
 #define NFI_STRADDR		(0x80)
 #define NFI_BYTELEN		(0x84)
 #define NFI_CSEL		(0x90)
@@ -699,7 +702,7 @@ static int mtk_nfc_do_write_page(struct
 	}
 
 	ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg,
-					(reg & CNTR_MASK) >= chip->ecc.steps,
+					ADDRCNTR_SEC(reg) >= chip->ecc.steps,
 					10, MTK_TIMEOUT);
 	if (ret)
 		dev_err(dev, "hwecc write timeout\n");
@@ -902,7 +905,7 @@ static int mtk_nfc_read_subpage(struct m
 		dev_warn(nfc->dev, "read ahb/dma done timeout\n");
 
 	rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg,
-				       (reg & CNTR_MASK) >= sectors, 10,
+				       ADDRCNTR_SEC(reg) >= sectors, 10,
 				       MTK_TIMEOUT);
 	if (rc < 0) {
 		dev_err(nfc->dev, "subpage done timeout\n");
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/mtd/nand/mxc_nand.c linux-libre-4.8-rc8-gnu/drivers/mtd/nand/mxc_nand.c
--- linux-libre-4.8-rc7-gnu/drivers/mtd/nand/mxc_nand.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/mtd/nand/mxc_nand.c	2016-09-25 21:47:13.000000000 -0400
@@ -943,7 +943,7 @@ static int mxc_v2_ooblayout_free(struct
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
 	int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26;
 
-	if (section > nand_chip->ecc.steps)
+	if (section >= nand_chip->ecc.steps)
 		return -ERANGE;
 
 	if (!section) {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/can/flexcan.c linux-libre-4.8-rc8-gnu/drivers/net/can/flexcan.c
--- linux-libre-4.8-rc7-gnu/drivers/net/can/flexcan.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/can/flexcan.c	2016-09-25 21:47:13.000000000 -0400
@@ -1268,11 +1268,10 @@ static int __maybe_unused flexcan_suspen
 	struct flexcan_priv *priv = netdev_priv(dev);
 	int err;
 
-	err = flexcan_chip_disable(priv);
-	if (err)
-		return err;
-
 	if (netif_running(dev)) {
+		err = flexcan_chip_disable(priv);
+		if (err)
+			return err;
 		netif_stop_queue(dev);
 		netif_device_detach(dev);
 	}
@@ -1285,13 +1284,17 @@ static int __maybe_unused flexcan_resume
 {
 	struct net_device *dev = dev_get_drvdata(device);
 	struct flexcan_priv *priv = netdev_priv(dev);
+	int err;
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 	if (netif_running(dev)) {
 		netif_device_attach(dev);
 		netif_start_queue(dev);
+		err = flexcan_chip_enable(priv);
+		if (err)
+			return err;
 	}
-	return flexcan_chip_enable(priv);
+	return 0;
 }
 
 static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/can/ifi_canfd/ifi_canfd.c linux-libre-4.8-rc8-gnu/drivers/net/can/ifi_canfd/ifi_canfd.c
--- linux-libre-4.8-rc7-gnu/drivers/net/can/ifi_canfd/ifi_canfd.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/can/ifi_canfd/ifi_canfd.c	2016-09-25 21:47:13.000000000 -0400
@@ -81,6 +81,10 @@
 #define IFI_CANFD_TIME_SET_TIMEA_4_12_6_6	BIT(15)
 
 #define IFI_CANFD_TDELAY			0x1c
+#define IFI_CANFD_TDELAY_DEFAULT		0xb
+#define IFI_CANFD_TDELAY_MASK			0x3fff
+#define IFI_CANFD_TDELAY_ABS			BIT(14)
+#define IFI_CANFD_TDELAY_EN			BIT(15)
 
 #define IFI_CANFD_ERROR				0x20
 #define IFI_CANFD_ERROR_TX_OFFSET		0
@@ -641,7 +645,7 @@ static void ifi_canfd_set_bittiming(stru
 	struct ifi_canfd_priv *priv = netdev_priv(ndev);
 	const struct can_bittiming *bt = &priv->can.bittiming;
 	const struct can_bittiming *dbt = &priv->can.data_bittiming;
-	u16 brp, sjw, tseg1, tseg2;
+	u16 brp, sjw, tseg1, tseg2, tdc;
 
 	/* Configure bit timing */
 	brp = bt->brp - 2;
@@ -664,6 +668,11 @@ static void ifi_canfd_set_bittiming(stru
 	       (brp << IFI_CANFD_TIME_PRESCALE_OFF) |
 	       (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8),
 	       priv->base + IFI_CANFD_FTIME);
+
+	/* Configure transmitter delay */
+	tdc = (dbt->brp * (dbt->phase_seg1 + 1)) & IFI_CANFD_TDELAY_MASK;
+	writel(IFI_CANFD_TDELAY_EN | IFI_CANFD_TDELAY_ABS | tdc,
+	       priv->base + IFI_CANFD_TDELAY);
 }
 
 static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id,
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/broadcom/bnx2.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/broadcom/bnx2.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/broadcom/bnx2.c	2016-09-22 01:05:38.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/broadcom/bnx2.c	2016-09-26 00:28:16.000000000 -0400
@@ -6352,10 +6352,6 @@ bnx2_open(struct net_device *dev)
 	struct bnx2 *bp = netdev_priv(dev);
 	int rc;
 
-	rc = bnx2_request_firmware(bp);
-	if (rc < 0)
-		goto out;
-
 	netif_carrier_off(dev);
 
 	bnx2_disable_int(bp);
@@ -6424,7 +6420,6 @@ open_err:
 	bnx2_free_irq(bp);
 	bnx2_free_mem(bp);
 	bnx2_del_napi(bp);
-	bnx2_release_firmware(bp);
 	goto out;
 }
 
@@ -8571,6 +8566,12 @@ bnx2_init_one(struct pci_dev *pdev, cons
 
 	pci_set_drvdata(pdev, dev);
 
+	rc = bnx2_request_firmware(bp);
+	if (rc < 0)
+		goto error;
+
+
+	bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
 	memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
 
 	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
@@ -8603,6 +8604,7 @@ bnx2_init_one(struct pci_dev *pdev, cons
 	return 0;
 
 error:
+	bnx2_release_firmware(bp);
 	pci_iounmap(pdev, bp->regview);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c	2016-09-22 01:05:31.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c	2016-09-26 00:28:08.000000000 -0400
@@ -31,15 +31,10 @@
 #define BNAD_NUM_TXF_COUNTERS 12
 #define BNAD_NUM_RXF_COUNTERS 10
 #define BNAD_NUM_CQ_COUNTERS (3 + 5)
-#define BNAD_NUM_RXQ_COUNTERS 6
+#define BNAD_NUM_RXQ_COUNTERS 7
 #define BNAD_NUM_TXQ_COUNTERS 5
 
-#define BNAD_ETHTOOL_STATS_NUM						\
-	(sizeof(struct rtnl_link_stats64) / sizeof(u64) +	\
-	sizeof(struct bnad_drv_stats) / sizeof(u64) +		\
-	offsetof(struct bfi_enet_stats, rxf_stats[0]) / sizeof(u64))
-
-static const char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
+static const char *bnad_net_stats_strings[] = {
 	"rx_packets",
 	"tx_packets",
 	"rx_bytes",
@@ -50,22 +45,10 @@ static const char *bnad_net_stats_string
 	"tx_dropped",
 	"multicast",
 	"collisions",
-
 	"rx_length_errors",
-	"rx_over_errors",
 	"rx_crc_errors",
 	"rx_frame_errors",
-	"rx_fifo_errors",
-	"rx_missed_errors",
-
-	"tx_aborted_errors",
-	"tx_carrier_errors",
 	"tx_fifo_errors",
-	"tx_heartbeat_errors",
-	"tx_window_errors",
-
-	"rx_compressed",
-	"tx_compressed",
 
 	"netif_queue_stop",
 	"netif_queue_wakeup",
@@ -254,6 +237,8 @@ static const char *bnad_net_stats_string
 	"fc_tx_fid_parity_errors",
 };
 
+#define BNAD_ETHTOOL_STATS_NUM	ARRAY_SIZE(bnad_net_stats_strings)
+
 static int
 bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 {
@@ -658,6 +643,8 @@ bnad_get_strings(struct net_device *netd
 				string += ETH_GSTRING_LEN;
 				sprintf(string, "rxq%d_allocbuf_failed", q_num);
 				string += ETH_GSTRING_LEN;
+				sprintf(string, "rxq%d_mapbuf_failed", q_num);
+				string += ETH_GSTRING_LEN;
 				sprintf(string, "rxq%d_producer_index", q_num);
 				string += ETH_GSTRING_LEN;
 				sprintf(string, "rxq%d_consumer_index", q_num);
@@ -678,6 +665,9 @@ bnad_get_strings(struct net_device *netd
 					sprintf(string, "rxq%d_allocbuf_failed",
 								q_num);
 					string += ETH_GSTRING_LEN;
+					sprintf(string, "rxq%d_mapbuf_failed",
+						q_num);
+					string += ETH_GSTRING_LEN;
 					sprintf(string, "rxq%d_producer_index",
 								q_num);
 					string += ETH_GSTRING_LEN;
@@ -854,9 +844,9 @@ bnad_get_ethtool_stats(struct net_device
 		       u64 *buf)
 {
 	struct bnad *bnad = netdev_priv(netdev);
-	int i, j, bi;
+	int i, j, bi = 0;
 	unsigned long flags;
-	struct rtnl_link_stats64 *net_stats64;
+	struct rtnl_link_stats64 net_stats64;
 	u64 *stats64;
 	u32 bmap;
 
@@ -871,14 +861,25 @@ bnad_get_ethtool_stats(struct net_device
 	 * under the same lock
 	 */
 	spin_lock_irqsave(&bnad->bna_lock, flags);
-	bi = 0;
-	memset(buf, 0, stats->n_stats * sizeof(u64));
 
-	net_stats64 = (struct rtnl_link_stats64 *)buf;
-	bnad_netdev_qstats_fill(bnad, net_stats64);
-	bnad_netdev_hwstats_fill(bnad, net_stats64);
+	memset(&net_stats64, 0, sizeof(net_stats64));
+	bnad_netdev_qstats_fill(bnad, &net_stats64);
+	bnad_netdev_hwstats_fill(bnad, &net_stats64);
 
-	bi = sizeof(*net_stats64) / sizeof(u64);
+	buf[bi++] = net_stats64.rx_packets;
+	buf[bi++] = net_stats64.tx_packets;
+	buf[bi++] = net_stats64.rx_bytes;
+	buf[bi++] = net_stats64.tx_bytes;
+	buf[bi++] = net_stats64.rx_errors;
+	buf[bi++] = net_stats64.tx_errors;
+	buf[bi++] = net_stats64.rx_dropped;
+	buf[bi++] = net_stats64.tx_dropped;
+	buf[bi++] = net_stats64.multicast;
+	buf[bi++] = net_stats64.collisions;
+	buf[bi++] = net_stats64.rx_length_errors;
+	buf[bi++] = net_stats64.rx_crc_errors;
+	buf[bi++] = net_stats64.rx_frame_errors;
+	buf[bi++] = net_stats64.tx_fifo_errors;
 
 	/* Get netif_queue_stopped from stack */
 	bnad->stats.drv_stats.netif_queue_stopped = netif_queue_stopped(netdev);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h	2016-09-25 21:47:13.000000000 -0400
@@ -419,8 +419,8 @@ struct link_config {
 	unsigned short supported;        /* link capabilities */
 	unsigned short advertising;      /* advertised capabilities */
 	unsigned short lp_advertising;   /* peer advertised capabilities */
-	unsigned short requested_speed;  /* speed user has requested */
-	unsigned short speed;            /* actual link speed */
+	unsigned int   requested_speed;  /* speed user has requested */
+	unsigned int   speed;            /* actual link speed */
 	unsigned char  requested_fc;     /* flow control user has requested */
 	unsigned char  fc;               /* actual link flow control */
 	unsigned char  autoneg;          /* autonegotiating? */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c	2016-09-22 01:06:12.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c	2016-09-26 00:28:56.000000000 -0400
@@ -4303,10 +4303,17 @@ static const struct pci_error_handlers c
 	.resume         = eeh_resume,
 };
 
+/* Return true if the Link Configuration supports "High Speeds" (those greater
+ * than 1Gb/s).
+ */
 static inline bool is_x_10g_port(const struct link_config *lc)
 {
-	return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 ||
-	       (lc->supported & FW_PORT_CAP_SPEED_40G) != 0;
+	unsigned int speeds, high_speeds;
+
+	speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported));
+	high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
+
+	return high_speeds != 0;
 }
 
 static inline void init_rspq(struct adapter *adap, struct sge_rspq *q,
@@ -4754,8 +4761,12 @@ static void print_port_info(const struct
 		bufp += sprintf(bufp, "1000/");
 	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
 		bufp += sprintf(bufp, "10G/");
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
+		bufp += sprintf(bufp, "25G/");
 	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
 		bufp += sprintf(bufp, "40G/");
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G)
+		bufp += sprintf(bufp, "100G/");
 	if (bufp != buf)
 		--bufp;
 	sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type));
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h	2016-09-25 21:47:13.000000000 -0400
@@ -2265,6 +2265,12 @@ enum fw_port_cap {
 	FW_PORT_CAP_802_3_ASM_DIR	= 0x8000,
 };
 
+#define FW_PORT_CAP_SPEED_S     0
+#define FW_PORT_CAP_SPEED_M     0x3f
+#define FW_PORT_CAP_SPEED_V(x)  ((x) << FW_PORT_CAP_SPEED_S)
+#define FW_PORT_CAP_SPEED_G(x) \
+	(((x) >> FW_PORT_CAP_SPEED_S) & FW_PORT_CAP_SPEED_M)
+
 enum fw_port_mdi {
 	FW_PORT_CAP_MDI_UNCHANGED,
 	FW_PORT_CAP_MDI_AUTO,
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c	2016-09-25 21:47:13.000000000 -0400
@@ -3627,7 +3627,8 @@ void t4_ulprx_read_la(struct adapter *ad
 }
 
 #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
-		     FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \
+		     FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \
+		     FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \
 		     FW_PORT_CAP_ANEG)
 
 /**
@@ -7196,8 +7197,12 @@ void t4_handle_get_port_info(struct port
 		speed = 1000;
 	else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
 		speed = 10000;
+	else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
+		speed = 25000;
 	else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
 		speed = 40000;
+	else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
+		speed = 100000;
 
 	lc = &pi->link_cfg;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h	2016-09-25 21:47:13.000000000 -0400
@@ -108,8 +108,8 @@ struct link_config {
 	unsigned int   supported;        /* link capabilities */
 	unsigned int   advertising;      /* advertised capabilities */
 	unsigned short lp_advertising;   /* peer advertised capabilities */
-	unsigned short requested_speed;  /* speed user has requested */
-	unsigned short speed;            /* actual link speed */
+	unsigned int   requested_speed;  /* speed user has requested */
+	unsigned int   speed;            /* actual link speed */
 	unsigned char  requested_fc;     /* flow control user has requested */
 	unsigned char  fc;               /* actual link flow control */
 	unsigned char  autoneg;          /* autonegotiating? */
@@ -271,10 +271,17 @@ static inline bool is_10g_port(const str
 	return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
 }
 
+/* Return true if the Link Configuration supports "High Speeds" (those greater
+ * than 1Gb/s).
+ */
 static inline bool is_x_10g_port(const struct link_config *lc)
 {
-	return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 ||
-		(lc->supported & FW_PORT_CAP_SPEED_40G) != 0;
+	unsigned int speeds, high_speeds;
+
+	speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported));
+	high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
+
+	return high_speeds != 0;
 }
 
 static inline unsigned int core_ticks_per_usec(const struct adapter *adapter)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c	2016-09-25 21:47:13.000000000 -0400
@@ -314,8 +314,9 @@ int t4vf_wr_mbox_core(struct adapter *ad
 }
 
 #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
-		     FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \
-		     FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG)
+		     FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \
+		     FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \
+		     FW_PORT_CAP_ANEG)
 
 /**
  *	init_link_config - initialize a link's SW state
@@ -1712,8 +1713,12 @@ int t4vf_handle_fw_rpl(struct adapter *a
 			speed = 1000;
 		else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
 			speed = 10000;
+		else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
+			speed = 25000;
 		else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
 			speed = 40000;
+		else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
+			speed = 100000;
 
 		/*
 		 * Scan all of our "ports" (Virtual Interfaces) looking for
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/ibm/emac/core.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/ibm/emac/core.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/ibm/emac/core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/ibm/emac/core.c	2016-09-25 21:47:13.000000000 -0400
@@ -977,7 +977,37 @@ static void emac_set_multicast_list(stru
 		dev->mcast_pending = 1;
 		return;
 	}
+
+	mutex_lock(&dev->link_lock);
 	__emac_set_multicast_list(dev);
+	mutex_unlock(&dev->link_lock);
+}
+
+static int emac_set_mac_address(struct net_device *ndev, void *sa)
+{
+	struct emac_instance *dev = netdev_priv(ndev);
+	struct sockaddr *addr = sa;
+	struct emac_regs __iomem *p = dev->emacp;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+	       return -EADDRNOTAVAIL;
+
+	mutex_lock(&dev->link_lock);
+
+	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+
+	emac_rx_disable(dev);
+	emac_tx_disable(dev);
+	out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]);
+	out_be32(&p->ialr, (ndev->dev_addr[2] << 24) |
+		(ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) |
+		ndev->dev_addr[5]);
+	emac_tx_enable(dev);
+	emac_rx_enable(dev);
+
+	mutex_unlock(&dev->link_lock);
+
+	return 0;
 }
 
 static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu)
@@ -2686,7 +2716,7 @@ static const struct net_device_ops emac_
 	.ndo_do_ioctl		= emac_ioctl,
 	.ndo_tx_timeout		= emac_tx_timeout,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_set_mac_address	= emac_set_mac_address,
 	.ndo_start_xmit		= emac_start_xmit,
 	.ndo_change_mtu		= eth_change_mtu,
 };
@@ -2699,7 +2729,7 @@ static const struct net_device_ops emac_
 	.ndo_do_ioctl		= emac_ioctl,
 	.ndo_tx_timeout		= emac_tx_timeout,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_set_mac_address	= emac_set_mac_address,
 	.ndo_start_xmit		= emac_start_xmit_sg,
 	.ndo_change_mtu		= emac_change_mtu,
 };
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c	2016-09-25 21:47:13.000000000 -0400
@@ -1923,6 +1923,7 @@ const struct of_device_id of_mtk_match[]
 	{ .compatible = "mediatek,mt7623-eth" },
 	{},
 };
+MODULE_DEVICE_TABLE(of, of_mtk_match);
 
 static struct platform_driver mtk_driver = {
 	.probe = mtk_probe,
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c	2016-09-25 21:47:13.000000000 -0400
@@ -1305,8 +1305,8 @@ int mlx4_init_eq_table(struct mlx4_dev *
 	return 0;
 
 err_out_unmap:
-	while (i >= 0)
-		mlx4_free_eq(dev, &priv->eq_table.eq[i--]);
+	while (i > 0)
+		mlx4_free_eq(dev, &priv->eq_table.eq[--i]);
 #ifdef CONFIG_RFS_ACCEL
 	for (i = 1; i <= dev->caps.num_ports; i++) {
 		if (mlx4_priv(dev)->port[i].rmap) {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/main.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/main.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2016-09-25 21:47:13.000000000 -0400
@@ -2970,6 +2970,7 @@ static int mlx4_init_port_info(struct ml
 		mlx4_err(dev, "Failed to create mtu file for port %d\n", port);
 		device_remove_file(&info->dev->persist->pdev->dev,
 				   &info->port_attr);
+		devlink_port_unregister(&info->devlink_port);
 		info->port = -1;
 	}
 
@@ -2984,6 +2985,8 @@ static void mlx4_cleanup_port_info(struc
 	device_remove_file(&info->dev->persist->pdev->dev, &info->port_attr);
 	device_remove_file(&info->dev->persist->pdev->dev,
 			   &info->port_mtu_attr);
+	devlink_port_unregister(&info->devlink_port);
+
 #ifdef CONFIG_RFS_ACCEL
 	free_irq_cpu_rmap(info->rmap);
 	info->rmap = NULL;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c	2016-09-25 21:47:13.000000000 -0400
@@ -1554,6 +1554,7 @@ int mlx5_eswitch_enable_sriov(struct mlx
 
 abort:
 	esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
+	esw->mode = SRIOV_NONE;
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c	2016-09-25 21:47:13.000000000 -0400
@@ -446,7 +446,7 @@ out:
 
 static int esw_offloads_start(struct mlx5_eswitch *esw)
 {
-	int err, num_vfs = esw->dev->priv.sriov.num_vfs;
+	int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs;
 
 	if (esw->mode != SRIOV_LEGACY) {
 		esw_warn(esw->dev, "Can't set offloads mode, SRIOV legacy not enabled\n");
@@ -455,8 +455,12 @@ static int esw_offloads_start(struct mlx
 
 	mlx5_eswitch_disable_sriov(esw);
 	err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS);
-	if (err)
-		esw_warn(esw->dev, "Failed set eswitch to offloads, err %d\n", err);
+	if (err) {
+		esw_warn(esw->dev, "Failed setting eswitch to offloads, err %d\n", err);
+		err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY);
+		if (err1)
+			esw_warn(esw->dev, "Failed setting eswitch back to legacy, err %d\n", err);
+	}
 	return err;
 }
 
@@ -508,12 +512,16 @@ create_ft_err:
 
 static int esw_offloads_stop(struct mlx5_eswitch *esw)
 {
-	int err, num_vfs = esw->dev->priv.sriov.num_vfs;
+	int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs;
 
 	mlx5_eswitch_disable_sriov(esw);
 	err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY);
-	if (err)
-		esw_warn(esw->dev, "Failed set eswitch legacy mode. err %d\n", err);
+	if (err) {
+		esw_warn(esw->dev, "Failed setting eswitch to legacy, err %d\n", err);
+		err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS);
+		if (err1)
+			esw_warn(esw->dev, "Failed setting eswitch back to offloads, err %d\n", err);
+	}
 
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c	2016-09-25 21:47:13.000000000 -0400
@@ -425,11 +425,11 @@ struct mlx5_cmd_fc_bulk *
 mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u16 id, int num)
 {
 	struct mlx5_cmd_fc_bulk *b;
-	int outlen = sizeof(*b) +
+	int outlen =
 		MLX5_ST_SZ_BYTES(query_flow_counter_out) +
 		MLX5_ST_SZ_BYTES(traffic_counter) * num;
 
-	b = kzalloc(outlen, GFP_KERNEL);
+	b = kzalloc(sizeof(*b) + outlen, GFP_KERNEL);
 	if (!b)
 		return NULL;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/netronome/nfp/nfp_net_common.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/netronome/nfp/nfp_net_common.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/netronome/nfp/nfp_net_common.c	2016-09-25 21:47:13.000000000 -0400
@@ -2044,12 +2044,16 @@ static int nfp_net_netdev_open(struct ne
 
 	nn->rx_rings = kcalloc(nn->num_rx_rings, sizeof(*nn->rx_rings),
 			       GFP_KERNEL);
-	if (!nn->rx_rings)
+	if (!nn->rx_rings) {
+		err = -ENOMEM;
 		goto err_free_lsc;
+	}
 	nn->tx_rings = kcalloc(nn->num_tx_rings, sizeof(*nn->tx_rings),
 			       GFP_KERNEL);
-	if (!nn->tx_rings)
+	if (!nn->tx_rings) {
+		err = -ENOMEM;
 		goto err_free_rx_rings;
+	}
 
 	for (r = 0; r < nn->num_r_vecs; r++) {
 		err = nfp_net_prepare_vector(nn, &nn->r_vecs[r], r);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/qlogic/qed/qed_mcp.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/qlogic/qed/qed_mcp.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/qlogic/qed/qed_mcp.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/qlogic/qed/qed_mcp.c	2016-09-25 21:47:13.000000000 -0400
@@ -1153,8 +1153,8 @@ qed_mcp_send_drv_version(struct qed_hwfn
 	p_drv_version = &union_data.drv_version;
 	p_drv_version->version = p_ver->version;
 
-	for (i = 0; i < MCP_DRV_VER_STR_SIZE - 1; i += 4) {
-		val = cpu_to_be32(p_ver->name[i]);
+	for (i = 0; i < (MCP_DRV_VER_STR_SIZE - 4) / sizeof(u32); i++) {
+		val = cpu_to_be32(*((u32 *)&p_ver->name[i * sizeof(u32)]));
 		*(__be32 *)&p_drv_version->name[i * sizeof(u32)] = val;
 	}
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c	2016-09-25 21:47:13.000000000 -0400
@@ -261,7 +261,7 @@ static void dwmac1000_pmt(struct mac_dev
 	}
 	if (mode & WAKE_UCAST) {
 		pr_debug("GMAC: WOL on global unicast\n");
-		pmt |= global_unicast;
+		pmt |= power_down | global_unicast | wake_up_frame_en;
 	}
 
 	writel(pmt, ioaddr + GMAC_PMT);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c linux-libre-4.8-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
--- linux-libre-4.8-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c	2016-09-25 21:47:13.000000000 -0400
@@ -102,7 +102,7 @@ static void dwmac4_pmt(struct mac_device
 	}
 	if (mode & WAKE_UCAST) {
 		pr_debug("GMAC: WOL on global unicast\n");
-		pmt |= global_unicast;
+		pmt |= power_down | global_unicast | wake_up_frame_en;
 	}
 
 	writel(pmt, ioaddr + GMAC_PMT);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/phy/mdio-xgene.c linux-libre-4.8-rc8-gnu/drivers/net/phy/mdio-xgene.c
--- linux-libre-4.8-rc7-gnu/drivers/net/phy/mdio-xgene.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/phy/mdio-xgene.c	2016-09-25 21:47:13.000000000 -0400
@@ -424,10 +424,8 @@ static int xgene_mdio_remove(struct plat
 	mdiobus_unregister(mdio_bus);
 	mdiobus_free(mdio_bus);
 
-	if (dev->of_node) {
-		if (IS_ERR(pdata->clk))
-			clk_disable_unprepare(pdata->clk);
-	}
+	if (dev->of_node)
+		clk_disable_unprepare(pdata->clk);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/usb/r8152.c linux-libre-4.8-rc8-gnu/drivers/net/usb/r8152.c
--- linux-libre-4.8-rc7-gnu/drivers/net/usb/r8152.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/usb/r8152.c	2016-09-25 21:47:13.000000000 -0400
@@ -32,7 +32,7 @@
 #define NETNEXT_VERSION		"08"
 
 /* Information for net */
-#define NET_VERSION		"5"
+#define NET_VERSION		"6"
 
 #define DRIVER_VERSION		"v1." NETNEXT_VERSION "." NET_VERSION
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
@@ -2552,6 +2552,77 @@ static void r8152_aldps_en(struct r8152
 	}
 }
 
+static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg)
+{
+	ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev);
+	ocp_reg_write(tp, OCP_EEE_DATA, reg);
+	ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev);
+}
+
+static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg)
+{
+	u16 data;
+
+	r8152_mmd_indirect(tp, dev, reg);
+	data = ocp_reg_read(tp, OCP_EEE_DATA);
+	ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
+
+	return data;
+}
+
+static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data)
+{
+	r8152_mmd_indirect(tp, dev, reg);
+	ocp_reg_write(tp, OCP_EEE_DATA, data);
+	ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
+}
+
+static void r8152_eee_en(struct r8152 *tp, bool enable)
+{
+	u16 config1, config2, config3;
+	u32 ocp_data;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
+	config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask;
+	config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2);
+	config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask;
+
+	if (enable) {
+		ocp_data |= EEE_RX_EN | EEE_TX_EN;
+		config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN;
+		config1 |= sd_rise_time(1);
+		config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN;
+		config3 |= fast_snr(42);
+	} else {
+		ocp_data &= ~(EEE_RX_EN | EEE_TX_EN);
+		config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN |
+			     RX_QUIET_EN);
+		config1 |= sd_rise_time(7);
+		config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN);
+		config3 |= fast_snr(511);
+	}
+
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
+	ocp_reg_write(tp, OCP_EEE_CONFIG1, config1);
+	ocp_reg_write(tp, OCP_EEE_CONFIG2, config2);
+	ocp_reg_write(tp, OCP_EEE_CONFIG3, config3);
+}
+
+static void r8152b_enable_eee(struct r8152 *tp)
+{
+	r8152_eee_en(tp, true);
+	r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX);
+}
+
+static void r8152b_enable_fc(struct r8152 *tp)
+{
+	u16 anar;
+
+	anar = r8152_mdio_read(tp, MII_ADVERTISE);
+	anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+	r8152_mdio_write(tp, MII_ADVERTISE, anar);
+}
+
 static void rtl8152_disable(struct r8152 *tp)
 {
 	r8152_aldps_en(tp, false);
@@ -2561,13 +2632,9 @@ static void rtl8152_disable(struct r8152
 
 static void r8152b_hw_phy_cfg(struct r8152 *tp)
 {
-	u16 data;
-
-	data = r8152_mdio_read(tp, MII_BMCR);
-	if (data & BMCR_PDOWN) {
-		data &= ~BMCR_PDOWN;
-		r8152_mdio_write(tp, MII_BMCR, data);
-	}
+	r8152b_enable_eee(tp);
+	r8152_aldps_en(tp, true);
+	r8152b_enable_fc(tp);
 
 	set_bit(PHY_RESET, &tp->flags);
 }
@@ -2701,20 +2768,52 @@ static void r8152b_enter_oob(struct r815
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 }
 
+static void r8153_aldps_en(struct r8152 *tp, bool enable)
+{
+	u16 data;
+
+	data = ocp_reg_read(tp, OCP_POWER_CFG);
+	if (enable) {
+		data |= EN_ALDPS;
+		ocp_reg_write(tp, OCP_POWER_CFG, data);
+	} else {
+		data &= ~EN_ALDPS;
+		ocp_reg_write(tp, OCP_POWER_CFG, data);
+		msleep(20);
+	}
+}
+
+static void r8153_eee_en(struct r8152 *tp, bool enable)
+{
+	u32 ocp_data;
+	u16 config;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
+	config = ocp_reg_read(tp, OCP_EEE_CFG);
+
+	if (enable) {
+		ocp_data |= EEE_RX_EN | EEE_TX_EN;
+		config |= EEE10_EN;
+	} else {
+		ocp_data &= ~(EEE_RX_EN | EEE_TX_EN);
+		config &= ~EEE10_EN;
+	}
+
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
+	ocp_reg_write(tp, OCP_EEE_CFG, config);
+}
+
 static void r8153_hw_phy_cfg(struct r8152 *tp)
 {
 	u32 ocp_data;
 	u16 data;
 
-	if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 ||
-	    tp->version == RTL_VER_05)
-		ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L);
+	/* disable ALDPS before updating the PHY parameters */
+	r8153_aldps_en(tp, false);
 
-	data = r8152_mdio_read(tp, MII_BMCR);
-	if (data & BMCR_PDOWN) {
-		data &= ~BMCR_PDOWN;
-		r8152_mdio_write(tp, MII_BMCR, data);
-	}
+	/* disable EEE before updating the PHY parameters */
+	r8153_eee_en(tp, false);
+	ocp_reg_write(tp, OCP_EEE_ADV, 0);
 
 	if (tp->version == RTL_VER_03) {
 		data = ocp_reg_read(tp, OCP_EEE_CFG);
@@ -2745,6 +2844,12 @@ static void r8153_hw_phy_cfg(struct r815
 	sram_write(tp, SRAM_10M_AMP1, 0x00af);
 	sram_write(tp, SRAM_10M_AMP2, 0x0208);
 
+	r8153_eee_en(tp, true);
+	ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+
+	r8153_aldps_en(tp, true);
+	r8152b_enable_fc(tp);
+
 	set_bit(PHY_RESET, &tp->flags);
 }
 
@@ -2866,21 +2971,6 @@ static void r8153_enter_oob(struct r8152
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 }
 
-static void r8153_aldps_en(struct r8152 *tp, bool enable)
-{
-	u16 data;
-
-	data = ocp_reg_read(tp, OCP_POWER_CFG);
-	if (enable) {
-		data |= EN_ALDPS;
-		ocp_reg_write(tp, OCP_POWER_CFG, data);
-	} else {
-		data &= ~EN_ALDPS;
-		ocp_reg_write(tp, OCP_POWER_CFG, data);
-		msleep(20);
-	}
-}
-
 static void rtl8153_disable(struct r8152 *tp)
 {
 	r8153_aldps_en(tp, false);
@@ -3246,103 +3336,6 @@ static int rtl8152_close(struct net_devi
 	return res;
 }
 
-static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg)
-{
-	ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev);
-	ocp_reg_write(tp, OCP_EEE_DATA, reg);
-	ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev);
-}
-
-static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg)
-{
-	u16 data;
-
-	r8152_mmd_indirect(tp, dev, reg);
-	data = ocp_reg_read(tp, OCP_EEE_DATA);
-	ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
-
-	return data;
-}
-
-static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data)
-{
-	r8152_mmd_indirect(tp, dev, reg);
-	ocp_reg_write(tp, OCP_EEE_DATA, data);
-	ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
-}
-
-static void r8152_eee_en(struct r8152 *tp, bool enable)
-{
-	u16 config1, config2, config3;
-	u32 ocp_data;
-
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-	config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask;
-	config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2);
-	config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask;
-
-	if (enable) {
-		ocp_data |= EEE_RX_EN | EEE_TX_EN;
-		config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN;
-		config1 |= sd_rise_time(1);
-		config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN;
-		config3 |= fast_snr(42);
-	} else {
-		ocp_data &= ~(EEE_RX_EN | EEE_TX_EN);
-		config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN |
-			     RX_QUIET_EN);
-		config1 |= sd_rise_time(7);
-		config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN);
-		config3 |= fast_snr(511);
-	}
-
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
-	ocp_reg_write(tp, OCP_EEE_CONFIG1, config1);
-	ocp_reg_write(tp, OCP_EEE_CONFIG2, config2);
-	ocp_reg_write(tp, OCP_EEE_CONFIG3, config3);
-}
-
-static void r8152b_enable_eee(struct r8152 *tp)
-{
-	r8152_eee_en(tp, true);
-	r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX);
-}
-
-static void r8153_eee_en(struct r8152 *tp, bool enable)
-{
-	u32 ocp_data;
-	u16 config;
-
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-	config = ocp_reg_read(tp, OCP_EEE_CFG);
-
-	if (enable) {
-		ocp_data |= EEE_RX_EN | EEE_TX_EN;
-		config |= EEE10_EN;
-	} else {
-		ocp_data &= ~(EEE_RX_EN | EEE_TX_EN);
-		config &= ~EEE10_EN;
-	}
-
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
-	ocp_reg_write(tp, OCP_EEE_CFG, config);
-}
-
-static void r8153_enable_eee(struct r8152 *tp)
-{
-	r8153_eee_en(tp, true);
-	ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
-}
-
-static void r8152b_enable_fc(struct r8152 *tp)
-{
-	u16 anar;
-
-	anar = r8152_mdio_read(tp, MII_ADVERTISE);
-	anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
-	r8152_mdio_write(tp, MII_ADVERTISE, anar);
-}
-
 static void rtl_tally_reset(struct r8152 *tp)
 {
 	u32 ocp_data;
@@ -3355,10 +3348,17 @@ static void rtl_tally_reset(struct r8152
 static void r8152b_init(struct r8152 *tp)
 {
 	u32 ocp_data;
+	u16 data;
 
 	if (test_bit(RTL8152_UNPLUG, &tp->flags))
 		return;
 
+	data = r8152_mdio_read(tp, MII_BMCR);
+	if (data & BMCR_PDOWN) {
+		data &= ~BMCR_PDOWN;
+		r8152_mdio_write(tp, MII_BMCR, data);
+	}
+
 	r8152_aldps_en(tp, false);
 
 	if (tp->version == RTL_VER_01) {
@@ -3380,9 +3380,6 @@ static void r8152b_init(struct r8152 *tp
 		   SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK;
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data);
 
-	r8152b_enable_eee(tp);
-	r8152_aldps_en(tp, true);
-	r8152b_enable_fc(tp);
 	rtl_tally_reset(tp);
 
 	/* enable rx aggregation */
@@ -3394,12 +3391,12 @@ static void r8152b_init(struct r8152 *tp
 static void r8153_init(struct r8152 *tp)
 {
 	u32 ocp_data;
+	u16 data;
 	int i;
 
 	if (test_bit(RTL8152_UNPLUG, &tp->flags))
 		return;
 
-	r8153_aldps_en(tp, false);
 	r8153_u1u2en(tp, false);
 
 	for (i = 0; i < 500; i++) {
@@ -3416,6 +3413,23 @@ static void r8153_init(struct r8152 *tp)
 		msleep(20);
 	}
 
+	if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 ||
+	    tp->version == RTL_VER_05)
+		ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L);
+
+	data = r8152_mdio_read(tp, MII_BMCR);
+	if (data & BMCR_PDOWN) {
+		data &= ~BMCR_PDOWN;
+		r8152_mdio_write(tp, MII_BMCR, data);
+	}
+
+	for (i = 0; i < 500; i++) {
+		ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK;
+		if (ocp_data == PHY_STAT_LAN_ON)
+			break;
+		msleep(20);
+	}
+
 	usb_disable_lpm(tp->udev);
 	r8153_u2p3en(tp, false);
 
@@ -3483,9 +3497,6 @@ static void r8153_init(struct r8152 *tp)
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0);
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0);
 
-	r8153_enable_eee(tp);
-	r8153_aldps_en(tp, true);
-	r8152b_enable_fc(tp);
 	rtl_tally_reset(tp);
 	r8153_u2p3en(tp, true);
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c linux-libre-4.8-rc8-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
--- linux-libre-4.8-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c	2016-09-25 21:47:13.000000000 -0400
@@ -513,6 +513,15 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv
 	int hdrlen = ieee80211_hdrlen(hdr->frame_control);
 	int queue;
 
+	/* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used
+	 * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel
+	 * queue. STATION (HS2.0) uses the auxiliary context of the FW,
+	 * and hence needs to be sent on the aux queue
+	 */
+	if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
+	    skb_info->control.vif->type == NL80211_IFTYPE_STATION)
+		IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue;
+
 	memcpy(&info, skb->cb, sizeof(info));
 
 	if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU))
@@ -526,16 +535,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv
 	/* This holds the amsdu headers length */
 	skb_info->driver_data[0] = (void *)(uintptr_t)0;
 
-	/*
-	 * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used
-	 * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel
-	 * queue. STATION (HS2.0) uses the auxiliary context of the FW,
-	 * and hence needs to be sent on the aux queue
-	 */
-	if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
-	    info.control.vif->type == NL80211_IFTYPE_STATION)
-		IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue;
-
 	queue = info.hw_queue;
 
 	/*
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/net/xen-netback/xenbus.c linux-libre-4.8-rc8-gnu/drivers/net/xen-netback/xenbus.c
--- linux-libre-4.8-rc7-gnu/drivers/net/xen-netback/xenbus.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/net/xen-netback/xenbus.c	2016-09-25 21:47:13.000000000 -0400
@@ -271,6 +271,11 @@ static int netback_probe(struct xenbus_d
 	be->dev = dev;
 	dev_set_drvdata(&dev->dev, be);
 
+	be->state = XenbusStateInitialising;
+	err = xenbus_switch_state(dev, XenbusStateInitialising);
+	if (err)
+		goto fail;
+
 	sg = 1;
 
 	do {
@@ -383,11 +388,6 @@ static int netback_probe(struct xenbus_d
 
 	be->hotplug_script = script;
 
-	err = xenbus_switch_state(dev, XenbusStateInitWait);
-	if (err)
-		goto fail;
-
-	be->state = XenbusStateInitWait;
 
 	/* This kicks hotplug scripts, so do it immediately. */
 	err = backend_create_xenvif(be);
@@ -492,20 +492,20 @@ static inline void backend_switch_state(
 
 /* Handle backend state transitions:
  *
- * The backend state starts in InitWait and the following transitions are
+ * The backend state starts in Initialising and the following transitions are
  * allowed.
  *
- * InitWait -> Connected
- *
- *    ^    \         |
- *    |     \        |
- *    |      \       |
- *    |       \      |
- *    |        \     |
- *    |         \    |
- *    |          V   V
+ * Initialising -> InitWait -> Connected
+ *          \
+ *           \        ^    \         |
+ *            \       |     \        |
+ *             \      |      \       |
+ *              \     |       \      |
+ *               \    |        \     |
+ *                \   |         \    |
+ *                 V  |          V   V
  *
- *  Closed  <-> Closing
+ *                  Closed  <-> Closing
  *
  * The state argument specifies the eventual state of the backend and the
  * function transitions to that state via the shortest path.
@@ -515,6 +515,20 @@ static void set_backend_state(struct bac
 {
 	while (be->state != state) {
 		switch (be->state) {
+		case XenbusStateInitialising:
+			switch (state) {
+			case XenbusStateInitWait:
+			case XenbusStateConnected:
+			case XenbusStateClosing:
+				backend_switch_state(be, XenbusStateInitWait);
+				break;
+			case XenbusStateClosed:
+				backend_switch_state(be, XenbusStateClosed);
+				break;
+			default:
+				BUG();
+			}
+			break;
 		case XenbusStateClosed:
 			switch (state) {
 			case XenbusStateInitWait:
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/nvme/host/rdma.c linux-libre-4.8-rc8-gnu/drivers/nvme/host/rdma.c
--- linux-libre-4.8-rc7-gnu/drivers/nvme/host/rdma.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/nvme/host/rdma.c	2016-09-25 21:47:13.000000000 -0400
@@ -561,7 +561,6 @@ static int nvme_rdma_init_queue(struct n
 
 	queue = &ctrl->queues[idx];
 	queue->ctrl = ctrl;
-	queue->flags = 0;
 	init_completion(&queue->cm_done);
 
 	if (idx > 0)
@@ -595,6 +594,7 @@ static int nvme_rdma_init_queue(struct n
 		goto out_destroy_cm_id;
 	}
 
+	clear_bit(NVME_RDMA_Q_DELETING, &queue->flags);
 	set_bit(NVME_RDMA_Q_CONNECTED, &queue->flags);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/rapidio/rio_cm.c linux-libre-4.8-rc8-gnu/drivers/rapidio/rio_cm.c
--- linux-libre-4.8-rc7-gnu/drivers/rapidio/rio_cm.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/rapidio/rio_cm.c	2016-09-25 21:47:13.000000000 -0400
@@ -2247,17 +2247,30 @@ static int rio_cm_shutdown(struct notifi
 {
 	struct rio_channel *ch;
 	unsigned int i;
+	LIST_HEAD(list);
 
 	riocm_debug(EXIT, ".");
 
+	/*
+	 * If there are any channels left in connected state send
+	 * close notification to the connection partner.
+	 * First build a list of channels that require a closing
+	 * notification because function riocm_send_close() should
+	 * be called outside of spinlock protected code.
+	 */
 	spin_lock_bh(&idr_lock);
 	idr_for_each_entry(&ch_idr, ch, i) {
-		riocm_debug(EXIT, "close ch %d", ch->id);
-		if (ch->state == RIO_CM_CONNECTED)
-			riocm_send_close(ch);
+		if (ch->state == RIO_CM_CONNECTED) {
+			riocm_debug(EXIT, "close ch %d", ch->id);
+			idr_remove(&ch_idr, ch->id);
+			list_add(&ch->ch_node, &list);
+		}
 	}
 	spin_unlock_bh(&idr_lock);
 
+	list_for_each_entry(ch, &list, ch_node)
+		riocm_send_close(ch);
+
 	return NOTIFY_DONE;
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_core.h linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_core.h
--- linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_core.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_core.h	2016-09-25 21:47:13.000000000 -0400
@@ -999,6 +999,7 @@ struct qeth_cmd_buffer *qeth_get_setassp
 						 __u16, __u16,
 						 enum qeth_prot_versions);
 int qeth_set_features(struct net_device *, netdev_features_t);
+int qeth_recover_features(struct net_device *);
 netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
 
 /* exports for OSN */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_core_main.c linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_core_main.c
--- linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_core_main.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_core_main.c	2016-09-25 21:47:13.000000000 -0400
@@ -3619,7 +3619,8 @@ static void qeth_qdio_cq_handler(struct
 		int e;
 
 		e = 0;
-		while (buffer->element[e].addr) {
+		while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) &&
+		       buffer->element[e].addr) {
 			unsigned long phys_aob_addr;
 
 			phys_aob_addr = (unsigned long) buffer->element[e].addr;
@@ -6131,6 +6132,35 @@ static int qeth_set_ipa_tso(struct qeth_
 	return rc;
 }
 
+/* try to restore device features on a device after recovery */
+int qeth_recover_features(struct net_device *dev)
+{
+	struct qeth_card *card = dev->ml_priv;
+	netdev_features_t recover = dev->features;
+
+	if (recover & NETIF_F_IP_CSUM) {
+		if (qeth_set_ipa_csum(card, 1, IPA_OUTBOUND_CHECKSUM))
+			recover ^= NETIF_F_IP_CSUM;
+	}
+	if (recover & NETIF_F_RXCSUM) {
+		if (qeth_set_ipa_csum(card, 1, IPA_INBOUND_CHECKSUM))
+			recover ^= NETIF_F_RXCSUM;
+	}
+	if (recover & NETIF_F_TSO) {
+		if (qeth_set_ipa_tso(card, 1))
+			recover ^= NETIF_F_TSO;
+	}
+
+	if (recover == dev->features)
+		return 0;
+
+	dev_warn(&card->gdev->dev,
+		 "Device recovery failed to restore all offload features\n");
+	dev->features = recover;
+	return -EIO;
+}
+EXPORT_SYMBOL_GPL(qeth_recover_features);
+
 int qeth_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct qeth_card *card = dev->ml_priv;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_l2_main.c linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_l2_main.c
--- linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_l2_main.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_l2_main.c	2016-09-25 21:47:13.000000000 -0400
@@ -1124,14 +1124,11 @@ static int qeth_l2_setup_netdev(struct q
 			card->dev->hw_features |= NETIF_F_RXCSUM;
 			card->dev->vlan_features |= NETIF_F_RXCSUM;
 		}
-		/* Turn on SG per default */
-		card->dev->features |= NETIF_F_SG;
 	}
 	card->info.broadcast_capable = 1;
 	qeth_l2_request_initial_mac(card);
 	card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) *
 				  PAGE_SIZE;
-	card->dev->gso_max_segs = (QETH_MAX_BUFFER_ELEMENTS(card) - 1);
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
 	netif_carrier_off(card->dev);
@@ -1246,6 +1243,9 @@ contin:
 		}
 		/* this also sets saved unicast addresses */
 		qeth_l2_set_rx_mode(card->dev);
+		rtnl_lock();
+		qeth_recover_features(card->dev);
+		rtnl_unlock();
 	}
 	/* let user_space know that device is online */
 	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_l3_main.c linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_l3_main.c
--- linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_l3_main.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_l3_main.c	2016-09-25 21:47:13.000000000 -0400
@@ -257,6 +257,11 @@ int qeth_l3_delete_ip(struct qeth_card *
 	if (addr->in_progress)
 		return -EINPROGRESS;
 
+	if (!qeth_card_hw_is_reachable(card)) {
+		addr->disp_flag = QETH_DISP_ADDR_DELETE;
+		return 0;
+	}
+
 	rc = qeth_l3_deregister_addr_entry(card, addr);
 
 	hash_del(&addr->hnode);
@@ -296,6 +301,11 @@ int qeth_l3_add_ip(struct qeth_card *car
 		hash_add(card->ip_htable, &addr->hnode,
 				qeth_l3_ipaddr_hash(addr));
 
+		if (!qeth_card_hw_is_reachable(card)) {
+			addr->disp_flag = QETH_DISP_ADDR_ADD;
+			return 0;
+		}
+
 		/* qeth_l3_register_addr_entry can go to sleep
 		 * if we add a IPV4 addr. It is caused by the reason
 		 * that SETIP ipa cmd starts ARP staff for IPV4 addr.
@@ -390,12 +400,16 @@ static void qeth_l3_recover_ip(struct qe
 	int i;
 	int rc;
 
-	QETH_CARD_TEXT(card, 4, "recoverip");
+	QETH_CARD_TEXT(card, 4, "recovrip");
 
 	spin_lock_bh(&card->ip_lock);
 
 	hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) {
-		if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
+		if (addr->disp_flag == QETH_DISP_ADDR_DELETE) {
+			qeth_l3_deregister_addr_entry(card, addr);
+			hash_del(&addr->hnode);
+			kfree(addr);
+		} else if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
 			if (addr->proto == QETH_PROT_IPV4) {
 				addr->in_progress = 1;
 				spin_unlock_bh(&card->ip_lock);
@@ -407,10 +421,8 @@ static void qeth_l3_recover_ip(struct qe
 
 			if (!rc) {
 				addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
-				if (addr->ref_counter < 1) {
+				if (addr->ref_counter < 1)
 					qeth_l3_delete_ip(card, addr);
-					kfree(addr);
-				}
 			} else {
 				hash_del(&addr->hnode);
 				kfree(addr);
@@ -689,7 +701,7 @@ int qeth_l3_add_vipa(struct qeth_card *c
 
 	spin_lock_bh(&card->ip_lock);
 
-	if (!qeth_l3_ip_from_hash(card, ipaddr))
+	if (qeth_l3_ip_from_hash(card, ipaddr))
 		rc = -EEXIST;
 	else
 		qeth_l3_add_ip(card, ipaddr);
@@ -757,7 +769,7 @@ int qeth_l3_add_rxip(struct qeth_card *c
 
 	spin_lock_bh(&card->ip_lock);
 
-	if (!qeth_l3_ip_from_hash(card, ipaddr))
+	if (qeth_l3_ip_from_hash(card, ipaddr))
 		rc = -EEXIST;
 	else
 		qeth_l3_add_ip(card, ipaddr);
@@ -3108,7 +3120,6 @@ static int qeth_l3_setup_netdev(struct q
 				card->dev->vlan_features = NETIF_F_SG |
 					NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
 					NETIF_F_TSO;
-				card->dev->features = NETIF_F_SG;
 			}
 		}
 	} else if (card->info.type == QETH_CARD_TYPE_IQD) {
@@ -3136,7 +3147,6 @@ static int qeth_l3_setup_netdev(struct q
 	netif_keep_dst(card->dev);
 	card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) *
 				  PAGE_SIZE;
-	card->dev->gso_max_segs = (QETH_MAX_BUFFER_ELEMENTS(card) - 1);
 
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
@@ -3269,6 +3279,7 @@ contin:
 		else
 			dev_open(card->dev);
 		qeth_l3_set_multicast_list(card->dev);
+		qeth_recover_features(card->dev);
 		rtnl_unlock();
 	}
 	qeth_trace_features(card);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_l3_sys.c linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_l3_sys.c
--- linux-libre-4.8-rc7-gnu/drivers/s390/net/qeth_l3_sys.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/s390/net/qeth_l3_sys.c	2016-09-25 21:47:13.000000000 -0400
@@ -297,7 +297,9 @@ static ssize_t qeth_l3_dev_hsuid_store(s
 		addr->u.a6.pfxlen = 0;
 		addr->type = QETH_IP_TYPE_NORMAL;
 
+		spin_lock_bh(&card->ip_lock);
 		qeth_l3_delete_ip(card, addr);
+		spin_unlock_bh(&card->ip_lock);
 		kfree(addr);
 	}
 
@@ -329,7 +331,10 @@ static ssize_t qeth_l3_dev_hsuid_store(s
 		addr->type = QETH_IP_TYPE_NORMAL;
 	} else
 		return -ENOMEM;
+
+	spin_lock_bh(&card->ip_lock);
 	qeth_l3_add_ip(card, addr);
+	spin_unlock_bh(&card->ip_lock);
 	kfree(addr);
 
 	return count;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/cec-adap.c linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/cec-adap.c
--- linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/cec-adap.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/cec-adap.c	2016-09-25 21:47:13.000000000 -0400
@@ -124,10 +124,10 @@ static void cec_queue_event(struct cec_a
 	u64 ts = ktime_get_ns();
 	struct cec_fh *fh;
 
-	mutex_lock(&adap->devnode.fhs_lock);
+	mutex_lock(&adap->devnode.lock);
 	list_for_each_entry(fh, &adap->devnode.fhs, list)
 		cec_queue_event_fh(fh, ev, ts);
-	mutex_unlock(&adap->devnode.fhs_lock);
+	mutex_unlock(&adap->devnode.lock);
 }
 
 /*
@@ -191,12 +191,12 @@ static void cec_queue_msg_monitor(struct
 	u32 monitor_mode = valid_la ? CEC_MODE_MONITOR :
 				      CEC_MODE_MONITOR_ALL;
 
-	mutex_lock(&adap->devnode.fhs_lock);
+	mutex_lock(&adap->devnode.lock);
 	list_for_each_entry(fh, &adap->devnode.fhs, list) {
 		if (fh->mode_follower >= monitor_mode)
 			cec_queue_msg_fh(fh, msg);
 	}
-	mutex_unlock(&adap->devnode.fhs_lock);
+	mutex_unlock(&adap->devnode.lock);
 }
 
 /*
@@ -207,12 +207,12 @@ static void cec_queue_msg_followers(stru
 {
 	struct cec_fh *fh;
 
-	mutex_lock(&adap->devnode.fhs_lock);
+	mutex_lock(&adap->devnode.lock);
 	list_for_each_entry(fh, &adap->devnode.fhs, list) {
 		if (fh->mode_follower == CEC_MODE_FOLLOWER)
 			cec_queue_msg_fh(fh, msg);
 	}
-	mutex_unlock(&adap->devnode.fhs_lock);
+	mutex_unlock(&adap->devnode.lock);
 }
 
 /* Notify userspace of an adapter state change. */
@@ -851,6 +851,9 @@ void cec_received_msg(struct cec_adapter
 	if (!valid_la || msg->len <= 1)
 		return;
 
+	if (adap->log_addrs.log_addr_mask == 0)
+		return;
+
 	/*
 	 * Process the message on the protocol level. If is_reply is true,
 	 * then cec_receive_notify() won't pass on the reply to the listener(s)
@@ -1047,11 +1050,17 @@ static int cec_config_thread_func(void *
 			dprintk(1, "could not claim LA %d\n", i);
 	}
 
+	if (adap->log_addrs.log_addr_mask == 0 &&
+	    !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK))
+		goto unconfigure;
+
 configured:
 	if (adap->log_addrs.log_addr_mask == 0) {
 		/* Fall back to unregistered */
 		las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED;
 		las->log_addr_mask = 1 << las->log_addr[0];
+		for (i = 1; i < las->num_log_addrs; i++)
+			las->log_addr[i] = CEC_LOG_ADDR_INVALID;
 	}
 	adap->is_configured = true;
 	adap->is_configuring = false;
@@ -1070,6 +1079,8 @@ configured:
 			cec_report_features(adap, i);
 		cec_report_phys_addr(adap, i);
 	}
+	for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
+		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
 	mutex_lock(&adap->lock);
 	adap->kthread_config = NULL;
 	mutex_unlock(&adap->lock);
@@ -1398,7 +1409,6 @@ static int cec_receive_notify(struct cec
 	u8 init_laddr = cec_msg_initiator(msg);
 	u8 devtype = cec_log_addr2dev(adap, dest_laddr);
 	int la_idx = cec_log_addr2idx(adap, dest_laddr);
-	bool is_directed = la_idx >= 0;
 	bool from_unregistered = init_laddr == 0xf;
 	struct cec_msg tx_cec_msg = { };
 
@@ -1560,7 +1570,7 @@ static int cec_receive_notify(struct cec
 		 * Unprocessed messages are aborted if userspace isn't doing
 		 * any processing either.
 		 */
-		if (is_directed && !is_reply && !adap->follower_cnt &&
+		if (!is_broadcast && !is_reply && !adap->follower_cnt &&
 		    !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT)
 			return cec_feature_abort(adap, msg);
 		break;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/cec-api.c linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/cec-api.c
--- linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/cec-api.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/cec-api.c	2016-09-25 21:47:13.000000000 -0400
@@ -162,7 +162,7 @@ static long cec_adap_s_log_addrs(struct
 		return -ENOTTY;
 	if (copy_from_user(&log_addrs, parg, sizeof(log_addrs)))
 		return -EFAULT;
-	log_addrs.flags = 0;
+	log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK;
 	mutex_lock(&adap->lock);
 	if (!adap->is_configuring &&
 	    (!log_addrs.num_log_addrs || !adap->is_configured) &&
@@ -435,7 +435,7 @@ static long cec_ioctl(struct file *filp,
 	void __user *parg = (void __user *)arg;
 
 	if (!devnode->registered)
-		return -EIO;
+		return -ENODEV;
 
 	switch (cmd) {
 	case CEC_ADAP_G_CAPS:
@@ -508,14 +508,14 @@ static int cec_open(struct inode *inode,
 
 	filp->private_data = fh;
 
-	mutex_lock(&devnode->fhs_lock);
+	mutex_lock(&devnode->lock);
 	/* Queue up initial state events */
 	ev_state.state_change.phys_addr = adap->phys_addr;
 	ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
 	cec_queue_event_fh(fh, &ev_state, 0);
 
 	list_add(&fh->list, &devnode->fhs);
-	mutex_unlock(&devnode->fhs_lock);
+	mutex_unlock(&devnode->lock);
 
 	return 0;
 }
@@ -540,9 +540,9 @@ static int cec_release(struct inode *ino
 		cec_monitor_all_cnt_dec(adap);
 	mutex_unlock(&adap->lock);
 
-	mutex_lock(&devnode->fhs_lock);
+	mutex_lock(&devnode->lock);
 	list_del(&fh->list);
-	mutex_unlock(&devnode->fhs_lock);
+	mutex_unlock(&devnode->lock);
 
 	/* Unhook pending transmits from this filehandle. */
 	mutex_lock(&adap->lock);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/cec-core.c linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/cec-core.c
--- linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/cec-core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/cec-core.c	2016-09-25 21:47:13.000000000 -0400
@@ -51,31 +51,29 @@ int cec_get_device(struct cec_devnode *d
 {
 	/*
 	 * Check if the cec device is available. This needs to be done with
-	 * the cec_devnode_lock held to prevent an open/unregister race:
+	 * the devnode->lock held to prevent an open/unregister race:
 	 * without the lock, the device could be unregistered and freed between
 	 * the devnode->registered check and get_device() calls, leading to
 	 * a crash.
 	 */
-	mutex_lock(&cec_devnode_lock);
+	mutex_lock(&devnode->lock);
 	/*
 	 * return ENXIO if the cec device has been removed
 	 * already or if it is not registered anymore.
 	 */
 	if (!devnode->registered) {
-		mutex_unlock(&cec_devnode_lock);
+		mutex_unlock(&devnode->lock);
 		return -ENXIO;
 	}
 	/* and increase the device refcount */
 	get_device(&devnode->dev);
-	mutex_unlock(&cec_devnode_lock);
+	mutex_unlock(&devnode->lock);
 	return 0;
 }
 
 void cec_put_device(struct cec_devnode *devnode)
 {
-	mutex_lock(&cec_devnode_lock);
 	put_device(&devnode->dev);
-	mutex_unlock(&cec_devnode_lock);
 }
 
 /* Called when the last user of the cec device exits. */
@@ -84,11 +82,10 @@ static void cec_devnode_release(struct d
 	struct cec_devnode *devnode = to_cec_devnode(cd);
 
 	mutex_lock(&cec_devnode_lock);
-
 	/* Mark device node number as free */
 	clear_bit(devnode->minor, cec_devnode_nums);
-
 	mutex_unlock(&cec_devnode_lock);
+
 	cec_delete_adapter(to_cec_adapter(devnode));
 }
 
@@ -117,7 +114,7 @@ static int __must_check cec_devnode_regi
 
 	/* Initialization */
 	INIT_LIST_HEAD(&devnode->fhs);
-	mutex_init(&devnode->fhs_lock);
+	mutex_init(&devnode->lock);
 
 	/* Part 1: Find a free minor number */
 	mutex_lock(&cec_devnode_lock);
@@ -160,7 +157,9 @@ static int __must_check cec_devnode_regi
 cdev_del:
 	cdev_del(&devnode->cdev);
 clr_bit:
+	mutex_lock(&cec_devnode_lock);
 	clear_bit(devnode->minor, cec_devnode_nums);
+	mutex_unlock(&cec_devnode_lock);
 	return ret;
 }
 
@@ -177,17 +176,21 @@ static void cec_devnode_unregister(struc
 {
 	struct cec_fh *fh;
 
+	mutex_lock(&devnode->lock);
+
 	/* Check if devnode was never registered or already unregistered */
-	if (!devnode->registered || devnode->unregistered)
+	if (!devnode->registered || devnode->unregistered) {
+		mutex_unlock(&devnode->lock);
 		return;
+	}
 
-	mutex_lock(&devnode->fhs_lock);
 	list_for_each_entry(fh, &devnode->fhs, list)
 		wake_up_interruptible(&fh->wait);
-	mutex_unlock(&devnode->fhs_lock);
 
 	devnode->registered = false;
 	devnode->unregistered = true;
+	mutex_unlock(&devnode->lock);
+
 	device_del(&devnode->dev);
 	cdev_del(&devnode->cdev);
 	put_device(&devnode->dev);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/TODO linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/TODO
--- linux-libre-4.8-rc7-gnu/drivers/staging/media/cec/TODO	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/staging/media/cec/TODO	2016-09-25 21:47:13.000000000 -0400
@@ -12,6 +12,7 @@ Hopefully this will happen later in 2016
 
 Other TODOs:
 
+- There are two possible replies to CEC_MSG_INITIATE_ARC. How to handle that?
 - Add a flag to inhibit passing CEC RC messages to the rc subsystem.
   Applications should be able to choose this when calling S_LOG_ADDRS.
 - If the reply field of cec_msg is set then when the reply arrives it
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/drivers/staging/media/pulse8-cec/pulse8-cec.c linux-libre-4.8-rc8-gnu/drivers/staging/media/pulse8-cec/pulse8-cec.c
--- linux-libre-4.8-rc7-gnu/drivers/staging/media/pulse8-cec/pulse8-cec.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/drivers/staging/media/pulse8-cec/pulse8-cec.c	2016-09-25 21:47:13.000000000 -0400
@@ -114,14 +114,11 @@ static void pulse8_irq_work_handler(stru
 		cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK,
 				  0, 0, 0, 0);
 		break;
-	case MSGCODE_TRANSMIT_FAILED_LINE:
-		cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ARB_LOST,
-				  1, 0, 0, 0);
-		break;
 	case MSGCODE_TRANSMIT_FAILED_ACK:
 		cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK,
 				  0, 1, 0, 0);
 		break;
+	case MSGCODE_TRANSMIT_FAILED_LINE:
 	case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
 	case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
 		cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR,
@@ -170,6 +167,9 @@ static irqreturn_t pulse8_interrupt(stru
 		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
 			schedule_work(&pulse8->work);
 			break;
+		case MSGCODE_HIGH_ERROR:
+		case MSGCODE_LOW_ERROR:
+		case MSGCODE_RECEIVE_FAILED:
 		case MSGCODE_TIMEOUT_ERROR:
 			break;
 		case MSGCODE_COMMAND_ACCEPTED:
@@ -388,7 +388,7 @@ static int pulse8_cec_adap_transmit(stru
 	int err;
 
 	cmd[0] = MSGCODE_TRANSMIT_IDLETIME;
-	cmd[1] = 3;
+	cmd[1] = signal_free_time;
 	err = pulse8_send_and_wait(pulse8, cmd, 2,
 				   MSGCODE_COMMAND_ACCEPTED, 1);
 	cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/autofs4/expire.c linux-libre-4.8-rc8-gnu/fs/autofs4/expire.c
--- linux-libre-4.8-rc7-gnu/fs/autofs4/expire.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/autofs4/expire.c	2016-09-25 21:47:13.000000000 -0400
@@ -417,6 +417,7 @@ static struct dentry *should_expire(stru
 	}
 	return NULL;
 }
+
 /*
  * Find an eligible tree to time-out
  * A tree is eligible if :-
@@ -432,6 +433,7 @@ struct dentry *autofs4_expire_indirect(s
 	struct dentry *root = sb->s_root;
 	struct dentry *dentry;
 	struct dentry *expired;
+	struct dentry *found;
 	struct autofs_info *ino;
 
 	if (!root)
@@ -442,31 +444,46 @@ struct dentry *autofs4_expire_indirect(s
 
 	dentry = NULL;
 	while ((dentry = get_next_positive_subdir(dentry, root))) {
+		int flags = how;
+
 		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(dentry);
-		if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
-			expired = NULL;
-		else
-			expired = should_expire(dentry, mnt, timeout, how);
-		if (!expired) {
+		if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {
 			spin_unlock(&sbi->fs_lock);
 			continue;
 		}
+		spin_unlock(&sbi->fs_lock);
+
+		expired = should_expire(dentry, mnt, timeout, flags);
+		if (!expired)
+			continue;
+
+		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(expired);
 		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
 		synchronize_rcu();
-		spin_lock(&sbi->fs_lock);
-		if (should_expire(expired, mnt, timeout, how)) {
-			if (expired != dentry)
-				dput(dentry);
-			goto found;
-		}
 
+		/* Make sure a reference is not taken on found if
+		 * things have changed.
+		 */
+		flags &= ~AUTOFS_EXP_LEAVES;
+		found = should_expire(expired, mnt, timeout, how);
+		if (!found || found != expired)
+			/* Something has changed, continue */
+			goto next;
+
+		if (expired != dentry)
+			dput(dentry);
+
+		spin_lock(&sbi->fs_lock);
+		goto found;
+next:
+		spin_lock(&sbi->fs_lock);
 		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
+		spin_unlock(&sbi->fs_lock);
 		if (expired != dentry)
 			dput(expired);
-		spin_unlock(&sbi->fs_lock);
 	}
 	return NULL;
 
@@ -483,6 +500,7 @@ int autofs4_expire_wait(struct dentry *d
 	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 	struct autofs_info *ino = autofs4_dentry_ino(dentry);
 	int status;
+	int state;
 
 	/* Block on any pending expire */
 	if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))
@@ -490,8 +508,19 @@ int autofs4_expire_wait(struct dentry *d
 	if (rcu_walk)
 		return -ECHILD;
 
+retry:
 	spin_lock(&sbi->fs_lock);
-	if (ino->flags & AUTOFS_INF_EXPIRING) {
+	state = ino->flags & (AUTOFS_INF_WANT_EXPIRE | AUTOFS_INF_EXPIRING);
+	if (state == AUTOFS_INF_WANT_EXPIRE) {
+		spin_unlock(&sbi->fs_lock);
+		/*
+		 * Possibly being selected for expire, wait until
+		 * it's selected or not.
+		 */
+		schedule_timeout_uninterruptible(HZ/10);
+		goto retry;
+	}
+	if (state & AUTOFS_INF_EXPIRING) {
 		spin_unlock(&sbi->fs_lock);
 
 		pr_debug("waiting for expire %p name=%pd\n", dentry, dentry);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/btrfs/extent-tree.c linux-libre-4.8-rc8-gnu/fs/btrfs/extent-tree.c
--- linux-libre-4.8-rc7-gnu/fs/btrfs/extent-tree.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/btrfs/extent-tree.c	2016-09-25 21:47:13.000000000 -0400
@@ -4271,13 +4271,10 @@ int btrfs_check_data_free_space(struct i
 	if (ret < 0)
 		return ret;
 
-	/*
-	 * Use new btrfs_qgroup_reserve_data to reserve precious data space
-	 *
-	 * TODO: Find a good method to avoid reserve data space for NOCOW
-	 * range, but don't impact performance on quota disable case.
-	 */
+	/* Use new btrfs_qgroup_reserve_data to reserve precious data space. */
 	ret = btrfs_qgroup_reserve_data(inode, start, len);
+	if (ret)
+		btrfs_free_reserved_data_space_noquota(inode, start, len);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/btrfs/ioctl.c linux-libre-4.8-rc8-gnu/fs/btrfs/ioctl.c
--- linux-libre-4.8-rc7-gnu/fs/btrfs/ioctl.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/btrfs/ioctl.c	2016-09-25 21:47:13.000000000 -0400
@@ -1634,6 +1634,9 @@ static noinline int btrfs_ioctl_snap_cre
 	int namelen;
 	int ret = 0;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	ret = mnt_want_write_file(file);
 	if (ret)
 		goto out;
@@ -1691,6 +1694,9 @@ static noinline int btrfs_ioctl_snap_cre
 	struct btrfs_ioctl_vol_args *vol_args;
 	int ret;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -1714,6 +1720,9 @@ static noinline int btrfs_ioctl_snap_cre
 	bool readonly = false;
 	struct btrfs_qgroup_inherit *inherit = NULL;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -2357,6 +2366,9 @@ static noinline int btrfs_ioctl_snap_des
 	int ret;
 	int err = 0;
 
+	if (!S_ISDIR(dir->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/configfs/file.c linux-libre-4.8-rc8-gnu/fs/configfs/file.c
--- linux-libre-4.8-rc7-gnu/fs/configfs/file.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/configfs/file.c	2016-09-25 21:47:13.000000000 -0400
@@ -333,6 +333,7 @@ configfs_write_bin_file(struct file *fil
 		if (bin_attr->cb_max_size &&
 			*ppos + count > bin_attr->cb_max_size) {
 			len = -EFBIG;
+			goto out;
 		}
 
 		tbuf = vmalloc(*ppos + count);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/notify/fanotify/fanotify.c linux-libre-4.8-rc8-gnu/fs/notify/fanotify/fanotify.c
--- linux-libre-4.8-rc7-gnu/fs/notify/fanotify/fanotify.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/notify/fanotify/fanotify.c	2016-09-25 21:47:13.000000000 -0400
@@ -67,18 +67,7 @@ static int fanotify_get_response(struct
 
 	pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-	wait_event(group->fanotify_data.access_waitq, event->response ||
-				atomic_read(&group->fanotify_data.bypass_perm));
-
-	if (!event->response) {	/* bypass_perm set */
-		/*
-		 * Event was canceled because group is being destroyed. Remove
-		 * it from group's event list because we are responsible for
-		 * freeing the permission event.
-		 */
-		fsnotify_remove_event(group, &event->fae.fse);
-		return 0;
-	}
+	wait_event(group->fanotify_data.access_waitq, event->response);
 
 	/* userspace responded, convert to something usable */
 	switch (event->response) {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/notify/fanotify/fanotify_user.c linux-libre-4.8-rc8-gnu/fs/notify/fanotify/fanotify_user.c
--- linux-libre-4.8-rc7-gnu/fs/notify/fanotify/fanotify_user.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/notify/fanotify/fanotify_user.c	2016-09-25 21:47:13.000000000 -0400
@@ -358,16 +358,20 @@ static int fanotify_release(struct inode
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
 	struct fanotify_perm_event_info *event, *next;
+	struct fsnotify_event *fsn_event;
 
 	/*
-	 * There may be still new events arriving in the notification queue
-	 * but since userspace cannot use fanotify fd anymore, no event can
-	 * enter or leave access_list by now.
+	 * Stop new events from arriving in the notification queue. since
+	 * userspace cannot use fanotify fd anymore, no event can enter or
+	 * leave access_list by now either.
 	 */
-	spin_lock(&group->fanotify_data.access_lock);
-
-	atomic_inc(&group->fanotify_data.bypass_perm);
+	fsnotify_group_stop_queueing(group);
 
+	/*
+	 * Process all permission events on access_list and notification queue
+	 * and simulate reply from userspace.
+	 */
+	spin_lock(&group->fanotify_data.access_lock);
 	list_for_each_entry_safe(event, next, &group->fanotify_data.access_list,
 				 fae.fse.list) {
 		pr_debug("%s: found group=%p event=%p\n", __func__, group,
@@ -379,12 +383,21 @@ static int fanotify_release(struct inode
 	spin_unlock(&group->fanotify_data.access_lock);
 
 	/*
-	 * Since bypass_perm is set, newly queued events will not wait for
-	 * access response. Wake up the already sleeping ones now.
-	 * synchronize_srcu() in fsnotify_destroy_group() will wait for all
-	 * processes sleeping in fanotify_handle_event() waiting for access
-	 * response and thus also for all permission events to be freed.
+	 * Destroy all non-permission events. For permission events just
+	 * dequeue them and set the response. They will be freed once the
+	 * response is consumed and fanotify_get_response() returns.
 	 */
+	mutex_lock(&group->notification_mutex);
+	while (!fsnotify_notify_queue_is_empty(group)) {
+		fsn_event = fsnotify_remove_first_event(group);
+		if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS))
+			fsnotify_destroy_event(group, fsn_event);
+		else
+			FANOTIFY_PE(fsn_event)->response = FAN_ALLOW;
+	}
+	mutex_unlock(&group->notification_mutex);
+
+	/* Response for all permission events it set, wakeup waiters */
 	wake_up(&group->fanotify_data.access_waitq);
 #endif
 
@@ -755,7 +768,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned
 	spin_lock_init(&group->fanotify_data.access_lock);
 	init_waitqueue_head(&group->fanotify_data.access_waitq);
 	INIT_LIST_HEAD(&group->fanotify_data.access_list);
-	atomic_set(&group->fanotify_data.bypass_perm, 0);
 #endif
 	switch (flags & FAN_ALL_CLASS_BITS) {
 	case FAN_CLASS_NOTIF:
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/notify/group.c linux-libre-4.8-rc8-gnu/fs/notify/group.c
--- linux-libre-4.8-rc7-gnu/fs/notify/group.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/notify/group.c	2016-09-25 21:47:13.000000000 -0400
@@ -40,6 +40,17 @@ static void fsnotify_final_destroy_group
 }
 
 /*
+ * Stop queueing new events for this group. Once this function returns
+ * fsnotify_add_event() will not add any new events to the group's queue.
+ */
+void fsnotify_group_stop_queueing(struct fsnotify_group *group)
+{
+	mutex_lock(&group->notification_mutex);
+	group->shutdown = true;
+	mutex_unlock(&group->notification_mutex);
+}
+
+/*
  * Trying to get rid of a group. Remove all marks, flush all events and release
  * the group reference.
  * Note that another thread calling fsnotify_clear_marks_by_group() may still
@@ -47,6 +58,14 @@ static void fsnotify_final_destroy_group
  */
 void fsnotify_destroy_group(struct fsnotify_group *group)
 {
+	/*
+	 * Stop queueing new events. The code below is careful enough to not
+	 * require this but fanotify needs to stop queuing events even before
+	 * fsnotify_destroy_group() is called and this makes the other callers
+	 * of fsnotify_destroy_group() to see the same behavior.
+	 */
+	fsnotify_group_stop_queueing(group);
+
 	/* clear all inode marks for this group, attach them to destroy_list */
 	fsnotify_detach_group_marks(group);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/notify/notification.c linux-libre-4.8-rc8-gnu/fs/notify/notification.c
--- linux-libre-4.8-rc7-gnu/fs/notify/notification.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/notify/notification.c	2016-09-25 21:47:13.000000000 -0400
@@ -82,7 +82,8 @@ void fsnotify_destroy_event(struct fsnot
  * Add an event to the group notification queue.  The group can later pull this
  * event off the queue to deal with.  The function returns 0 if the event was
  * added to the queue, 1 if the event was merged with some other queued event,
- * 2 if the queue of events has overflown.
+ * 2 if the event was not queued - either the queue of events has overflown
+ * or the group is shutting down.
  */
 int fsnotify_add_event(struct fsnotify_group *group,
 		       struct fsnotify_event *event,
@@ -96,6 +97,11 @@ int fsnotify_add_event(struct fsnotify_g
 
 	mutex_lock(&group->notification_mutex);
 
+	if (group->shutdown) {
+		mutex_unlock(&group->notification_mutex);
+		return 2;
+	}
+
 	if (group->q_len >= group->max_events) {
 		ret = 2;
 		/* Queue overflow event only if it isn't already queued */
@@ -126,21 +132,6 @@ queue:
 }
 
 /*
- * Remove @event from group's notification queue. It is the responsibility of
- * the caller to destroy the event.
- */
-void fsnotify_remove_event(struct fsnotify_group *group,
-			   struct fsnotify_event *event)
-{
-	mutex_lock(&group->notification_mutex);
-	if (!list_empty(&event->list)) {
-		list_del_init(&event->list);
-		group->q_len--;
-	}
-	mutex_unlock(&group->notification_mutex);
-}
-
-/*
  * Remove and return the first event from the notification list.  It is the
  * responsibility of the caller to destroy the obtained event
  */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/ocfs2/alloc.c linux-libre-4.8-rc8-gnu/fs/ocfs2/alloc.c
--- linux-libre-4.8-rc7-gnu/fs/ocfs2/alloc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/ocfs2/alloc.c	2016-09-25 21:47:13.000000000 -0400
@@ -5922,7 +5922,6 @@ bail:
 }
 
 static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
-					 handle_t *handle,
 					 struct inode *data_alloc_inode,
 					 struct buffer_head *data_alloc_bh)
 {
@@ -5935,11 +5934,19 @@ static int ocfs2_replay_truncate_records
 	struct ocfs2_truncate_log *tl;
 	struct inode *tl_inode = osb->osb_tl_inode;
 	struct buffer_head *tl_bh = osb->osb_tl_bh;
+	handle_t *handle;
 
 	di = (struct ocfs2_dinode *) tl_bh->b_data;
 	tl = &di->id2.i_dealloc;
 	i = le16_to_cpu(tl->tl_used) - 1;
 	while (i >= 0) {
+		handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
+		if (IS_ERR(handle)) {
+			status = PTR_ERR(handle);
+			mlog_errno(status);
+			goto bail;
+		}
+
 		/* Caller has given us at least enough credits to
 		 * update the truncate log dinode */
 		status = ocfs2_journal_access_di(handle, INODE_CACHE(tl_inode), tl_bh,
@@ -5974,12 +5981,7 @@ static int ocfs2_replay_truncate_records
 			}
 		}
 
-		status = ocfs2_extend_trans(handle,
-				OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+		ocfs2_commit_trans(osb, handle);
 		i--;
 	}
 
@@ -5994,7 +5996,6 @@ int __ocfs2_flush_truncate_log(struct oc
 {
 	int status;
 	unsigned int num_to_flush;
-	handle_t *handle;
 	struct inode *tl_inode = osb->osb_tl_inode;
 	struct inode *data_alloc_inode = NULL;
 	struct buffer_head *tl_bh = osb->osb_tl_bh;
@@ -6038,21 +6039,11 @@ int __ocfs2_flush_truncate_log(struct oc
 		goto out_mutex;
 	}
 
-	handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
-	if (IS_ERR(handle)) {
-		status = PTR_ERR(handle);
-		mlog_errno(status);
-		goto out_unlock;
-	}
-
-	status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode,
+	status = ocfs2_replay_truncate_records(osb, data_alloc_inode,
 					       data_alloc_bh);
 	if (status < 0)
 		mlog_errno(status);
 
-	ocfs2_commit_trans(osb, handle);
-
-out_unlock:
 	brelse(data_alloc_bh);
 	ocfs2_inode_unlock(data_alloc_inode, 1);
 
@@ -6413,43 +6404,34 @@ static int ocfs2_free_cached_blocks(stru
 		goto out_mutex;
 	}
 
-	handle = ocfs2_start_trans(osb, OCFS2_SUBALLOC_FREE);
-	if (IS_ERR(handle)) {
-		ret = PTR_ERR(handle);
-		mlog_errno(ret);
-		goto out_unlock;
-	}
-
 	while (head) {
 		if (head->free_bg)
 			bg_blkno = head->free_bg;
 		else
 			bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
 							      head->free_bit);
+		handle = ocfs2_start_trans(osb, OCFS2_SUBALLOC_FREE);
+		if (IS_ERR(handle)) {
+			ret = PTR_ERR(handle);
+			mlog_errno(ret);
+			goto out_unlock;
+		}
+
 		trace_ocfs2_free_cached_blocks(
 		     (unsigned long long)head->free_blk, head->free_bit);
 
 		ret = ocfs2_free_suballoc_bits(handle, inode, di_bh,
 					       head->free_bit, bg_blkno, 1);
-		if (ret) {
+		if (ret)
 			mlog_errno(ret);
-			goto out_journal;
-		}
 
-		ret = ocfs2_extend_trans(handle, OCFS2_SUBALLOC_FREE);
-		if (ret) {
-			mlog_errno(ret);
-			goto out_journal;
-		}
+		ocfs2_commit_trans(osb, handle);
 
 		tmp = head;
 		head = head->free_next;
 		kfree(tmp);
 	}
 
-out_journal:
-	ocfs2_commit_trans(osb, handle);
-
 out_unlock:
 	ocfs2_inode_unlock(inode, 1);
 	brelse(di_bh);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/ocfs2/cluster/tcp_internal.h linux-libre-4.8-rc8-gnu/fs/ocfs2/cluster/tcp_internal.h
--- linux-libre-4.8-rc7-gnu/fs/ocfs2/cluster/tcp_internal.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/ocfs2/cluster/tcp_internal.h	2016-09-25 21:47:13.000000000 -0400
@@ -44,9 +44,6 @@
  * version here in tcp_internal.h should not need to be bumped for
  * filesystem locking changes.
  *
- * New in version 12
- *	- Negotiate hb timeout when storage is down.
- *
  * New in version 11
  * 	- Negotiation of filesystem locking in the dlm join.
  *
@@ -78,7 +75,7 @@
  * 	- full 64 bit i_size in the metadata lock lvbs
  * 	- introduction of "rw" lock and pushing meta/data locking down
  */
-#define O2NET_PROTOCOL_VERSION 12ULL
+#define O2NET_PROTOCOL_VERSION 11ULL
 struct o2net_handshake {
 	__be64	protocol_version;
 	__be64	connector_id;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/ocfs2/dlm/dlmconvert.c linux-libre-4.8-rc8-gnu/fs/ocfs2/dlm/dlmconvert.c
--- linux-libre-4.8-rc7-gnu/fs/ocfs2/dlm/dlmconvert.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/ocfs2/dlm/dlmconvert.c	2016-09-25 21:47:13.000000000 -0400
@@ -268,7 +268,6 @@ enum dlm_status dlmconvert_remote(struct
 				  struct dlm_lock *lock, int flags, int type)
 {
 	enum dlm_status status;
-	u8 old_owner = res->owner;
 
 	mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type,
 	     lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS);
@@ -335,7 +334,6 @@ enum dlm_status dlmconvert_remote(struct
 
 	spin_lock(&res->spinlock);
 	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
-	lock->convert_pending = 0;
 	/* if it failed, move it back to granted queue.
 	 * if master returns DLM_NORMAL and then down before sending ast,
 	 * it may have already been moved to granted queue, reset to
@@ -344,12 +342,14 @@ enum dlm_status dlmconvert_remote(struct
 		if (status != DLM_NOTQUEUED)
 			dlm_error(status);
 		dlm_revert_pending_convert(res, lock);
-	} else if ((res->state & DLM_LOCK_RES_RECOVERING) ||
-			(old_owner != res->owner)) {
-		mlog(0, "res %.*s is in recovering or has been recovered.\n",
-				res->lockname.len, res->lockname.name);
+	} else if (!lock->convert_pending) {
+		mlog(0, "%s: res %.*s, owner died and lock has been moved back "
+				"to granted list, retry convert.\n",
+				dlm->name, res->lockname.len, res->lockname.name);
 		status = DLM_RECOVERING;
 	}
+
+	lock->convert_pending = 0;
 bail:
 	spin_unlock(&res->spinlock);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/ocfs2/file.c linux-libre-4.8-rc8-gnu/fs/ocfs2/file.c
--- linux-libre-4.8-rc7-gnu/fs/ocfs2/file.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/ocfs2/file.c	2016-09-25 21:47:13.000000000 -0400
@@ -1506,7 +1506,8 @@ static int ocfs2_zero_partial_clusters(s
 				       u64 start, u64 len)
 {
 	int ret = 0;
-	u64 tmpend, end = start + len;
+	u64 tmpend = 0;
+	u64 end = start + len;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	unsigned int csize = osb->s_clustersize;
 	handle_t *handle;
@@ -1538,18 +1539,31 @@ static int ocfs2_zero_partial_clusters(s
 	}
 
 	/*
-	 * We want to get the byte offset of the end of the 1st cluster.
+	 * If start is on a cluster boundary and end is somewhere in another
+	 * cluster, we have not COWed the cluster starting at start, unless
+	 * end is also within the same cluster. So, in this case, we skip this
+	 * first call to ocfs2_zero_range_for_truncate() truncate and move on
+	 * to the next one.
 	 */
-	tmpend = (u64)osb->s_clustersize + (start & ~(osb->s_clustersize - 1));
-	if (tmpend > end)
-		tmpend = end;
+	if ((start & (csize - 1)) != 0) {
+		/*
+		 * We want to get the byte offset of the end of the 1st
+		 * cluster.
+		 */
+		tmpend = (u64)osb->s_clustersize +
+			(start & ~(osb->s_clustersize - 1));
+		if (tmpend > end)
+			tmpend = end;
 
-	trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start,
-						 (unsigned long long)tmpend);
+		trace_ocfs2_zero_partial_clusters_range1(
+			(unsigned long long)start,
+			(unsigned long long)tmpend);
 
-	ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend);
-	if (ret)
-		mlog_errno(ret);
+		ret = ocfs2_zero_range_for_truncate(inode, handle, start,
+						    tmpend);
+		if (ret)
+			mlog_errno(ret);
+	}
 
 	if (tmpend < end) {
 		/*
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/ocfs2/suballoc.c linux-libre-4.8-rc8-gnu/fs/ocfs2/suballoc.c
--- linux-libre-4.8-rc7-gnu/fs/ocfs2/suballoc.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/ocfs2/suballoc.c	2016-09-25 21:47:13.000000000 -0400
@@ -1199,14 +1199,24 @@ retry:
 			inode_unlock((*ac)->ac_inode);
 
 			ret = ocfs2_try_to_free_truncate_log(osb, bits_wanted);
-			if (ret == 1)
+			if (ret == 1) {
+				iput((*ac)->ac_inode);
+				(*ac)->ac_inode = NULL;
 				goto retry;
+			}
 
 			if (ret < 0)
 				mlog_errno(ret);
 
 			inode_lock((*ac)->ac_inode);
-			ocfs2_inode_lock((*ac)->ac_inode, NULL, 1);
+			ret = ocfs2_inode_lock((*ac)->ac_inode, NULL, 1);
+			if (ret < 0) {
+				mlog_errno(ret);
+				inode_unlock((*ac)->ac_inode);
+				iput((*ac)->ac_inode);
+				(*ac)->ac_inode = NULL;
+				goto bail;
+			}
 		}
 		if (status < 0) {
 			if (status != -ENOSPC)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/proc/kcore.c linux-libre-4.8-rc8-gnu/fs/proc/kcore.c
--- linux-libre-4.8-rc7-gnu/fs/proc/kcore.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/proc/kcore.c	2016-09-25 21:47:13.000000000 -0400
@@ -430,6 +430,7 @@ static void elf_kcore_store_hdr(char *bu
 static ssize_t
 read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
 {
+	char *buf = file->private_data;
 	ssize_t acc = 0;
 	size_t size, tsz;
 	size_t elf_buflen;
@@ -500,23 +501,20 @@ read_kcore(struct file *file, char __use
 			if (clear_user(buffer, tsz))
 				return -EFAULT;
 		} else if (is_vmalloc_or_module_addr((void *)start)) {
-			char * elf_buf;
-
-			elf_buf = kzalloc(tsz, GFP_KERNEL);
-			if (!elf_buf)
-				return -ENOMEM;
-			vread(elf_buf, (char *)start, tsz);
+			vread(buf, (char *)start, tsz);
 			/* we have to zero-fill user buffer even if no read */
-			if (copy_to_user(buffer, elf_buf, tsz)) {
-				kfree(elf_buf);
+			if (copy_to_user(buffer, buf, tsz))
 				return -EFAULT;
-			}
-			kfree(elf_buf);
 		} else {
 			if (kern_addr_valid(start)) {
 				unsigned long n;
 
-				n = copy_to_user(buffer, (char *)start, tsz);
+				/*
+				 * Using bounce buffer to bypass the
+				 * hardened user copy kernel text checks.
+				 */
+				memcpy(buf, (char *) start, tsz);
+				n = copy_to_user(buffer, buf, tsz);
 				/*
 				 * We cannot distinguish between fault on source
 				 * and fault on destination. When this happens
@@ -549,6 +547,11 @@ static int open_kcore(struct inode *inod
 {
 	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
+
+	filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!filp->private_data)
+		return -ENOMEM;
+
 	if (kcore_need_update)
 		kcore_update_ram();
 	if (i_size_read(inode) != proc_root_kcore->size) {
@@ -559,10 +562,16 @@ static int open_kcore(struct inode *inod
 	return 0;
 }
 
+static int release_kcore(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
 
 static const struct file_operations proc_kcore_operations = {
 	.read		= read_kcore,
 	.open		= open_kcore,
+	.release	= release_kcore,
 	.llseek		= default_llseek,
 };
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/fs/ramfs/file-mmu.c linux-libre-4.8-rc8-gnu/fs/ramfs/file-mmu.c
--- linux-libre-4.8-rc7-gnu/fs/ramfs/file-mmu.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/fs/ramfs/file-mmu.c	2016-09-25 21:47:13.000000000 -0400
@@ -27,9 +27,17 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/ramfs.h>
+#include <linux/sched.h>
 
 #include "internal.h"
 
+static unsigned long ramfs_mmu_get_unmapped_area(struct file *file,
+		unsigned long addr, unsigned long len, unsigned long pgoff,
+		unsigned long flags)
+{
+	return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
+}
+
 const struct file_operations ramfs_file_operations = {
 	.read_iter	= generic_file_read_iter,
 	.write_iter	= generic_file_write_iter,
@@ -38,6 +46,7 @@ const struct file_operations ramfs_file_
 	.splice_read	= generic_file_splice_read,
 	.splice_write	= iter_file_splice_write,
 	.llseek		= generic_file_llseek,
+	.get_unmapped_area	= ramfs_mmu_get_unmapped_area,
 };
 
 const struct inode_operations ramfs_file_inode_operations = {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/linux/cec-funcs.h linux-libre-4.8-rc8-gnu/include/linux/cec-funcs.h
--- linux-libre-4.8-rc7-gnu/include/linux/cec-funcs.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/linux/cec-funcs.h	2016-09-25 21:47:13.000000000 -0400
@@ -162,10 +162,11 @@ static inline void cec_msg_standby(struc
 
 
 /* One Touch Record Feature */
-static inline void cec_msg_record_off(struct cec_msg *msg)
+static inline void cec_msg_record_off(struct cec_msg *msg, bool reply)
 {
 	msg->len = 2;
 	msg->msg[1] = CEC_MSG_RECORD_OFF;
+	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;
 }
 
 struct cec_op_arib_data {
@@ -227,7 +228,7 @@ static inline void cec_set_digital_servi
 	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
 		*msg++ = (digital->channel.channel_number_fmt << 2) |
 			 (digital->channel.major >> 8);
-		*msg++ = digital->channel.major && 0xff;
+		*msg++ = digital->channel.major & 0xff;
 		*msg++ = digital->channel.minor >> 8;
 		*msg++ = digital->channel.minor & 0xff;
 		*msg++ = 0;
@@ -323,6 +324,7 @@ static inline void cec_msg_record_on_phy
 }
 
 static inline void cec_msg_record_on(struct cec_msg *msg,
+				     bool reply,
 				     const struct cec_op_record_src *rec_src)
 {
 	switch (rec_src->type) {
@@ -346,6 +348,7 @@ static inline void cec_msg_record_on(str
 					    rec_src->ext_phys_addr.phys_addr);
 		break;
 	}
+	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;
 }
 
 static inline void cec_ops_record_on(const struct cec_msg *msg,
@@ -1141,6 +1144,75 @@ static inline void cec_msg_give_device_v
 	msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0;
 }
 
+static inline void cec_msg_vendor_command(struct cec_msg *msg,
+					  __u8 size, const __u8 *vendor_cmd)
+{
+	if (size > 14)
+		size = 14;
+	msg->len = 2 + size;
+	msg->msg[1] = CEC_MSG_VENDOR_COMMAND;
+	memcpy(msg->msg + 2, vendor_cmd, size);
+}
+
+static inline void cec_ops_vendor_command(const struct cec_msg *msg,
+					  __u8 *size,
+					  const __u8 **vendor_cmd)
+{
+	*size = msg->len - 2;
+
+	if (*size > 14)
+		*size = 14;
+	*vendor_cmd = msg->msg + 2;
+}
+
+static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg,
+						  __u32 vendor_id, __u8 size,
+						  const __u8 *vendor_cmd)
+{
+	if (size > 11)
+		size = 11;
+	msg->len = 5 + size;
+	msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID;
+	msg->msg[2] = vendor_id >> 16;
+	msg->msg[3] = (vendor_id >> 8) & 0xff;
+	msg->msg[4] = vendor_id & 0xff;
+	memcpy(msg->msg + 5, vendor_cmd, size);
+}
+
+static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg,
+						  __u32 *vendor_id,  __u8 *size,
+						  const __u8 **vendor_cmd)
+{
+	*size = msg->len - 5;
+
+	if (*size > 11)
+		*size = 11;
+	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
+	*vendor_cmd = msg->msg + 5;
+}
+
+static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg,
+						     __u8 size,
+						     const __u8 *rc_code)
+{
+	if (size > 14)
+		size = 14;
+	msg->len = 2 + size;
+	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN;
+	memcpy(msg->msg + 2, rc_code, size);
+}
+
+static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg,
+						     __u8 *size,
+						     const __u8 **rc_code)
+{
+	*size = msg->len - 2;
+
+	if (*size > 14)
+		*size = 14;
+	*rc_code = msg->msg + 2;
+}
+
 static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg)
 {
 	msg->len = 2;
@@ -1277,7 +1349,7 @@ static inline void cec_msg_user_control_
 		msg->len += 4;
 		msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) |
 			      (ui_cmd->channel_identifier.major >> 8);
-		msg->msg[4] = ui_cmd->channel_identifier.major && 0xff;
+		msg->msg[4] = ui_cmd->channel_identifier.major & 0xff;
 		msg->msg[5] = ui_cmd->channel_identifier.minor >> 8;
 		msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff;
 		break;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/linux/cec.h linux-libre-4.8-rc8-gnu/include/linux/cec.h
--- linux-libre-4.8-rc7-gnu/include/linux/cec.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/linux/cec.h	2016-09-25 21:47:13.000000000 -0400
@@ -364,7 +364,7 @@ struct cec_caps {
  * @num_log_addrs: how many logical addresses should be claimed. Set by the
  *	caller.
  * @vendor_id: the vendor ID of the device. Set by the caller.
- * @flags: set to 0.
+ * @flags: flags.
  * @osd_name: the OSD name of the device. Set by the caller.
  * @primary_device_type: the primary device type for each logical address.
  *	Set by the caller.
@@ -389,6 +389,9 @@ struct cec_log_addrs {
 	__u8 features[CEC_MAX_LOG_ADDRS][12];
 };
 
+/* Allow a fallback to unregistered */
+#define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK	(1 << 0)
+
 /* Events */
 
 /* Event that occurs when the adapter state changes */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/linux/fsnotify_backend.h linux-libre-4.8-rc8-gnu/include/linux/fsnotify_backend.h
--- linux-libre-4.8-rc7-gnu/include/linux/fsnotify_backend.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/linux/fsnotify_backend.h	2016-09-25 21:47:13.000000000 -0400
@@ -148,6 +148,7 @@ struct fsnotify_group {
 	#define FS_PRIO_1	1 /* fanotify content based access control */
 	#define FS_PRIO_2	2 /* fanotify pre-content access */
 	unsigned int priority;
+	bool shutdown;		/* group is being shut down, don't queue more events */
 
 	/* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
 	struct mutex mark_mutex;	/* protect marks_list */
@@ -179,7 +180,6 @@ struct fsnotify_group {
 			spinlock_t access_lock;
 			struct list_head access_list;
 			wait_queue_head_t access_waitq;
-			atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
 			int f_flags;
 			unsigned int max_marks;
@@ -292,6 +292,8 @@ extern struct fsnotify_group *fsnotify_a
 extern void fsnotify_get_group(struct fsnotify_group *group);
 /* drop reference on a group from fsnotify_alloc_group */
 extern void fsnotify_put_group(struct fsnotify_group *group);
+/* group destruction begins, stop queuing new events */
+extern void fsnotify_group_stop_queueing(struct fsnotify_group *group);
 /* destroy group */
 extern void fsnotify_destroy_group(struct fsnotify_group *group);
 /* fasync handler function */
@@ -304,8 +306,6 @@ extern int fsnotify_add_event(struct fsn
 			      struct fsnotify_event *event,
 			      int (*merge)(struct list_head *,
 					   struct fsnotify_event *));
-/* Remove passed event from groups notification queue */
-extern void fsnotify_remove_event(struct fsnotify_group *group, struct fsnotify_event *event);
 /* true if the group notification queue is empty */
 extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
 /* return, but do not dequeue the first event on the notification queue */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/linux/pagemap.h linux-libre-4.8-rc8-gnu/include/linux/pagemap.h
--- linux-libre-4.8-rc7-gnu/include/linux/pagemap.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/linux/pagemap.h	2016-09-25 21:47:13.000000000 -0400
@@ -571,56 +571,57 @@ static inline int fault_in_pages_readabl
  */
 static inline int fault_in_multipages_writeable(char __user *uaddr, int size)
 {
-	int ret = 0;
 	char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
 
+	if (unlikely(uaddr > end))
+		return -EFAULT;
 	/*
 	 * Writing zeroes into userspace here is OK, because we know that if
 	 * the zero gets there, we'll be overwriting it.
 	 */
-	while (uaddr <= end) {
-		ret = __put_user(0, uaddr);
-		if (ret != 0)
-			return ret;
+	do {
+		if (unlikely(__put_user(0, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK))
-		ret = __put_user(0, end);
+		return __put_user(0, end);
 
-	return ret;
+	return 0;
 }
 
 static inline int fault_in_multipages_readable(const char __user *uaddr,
 					       int size)
 {
 	volatile char c;
-	int ret = 0;
 	const char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
 
-	while (uaddr <= end) {
-		ret = __get_user(c, uaddr);
-		if (ret != 0)
-			return ret;
+	if (unlikely(uaddr > end))
+		return -EFAULT;
+
+	do {
+		if (unlikely(__get_user(c, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK)) {
-		ret = __get_user(c, end);
-		(void)c;
+		return __get_user(c, end);
 	}
 
-	return ret;
+	(void)c;
+	return 0;
 }
 
 int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/media/cec.h linux-libre-4.8-rc8-gnu/include/media/cec.h
--- linux-libre-4.8-rc7-gnu/include/media/cec.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/media/cec.h	2016-09-25 21:47:13.000000000 -0400
@@ -57,8 +57,8 @@ struct cec_devnode {
 	int minor;
 	bool registered;
 	bool unregistered;
-	struct mutex fhs_lock;
 	struct list_head fhs;
+	struct mutex lock;
 };
 
 struct cec_adapter;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/net/netfilter/nf_conntrack_synproxy.h linux-libre-4.8-rc8-gnu/include/net/netfilter/nf_conntrack_synproxy.h
--- linux-libre-4.8-rc7-gnu/include/net/netfilter/nf_conntrack_synproxy.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/net/netfilter/nf_conntrack_synproxy.h	2016-09-25 21:47:13.000000000 -0400
@@ -27,6 +27,20 @@ static inline struct nf_conn_synproxy *n
 #endif
 }
 
+static inline bool nf_ct_add_synproxy(struct nf_conn *ct,
+				      const struct nf_conn *tmpl)
+{
+	if (tmpl && nfct_synproxy(tmpl)) {
+		if (!nfct_seqadj_ext_add(ct))
+			return false;
+
+		if (!nfct_synproxy_ext_add(ct))
+			return false;
+	}
+
+	return true;
+}
+
 struct synproxy_stats {
 	unsigned int			syn_received;
 	unsigned int			cookie_invalid;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/net/sctp/sm.h linux-libre-4.8-rc8-gnu/include/net/sctp/sm.h
--- linux-libre-4.8-rc7-gnu/include/net/sctp/sm.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/net/sctp/sm.h	2016-09-25 21:47:13.000000000 -0400
@@ -382,7 +382,7 @@ enum {
 	ADDIP_SERIAL_SIGN_BIT = (1<<31)
 };
 
-static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t)
+static inline int ADDIP_SERIAL_gte(__u32 s, __u32 t)
 {
 	return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT);
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/net/sock.h linux-libre-4.8-rc8-gnu/include/net/sock.h
--- linux-libre-4.8-rc7-gnu/include/net/sock.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/net/sock.h	2016-09-25 21:47:13.000000000 -0400
@@ -1332,6 +1332,16 @@ static inline void sk_mem_uncharge(struc
 	if (!sk_has_account(sk))
 		return;
 	sk->sk_forward_alloc += size;
+
+	/* Avoid a possible overflow.
+	 * TCP send queues can make this happen, if sk_mem_reclaim()
+	 * is not called and more than 2 GBytes are released at once.
+	 *
+	 * If we reach 2 MBytes, reclaim 1 MBytes right now, there is
+	 * no need to hold that much forward allocation anyway.
+	 */
+	if (unlikely(sk->sk_forward_alloc >= 1 << 21))
+		__sk_mem_reclaim(sk, 1 << 20);
 }
 
 static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/include/net/xfrm.h linux-libre-4.8-rc8-gnu/include/net/xfrm.h
--- linux-libre-4.8-rc7-gnu/include/net/xfrm.h	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/include/net/xfrm.h	2016-09-25 21:47:13.000000000 -0400
@@ -1540,8 +1540,10 @@ int xfrm4_tunnel_deregister(struct xfrm_
 void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
 int xfrm6_extract_header(struct sk_buff *skb);
 int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
+		  struct ip6_tnl *t);
 int xfrm6_transport_finish(struct sk_buff *skb, int async);
+int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
 int xfrm6_rcv(struct sk_buff *skb);
 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 		     xfrm_address_t *saddr, u8 proto);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/kernel/cgroup.c linux-libre-4.8-rc8-gnu/kernel/cgroup.c
--- linux-libre-4.8-rc7-gnu/kernel/cgroup.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/kernel/cgroup.c	2016-09-25 21:47:13.000000000 -0400
@@ -6270,6 +6270,12 @@ void cgroup_sk_alloc(struct sock_cgroup_
 	if (cgroup_sk_alloc_disabled)
 		return;
 
+	/* Socket clone path */
+	if (skcd->val) {
+		cgroup_get(sock_cgroup_ptr(skcd));
+		return;
+	}
+
 	rcu_read_lock();
 
 	while (true) {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/kernel/events/core.c linux-libre-4.8-rc8-gnu/kernel/events/core.c
--- linux-libre-4.8-rc7-gnu/kernel/events/core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/kernel/events/core.c	2016-09-25 21:47:13.000000000 -0400
@@ -3929,7 +3929,7 @@ static void exclusive_event_destroy(stru
 
 static bool exclusive_event_match(struct perf_event *e1, struct perf_event *e2)
 {
-	if ((e1->pmu->capabilities & PERF_PMU_CAP_EXCLUSIVE) &&
+	if ((e1->pmu == e2->pmu) &&
 	    (e1->cpu == e2->cpu ||
 	     e1->cpu == -1 ||
 	     e2->cpu == -1))
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/kernel/irq/chip.c linux-libre-4.8-rc8-gnu/kernel/irq/chip.c
--- linux-libre-4.8-rc7-gnu/kernel/irq/chip.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/kernel/irq/chip.c	2016-09-25 21:47:13.000000000 -0400
@@ -820,6 +820,8 @@ __irq_do_set_handler(struct irq_desc *de
 	desc->name = name;
 
 	if (handle != handle_bad_irq && is_chained) {
+		unsigned int type = irqd_get_trigger_type(&desc->irq_data);
+
 		/*
 		 * We're about to start this interrupt immediately,
 		 * hence the need to set the trigger configuration.
@@ -828,8 +830,10 @@ __irq_do_set_handler(struct irq_desc *de
 		 * chained interrupt. Reset it immediately because we
 		 * do know better.
 		 */
-		__irq_set_trigger(desc, irqd_get_trigger_type(&desc->irq_data));
-		desc->handle_irq = handle;
+		if (type != IRQ_TYPE_NONE) {
+			__irq_set_trigger(desc, type);
+			desc->handle_irq = handle;
+		}
 
 		irq_settings_set_noprobe(desc);
 		irq_settings_set_norequest(desc);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/kernel/trace/trace.c linux-libre-4.8-rc8-gnu/kernel/trace/trace.c
--- linux-libre-4.8-rc7-gnu/kernel/trace/trace.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/kernel/trace/trace.c	2016-09-25 21:47:13.000000000 -0400
@@ -5124,19 +5124,20 @@ tracing_read_pipe(struct file *filp, cha
 	struct trace_iterator *iter = filp->private_data;
 	ssize_t sret;
 
-	/* return any leftover data */
-	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
-	if (sret != -EBUSY)
-		return sret;
-
-	trace_seq_init(&iter->seq);
-
 	/*
 	 * Avoid more than one consumer on a single file descriptor
 	 * This is just a matter of traces coherency, the ring buffer itself
 	 * is protected.
 	 */
 	mutex_lock(&iter->mutex);
+
+	/* return any leftover data */
+	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+	if (sret != -EBUSY)
+		goto out;
+
+	trace_seq_init(&iter->seq);
+
 	if (iter->trace->read) {
 		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
 		if (sret)
@@ -6163,9 +6164,6 @@ tracing_buffers_splice_read(struct file
 		return -EBUSY;
 #endif
 
-	if (splice_grow_spd(pipe, &spd))
-		return -ENOMEM;
-
 	if (*ppos & (PAGE_SIZE - 1))
 		return -EINVAL;
 
@@ -6175,6 +6173,9 @@ tracing_buffers_splice_read(struct file
 		len &= PAGE_MASK;
 	}
 
+	if (splice_grow_spd(pipe, &spd))
+		return -ENOMEM;
+
  again:
 	trace_access_lock(iter->cpu_file);
 	entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file);
@@ -6232,19 +6233,21 @@ tracing_buffers_splice_read(struct file
 	/* did we read anything? */
 	if (!spd.nr_pages) {
 		if (ret)
-			return ret;
+			goto out;
 
+		ret = -EAGAIN;
 		if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
-			return -EAGAIN;
+			goto out;
 
 		ret = wait_on_pipe(iter, true);
 		if (ret)
-			return ret;
+			goto out;
 
 		goto again;
 	}
 
 	ret = splice_to_pipe(pipe, &spd);
+out:
 	splice_shrink_spd(&spd);
 
 	return ret;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/lib/Kconfig.debug linux-libre-4.8-rc8-gnu/lib/Kconfig.debug
--- linux-libre-4.8-rc7-gnu/lib/Kconfig.debug	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/lib/Kconfig.debug	2016-09-25 21:47:13.000000000 -0400
@@ -821,7 +821,7 @@ config DETECT_HUNG_TASK
 	help
 	  Say Y here to enable the kernel to detect "hung tasks",
 	  which are bugs that cause the task to be stuck in
-	  uninterruptible "D" state indefinitiley.
+	  uninterruptible "D" state indefinitely.
 
 	  When a hung task is detected, the kernel will print the
 	  current stack trace (which you should report), but the
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/lib/radix-tree.c linux-libre-4.8-rc8-gnu/lib/radix-tree.c
--- linux-libre-4.8-rc7-gnu/lib/radix-tree.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/lib/radix-tree.c	2016-09-25 21:47:13.000000000 -0400
@@ -105,10 +105,10 @@ static unsigned int radix_tree_descend(s
 
 #ifdef CONFIG_RADIX_TREE_MULTIORDER
 	if (radix_tree_is_internal_node(entry)) {
-		unsigned long siboff = get_slot_offset(parent, entry);
-		if (siboff < RADIX_TREE_MAP_SIZE) {
-			offset = siboff;
-			entry = rcu_dereference_raw(parent->slots[offset]);
+		if (is_sibling_entry(parent, entry)) {
+			void **sibentry = (void **) entry_to_node(entry);
+			offset = get_slot_offset(parent, sibentry);
+			entry = rcu_dereference_raw(*sibentry);
 		}
 	}
 #endif
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/MAINTAINERS linux-libre-4.8-rc8-gnu/MAINTAINERS
--- linux-libre-4.8-rc7-gnu/MAINTAINERS	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/MAINTAINERS	2016-09-25 21:47:13.000000000 -0400
@@ -2501,7 +2501,7 @@ S:	Supported
 F:	kernel/bpf/
 
 BROADCOM B44 10/100 ETHERNET DRIVER
-M:	Gary Zambrano <zambrano@broadcom.com>
+M:	Michael Chan <michael.chan@broadcom.com>
 L:	netdev@vger.kernel.org
 S:	Supported
 F:	drivers/net/ethernet/broadcom/b44.*
@@ -6103,7 +6103,7 @@ S:	Supported
 F:	drivers/cpufreq/intel_pstate.c
 
 INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
-M:	Maik Broemme <mbroemme@plusserver.de>
+M:	Maik Broemme <mbroemme@libmpq.org>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
 F:	Documentation/fb/intelfb.txt
@@ -8161,6 +8161,15 @@ S:	Maintained
 W:	https://fedorahosted.org/dropwatch/
 F:	net/core/drop_monitor.c
 
+NETWORKING [DSA]
+M:	Andrew Lunn <andrew@lunn.ch>
+M:	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+M:	Florian Fainelli <f.fainelli@gmail.com>
+S:	Maintained
+F:	net/dsa/
+F:	include/net/dsa.h
+F:	drivers/net/dsa/
+
 NETWORKING [GENERAL]
 M:	"David S. Miller" <davem@davemloft.net>
 L:	netdev@vger.kernel.org
@@ -12569,7 +12578,7 @@ F:	include/linux/if_*vlan.h
 F:	net/8021q/
 
 VLYNQ BUS
-M:	Florian Fainelli <florian@openwrt.org>
+M:	Florian Fainelli <f.fainelli@gmail.com>
 L:	openwrt-devel@lists.openwrt.org (subscribers-only)
 S:	Maintained
 F:	drivers/vlynq/vlynq.c
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/Makefile linux-libre-4.8-rc8-gnu/Makefile
--- linux-libre-4.8-rc7-gnu/Makefile	2016-09-22 00:55:20.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/Makefile	2016-09-26 00:18:28.000000000 -0400
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 8
 SUBLEVEL = 0
-EXTRAVERSION = -rc7-gnu
+EXTRAVERSION = -rc8-gnu
 NAME = Psychotic Stoned Sheep
 
 # *DOCUMENTATION*
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/debug.c linux-libre-4.8-rc8-gnu/mm/debug.c
--- linux-libre-4.8-rc7-gnu/mm/debug.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/debug.c	2016-09-25 21:47:13.000000000 -0400
@@ -42,9 +42,11 @@ const struct trace_print_flags vmaflag_n
 
 void __dump_page(struct page *page, const char *reason)
 {
+	int mapcount = PageSlab(page) ? 0 : page_mapcount(page);
+
 	pr_emerg("page:%p count:%d mapcount:%d mapping:%p index:%#lx",
-		  page, page_ref_count(page), page_mapcount(page),
-		  page->mapping, page->index);
+		  page, page_ref_count(page), mapcount,
+		  page->mapping, page_to_pgoff(page));
 	if (PageCompound(page))
 		pr_cont(" compound_mapcount: %d", compound_mapcount(page));
 	pr_cont("\n");
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/huge_memory.c linux-libre-4.8-rc8-gnu/mm/huge_memory.c
--- linux-libre-4.8-rc7-gnu/mm/huge_memory.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/huge_memory.c	2016-09-25 21:47:13.000000000 -0400
@@ -1138,9 +1138,6 @@ int do_huge_pmd_numa_page(struct fault_e
 	bool was_writable;
 	int flags = 0;
 
-	/* A PROT_NONE fault should not end up here */
-	BUG_ON(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)));
-
 	fe->ptl = pmd_lock(vma->vm_mm, fe->pmd);
 	if (unlikely(!pmd_same(pmd, *fe->pmd)))
 		goto out_unlock;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/khugepaged.c linux-libre-4.8-rc8-gnu/mm/khugepaged.c
--- linux-libre-4.8-rc7-gnu/mm/khugepaged.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/khugepaged.c	2016-09-25 21:47:13.000000000 -0400
@@ -838,7 +838,8 @@ static bool hugepage_vma_check(struct vm
  * value (scan code).
  */
 
-static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address)
+static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address,
+		struct vm_area_struct **vmap)
 {
 	struct vm_area_struct *vma;
 	unsigned long hstart, hend;
@@ -846,7 +847,7 @@ static int hugepage_vma_revalidate(struc
 	if (unlikely(khugepaged_test_exit(mm)))
 		return SCAN_ANY_PROCESS;
 
-	vma = find_vma(mm, address);
+	*vmap = vma = find_vma(mm, address);
 	if (!vma)
 		return SCAN_VMA_NULL;
 
@@ -881,6 +882,11 @@ static bool __collapse_huge_page_swapin(
 		.pmd = pmd,
 	};
 
+	/* we only decide to swapin, if there is enough young ptes */
+	if (referenced < HPAGE_PMD_NR/2) {
+		trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0);
+		return false;
+	}
 	fe.pte = pte_offset_map(pmd, address);
 	for (; fe.address < address + HPAGE_PMD_NR*PAGE_SIZE;
 			fe.pte++, fe.address += PAGE_SIZE) {
@@ -888,17 +894,12 @@ static bool __collapse_huge_page_swapin(
 		if (!is_swap_pte(pteval))
 			continue;
 		swapped_in++;
-		/* we only decide to swapin, if there is enough young ptes */
-		if (referenced < HPAGE_PMD_NR/2) {
-			trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0);
-			return false;
-		}
 		ret = do_swap_page(&fe, pteval);
 
 		/* do_swap_page returns VM_FAULT_RETRY with released mmap_sem */
 		if (ret & VM_FAULT_RETRY) {
 			down_read(&mm->mmap_sem);
-			if (hugepage_vma_revalidate(mm, address)) {
+			if (hugepage_vma_revalidate(mm, address, &fe.vma)) {
 				/* vma is no longer available, don't continue to swapin */
 				trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0);
 				return false;
@@ -923,7 +924,6 @@ static bool __collapse_huge_page_swapin(
 static void collapse_huge_page(struct mm_struct *mm,
 				   unsigned long address,
 				   struct page **hpage,
-				   struct vm_area_struct *vma,
 				   int node, int referenced)
 {
 	pmd_t *pmd, _pmd;
@@ -933,6 +933,7 @@ static void collapse_huge_page(struct mm
 	spinlock_t *pmd_ptl, *pte_ptl;
 	int isolated = 0, result = 0;
 	struct mem_cgroup *memcg;
+	struct vm_area_struct *vma;
 	unsigned long mmun_start;	/* For mmu_notifiers */
 	unsigned long mmun_end;		/* For mmu_notifiers */
 	gfp_t gfp;
@@ -961,7 +962,7 @@ static void collapse_huge_page(struct mm
 	}
 
 	down_read(&mm->mmap_sem);
-	result = hugepage_vma_revalidate(mm, address);
+	result = hugepage_vma_revalidate(mm, address, &vma);
 	if (result) {
 		mem_cgroup_cancel_charge(new_page, memcg, true);
 		up_read(&mm->mmap_sem);
@@ -994,7 +995,7 @@ static void collapse_huge_page(struct mm
 	 * handled by the anon_vma lock + PG_lock.
 	 */
 	down_write(&mm->mmap_sem);
-	result = hugepage_vma_revalidate(mm, address);
+	result = hugepage_vma_revalidate(mm, address, &vma);
 	if (result)
 		goto out;
 	/* check if the pmd is still valid */
@@ -1202,7 +1203,7 @@ out_unmap:
 	if (ret) {
 		node = khugepaged_find_target_node();
 		/* collapse_huge_page will return with the mmap_sem released */
-		collapse_huge_page(mm, address, hpage, vma, node, referenced);
+		collapse_huge_page(mm, address, hpage, node, referenced);
 	}
 out:
 	trace_mm_khugepaged_scan_pmd(mm, page, writable, referenced,
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/memcontrol.c linux-libre-4.8-rc8-gnu/mm/memcontrol.c
--- linux-libre-4.8-rc7-gnu/mm/memcontrol.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/memcontrol.c	2016-09-25 21:47:13.000000000 -0400
@@ -1740,17 +1740,22 @@ static DEFINE_MUTEX(percpu_charge_mutex)
 static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
 {
 	struct memcg_stock_pcp *stock;
+	unsigned long flags;
 	bool ret = false;
 
 	if (nr_pages > CHARGE_BATCH)
 		return ret;
 
-	stock = &get_cpu_var(memcg_stock);
+	local_irq_save(flags);
+
+	stock = this_cpu_ptr(&memcg_stock);
 	if (memcg == stock->cached && stock->nr_pages >= nr_pages) {
 		stock->nr_pages -= nr_pages;
 		ret = true;
 	}
-	put_cpu_var(memcg_stock);
+
+	local_irq_restore(flags);
+
 	return ret;
 }
 
@@ -1771,15 +1776,18 @@ static void drain_stock(struct memcg_sto
 	stock->cached = NULL;
 }
 
-/*
- * This must be called under preempt disabled or must be called by
- * a thread which is pinned to local cpu.
- */
 static void drain_local_stock(struct work_struct *dummy)
 {
-	struct memcg_stock_pcp *stock = this_cpu_ptr(&memcg_stock);
+	struct memcg_stock_pcp *stock;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	stock = this_cpu_ptr(&memcg_stock);
 	drain_stock(stock);
 	clear_bit(FLUSHING_CACHED_CHARGE, &stock->flags);
+
+	local_irq_restore(flags);
 }
 
 /*
@@ -1788,14 +1796,19 @@ static void drain_local_stock(struct wor
  */
 static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
 {
-	struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock);
+	struct memcg_stock_pcp *stock;
+	unsigned long flags;
+
+	local_irq_save(flags);
 
+	stock = this_cpu_ptr(&memcg_stock);
 	if (stock->cached != memcg) { /* reset if necessary */
 		drain_stock(stock);
 		stock->cached = memcg;
 	}
 	stock->nr_pages += nr_pages;
-	put_cpu_var(memcg_stock);
+
+	local_irq_restore(flags);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/memory.c linux-libre-4.8-rc8-gnu/mm/memory.c
--- linux-libre-4.8-rc7-gnu/mm/memory.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/memory.c	2016-09-25 21:47:13.000000000 -0400
@@ -3351,9 +3351,6 @@ static int do_numa_page(struct fault_env
 	bool was_writable = pte_write(pte);
 	int flags = 0;
 
-	/* A PROT_NONE fault should not end up here */
-	BUG_ON(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)));
-
 	/*
 	* The "pte" at this point cannot be used safely without
 	* validation through pte_unmap_same(). It's of NUMA type but
@@ -3458,6 +3455,11 @@ static int wp_huge_pmd(struct fault_env
 	return VM_FAULT_FALLBACK;
 }
 
+static inline bool vma_is_accessible(struct vm_area_struct *vma)
+{
+	return vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE);
+}
+
 /*
  * These routines also need to handle stuff like marking pages dirty
  * and/or accessed for architectures that don't do it in hardware (most
@@ -3524,7 +3526,7 @@ static int handle_pte_fault(struct fault
 	if (!pte_present(entry))
 		return do_swap_page(fe, entry);
 
-	if (pte_protnone(entry))
+	if (pte_protnone(entry) && vma_is_accessible(fe->vma))
 		return do_numa_page(fe, entry);
 
 	fe->ptl = pte_lockptr(fe->vma->vm_mm, fe->pmd);
@@ -3590,7 +3592,7 @@ static int __handle_mm_fault(struct vm_a
 
 		barrier();
 		if (pmd_trans_huge(orig_pmd) || pmd_devmap(orig_pmd)) {
-			if (pmd_protnone(orig_pmd))
+			if (pmd_protnone(orig_pmd) && vma_is_accessible(vma))
 				return do_huge_pmd_numa_page(&fe, orig_pmd);
 
 			if ((fe.flags & FAULT_FLAG_WRITE) &&
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/memory_hotplug.c linux-libre-4.8-rc8-gnu/mm/memory_hotplug.c
--- linux-libre-4.8-rc7-gnu/mm/memory_hotplug.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/memory_hotplug.c	2016-09-25 21:47:13.000000000 -0400
@@ -1567,7 +1567,9 @@ static struct page *new_node_page(struct
 		return alloc_huge_page_node(page_hstate(compound_head(page)),
 					next_node_in(nid, nmask));
 
-	node_clear(nid, nmask);
+	if (nid != next_node_in(nid, nmask))
+		node_clear(nid, nmask);
+
 	if (PageHighMem(page)
 	    || (zone_idx(page_zone(page)) == ZONE_MOVABLE))
 		gfp_mask |= __GFP_HIGHMEM;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/page_io.c linux-libre-4.8-rc8-gnu/mm/page_io.c
--- linux-libre-4.8-rc7-gnu/mm/page_io.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/page_io.c	2016-09-25 21:47:13.000000000 -0400
@@ -264,6 +264,7 @@ int __swap_writepage(struct page *page,
 	int ret;
 	struct swap_info_struct *sis = page_swap_info(page);
 
+	BUG_ON(!PageSwapCache(page));
 	if (sis->flags & SWP_FILE) {
 		struct kiocb kiocb;
 		struct file *swap_file = sis->swap_file;
@@ -337,6 +338,7 @@ int swap_readpage(struct page *page)
 	int ret = 0;
 	struct swap_info_struct *sis = page_swap_info(page);
 
+	BUG_ON(!PageSwapCache(page));
 	VM_BUG_ON_PAGE(!PageLocked(page), page);
 	VM_BUG_ON_PAGE(PageUptodate(page), page);
 	if (frontswap_load(page) == 0) {
@@ -386,6 +388,7 @@ int swap_set_page_dirty(struct page *pag
 
 	if (sis->flags & SWP_FILE) {
 		struct address_space *mapping = sis->swap_file->f_mapping;
+		BUG_ON(!PageSwapCache(page));
 		return mapping->a_ops->set_page_dirty(page);
 	} else {
 		return __set_page_dirty_no_writeback(page);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/shmem.c linux-libre-4.8-rc8-gnu/mm/shmem.c
--- linux-libre-4.8-rc7-gnu/mm/shmem.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/shmem.c	2016-09-25 21:47:13.000000000 -0400
@@ -270,7 +270,7 @@ bool shmem_charge(struct inode *inode, l
 		info->alloced -= pages;
 		shmem_recalc_inode(inode);
 		spin_unlock_irqrestore(&info->lock, flags);
-
+		shmem_unacct_blocks(info->flags, pages);
 		return false;
 	}
 	percpu_counter_add(&sbinfo->used_blocks, pages);
@@ -291,6 +291,7 @@ void shmem_uncharge(struct inode *inode,
 
 	if (sbinfo->max_blocks)
 		percpu_counter_sub(&sbinfo->used_blocks, pages);
+	shmem_unacct_blocks(info->flags, pages);
 }
 
 /*
@@ -1980,7 +1981,7 @@ unsigned long shmem_get_unmapped_area(st
 				return addr;
 			sb = shm_mnt->mnt_sb;
 		}
-		if (SHMEM_SB(sb)->huge != SHMEM_HUGE_NEVER)
+		if (SHMEM_SB(sb)->huge == SHMEM_HUGE_NEVER)
 			return addr;
 	}
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/swapfile.c linux-libre-4.8-rc8-gnu/mm/swapfile.c
--- linux-libre-4.8-rc7-gnu/mm/swapfile.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/swapfile.c	2016-09-25 21:47:13.000000000 -0400
@@ -2724,7 +2724,6 @@ int swapcache_prepare(swp_entry_t entry)
 struct swap_info_struct *page_swap_info(struct page *page)
 {
 	swp_entry_t swap = { .val = page_private(page) };
-	BUG_ON(!PageSwapCache(page));
 	return swap_info[swp_type(swap)];
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/usercopy.c linux-libre-4.8-rc8-gnu/mm/usercopy.c
--- linux-libre-4.8-rc7-gnu/mm/usercopy.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/usercopy.c	2016-09-25 21:47:13.000000000 -0400
@@ -207,8 +207,11 @@ static inline const char *check_heap_obj
 	 * Some architectures (arm64) return true for virt_addr_valid() on
 	 * vmalloced addresses. Work around this by checking for vmalloc
 	 * first.
+	 *
+	 * We also need to check for module addresses explicitly since we
+	 * may copy static data from modules to userspace
 	 */
-	if (is_vmalloc_addr(ptr))
+	if (is_vmalloc_or_module_addr(ptr))
 		return NULL;
 
 	if (!virt_addr_valid(ptr))
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/mm/vmscan.c linux-libre-4.8-rc8-gnu/mm/vmscan.c
--- linux-libre-4.8-rc7-gnu/mm/vmscan.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/mm/vmscan.c	2016-09-25 21:47:13.000000000 -0400
@@ -2303,23 +2303,6 @@ out:
 	}
 }
 
-#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
-static void init_tlb_ubc(void)
-{
-	/*
-	 * This deliberately does not clear the cpumask as it's expensive
-	 * and unnecessary. If there happens to be data in there then the
-	 * first SWAP_CLUSTER_MAX pages will send an unnecessary IPI and
-	 * then will be cleared.
-	 */
-	current->tlb_ubc.flush_required = false;
-}
-#else
-static inline void init_tlb_ubc(void)
-{
-}
-#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
-
 /*
  * This is a basic per-node page freer.  Used by both kswapd and direct reclaim.
  */
@@ -2355,8 +2338,6 @@ static void shrink_node_memcg(struct pgl
 	scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() &&
 			 sc->priority == DEF_PRIORITY);
 
-	init_tlb_ubc();
-
 	blk_start_plug(&plug);
 	while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
 					nr[LRU_INACTIVE_FILE]) {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/batman-adv/bat_v_elp.c linux-libre-4.8-rc8-gnu/net/batman-adv/bat_v_elp.c
--- linux-libre-4.8-rc7-gnu/net/batman-adv/bat_v_elp.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/batman-adv/bat_v_elp.c	2016-09-25 21:47:13.000000000 -0400
@@ -335,7 +335,7 @@ int batadv_v_elp_iface_enable(struct bat
 		goto out;
 
 	skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN);
-	elp_buff = skb_push(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN);
+	elp_buff = skb_put(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN);
 	elp_packet = (struct batadv_elp_packet *)elp_buff;
 	memset(elp_packet, 0, BATADV_ELP_HLEN);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/batman-adv/routing.c linux-libre-4.8-rc8-gnu/net/batman-adv/routing.c
--- linux-libre-4.8-rc7-gnu/net/batman-adv/routing.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/batman-adv/routing.c	2016-09-25 21:47:13.000000000 -0400
@@ -470,6 +470,29 @@ static int batadv_check_unicast_packet(s
 }
 
 /**
+ * batadv_last_bonding_get - Get last_bonding_candidate of orig_node
+ * @orig_node: originator node whose last bonding candidate should be retrieved
+ *
+ * Return: last bonding candidate of router or NULL if not found
+ *
+ * The object is returned with refcounter increased by 1.
+ */
+static struct batadv_orig_ifinfo *
+batadv_last_bonding_get(struct batadv_orig_node *orig_node)
+{
+	struct batadv_orig_ifinfo *last_bonding_candidate;
+
+	spin_lock_bh(&orig_node->neigh_list_lock);
+	last_bonding_candidate = orig_node->last_bonding_candidate;
+
+	if (last_bonding_candidate)
+		kref_get(&last_bonding_candidate->refcount);
+	spin_unlock_bh(&orig_node->neigh_list_lock);
+
+	return last_bonding_candidate;
+}
+
+/**
  * batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node
  * @orig_node: originator node whose bonding candidates should be replaced
  * @new_candidate: new bonding candidate or NULL
@@ -539,7 +562,7 @@ batadv_find_router(struct batadv_priv *b
 	 * router - obviously there are no other candidates.
 	 */
 	rcu_read_lock();
-	last_candidate = orig_node->last_bonding_candidate;
+	last_candidate = batadv_last_bonding_get(orig_node);
 	if (last_candidate)
 		last_cand_router = rcu_dereference(last_candidate->router);
 
@@ -631,6 +654,9 @@ next:
 		batadv_orig_ifinfo_put(next_candidate);
 	}
 
+	if (last_candidate)
+		batadv_orig_ifinfo_put(last_candidate);
+
 	return router;
 }
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/core/sock.c linux-libre-4.8-rc8-gnu/net/core/sock.c
--- linux-libre-4.8-rc7-gnu/net/core/sock.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/core/sock.c	2016-09-25 21:47:13.000000000 -0400
@@ -1362,7 +1362,6 @@ static struct sock *sk_prot_alloc(struct
 		if (!try_module_get(prot->owner))
 			goto out_free_sec;
 		sk_tx_queue_clear(sk);
-		cgroup_sk_alloc(&sk->sk_cgrp_data);
 	}
 
 	return sk;
@@ -1422,6 +1421,7 @@ struct sock *sk_alloc(struct net *net, i
 		sock_net_set(sk, net);
 		atomic_set(&sk->sk_wmem_alloc, 1);
 
+		cgroup_sk_alloc(&sk->sk_cgrp_data);
 		sock_update_classid(&sk->sk_cgrp_data);
 		sock_update_netprioidx(&sk->sk_cgrp_data);
 	}
@@ -1566,6 +1566,9 @@ struct sock *sk_clone_lock(const struct
 		newsk->sk_priority = 0;
 		newsk->sk_incoming_cpu = raw_smp_processor_id();
 		atomic64_set(&newsk->sk_cookie, 0);
+
+		cgroup_sk_alloc(&newsk->sk_cgrp_data);
+
 		/*
 		 * Before updating sk_refcnt, we must commit prior changes to memory
 		 * (Documentation/RCU/rculist_nulls.txt for details)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/ip_input.c linux-libre-4.8-rc8-gnu/net/ipv4/ip_input.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/ip_input.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/ip_input.c	2016-09-25 21:47:13.000000000 -0400
@@ -312,6 +312,7 @@ static int ip_rcv_finish(struct net *net
 {
 	const struct iphdr *iph = ip_hdr(skb);
 	struct rtable *rt;
+	struct net_device *dev = skb->dev;
 
 	/* if ingress device is enslaved to an L3 master device pass the
 	 * skb to its handler for processing
@@ -341,7 +342,7 @@ static int ip_rcv_finish(struct net *net
 	 */
 	if (!skb_valid_dst(skb)) {
 		int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
-					       iph->tos, skb->dev);
+					       iph->tos, dev);
 		if (unlikely(err)) {
 			if (err == -EXDEV)
 				__NET_INC_STATS(net, LINUX_MIB_IPRPFILTER);
@@ -370,7 +371,7 @@ static int ip_rcv_finish(struct net *net
 		__IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len);
 	} else if (skb->pkt_type == PACKET_BROADCAST ||
 		   skb->pkt_type == PACKET_MULTICAST) {
-		struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
+		struct in_device *in_dev = __in_dev_get_rcu(dev);
 
 		/* RFC 1122 3.3.6:
 		 *
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/ipmr.c linux-libre-4.8-rc8-gnu/net/ipv4/ipmr.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/ipmr.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/ipmr.c	2016-09-25 21:47:13.000000000 -0400
@@ -2076,6 +2076,7 @@ static int __ipmr_fill_mroute(struct mr_
 	struct rta_mfc_stats mfcs;
 	struct nlattr *mp_attr;
 	struct rtnexthop *nhp;
+	unsigned long lastuse;
 	int ct;
 
 	/* If cache is unresolved, don't try to parse IIF and OIF */
@@ -2105,12 +2106,14 @@ static int __ipmr_fill_mroute(struct mr_
 
 	nla_nest_end(skb, mp_attr);
 
+	lastuse = READ_ONCE(c->mfc_un.res.lastuse);
+	lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
+
 	mfcs.mfcs_packets = c->mfc_un.res.pkt;
 	mfcs.mfcs_bytes = c->mfc_un.res.bytes;
 	mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
 	if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
-	    nla_put_u64_64bit(skb, RTA_EXPIRES,
-			      jiffies_to_clock_t(c->mfc_un.res.lastuse),
+	    nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
 			      RTA_PAD))
 		return -EMSGSIZE;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/ip_vti.c linux-libre-4.8-rc8-gnu/net/ipv4/ip_vti.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/ip_vti.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/ip_vti.c	2016-09-25 21:47:13.000000000 -0400
@@ -88,6 +88,7 @@ static int vti_rcv_cb(struct sk_buff *sk
 	struct net_device *dev;
 	struct pcpu_sw_netstats *tstats;
 	struct xfrm_state *x;
+	struct xfrm_mode *inner_mode;
 	struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
 	u32 orig_mark = skb->mark;
 	int ret;
@@ -105,7 +106,19 @@ static int vti_rcv_cb(struct sk_buff *sk
 	}
 
 	x = xfrm_input_state(skb);
-	family = x->inner_mode->afinfo->family;
+
+	inner_mode = x->inner_mode;
+
+	if (x->sel.family == AF_UNSPEC) {
+		inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
+		if (inner_mode == NULL) {
+			XFRM_INC_STATS(dev_net(skb->dev),
+				       LINUX_MIB_XFRMINSTATEMODEERROR);
+			return -EINVAL;
+		}
+	}
+
+	family = inner_mode->afinfo->family;
 
 	skb->mark = be32_to_cpu(tunnel->parms.i_key);
 	ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/netfilter/nft_chain_route_ipv4.c linux-libre-4.8-rc8-gnu/net/ipv4/netfilter/nft_chain_route_ipv4.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/netfilter/nft_chain_route_ipv4.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/netfilter/nft_chain_route_ipv4.c	2016-09-25 21:47:13.000000000 -0400
@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(
 	__be32 saddr, daddr;
 	u_int8_t tos;
 	const struct iphdr *iph;
+	int err;
 
 	/* root is playing with raw sockets. */
 	if (skb->len < sizeof(struct iphdr) ||
@@ -46,15 +47,17 @@ static unsigned int nf_route_table_hook(
 	tos = iph->tos;
 
 	ret = nft_do_chain(&pkt, priv);
-	if (ret != NF_DROP && ret != NF_QUEUE) {
+	if (ret != NF_DROP && ret != NF_STOLEN) {
 		iph = ip_hdr(skb);
 
 		if (iph->saddr != saddr ||
 		    iph->daddr != daddr ||
 		    skb->mark != mark ||
-		    iph->tos != tos)
-			if (ip_route_me_harder(state->net, skb, RTN_UNSPEC))
-				ret = NF_DROP;
+		    iph->tos != tos) {
+			err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
+			if (err < 0)
+				ret = NF_DROP_ERR(err);
+		}
 	}
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/route.c linux-libre-4.8-rc8-gnu/net/ipv4/route.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/route.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/route.c	2016-09-25 21:47:13.000000000 -0400
@@ -476,12 +476,18 @@ u32 ip_idents_reserve(u32 hash, int segs
 	atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ;
 	u32 old = ACCESS_ONCE(*p_tstamp);
 	u32 now = (u32)jiffies;
-	u32 delta = 0;
+	u32 new, delta = 0;
 
 	if (old != now && cmpxchg(p_tstamp, old, now) == old)
 		delta = prandom_u32_max(now - old);
 
-	return atomic_add_return(segs + delta, p_id) - segs;
+	/* Do not use atomic_add_return() as it makes UBSAN unhappy */
+	do {
+		old = (u32)atomic_read(p_id);
+		new = old + delta + segs;
+	} while (atomic_cmpxchg(p_id, old, new) != old);
+
+	return new - segs;
 }
 EXPORT_SYMBOL(ip_idents_reserve);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/tcp_input.c linux-libre-4.8-rc8-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/tcp_input.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/tcp_input.c	2016-09-25 21:47:13.000000000 -0400
@@ -5885,7 +5885,7 @@ int tcp_rcv_state_process(struct sock *s
 		 * so release it.
 		 */
 		if (req) {
-			tp->total_retrans = req->num_retrans;
+			inet_csk(sk)->icsk_retransmits = 0;
 			reqsk_fastopen_remove(sk, req, false);
 		} else {
 			/* Make sure socket is routed, for correct metrics. */
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/tcp_output.c linux-libre-4.8-rc8-gnu/net/ipv4/tcp_output.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/tcp_output.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/tcp_output.c	2016-09-25 21:47:13.000000000 -0400
@@ -2605,7 +2605,8 @@ int __tcp_retransmit_skb(struct sock *sk
 	 * copying overhead: fragmentation, tunneling, mangling etc.
 	 */
 	if (atomic_read(&sk->sk_wmem_alloc) >
-	    min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
+	    min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2),
+		  sk->sk_sndbuf))
 		return -EAGAIN;
 
 	if (skb_still_in_host_queue(sk, skb))
@@ -2830,7 +2831,7 @@ begin_fwd:
 		if (tcp_retransmit_skb(sk, skb, segs))
 			return;
 
-		NET_INC_STATS(sock_net(sk), mib_idx);
+		NET_ADD_STATS(sock_net(sk), mib_idx, tcp_skb_pcount(skb));
 
 		if (tcp_in_cwnd_reduction(sk))
 			tp->prr_out += tcp_skb_pcount(skb);
@@ -3567,6 +3568,8 @@ int tcp_rtx_synack(const struct sock *sk
 	if (!res) {
 		__TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS);
 		__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS);
+		if (unlikely(tcp_passive_fastopen(sk)))
+			tcp_sk(sk)->total_retrans++;
 	}
 	return res;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv4/tcp_timer.c linux-libre-4.8-rc8-gnu/net/ipv4/tcp_timer.c
--- linux-libre-4.8-rc7-gnu/net/ipv4/tcp_timer.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv4/tcp_timer.c	2016-09-25 21:47:13.000000000 -0400
@@ -384,6 +384,7 @@ static void tcp_fastopen_synack_timer(st
 	 */
 	inet_rtx_syn_ack(sk, req);
 	req->num_timeout++;
+	icsk->icsk_retransmits++;
 	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
 			  TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv6/ip6mr.c linux-libre-4.8-rc8-gnu/net/ipv6/ip6mr.c
--- linux-libre-4.8-rc7-gnu/net/ipv6/ip6mr.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv6/ip6mr.c	2016-09-25 21:47:13.000000000 -0400
@@ -2239,6 +2239,7 @@ static int __ip6mr_fill_mroute(struct mr
 	struct rta_mfc_stats mfcs;
 	struct nlattr *mp_attr;
 	struct rtnexthop *nhp;
+	unsigned long lastuse;
 	int ct;
 
 	/* If cache is unresolved, don't try to parse IIF and OIF */
@@ -2269,12 +2270,14 @@ static int __ip6mr_fill_mroute(struct mr
 
 	nla_nest_end(skb, mp_attr);
 
+	lastuse = READ_ONCE(c->mfc_un.res.lastuse);
+	lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
+
 	mfcs.mfcs_packets = c->mfc_un.res.pkt;
 	mfcs.mfcs_bytes = c->mfc_un.res.bytes;
 	mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
 	if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
-	    nla_put_u64_64bit(skb, RTA_EXPIRES,
-			      jiffies_to_clock_t(c->mfc_un.res.lastuse),
+	    nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
 			      RTA_PAD))
 		return -EMSGSIZE;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv6/ip6_vti.c linux-libre-4.8-rc8-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.8-rc7-gnu/net/ipv6/ip6_vti.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv6/ip6_vti.c	2016-09-25 21:47:13.000000000 -0400
@@ -321,11 +321,9 @@ static int vti6_rcv(struct sk_buff *skb)
 			goto discard;
 		}
 
-		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
-
 		rcu_read_unlock();
 
-		return xfrm6_rcv(skb);
+		return xfrm6_rcv_tnl(skb, t);
 	}
 	rcu_read_unlock();
 	return -EINVAL;
@@ -340,6 +338,7 @@ static int vti6_rcv_cb(struct sk_buff *s
 	struct net_device *dev;
 	struct pcpu_sw_netstats *tstats;
 	struct xfrm_state *x;
+	struct xfrm_mode *inner_mode;
 	struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6;
 	u32 orig_mark = skb->mark;
 	int ret;
@@ -357,7 +356,19 @@ static int vti6_rcv_cb(struct sk_buff *s
 	}
 
 	x = xfrm_input_state(skb);
-	family = x->inner_mode->afinfo->family;
+
+	inner_mode = x->inner_mode;
+
+	if (x->sel.family == AF_UNSPEC) {
+		inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
+		if (inner_mode == NULL) {
+			XFRM_INC_STATS(dev_net(skb->dev),
+				       LINUX_MIB_XFRMINSTATEMODEERROR);
+			return -EINVAL;
+		}
+	}
+
+	family = inner_mode->afinfo->family;
 
 	skb->mark = be32_to_cpu(t->parms.i_key);
 	ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv6/netfilter/nft_chain_route_ipv6.c linux-libre-4.8-rc8-gnu/net/ipv6/netfilter/nft_chain_route_ipv6.c
--- linux-libre-4.8-rc7-gnu/net/ipv6/netfilter/nft_chain_route_ipv6.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv6/netfilter/nft_chain_route_ipv6.c	2016-09-25 21:47:13.000000000 -0400
@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(
 	struct in6_addr saddr, daddr;
 	u_int8_t hop_limit;
 	u32 mark, flowlabel;
+	int err;
 
 	/* malformed packet, drop it */
 	if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0)
@@ -46,13 +47,16 @@ static unsigned int nf_route_table_hook(
 	flowlabel = *((u32 *)ipv6_hdr(skb));
 
 	ret = nft_do_chain(&pkt, priv);
-	if (ret != NF_DROP && ret != NF_QUEUE &&
+	if (ret != NF_DROP && ret != NF_STOLEN &&
 	    (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
 	     memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
 	     skb->mark != mark ||
 	     ipv6_hdr(skb)->hop_limit != hop_limit ||
-	     flowlabel != *((u_int32_t *)ipv6_hdr(skb))))
-		return ip6_route_me_harder(state->net, skb) == 0 ? ret : NF_DROP;
+	     flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
+		err = ip6_route_me_harder(state->net, skb);
+		if (err < 0)
+			ret = NF_DROP_ERR(err);
+	}
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv6/route.c linux-libre-4.8-rc8-gnu/net/ipv6/route.c
--- linux-libre-4.8-rc7-gnu/net/ipv6/route.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv6/route.c	2016-09-25 21:47:13.000000000 -0400
@@ -1986,9 +1986,18 @@ static struct rt6_info *ip6_route_info_c
 			if (!(gwa_type & IPV6_ADDR_UNICAST))
 				goto out;
 
-			if (cfg->fc_table)
+			if (cfg->fc_table) {
 				grt = ip6_nh_lookup_table(net, cfg, gw_addr);
 
+				if (grt) {
+					if (grt->rt6i_flags & RTF_GATEWAY ||
+					    (dev && dev != grt->dst.dev)) {
+						ip6_rt_put(grt);
+						grt = NULL;
+					}
+				}
+			}
+
 			if (!grt)
 				grt = rt6_lookup(net, gw_addr, NULL,
 						 cfg->fc_ifindex, 1);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv6/xfrm6_input.c linux-libre-4.8-rc8-gnu/net/ipv6/xfrm6_input.c
--- linux-libre-4.8-rc7-gnu/net/ipv6/xfrm6_input.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv6/xfrm6_input.c	2016-09-25 21:47:13.000000000 -0400
@@ -21,9 +21,10 @@ int xfrm6_extract_input(struct xfrm_stat
 	return xfrm6_extract_header(skb);
 }
 
-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
+		  struct ip6_tnl *t)
 {
-	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
+	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
 	XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
 	return xfrm_input(skb, nexthdr, spi, 0);
@@ -49,13 +50,18 @@ int xfrm6_transport_finish(struct sk_buf
 	return -1;
 }
 
-int xfrm6_rcv(struct sk_buff *skb)
+int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
 {
 	return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
-			     0);
+			     0, t);
 }
-EXPORT_SYMBOL(xfrm6_rcv);
+EXPORT_SYMBOL(xfrm6_rcv_tnl);
 
+int xfrm6_rcv(struct sk_buff *skb)
+{
+	return xfrm6_rcv_tnl(skb, NULL);
+}
+EXPORT_SYMBOL(xfrm6_rcv);
 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 		     xfrm_address_t *saddr, u8 proto)
 {
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/ipv6/xfrm6_tunnel.c linux-libre-4.8-rc8-gnu/net/ipv6/xfrm6_tunnel.c
--- linux-libre-4.8-rc7-gnu/net/ipv6/xfrm6_tunnel.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/ipv6/xfrm6_tunnel.c	2016-09-25 21:47:13.000000000 -0400
@@ -236,7 +236,7 @@ static int xfrm6_tunnel_rcv(struct sk_bu
 	__be32 spi;
 
 	spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr);
-	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi);
+	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL);
 }
 
 static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/irda/af_irda.c linux-libre-4.8-rc8-gnu/net/irda/af_irda.c
--- linux-libre-4.8-rc7-gnu/net/irda/af_irda.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/irda/af_irda.c	2016-09-25 21:47:13.000000000 -0400
@@ -832,7 +832,7 @@ static int irda_accept(struct socket *so
 	struct sock *sk = sock->sk;
 	struct irda_sock *new, *self = irda_sk(sk);
 	struct sock *newsk;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
 	int err;
 
 	err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
@@ -900,7 +900,6 @@ static int irda_accept(struct socket *so
 	err = -EPERM; /* value does not seem to make sense. -arnd */
 	if (!new->tsap) {
 		pr_debug("%s(), dup failed!\n", __func__);
-		kfree_skb(skb);
 		goto out;
 	}
 
@@ -919,7 +918,6 @@ static int irda_accept(struct socket *so
 	/* Clean up the original one to keep it in listen state */
 	irttp_listen(self->tsap);
 
-	kfree_skb(skb);
 	sk->sk_ack_backlog--;
 
 	newsock->state = SS_CONNECTED;
@@ -927,6 +925,7 @@ static int irda_accept(struct socket *so
 	irda_connect_response(new);
 	err = 0;
 out:
+	kfree_skb(skb);
 	release_sock(sk);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/mac80211/agg-rx.c linux-libre-4.8-rc8-gnu/net/mac80211/agg-rx.c
--- linux-libre-4.8-rc7-gnu/net/mac80211/agg-rx.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/mac80211/agg-rx.c	2016-09-25 21:47:13.000000000 -0400
@@ -261,10 +261,16 @@ void __ieee80211_start_rx_ba_session(str
 		.timeout = timeout,
 		.ssn = start_seq_num,
 	};
-
 	int i, ret = -EOPNOTSUPP;
 	u16 status = WLAN_STATUS_REQUEST_DECLINED;
 
+	if (tid >= IEEE80211_FIRST_TSPEC_TSID) {
+		ht_dbg(sta->sdata,
+		       "STA %pM requests BA session on unsupported tid %d\n",
+		       sta->sta.addr, tid);
+		goto end_no_lock;
+	}
+
 	if (!sta->sta.ht_cap.ht_supported) {
 		ht_dbg(sta->sdata,
 		       "STA %pM erroneously requests BA session on tid %d w/o QoS\n",
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/mac80211/agg-tx.c linux-libre-4.8-rc8-gnu/net/mac80211/agg-tx.c
--- linux-libre-4.8-rc7-gnu/net/mac80211/agg-tx.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/mac80211/agg-tx.c	2016-09-25 21:47:13.000000000 -0400
@@ -584,6 +584,9 @@ int ieee80211_start_tx_ba_session(struct
 	    ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW))
 		return -EINVAL;
 
+	if (WARN_ON(tid >= IEEE80211_FIRST_TSPEC_TSID))
+		return -EINVAL;
+
 	ht_dbg(sdata, "Open BA session requested for %pM tid %u\n",
 	       pubsta->addr, tid);
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/mac80211/mesh_hwmp.c linux-libre-4.8-rc8-gnu/net/mac80211/mesh_hwmp.c
--- linux-libre-4.8-rc7-gnu/net/mac80211/mesh_hwmp.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/mac80211/mesh_hwmp.c	2016-09-25 21:47:13.000000000 -0400
@@ -746,6 +746,7 @@ static void hwmp_perr_frame_process(stru
 		sta = next_hop_deref_protected(mpath);
 		if (mpath->flags & MESH_PATH_ACTIVE &&
 		    ether_addr_equal(ta, sta->sta.addr) &&
+		    !(mpath->flags & MESH_PATH_FIXED) &&
 		    (!(mpath->flags & MESH_PATH_SN_VALID) ||
 		    SN_GT(target_sn, mpath->sn)  || target_sn == 0)) {
 			mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -1012,7 +1013,7 @@ void mesh_path_start_discovery(struct ie
 		goto enddiscovery;
 
 	spin_lock_bh(&mpath->state_lock);
-	if (mpath->flags & MESH_PATH_DELETED) {
+	if (mpath->flags & (MESH_PATH_DELETED | MESH_PATH_FIXED)) {
 		spin_unlock_bh(&mpath->state_lock);
 		goto enddiscovery;
 	}
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/mac80211/mesh_pathtbl.c linux-libre-4.8-rc8-gnu/net/mac80211/mesh_pathtbl.c
--- linux-libre-4.8-rc7-gnu/net/mac80211/mesh_pathtbl.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/mac80211/mesh_pathtbl.c	2016-09-25 21:47:13.000000000 -0400
@@ -826,7 +826,7 @@ void mesh_path_fix_nexthop(struct mesh_p
 	mpath->metric = 0;
 	mpath->hop_count = 0;
 	mpath->exp_time = 0;
-	mpath->flags |= MESH_PATH_FIXED;
+	mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
 	mesh_path_activate(mpath);
 	spin_unlock_bh(&mpath->state_lock);
 	mesh_path_tx_pending(mpath);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/mac80211/sta_info.c linux-libre-4.8-rc8-gnu/net/mac80211/sta_info.c
--- linux-libre-4.8-rc7-gnu/net/mac80211/sta_info.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/mac80211/sta_info.c	2016-09-25 21:47:13.000000000 -0400
@@ -1616,7 +1616,6 @@ ieee80211_sta_ps_deliver_response(struct
 
 		sta_info_recalc_tim(sta);
 	} else {
-		unsigned long tids = sta->txq_buffered_tids & driver_release_tids;
 		int tid;
 
 		/*
@@ -1648,7 +1647,8 @@ ieee80211_sta_ps_deliver_response(struct
 		for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
 			struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
 
-			if (!(tids & BIT(tid)) || txqi->tin.backlog_packets)
+			if (!(driver_release_tids & BIT(tid)) ||
+			    txqi->tin.backlog_packets)
 				continue;
 
 			sta_info_recalc_tim(sta);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/mac80211/tx.c linux-libre-4.8-rc8-gnu/net/mac80211/tx.c
--- linux-libre-4.8-rc7-gnu/net/mac80211/tx.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/mac80211/tx.c	2016-09-25 21:47:13.000000000 -0400
@@ -796,6 +796,36 @@ static __le16 ieee80211_tx_next_seq(stru
 	return ret;
 }
 
+static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
+					  struct ieee80211_vif *vif,
+					  struct ieee80211_sta *pubsta,
+					  struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_txq *txq = NULL;
+
+	if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
+	    (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
+		return NULL;
+
+	if (!ieee80211_is_data(hdr->frame_control))
+		return NULL;
+
+	if (pubsta) {
+		u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+
+		txq = pubsta->txq[tid];
+	} else if (vif) {
+		txq = vif->txq;
+	}
+
+	if (!txq)
+		return NULL;
+
+	return to_txq_info(txq);
+}
+
 static ieee80211_tx_result debug_noinline
 ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
 {
@@ -853,7 +883,8 @@ ieee80211_tx_h_sequence(struct ieee80211
 	tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
 	tx->sta->tx_stats.msdu[tid]++;
 
-	if (!tx->sta->sta.txq[0])
+	if (!ieee80211_get_txq(tx->local, info->control.vif, &tx->sta->sta,
+			       tx->skb))
 		hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
 
 	return TX_CONTINUE;
@@ -1243,36 +1274,6 @@ ieee80211_tx_prepare(struct ieee80211_su
 	return TX_CONTINUE;
 }
 
-static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
-					  struct ieee80211_vif *vif,
-					  struct ieee80211_sta *pubsta,
-					  struct sk_buff *skb)
-{
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_txq *txq = NULL;
-
-	if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
-	    (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
-		return NULL;
-
-	if (!ieee80211_is_data(hdr->frame_control))
-		return NULL;
-
-	if (pubsta) {
-		u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
-
-		txq = pubsta->txq[tid];
-	} else if (vif) {
-		txq = vif->txq;
-	}
-
-	if (!txq)
-		return NULL;
-
-	return to_txq_info(txq);
-}
-
 static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
 {
 	IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
@@ -1514,8 +1515,12 @@ out:
 	spin_unlock_bh(&fq->lock);
 
 	if (skb && skb_has_frag_list(skb) &&
-	    !ieee80211_hw_check(&local->hw, TX_FRAG_LIST))
-		skb_linearize(skb);
+	    !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
+		if (skb_linearize(skb)) {
+			ieee80211_free_txskb(&local->hw, skb);
+			return NULL;
+		}
+	}
 
 	return skb;
 }
@@ -3264,7 +3269,7 @@ static bool ieee80211_xmit_fast(struct i
 
 	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
 		*ieee80211_get_qos_ctl(hdr) = tid;
-		if (!sta->sta.txq[0])
+		if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb))
 			hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
 	} else {
 		info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/netfilter/nf_conntrack_core.c linux-libre-4.8-rc8-gnu/net/netfilter/nf_conntrack_core.c
--- linux-libre-4.8-rc7-gnu/net/netfilter/nf_conntrack_core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/netfilter/nf_conntrack_core.c	2016-09-25 21:47:13.000000000 -0400
@@ -1035,9 +1035,9 @@ init_conntrack(struct net *net, struct n
 	if (IS_ERR(ct))
 		return (struct nf_conntrack_tuple_hash *)ct;
 
-	if (tmpl && nfct_synproxy(tmpl)) {
-		nfct_seqadj_ext_add(ct);
-		nfct_synproxy_ext_add(ct);
+	if (!nf_ct_add_synproxy(ct, tmpl)) {
+		nf_conntrack_free(ct);
+		return ERR_PTR(-ENOMEM);
 	}
 
 	timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/netfilter/nf_nat_core.c linux-libre-4.8-rc8-gnu/net/netfilter/nf_nat_core.c
--- linux-libre-4.8-rc7-gnu/net/netfilter/nf_nat_core.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/netfilter/nf_nat_core.c	2016-09-25 21:47:13.000000000 -0400
@@ -441,7 +441,8 @@ nf_nat_setup_info(struct nf_conn *ct,
 			ct->status |= IPS_DST_NAT;
 
 		if (nfct_help(ct))
-			nfct_seqadj_ext_add(ct);
+			if (!nfct_seqadj_ext_add(ct))
+				return NF_DROP;
 	}
 
 	if (maniptype == NF_NAT_MANIP_SRC) {
@@ -807,7 +808,7 @@ nfnetlink_parse_nat_setup(struct nf_conn
 	if (err < 0)
 		return err;
 
-	return nf_nat_setup_info(ct, &range, manip);
+	return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0;
 }
 #else
 static int
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/netfilter/nf_tables_trace.c linux-libre-4.8-rc8-gnu/net/netfilter/nf_tables_trace.c
--- linux-libre-4.8-rc7-gnu/net/netfilter/nf_tables_trace.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/netfilter/nf_tables_trace.c	2016-09-25 21:47:13.000000000 -0400
@@ -237,7 +237,7 @@ void nft_trace_notify(struct nft_tracein
 		break;
 	case NFT_TRACETYPE_POLICY:
 		if (nla_put_be32(skb, NFTA_TRACE_POLICY,
-				 info->basechain->policy))
+				 htonl(info->basechain->policy)))
 			goto nla_put_failure;
 		break;
 	}
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/sctp/input.c linux-libre-4.8-rc8-gnu/net/sctp/input.c
--- linux-libre-4.8-rc7-gnu/net/sctp/input.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/sctp/input.c	2016-09-25 21:47:13.000000000 -0400
@@ -796,27 +796,34 @@ struct sctp_hash_cmp_arg {
 static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg,
 				const void *ptr)
 {
+	struct sctp_transport *t = (struct sctp_transport *)ptr;
 	const struct sctp_hash_cmp_arg *x = arg->key;
-	const struct sctp_transport *t = ptr;
-	struct sctp_association *asoc = t->asoc;
-	const struct net *net = x->net;
+	struct sctp_association *asoc;
+	int err = 1;
 
 	if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr))
-		return 1;
-	if (!net_eq(sock_net(asoc->base.sk), net))
-		return 1;
+		return err;
+	if (!sctp_transport_hold(t))
+		return err;
+
+	asoc = t->asoc;
+	if (!net_eq(sock_net(asoc->base.sk), x->net))
+		goto out;
 	if (x->ep) {
 		if (x->ep != asoc->ep)
-			return 1;
+			goto out;
 	} else {
 		if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port))
-			return 1;
+			goto out;
 		if (!sctp_bind_addr_match(&asoc->base.bind_addr,
 					  x->laddr, sctp_sk(asoc->base.sk)))
-			return 1;
+			goto out;
 	}
 
-	return 0;
+	err = 0;
+out:
+	sctp_transport_put(t);
+	return err;
 }
 
 static inline u32 sctp_hash_obj(const void *data, u32 len, u32 seed)
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/wireless/nl80211.c linux-libre-4.8-rc8-gnu/net/wireless/nl80211.c
--- linux-libre-4.8-rc7-gnu/net/wireless/nl80211.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/wireless/nl80211.c	2016-09-25 21:47:13.000000000 -0400
@@ -6978,7 +6978,7 @@ static int nl80211_channel_switch(struct
 
 		params.n_counter_offsets_presp = len / sizeof(u16);
 		if (rdev->wiphy.max_num_csa_counters &&
-		    (params.n_counter_offsets_beacon >
+		    (params.n_counter_offsets_presp >
 		     rdev->wiphy.max_num_csa_counters))
 			return -EINVAL;
 
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/xfrm/xfrm_state.c linux-libre-4.8-rc8-gnu/net/xfrm/xfrm_state.c
--- linux-libre-4.8-rc7-gnu/net/xfrm/xfrm_state.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/xfrm/xfrm_state.c	2016-09-25 21:47:13.000000000 -0400
@@ -332,6 +332,7 @@ static void xfrm_state_gc_destroy(struct
 {
 	tasklet_hrtimer_cancel(&x->mtimer);
 	del_timer_sync(&x->rtimer);
+	kfree(x->aead);
 	kfree(x->aalg);
 	kfree(x->ealg);
 	kfree(x->calg);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/net/xfrm/xfrm_user.c linux-libre-4.8-rc8-gnu/net/xfrm/xfrm_user.c
--- linux-libre-4.8-rc7-gnu/net/xfrm/xfrm_user.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/net/xfrm/xfrm_user.c	2016-09-25 21:47:13.000000000 -0400
@@ -581,9 +581,12 @@ static struct xfrm_state *xfrm_state_con
 	if (err)
 		goto error;
 
-	if (attrs[XFRMA_SEC_CTX] &&
-	    security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX])))
-		goto error;
+	if (attrs[XFRMA_SEC_CTX]) {
+		err = security_xfrm_state_alloc(x,
+						nla_data(attrs[XFRMA_SEC_CTX]));
+		if (err)
+			goto error;
+	}
 
 	if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn,
 					       attrs[XFRMA_REPLAY_ESN_VAL])))
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/scripts/faddr2line linux-libre-4.8-rc8-gnu/scripts/faddr2line
--- linux-libre-4.8-rc7-gnu/scripts/faddr2line	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.8-rc8-gnu/scripts/faddr2line	2016-09-25 21:47:13.000000000 -0400
@@ -0,0 +1,177 @@
+#!/bin/bash
+#
+# Translate stack dump function offsets.
+#
+# addr2line doesn't work with KASLR addresses.  This works similarly to
+# addr2line, but instead takes the 'func+0x123' format as input:
+#
+#   $ ./scripts/faddr2line ~/k/vmlinux meminfo_proc_show+0x5/0x568
+#   meminfo_proc_show+0x5/0x568:
+#   meminfo_proc_show at fs/proc/meminfo.c:27
+#
+# If the address is part of an inlined function, the full inline call chain is
+# printed:
+#
+#   $ ./scripts/faddr2line ~/k/vmlinux native_write_msr+0x6/0x27
+#   native_write_msr+0x6/0x27:
+#   arch_static_branch at arch/x86/include/asm/msr.h:121
+#    (inlined by) static_key_false at include/linux/jump_label.h:125
+#    (inlined by) native_write_msr at arch/x86/include/asm/msr.h:125
+#
+# The function size after the '/' in the input is optional, but recommended.
+# It's used to help disambiguate any duplicate symbol names, which can occur
+# rarely.  If the size is omitted for a duplicate symbol then it's possible for
+# multiple code sites to be printed:
+#
+#   $ ./scripts/faddr2line ~/k/vmlinux raw_ioctl+0x5
+#   raw_ioctl+0x5/0x20:
+#   raw_ioctl at drivers/char/raw.c:122
+#
+#   raw_ioctl+0x5/0xb1:
+#   raw_ioctl at net/ipv4/raw.c:876
+#
+# Multiple addresses can be specified on a single command line:
+#
+#   $ ./scripts/faddr2line ~/k/vmlinux type_show+0x10/45 free_reserved_area+0x90
+#   type_show+0x10/0x2d:
+#   type_show at drivers/video/backlight/backlight.c:213
+#
+#   free_reserved_area+0x90/0x123:
+#   free_reserved_area at mm/page_alloc.c:6429 (discriminator 2)
+
+
+set -o errexit
+set -o nounset
+
+command -v awk >/dev/null 2>&1 || die "awk isn't installed"
+command -v readelf >/dev/null 2>&1 || die "readelf isn't installed"
+command -v addr2line >/dev/null 2>&1 || die "addr2line isn't installed"
+
+usage() {
+	echo "usage: faddr2line <object file> <func+offset> <func+offset>..." >&2
+	exit 1
+}
+
+warn() {
+	echo "$1" >&2
+}
+
+die() {
+	echo "ERROR: $1" >&2
+	exit 1
+}
+
+# Try to figure out the source directory prefix so we can remove it from the
+# addr2line output.  HACK ALERT: This assumes that start_kernel() is in
+# kernel/init.c!  This only works for vmlinux.  Otherwise it falls back to
+# printing the absolute path.
+find_dir_prefix() {
+	local objfile=$1
+
+	local start_kernel_addr=$(readelf -sW $objfile | awk '$8 == "start_kernel" {printf "0x%s", $2}')
+	[[ -z $start_kernel_addr ]] && return
+
+	local file_line=$(addr2line -e $objfile $start_kernel_addr)
+	[[ -z $file_line ]] && return
+
+	local prefix=${file_line%init/main.c:*}
+	if [[ -z $prefix ]] || [[ $prefix = $file_line ]]; then
+		return
+	fi
+
+	DIR_PREFIX=$prefix
+	return 0
+}
+
+__faddr2line() {
+	local objfile=$1
+	local func_addr=$2
+	local dir_prefix=$3
+	local print_warnings=$4
+
+	local func=${func_addr%+*}
+	local offset=${func_addr#*+}
+	offset=${offset%/*}
+	local size=
+	[[ $func_addr =~ "/" ]] && size=${func_addr#*/}
+
+	if [[ -z $func ]] || [[ -z $offset ]] || [[ $func = $func_addr ]]; then
+		warn "bad func+offset $func_addr"
+		DONE=1
+		return
+	fi
+
+	# Go through each of the object's symbols which match the func name.
+	# In rare cases there might be duplicates.
+	while read symbol; do
+		local fields=($symbol)
+		local sym_base=0x${fields[1]}
+		local sym_size=${fields[2]}
+		local sym_type=${fields[3]}
+
+		# calculate the address
+		local addr=$(($sym_base + $offset))
+		if [[ -z $addr ]] || [[ $addr = 0 ]]; then
+			warn "bad address: $sym_base + $offset"
+			DONE=1
+			return
+		fi
+		local hexaddr=0x$(printf %x $addr)
+
+		# weed out non-function symbols
+		if [[ $sym_type != "FUNC" ]]; then
+			[[ $print_warnings = 1 ]] &&
+				echo "skipping $func address at $hexaddr due to non-function symbol"
+			continue
+		fi
+
+		# if the user provided a size, make sure it matches the symbol's size
+		if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then
+			[[ $print_warnings = 1 ]] &&
+				echo "skipping $func address at $hexaddr due to size mismatch ($size != $sym_size)"
+			continue;
+		fi
+
+		# make sure the provided offset is within the symbol's range
+		if [[ $offset -gt $sym_size ]]; then
+			[[ $print_warnings = 1 ]] &&
+				echo "skipping $func address at $hexaddr due to size mismatch ($offset > $sym_size)"
+			continue
+		fi
+
+		# separate multiple entries with a blank line
+		[[ $FIRST = 0 ]] && echo
+		FIRST=0
+
+		local hexsize=0x$(printf %x $sym_size)
+		echo "$func+$offset/$hexsize:"
+		addr2line -fpie $objfile $hexaddr | sed "s; $dir_prefix\(\./\)*; ;"
+		DONE=1
+
+	done < <(readelf -sW $objfile | awk -v f=$func '$8 == f {print}')
+}
+
+[[ $# -lt 2 ]] && usage
+
+objfile=$1
+[[ ! -f $objfile ]] && die "can't find objfile $objfile"
+shift
+
+DIR_PREFIX=supercalifragilisticexpialidocious
+find_dir_prefix $objfile
+
+FIRST=1
+while [[ $# -gt 0 ]]; do
+	func_addr=$1
+	shift
+
+	# print any matches found
+	DONE=0
+	__faddr2line $objfile $func_addr $DIR_PREFIX 0
+
+	# if no match was found, print warnings
+	if [[ $DONE = 0 ]]; then
+		__faddr2line $objfile $func_addr $DIR_PREFIX 1
+		warn "no match for $func_addr"
+	fi
+done
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/security/keys/encrypted-keys/encrypted.c linux-libre-4.8-rc8-gnu/security/keys/encrypted-keys/encrypted.c
--- linux-libre-4.8-rc7-gnu/security/keys/encrypted-keys/encrypted.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/security/keys/encrypted-keys/encrypted.c	2016-09-25 21:47:13.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/rcupdate.h>
 #include <linux/scatterlist.h>
 #include <linux/ctype.h>
+#include <crypto/aes.h>
 #include <crypto/hash.h>
 #include <crypto/sha.h>
 #include <crypto/skcipher.h>
@@ -478,6 +479,7 @@ static int derived_key_encrypt(struct en
 	struct crypto_skcipher *tfm;
 	struct skcipher_request *req;
 	unsigned int encrypted_datalen;
+	u8 iv[AES_BLOCK_SIZE];
 	unsigned int padlen;
 	char pad[16];
 	int ret;
@@ -500,8 +502,8 @@ static int derived_key_encrypt(struct en
 	sg_init_table(sg_out, 1);
 	sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen);
 
-	skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen,
-				   epayload->iv);
+	memcpy(iv, epayload->iv, sizeof(iv));
+	skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv);
 	ret = crypto_skcipher_encrypt(req);
 	tfm = crypto_skcipher_reqtfm(req);
 	skcipher_request_free(req);
@@ -581,6 +583,7 @@ static int derived_key_decrypt(struct en
 	struct crypto_skcipher *tfm;
 	struct skcipher_request *req;
 	unsigned int encrypted_datalen;
+	u8 iv[AES_BLOCK_SIZE];
 	char pad[16];
 	int ret;
 
@@ -599,8 +602,8 @@ static int derived_key_decrypt(struct en
 		   epayload->decrypted_datalen);
 	sg_set_buf(&sg_out[1], pad, sizeof pad);
 
-	skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen,
-				   epayload->iv);
+	memcpy(iv, epayload->iv, sizeof(iv));
+	skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv);
 	ret = crypto_skcipher_decrypt(req);
 	tfm = crypto_skcipher_reqtfm(req);
 	skcipher_request_free(req);
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/tools/testing/radix-tree/Makefile linux-libre-4.8-rc8-gnu/tools/testing/radix-tree/Makefile
--- linux-libre-4.8-rc7-gnu/tools/testing/radix-tree/Makefile	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/tools/testing/radix-tree/Makefile	2016-09-25 21:47:13.000000000 -0400
@@ -1,5 +1,5 @@
 
-CFLAGS += -I. -g -Wall -D_LGPL_SOURCE
+CFLAGS += -I. -g -O2 -Wall -D_LGPL_SOURCE
 LDFLAGS += -lpthread -lurcu
 TARGETS = main
 OFILES = main.o radix-tree.o linux.o test.o tag_check.o find_next_bit.o \
diff -druNp --no-dereference linux-libre-4.8-rc7-gnu/tools/testing/radix-tree/multiorder.c linux-libre-4.8-rc8-gnu/tools/testing/radix-tree/multiorder.c
--- linux-libre-4.8-rc7-gnu/tools/testing/radix-tree/multiorder.c	2016-09-18 20:27:41.000000000 -0400
+++ linux-libre-4.8-rc8-gnu/tools/testing/radix-tree/multiorder.c	2016-09-25 21:47:13.000000000 -0400
@@ -124,6 +124,8 @@ static void multiorder_check(unsigned lo
 	unsigned long i;
 	unsigned long min = index & ~((1UL << order) - 1);
 	unsigned long max = min + (1UL << order);
+	void **slot;
+	struct item *item2 = item_create(min);
 	RADIX_TREE(tree, GFP_KERNEL);
 
 	printf("Multiorder index %ld, order %d\n", index, order);
@@ -139,13 +141,19 @@ static void multiorder_check(unsigned lo
 		item_check_absent(&tree, i);
 	for (i = max; i < 2*max; i++)
 		item_check_absent(&tree, i);
+	for (i = min; i < max; i++)
+		assert(radix_tree_insert(&tree, i, item2) == -EEXIST);
+
+	slot = radix_tree_lookup_slot(&tree, index);
+	free(*slot);
+	radix_tree_replace_slot(slot, item2);
 	for (i = min; i < max; i++) {
-		static void *entry = (void *)
-					(0xA0 | RADIX_TREE_EXCEPTIONAL_ENTRY);
-		assert(radix_tree_insert(&tree, i, entry) == -EEXIST);
+		struct item *item = item_lookup(&tree, i);
+		assert(item != 0);
+		assert(item->index == min);
 	}
 
-	assert(item_delete(&tree, index) != 0);
+	assert(item_delete(&tree, min) != 0);
 
 	for (i = 0; i < 2*max; i++)
 		item_check_absent(&tree, i);
