diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/arc/include/asm/processor.h linux-libre-4.12-gnu/arch/arc/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/arc/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/arc/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -86,8 +86,6 @@ struct task_struct;
 #define TSK_K_BLINK(tsk)	TSK_K_REG(tsk, 4)
 #define TSK_K_FP(tsk)		TSK_K_REG(tsk, 0)
 
-#define thread_saved_pc(tsk)	TSK_K_BLINK(tsk)
-
 extern void start_thread(struct pt_regs * regs, unsigned long pc,
 			 unsigned long usp);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/arm/boot/compressed/efi-header.S linux-libre-4.12-gnu/arch/arm/boot/compressed/efi-header.S
--- linux-libre-4.12-rc7-gnu/arch/arm/boot/compressed/efi-header.S	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/arm/boot/compressed/efi-header.S	2017-07-02 19:07:02.000000000 -0400
@@ -17,7 +17,8 @@
 		@ there.
 		.inst	'M' | ('Z' << 8) | (0x1310 << 16)   @ tstne r0, #0x4d000
 #else
-		W(mov)	r0, r0
+ AR_CLASS(	mov	r0, r0		)
+  M_CLASS(	nop.w			)
 #endif
 		.endm
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/arm/Kconfig linux-libre-4.12-gnu/arch/arm/Kconfig
--- linux-libre-4.12-rc7-gnu/arch/arm/Kconfig	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/arm/Kconfig	2017-07-02 19:07:02.000000000 -0400
@@ -1416,6 +1416,7 @@ choice
 	config VMSPLIT_3G
 		bool "3G/1G user/kernel split"
 	config VMSPLIT_3G_OPT
+		depends on !ARM_LPAE
 		bool "3G/1G user/kernel split (for full 1G low memory)"
 	config VMSPLIT_2G
 		bool "2G/2G user/kernel split"
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/arm/kernel/setup.c linux-libre-4.12-gnu/arch/arm/kernel/setup.c
--- linux-libre-4.12-rc7-gnu/arch/arm/kernel/setup.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/arm/kernel/setup.c	2017-07-02 19:07:02.000000000 -0400
@@ -315,7 +315,7 @@ static void __init cacheid_init(void)
 	if (arch >= CPU_ARCH_ARMv6) {
 		unsigned int cachetype = read_cpuid_cachetype();
 
-		if ((arch == CPU_ARCH_ARMv7M) && !cachetype) {
+		if ((arch == CPU_ARCH_ARMv7M) && !(cachetype & 0xf000f)) {
 			cacheid = 0;
 		} else if ((cachetype & (7 << 29)) == 4 << 29) {
 			/* ARMv7 register format */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/arm/mm/mmu.c linux-libre-4.12-gnu/arch/arm/mm/mmu.c
--- linux-libre-4.12-rc7-gnu/arch/arm/mm/mmu.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/arm/mm/mmu.c	2017-07-02 19:07:02.000000000 -0400
@@ -1218,15 +1218,15 @@ void __init adjust_lowmem_bounds(void)
 
 	high_memory = __va(arm_lowmem_limit - 1) + 1;
 
+	if (!memblock_limit)
+		memblock_limit = arm_lowmem_limit;
+
 	/*
 	 * Round the memblock limit down to a pmd size.  This
 	 * helps to ensure that we will allocate memory from the
 	 * last full pmd, which should be mapped.
 	 */
-	if (memblock_limit)
-		memblock_limit = round_down(memblock_limit, PMD_SIZE);
-	if (!memblock_limit)
-		memblock_limit = arm_lowmem_limit;
+	memblock_limit = round_down(memblock_limit, PMD_SIZE);
 
 	if (!IS_ENABLED(CONFIG_HIGHMEM) || cache_is_vipt_aliasing()) {
 		if (memblock_end_of_DRAM() > arm_lowmem_limit) {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/blackfin/include/asm/processor.h linux-libre-4.12-gnu/arch/blackfin/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/blackfin/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/blackfin/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -75,11 +75,6 @@ static inline void release_thread(struct
 {
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-#define thread_saved_pc(tsk)	(tsk->thread.pc)
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define	KSTK_EIP(tsk)							\
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/c6x/include/asm/processor.h linux-libre-4.12-gnu/arch/c6x/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/c6x/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/c6x/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -96,11 +96,6 @@ static inline void release_thread(struct
 #define release_segments(mm)		do { } while (0)
 
 /*
- * saved PC of a blocked thread.
- */
-#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc)
-
-/*
  * saved kernel SP and DP of a blocked thread.
  */
 #ifdef _BIG_ENDIAN
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/cris/arch-v10/kernel/process.c linux-libre-4.12-gnu/arch/cris/arch-v10/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/cris/arch-v10/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/cris/arch-v10/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -69,14 +69,6 @@ void hard_reset_now (void)
 	while(1) /* waiting for RETRIBUTION! */ ;
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-	return task_pt_regs(t)->irp;
-}
-
 /* setup the child's kernel stack with a pt_regs and switch_stack on it.
  * it will be un-nested during _resume and _ret_from_sys_call when the
  * new thread is scheduled.
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/cris/arch-v32/kernel/process.c linux-libre-4.12-gnu/arch/cris/arch-v32/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/cris/arch-v32/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/cris/arch-v32/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -85,14 +85,6 @@ hard_reset_now(void)
 }
 
 /*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-	return task_pt_regs(t)->erp;
-}
-
-/*
  * Setup the child's kernel stack with a pt_regs and call switch_stack() on it.
  * It will be unnested during _resume and _ret_from_sys_call when the new thread
  * is scheduled.
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/cris/include/asm/processor.h linux-libre-4.12-gnu/arch/cris/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/cris/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/cris/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -52,8 +52,6 @@ unsigned long get_wchan(struct task_stru
 
 #define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 /* Free all resources held by a thread. */
 static inline void release_thread(struct task_struct *dead_task)
 {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/frv/include/asm/processor.h linux-libre-4.12-gnu/arch/frv/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/frv/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/frv/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -96,11 +96,6 @@ extern asmlinkage void *restore_user_reg
 #define release_segments(mm)		do { } while (0)
 #define forget_segments()		do { } while (0)
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define	KSTK_EIP(tsk)	((tsk)->thread.frame0->pc)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/frv/kernel/process.c linux-libre-4.12-gnu/arch/frv/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/frv/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/frv/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -198,15 +198,6 @@ unsigned long get_wchan(struct task_stru
 	return 0;
 }
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	/* Check whether the thread is blocked in resume() */
-	if (in_sched_functions(tsk->thread.pc))
-		return ((unsigned long *)tsk->thread.fp)[2];
-	else
-		return tsk->thread.pc;
-}
-
 int elf_check_arch(const struct elf32_hdr *hdr)
 {
 	unsigned long hsr0 = __get_HSR(0);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/h8300/include/asm/processor.h linux-libre-4.12-gnu/arch/h8300/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/h8300/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/h8300/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -110,10 +110,6 @@ static inline void release_thread(struct
 {
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk);
 unsigned long get_wchan(struct task_struct *p);
 
 #define	KSTK_EIP(tsk)	\
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/h8300/kernel/process.c linux-libre-4.12-gnu/arch/h8300/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/h8300/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/h8300/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -129,11 +129,6 @@ int copy_thread(unsigned long clone_flag
 	return 0;
 }
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	return ((struct pt_regs *)tsk->thread.esp0)->pc;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	unsigned long fp, pc;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/hexagon/include/asm/processor.h linux-libre-4.12-gnu/arch/hexagon/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/hexagon/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/hexagon/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -33,9 +33,6 @@
 /*  task_struct, defined elsewhere, is the "process descriptor" */
 struct task_struct;
 
-/*  this is defined in arch/process.c  */
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
 
 /*
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/hexagon/kernel/process.c linux-libre-4.12-gnu/arch/hexagon/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/hexagon/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/hexagon/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -61,14 +61,6 @@ void arch_cpu_idle(void)
 }
 
 /*
- *  Return saved PC of a blocked thread
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	return 0;
-}
-
-/*
  * Copy architecture-specific thread state
  */
 int copy_thread(unsigned long clone_flags, unsigned long usp,
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/ia64/include/asm/processor.h linux-libre-4.12-gnu/arch/ia64/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/ia64/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/ia64/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -602,23 +602,6 @@ ia64_set_unat (__u64 *unat, void *spill_
 }
 
 /*
- * Return saved PC of a blocked thread.
- * Note that the only way T can block is through a call to schedule() -> switch_to().
- */
-static inline unsigned long
-thread_saved_pc (struct task_struct *t)
-{
-	struct unw_frame_info info;
-	unsigned long ip;
-
-	unw_init_from_blocked_task(&info, t);
-	if (unw_unwind(&info) < 0)
-		return 0;
-	unw_get_ip(&info, &ip);
-	return ip;
-}
-
-/*
  * Get the current instruction/program counter value.
  */
 #define current_text_addr() \
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/m32r/include/asm/processor.h linux-libre-4.12-gnu/arch/m32r/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/m32r/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/m32r/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -122,8 +122,6 @@ extern void release_thread(struct task_s
 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
 extern void release_segments(struct mm_struct * mm);
 
-extern unsigned long thread_saved_pc(struct task_struct *);
-
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(p, mm)  do { } while (0)
 #define release_segments(mm)  do { } while (0)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/m32r/kernel/process.c linux-libre-4.12-gnu/arch/m32r/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/m32r/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/m32r/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -39,14 +39,6 @@
 
 #include <linux/err.h>
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	return tsk->thread.lr;
-}
-
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/m68k/include/asm/processor.h linux-libre-4.12-gnu/arch/m68k/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/m68k/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/m68k/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -130,8 +130,6 @@ static inline void release_thread(struct
 {
 }
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define	KSTK_EIP(tsk)	\
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/m68k/kernel/process.c linux-libre-4.12-gnu/arch/m68k/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/m68k/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/m68k/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -40,20 +40,6 @@
 asmlinkage void ret_from_fork(void);
 asmlinkage void ret_from_kernel_thread(void);
 
-
-/*
- * Return saved PC from a blocked thread
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
-	/* Check whether the thread is blocked in resume() */
-	if (in_sched_functions(sw->retpc))
-		return ((unsigned long *)sw->a6)[1];
-	else
-		return sw->retpc;
-}
-
 void arch_cpu_idle(void)
 {
 #if defined(MACH_ATARI_ONLY)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/microblaze/include/asm/processor.h linux-libre-4.12-gnu/arch/microblaze/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/microblaze/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/microblaze/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -69,8 +69,6 @@ static inline void release_thread(struct
 {
 }
 
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 extern unsigned long get_wchan(struct task_struct *p);
 
 # define KSTK_EIP(tsk)	(0)
@@ -121,10 +119,6 @@ static inline void release_thread(struct
 {
 }
 
-/* Return saved (kernel) PC of a blocked thread.  */
-#  define thread_saved_pc(tsk)	\
-	((tsk)->thread.regs ? (tsk)->thread.regs->r15 : 0)
-
 unsigned long get_wchan(struct task_struct *p);
 
 /* The size allocated for kernel stacks. This _must_ be a power of two! */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/microblaze/kernel/process.c linux-libre-4.12-gnu/arch/microblaze/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/microblaze/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/microblaze/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -119,23 +119,6 @@ int copy_thread(unsigned long clone_flag
 	return 0;
 }
 
-#ifndef CONFIG_MMU
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	struct cpu_context *ctx =
-		&(((struct thread_info *)(tsk->stack))->cpu_context);
-
-	/* Check whether the thread is blocked in resume() */
-	if (in_sched_functions(ctx->r15))
-		return (unsigned long)ctx->r15;
-	else
-		return ctx->r14;
-}
-#endif
-
 unsigned long get_wchan(struct task_struct *p)
 {
 /* TBD (used by procfs) */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/kernel/entry.S linux-libre-4.12-gnu/arch/mips/kernel/entry.S
--- linux-libre-4.12-rc7-gnu/arch/mips/kernel/entry.S	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/kernel/entry.S	2017-07-02 19:07:02.000000000 -0400
@@ -11,6 +11,7 @@
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/compiler.h>
+#include <asm/irqflags.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
@@ -119,6 +120,7 @@ work_pending:
 	andi	t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
 	beqz	t0, work_notifysig
 work_resched:
+	TRACE_IRQS_OFF
 	jal	schedule
 
 	local_irq_disable		# make sure need_resched and
@@ -155,6 +157,7 @@ syscall_exit_work:
 	beqz	t0, work_pending	# trace bit set?
 	local_irq_enable		# could let syscall_trace_leave()
 					# call schedule() instead
+	TRACE_IRQS_ON
 	move	a0, sp
 	jal	syscall_trace_leave
 	b	resume_userspace
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/kernel/head.S linux-libre-4.12-gnu/arch/mips/kernel/head.S
--- linux-libre-4.12-rc7-gnu/arch/mips/kernel/head.S	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/kernel/head.S	2017-07-02 19:07:02.000000000 -0400
@@ -106,8 +106,8 @@ NESTED(kernel_entry, 16, sp)			# kernel
 	beq		t0, t1, dtb_found
 #endif
 	li		t1, -2
-	beq		a0, t1, dtb_found
 	move		t2, a1
+	beq		a0, t1, dtb_found
 
 	li		t2, 0
 dtb_found:
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/kernel/pm-cps.c linux-libre-4.12-gnu/arch/mips/kernel/pm-cps.c
--- linux-libre-4.12-rc7-gnu/arch/mips/kernel/pm-cps.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/kernel/pm-cps.c	2017-07-02 19:07:02.000000000 -0400
@@ -56,7 +56,6 @@ DECLARE_BITMAP(state_support, CPS_PM_STA
  * state. Actually per-core rather than per-CPU.
  */
 static DEFINE_PER_CPU_ALIGNED(u32*, ready_count);
-static DEFINE_PER_CPU_ALIGNED(void*, ready_count_alloc);
 
 /* Indicates online CPUs coupled with the current CPU */
 static DEFINE_PER_CPU_ALIGNED(cpumask_t, online_coupled);
@@ -642,7 +641,6 @@ static int cps_pm_online_cpu(unsigned in
 {
 	enum cps_pm_state state;
 	unsigned core = cpu_data[cpu].core;
-	unsigned dlinesz = cpu_data[cpu].dcache.linesz;
 	void *entry_fn, *core_rc;
 
 	for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
@@ -662,16 +660,11 @@ static int cps_pm_online_cpu(unsigned in
 	}
 
 	if (!per_cpu(ready_count, core)) {
-		core_rc = kmalloc(dlinesz * 2, GFP_KERNEL);
+		core_rc = kmalloc(sizeof(u32), GFP_KERNEL);
 		if (!core_rc) {
 			pr_err("Failed allocate core %u ready_count\n", core);
 			return -ENOMEM;
 		}
-		per_cpu(ready_count_alloc, core) = core_rc;
-
-		/* Ensure ready_count is aligned to a cacheline boundary */
-		core_rc += dlinesz - 1;
-		core_rc = (void *)((unsigned long)core_rc & ~(dlinesz - 1));
 		per_cpu(ready_count, core) = core_rc;
 	}
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/kernel/traps.c linux-libre-4.12-gnu/arch/mips/kernel/traps.c
--- linux-libre-4.12-rc7-gnu/arch/mips/kernel/traps.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/kernel/traps.c	2017-07-02 19:07:02.000000000 -0400
@@ -201,6 +201,8 @@ void show_stack(struct task_struct *task
 {
 	struct pt_regs regs;
 	mm_segment_t old_fs = get_fs();
+
+	regs.cp0_status = KSU_KERNEL;
 	if (sp) {
 		regs.regs[29] = (unsigned long)sp;
 		regs.regs[31] = 0;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/math-emu/dp_maddf.c linux-libre-4.12-gnu/arch/mips/math-emu/dp_maddf.c
--- linux-libre-4.12-rc7-gnu/arch/mips/math-emu/dp_maddf.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/math-emu/dp_maddf.c	2017-07-02 19:07:02.000000000 -0400
@@ -54,7 +54,7 @@ static union ieee754dp _dp_maddf(union i
 		return ieee754dp_nanxcpt(z);
 	case IEEE754_CLASS_DNORM:
 		DPDNORMZ;
-	/* QNAN is handled separately below */
+	/* QNAN and ZERO cases are handled separately below */
 	}
 
 	switch (CLPAIR(xc, yc)) {
@@ -210,6 +210,9 @@ static union ieee754dp _dp_maddf(union i
 	}
 	assert(rm & (DP_HIDDEN_BIT << 3));
 
+	if (zc == IEEE754_CLASS_ZERO)
+		return ieee754dp_format(rs, re, rm);
+
 	/* And now the addition */
 	assert(zm & DP_HIDDEN_BIT);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/math-emu/sp_maddf.c linux-libre-4.12-gnu/arch/mips/math-emu/sp_maddf.c
--- linux-libre-4.12-rc7-gnu/arch/mips/math-emu/sp_maddf.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/math-emu/sp_maddf.c	2017-07-02 19:07:02.000000000 -0400
@@ -54,7 +54,7 @@ static union ieee754sp _sp_maddf(union i
 		return ieee754sp_nanxcpt(z);
 	case IEEE754_CLASS_DNORM:
 		SPDNORMZ;
-	/* QNAN is handled separately below */
+	/* QNAN and ZERO cases are handled separately below */
 	}
 
 	switch (CLPAIR(xc, yc)) {
@@ -203,6 +203,9 @@ static union ieee754sp _sp_maddf(union i
 	}
 	assert(rm & (SP_HIDDEN_BIT << 3));
 
+	if (zc == IEEE754_CLASS_ZERO)
+		return ieee754sp_format(rs, re, rm);
+
 	/* And now the addition */
 
 	assert(zm & SP_HIDDEN_BIT);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mips/mm/dma-default.c linux-libre-4.12-gnu/arch/mips/mm/dma-default.c
--- linux-libre-4.12-rc7-gnu/arch/mips/mm/dma-default.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mips/mm/dma-default.c	2017-07-02 19:07:02.000000000 -0400
@@ -68,12 +68,25 @@ static inline struct page *dma_addr_to_p
  * systems and only the R10000 and R12000 are used in such systems, the
  * SGI IP28 Indigo² rsp. SGI IP32 aka O2.
  */
-static inline int cpu_needs_post_dma_flush(struct device *dev)
+static inline bool cpu_needs_post_dma_flush(struct device *dev)
 {
-	return !plat_device_is_coherent(dev) &&
-	       (boot_cpu_type() == CPU_R10000 ||
-		boot_cpu_type() == CPU_R12000 ||
-		boot_cpu_type() == CPU_BMIPS5000);
+	if (plat_device_is_coherent(dev))
+		return false;
+
+	switch (boot_cpu_type()) {
+	case CPU_R10000:
+	case CPU_R12000:
+	case CPU_BMIPS5000:
+		return true;
+
+	default:
+		/*
+		 * Presence of MAARs suggests that the CPU supports
+		 * speculatively prefetching data, and therefore requires
+		 * the post-DMA flush/invalidate.
+		 */
+		return cpu_has_maar;
+	}
 }
 
 static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mn10300/include/asm/processor.h linux-libre-4.12-gnu/arch/mn10300/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/mn10300/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mn10300/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -132,11 +132,6 @@ static inline void start_thread(struct p
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define task_pt_regs(task) ((task)->thread.uregs)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/mn10300/kernel/process.c linux-libre-4.12-gnu/arch/mn10300/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/mn10300/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/mn10300/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -40,14 +40,6 @@
 #include "internal.h"
 
 /*
- * return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	return ((unsigned long *) tsk->thread.sp)[3];
-}
-
-/*
  * power off function, if any
  */
 void (*pm_power_off)(void);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/nios2/include/asm/processor.h linux-libre-4.12-gnu/arch/nios2/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/nios2/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/nios2/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -75,9 +75,6 @@ static inline void release_thread(struct
 {
 }
 
-/* Return saved PC of a blocked thread. */
-#define thread_saved_pc(tsk)	((tsk)->thread.kregs->ea)
-
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define task_pt_regs(p) \
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/openrisc/include/asm/processor.h linux-libre-4.12-gnu/arch/openrisc/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/openrisc/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/openrisc/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -84,11 +84,6 @@ void start_thread(struct pt_regs *regs,
 void release_thread(struct task_struct *);
 unsigned long get_wchan(struct task_struct *p);
 
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 #define init_stack      (init_thread_union.stack)
 
 #define cpu_relax()     barrier()
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/openrisc/kernel/process.c linux-libre-4.12-gnu/arch/openrisc/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/openrisc/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/openrisc/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -110,11 +110,6 @@ void show_regs(struct pt_regs *regs)
 	show_registers(regs);
 }
 
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-	return (unsigned long)user_regs(t->stack)->pc;
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 }
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/parisc/include/asm/processor.h linux-libre-4.12-gnu/arch/parisc/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/parisc/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/parisc/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -163,12 +163,7 @@ struct thread_struct {
 	.flags		= 0 \
 	}
 
-/*
- * Return saved PC of a blocked thread.  This is used by ps mostly.
- */
-
 struct task_struct;
-unsigned long thread_saved_pc(struct task_struct *t);
 void show_trace(struct task_struct *task, unsigned long *stack);
 
 /*
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/parisc/kernel/process.c linux-libre-4.12-gnu/arch/parisc/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/parisc/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/parisc/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -239,11 +239,6 @@ copy_thread(unsigned long clone_flags, u
 	return 0;
 }
 
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-	return t->thread.regs.kpc;
-}
-
 unsigned long
 get_wchan(struct task_struct *p)
 {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/powerpc/include/asm/processor.h linux-libre-4.12-gnu/arch/powerpc/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/powerpc/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/powerpc/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -378,12 +378,6 @@ struct thread_struct {
 }
 #endif
 
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-#define thread_saved_pc(tsk)    \
-        ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-
 #define task_pt_regs(tsk)	((struct pt_regs *)(tsk)->thread.regs)
 
 unsigned long get_wchan(struct task_struct *p);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/powerpc/include/asm/uaccess.h linux-libre-4.12-gnu/arch/powerpc/include/asm/uaccess.h
--- linux-libre-4.12-rc7-gnu/arch/powerpc/include/asm/uaccess.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/powerpc/include/asm/uaccess.h	2017-07-02 19:07:02.000000000 -0400
@@ -267,13 +267,7 @@ do {								\
 extern unsigned long __copy_tofrom_user(void __user *to,
 		const void __user *from, unsigned long size);
 
-#ifndef __powerpc64__
-
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
-
-#else /* __powerpc64__ */
-
+#ifdef __powerpc64__
 static inline unsigned long
 raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
 {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/s390/include/asm/processor.h linux-libre-4.12-gnu/arch/s390/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/s390/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/s390/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -221,11 +221,6 @@ extern void release_thread(struct task_s
 /* Free guarded storage control block for current */
 void exit_thread_gs(void);
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 unsigned long get_wchan(struct task_struct *p);
 #define task_pt_regs(tsk) ((struct pt_regs *) \
         (task_stack_page(tsk) + THREAD_SIZE) - 1)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/s390/kernel/ipl.c linux-libre-4.12-gnu/arch/s390/kernel/ipl.c
--- linux-libre-4.12-rc7-gnu/arch/s390/kernel/ipl.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/s390/kernel/ipl.c	2017-07-02 19:07:02.000000000 -0400
@@ -564,8 +564,6 @@ static struct kset *ipl_kset;
 
 static void __ipl_run(void *unused)
 {
-	if (MACHINE_IS_LPAR && ipl_info.type == IPL_TYPE_CCW)
-		diag308(DIAG308_LOAD_NORMAL_DUMP, NULL);
 	diag308(DIAG308_LOAD_CLEAR, NULL);
 	if (MACHINE_IS_VM)
 		__cpcmd("IPL", NULL, 0, NULL);
@@ -1088,10 +1086,7 @@ static void __reipl_run(void *unused)
 		break;
 	case REIPL_METHOD_CCW_DIAG:
 		diag308(DIAG308_SET, reipl_block_ccw);
-		if (MACHINE_IS_LPAR)
-			diag308(DIAG308_LOAD_NORMAL_DUMP, NULL);
-		else
-			diag308(DIAG308_LOAD_CLEAR, NULL);
+		diag308(DIAG308_LOAD_CLEAR, NULL);
 		break;
 	case REIPL_METHOD_FCP_RW_DIAG:
 		diag308(DIAG308_SET, reipl_block_fcp);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/s390/kernel/process.c linux-libre-4.12-gnu/arch/s390/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/s390/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/s390/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -41,31 +41,6 @@
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
 
-/*
- * Return saved PC of a blocked thread. used in kernel/sched.
- * resume in entry.S does not create a new stack frame, it
- * just stores the registers %r6-%r15 to the frame given by
- * schedule. We want to return the address of the caller of
- * schedule, so we have to walk the backchain one time to
- * find the frame schedule() store its return address.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	struct stack_frame *sf, *low, *high;
-
-	if (!tsk || !task_stack_page(tsk))
-		return 0;
-	low = task_stack_page(tsk);
-	high = (struct stack_frame *) task_pt_regs(tsk);
-	sf = (struct stack_frame *) tsk->thread.ksp;
-	if (sf <= low || sf > high)
-		return 0;
-	sf = (struct stack_frame *) sf->back_chain;
-	if (sf <= low || sf > high)
-		return 0;
-	return sf->gprs[8];
-}
-
 extern void kernel_thread_starter(void);
 
 /*
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/score/include/asm/processor.h linux-libre-4.12-gnu/arch/score/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/score/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/score/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -13,7 +13,6 @@ struct task_struct;
  */
 extern void (*cpu_wait)(void);
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
 extern void start_thread(struct pt_regs *regs,
 			unsigned long pc, unsigned long sp);
 extern unsigned long get_wchan(struct task_struct *p);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/score/kernel/process.c linux-libre-4.12-gnu/arch/score/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/score/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/score/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -101,11 +101,6 @@ int dump_fpu(struct pt_regs *regs, elf_f
 	return 1;
 }
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	return task_pt_regs(tsk)->cp0_epc;
-}
-
 unsigned long get_wchan(struct task_struct *task)
 {
 	if (!task || task == current || task->state == TASK_RUNNING)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/sparc/include/asm/processor_32.h linux-libre-4.12-gnu/arch/sparc/include/asm/processor_32.h
--- linux-libre-4.12-rc7-gnu/arch/sparc/include/asm/processor_32.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/sparc/include/asm/processor_32.h	2017-07-02 19:07:02.000000000 -0400
@@ -67,9 +67,6 @@ struct thread_struct {
 	.current_ds = KERNEL_DS, \
 }
 
-/* Return saved PC of a blocked thread. */
-unsigned long thread_saved_pc(struct task_struct *t);
-
 /* Do necessary setup to start up a newly executed thread. */
 static inline void start_thread(struct pt_regs * regs, unsigned long pc,
 				    unsigned long sp)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/sparc/include/asm/processor_64.h linux-libre-4.12-gnu/arch/sparc/include/asm/processor_64.h
--- linux-libre-4.12-rc7-gnu/arch/sparc/include/asm/processor_64.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/sparc/include/asm/processor_64.h	2017-07-02 19:07:02.000000000 -0400
@@ -89,9 +89,7 @@ struct thread_struct {
 #include <linux/types.h>
 #include <asm/fpumacro.h>
 
-/* Return saved PC of a blocked thread. */
 struct task_struct;
-unsigned long thread_saved_pc(struct task_struct *);
 
 /* On Uniprocessor, even in RMO processes see TSO semantics */
 #ifdef CONFIG_SMP
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/sparc/kernel/process_32.c linux-libre-4.12-gnu/arch/sparc/kernel/process_32.c
--- linux-libre-4.12-rc7-gnu/arch/sparc/kernel/process_32.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/sparc/kernel/process_32.c	2017-07-02 19:07:02.000000000 -0400
@@ -177,14 +177,6 @@ void show_stack(struct task_struct *tsk,
 }
 
 /*
- * Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	return task_thread_info(tsk)->kpc;
-}
-
-/*
  * Free current thread data structures etc..
  */
 void exit_thread(struct task_struct *tsk)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/sparc/kernel/process_64.c linux-libre-4.12-gnu/arch/sparc/kernel/process_64.c
--- linux-libre-4.12-rc7-gnu/arch/sparc/kernel/process_64.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/sparc/kernel/process_64.c	2017-07-02 19:07:02.000000000 -0400
@@ -400,25 +400,6 @@ core_initcall(sparc_sysrq_init);
 
 #endif
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	struct thread_info *ti = task_thread_info(tsk);
-	unsigned long ret = 0xdeadbeefUL;
-	
-	if (ti && ti->ksp) {
-		unsigned long *sp;
-		sp = (unsigned long *)(ti->ksp + STACK_BIAS);
-		if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL &&
-		    sp[14]) {
-			unsigned long *fp;
-			fp = (unsigned long *)(sp[14] + STACK_BIAS);
-			if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL)
-				ret = fp[15];
-		}
-	}
-	return ret;
-}
-
 /* Free current thread data structures etc.. */
 void exit_thread(struct task_struct *tsk)
 {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/tile/include/asm/processor.h linux-libre-4.12-gnu/arch/tile/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/tile/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/tile/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -214,13 +214,6 @@ static inline void release_thread(struct
 
 extern void prepare_exit_to_usermode(struct pt_regs *regs, u32 flags);
 
-
-/*
- * Return saved (kernel) PC of a blocked thread.
- * Only used in a printk() in kernel/sched/core.c, so don't work too hard.
- */
-#define thread_saved_pc(t)   ((t)->thread.pc)
-
 unsigned long get_wchan(struct task_struct *p);
 
 /* Return initial ksp value for given task. */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/um/include/asm/processor-generic.h linux-libre-4.12-gnu/arch/um/include/asm/processor-generic.h
--- linux-libre-4.12-rc7-gnu/arch/um/include/asm/processor-generic.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/um/include/asm/processor-generic.h	2017-07-02 19:07:02.000000000 -0400
@@ -58,8 +58,6 @@ static inline void release_thread(struct
 {
 }
 
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 static inline void mm_copy_segments(struct mm_struct *from_mm,
 				    struct mm_struct *new_mm)
 {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/um/kernel/um_arch.c linux-libre-4.12-gnu/arch/um/kernel/um_arch.c
--- linux-libre-4.12-rc7-gnu/arch/um/kernel/um_arch.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/um/kernel/um_arch.c	2017-07-02 19:07:02.000000000 -0400
@@ -56,12 +56,6 @@ union thread_union cpu0_irqstack
 	__attribute__((__section__(".data..init_irqstack"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
-unsigned long thread_saved_pc(struct task_struct *task)
-{
-	/* FIXME: Need to look up userspace_pid by cpu */
-	return os_process_pc(userspace_pid[0]);
-}
-
 /* Changed in setup_arch, which is called in early boot */
 static char host_info[(__NEW_UTS_LEN + 1) * 5];
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/boot/compressed/kaslr.c linux-libre-4.12-gnu/arch/x86/boot/compressed/kaslr.c
--- linux-libre-4.12-rc7-gnu/arch/x86/boot/compressed/kaslr.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/boot/compressed/kaslr.c	2017-07-02 19:07:02.000000000 -0400
@@ -564,9 +564,6 @@ void choose_random_location(unsigned lon
 {
 	unsigned long random_addr, min_addr;
 
-	/* By default, keep output position unchanged. */
-	*virt_addr = *output;
-
 	if (cmdline_find_option_bool("nokaslr")) {
 		warn("KASLR disabled: 'nokaslr' on cmdline.");
 		return;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/boot/compressed/misc.c linux-libre-4.12-gnu/arch/x86/boot/compressed/misc.c
--- linux-libre-4.12-rc7-gnu/arch/x86/boot/compressed/misc.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/boot/compressed/misc.c	2017-07-02 19:07:02.000000000 -0400
@@ -338,7 +338,7 @@ asmlinkage __visible void *extract_kerne
 				  unsigned long output_len)
 {
 	const unsigned long kernel_total_size = VO__end - VO__text;
-	unsigned long virt_addr = (unsigned long)output;
+	unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
 
 	/* Retain x86 boot parameters pointer passed from startup_32/64. */
 	boot_params = rmode;
@@ -390,6 +390,8 @@ asmlinkage __visible void *extract_kerne
 #ifdef CONFIG_X86_64
 	if (heap > 0x3fffffffffffUL)
 		error("Destination address too large");
+	if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE)
+		error("Destination virtual address is beyond the kernel mapping area");
 #else
 	if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
 		error("Destination address too large");
@@ -397,7 +399,7 @@ asmlinkage __visible void *extract_kerne
 #ifndef CONFIG_RELOCATABLE
 	if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
 		error("Destination address does not match LOAD_PHYSICAL_ADDR");
-	if ((unsigned long)output != virt_addr)
+	if (virt_addr != LOAD_PHYSICAL_ADDR)
 		error("Destination virtual address changed when not relocatable");
 #endif
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/boot/compressed/misc.h linux-libre-4.12-gnu/arch/x86/boot/compressed/misc.h
--- linux-libre-4.12-rc7-gnu/arch/x86/boot/compressed/misc.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/boot/compressed/misc.h	2017-07-02 19:07:02.000000000 -0400
@@ -81,8 +81,6 @@ static inline void choose_random_locatio
 					  unsigned long output_size,
 					  unsigned long *virt_addr)
 {
-	/* No change from existing output location. */
-	*virt_addr = *output;
 }
 #endif
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/events/intel/uncore.c linux-libre-4.12-gnu/arch/x86/events/intel/uncore.c
--- linux-libre-4.12-rc7-gnu/arch/x86/events/intel/uncore.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/events/intel/uncore.c	2017-07-02 19:07:02.000000000 -0400
@@ -1170,7 +1170,7 @@ static int uncore_event_cpu_online(unsig
 		pmu = type->pmus;
 		for (i = 0; i < type->num_boxes; i++, pmu++) {
 			box = pmu->boxes[pkg];
-			if (!box && atomic_inc_return(&box->refcnt) == 1)
+			if (box && atomic_inc_return(&box->refcnt) == 1)
 				uncore_box_init(box);
 		}
 	}
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/include/asm/processor.h linux-libre-4.12-gnu/arch/x86/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/x86/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -860,8 +860,6 @@ extern unsigned long KSTK_ESP(struct tas
 
 #endif /* CONFIG_X86_64 */
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 					       unsigned long new_sp);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c linux-libre-4.12-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
--- linux-libre-4.12-rc7-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c	2017-07-02 19:07:02.000000000 -0400
@@ -856,11 +856,13 @@ static struct dentry *rdt_mount(struct f
 	dentry = kernfs_mount(fs_type, flags, rdt_root,
 			      RDTGROUP_SUPER_MAGIC, NULL);
 	if (IS_ERR(dentry))
-		goto out_cdp;
+		goto out_destroy;
 
 	static_branch_enable(&rdt_enable_key);
 	goto out;
 
+out_destroy:
+	kernfs_remove(kn_info);
 out_cdp:
 	cdp_disable();
 out:
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/kernel/process.c linux-libre-4.12-gnu/arch/x86/kernel/process.c
--- linux-libre-4.12-rc7-gnu/arch/x86/kernel/process.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
@@ -545,17 +545,6 @@ unsigned long arch_randomize_brk(struct
 }
 
 /*
- * Return saved PC of a blocked thread.
- * What is this good for? it will be always the scheduler or ret_from_fork.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-	struct inactive_task_frame *frame =
-		(struct inactive_task_frame *) READ_ONCE(tsk->thread.sp);
-	return READ_ONCE_NOCHECK(frame->ret_addr);
-}
-
-/*
  * Called from fs/proc with a reference on @p to find the function
  * which called into schedule(). This needs to be done carefully
  * because the task might wake up and we might look at a stack
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/kernel/tboot.c linux-libre-4.12-gnu/arch/x86/kernel/tboot.c
--- linux-libre-4.12-rc7-gnu/arch/x86/kernel/tboot.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/kernel/tboot.c	2017-07-02 19:07:02.000000000 -0400
@@ -514,7 +514,7 @@ int tboot_force_iommu(void)
 	if (!tboot_enabled())
 		return 0;
 
-	if (!intel_iommu_tboot_noforce)
+	if (intel_iommu_tboot_noforce)
 		return 1;
 
 	if (no_iommu || swiotlb || dmar_disabled)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/x86/mm/init_64.c linux-libre-4.12-gnu/arch/x86/mm/init_64.c
--- linux-libre-4.12-rc7-gnu/arch/x86/mm/init_64.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/x86/mm/init_64.c	2017-07-02 19:07:02.000000000 -0400
@@ -990,7 +990,13 @@ remove_p4d_table(p4d_t *p4d_start, unsig
 
 		pud_base = pud_offset(p4d, 0);
 		remove_pud_table(pud_base, addr, next, direct);
-		free_pud_table(pud_base, p4d);
+		/*
+		 * For 4-level page tables we do not want to free PUDs, but in the
+		 * 5-level case we should free them. This code will have to change
+		 * to adapt for boot-time switching between 4 and 5 level page tables.
+		 */
+		if (CONFIG_PGTABLE_LEVELS == 5)
+			free_pud_table(pud_base, p4d);
 	}
 
 	if (direct)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/arch/xtensa/include/asm/processor.h linux-libre-4.12-gnu/arch/xtensa/include/asm/processor.h
--- linux-libre-4.12-rc7-gnu/arch/xtensa/include/asm/processor.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/arch/xtensa/include/asm/processor.h	2017-07-02 19:07:02.000000000 -0400
@@ -213,8 +213,6 @@ struct mm_struct;
 #define release_segments(mm)	do { } while(0)
 #define forget_segments()	do { } while (0)
 
-#define thread_saved_pc(tsk)	(task_pt_regs(tsk)->pc)
-
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)		(task_pt_regs(tsk)->pc)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/block/bio.c linux-libre-4.12-gnu/block/bio.c
--- linux-libre-4.12-rc7-gnu/block/bio.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/block/bio.c	2017-07-02 19:07:02.000000000 -0400
@@ -240,20 +240,21 @@ fallback:
 	return bvl;
 }
 
-static void __bio_free(struct bio *bio)
+void bio_uninit(struct bio *bio)
 {
 	bio_disassociate_task(bio);
 
 	if (bio_integrity(bio))
 		bio_integrity_free(bio);
 }
+EXPORT_SYMBOL(bio_uninit);
 
 static void bio_free(struct bio *bio)
 {
 	struct bio_set *bs = bio->bi_pool;
 	void *p;
 
-	__bio_free(bio);
+	bio_uninit(bio);
 
 	if (bs) {
 		bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio));
@@ -271,6 +272,11 @@ static void bio_free(struct bio *bio)
 	}
 }
 
+/*
+ * Users of this function have their own bio allocation. Subsequently,
+ * they must remember to pair any call to bio_init() with bio_uninit()
+ * when IO has completed, or when the bio is released.
+ */
 void bio_init(struct bio *bio, struct bio_vec *table,
 	      unsigned short max_vecs)
 {
@@ -297,7 +303,7 @@ void bio_reset(struct bio *bio)
 {
 	unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS);
 
-	__bio_free(bio);
+	bio_uninit(bio);
 
 	memset(bio, 0, BIO_RESET_BYTES);
 	bio->bi_flags = flags;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpio/gpiolib-acpi.c linux-libre-4.12-gnu/drivers/gpio/gpiolib-acpi.c
--- linux-libre-4.12-rc7-gnu/drivers/gpio/gpiolib-acpi.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpio/gpiolib-acpi.c	2017-07-02 19:07:02.000000000 -0400
@@ -201,7 +201,7 @@ static acpi_status acpi_gpiochip_request
 			handler = acpi_gpio_irq_handler_evt;
 	}
 	if (!handler)
-		return AE_BAD_PARAMETER;
+		return AE_OK;
 
 	pin = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin);
 	if (pin < 0)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpio/gpiolib.c linux-libre-4.12-gnu/drivers/gpio/gpiolib.c
--- linux-libre-4.12-rc7-gnu/drivers/gpio/gpiolib.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpio/gpiolib.c	2017-07-02 19:07:02.000000000 -0400
@@ -708,7 +708,8 @@ static irqreturn_t lineevent_irq_thread(
 
 	ge.timestamp = ktime_get_real_ns();
 
-	if (le->eflags & GPIOEVENT_REQUEST_BOTH_EDGES) {
+	if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
+	    && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
 		int level = gpiod_get_value_cansleep(le->desc);
 
 		if (level)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem.h linux-libre-4.12-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem.h
--- linux-libre-4.12-rc7-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem.h	2017-07-02 19:07:02.000000000 -0400
@@ -106,9 +106,10 @@ struct etnaviv_gem_submit {
 	struct etnaviv_gpu *gpu;
 	struct ww_acquire_ctx ticket;
 	struct dma_fence *fence;
+	u32 flags;
 	unsigned int nr_bos;
 	struct etnaviv_gem_submit_bo bos[0];
-	u32 flags;
+	/* No new members here, the previous one is variable-length! */
 };
 
 int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj,
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c linux-libre-4.12-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
--- linux-libre-4.12-rc7-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c	2017-07-02 19:07:02.000000000 -0400
@@ -172,7 +172,7 @@ static int submit_fence_sync(const struc
 	for (i = 0; i < submit->nr_bos; i++) {
 		struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;
 		bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE;
-		bool explicit = !(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
+		bool explicit = !!(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
 
 		ret = etnaviv_gpu_fence_sync_obj(etnaviv_obj, context, write,
 						 explicit);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpu/drm/i915/i915_debugfs.c linux-libre-4.12-gnu/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-libre-4.12-rc7-gnu/drivers/gpu/drm/i915/i915_debugfs.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpu/drm/i915/i915_debugfs.c	2017-07-02 19:07:02.000000000 -0400
@@ -292,6 +292,8 @@ static int per_file_stats(int id, void *
 	struct file_stats *stats = data;
 	struct i915_vma *vma;
 
+	lockdep_assert_held(&obj->base.dev->struct_mutex);
+
 	stats->count++;
 	stats->total += obj->base.size;
 	if (!obj->bind_count)
@@ -476,6 +478,8 @@ static int i915_gem_object_info(struct s
 		struct drm_i915_gem_request *request;
 		struct task_struct *task;
 
+		mutex_lock(&dev->struct_mutex);
+
 		memset(&stats, 0, sizeof(stats));
 		stats.file_priv = file->driver_priv;
 		spin_lock(&file->table_lock);
@@ -487,7 +491,6 @@ static int i915_gem_object_info(struct s
 		 * still alive (e.g. get_pid(current) => fork() => exit()).
 		 * Therefore, we need to protect this ->comm access using RCU.
 		 */
-		mutex_lock(&dev->struct_mutex);
 		request = list_first_entry_or_null(&file_priv->mm.request_list,
 						   struct drm_i915_gem_request,
 						   client_link);
@@ -497,6 +500,7 @@ static int i915_gem_object_info(struct s
 				PIDTYPE_PID);
 		print_file_stats(m, task ? task->comm : "<unknown>", stats);
 		rcu_read_unlock();
+
 		mutex_unlock(&dev->struct_mutex);
 	}
 	mutex_unlock(&dev->filelist_mutex);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c linux-libre-4.12-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c
--- linux-libre-4.12-rc7-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2017-07-02 19:07:02.000000000 -0400
@@ -546,11 +546,12 @@ repeat:
 }
 
 static int
-i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+i915_gem_execbuffer_relocate_entry(struct i915_vma *vma,
 				   struct eb_vmas *eb,
 				   struct drm_i915_gem_relocation_entry *reloc,
 				   struct reloc_cache *cache)
 {
+	struct drm_i915_gem_object *obj = vma->obj;
 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
 	struct drm_gem_object *target_obj;
 	struct drm_i915_gem_object *target_i915_obj;
@@ -628,6 +629,16 @@ i915_gem_execbuffer_relocate_entry(struc
 		return -EINVAL;
 	}
 
+	/*
+	 * If we write into the object, we need to force the synchronisation
+	 * barrier, either with an asynchronous clflush or if we executed the
+	 * patching using the GPU (though that should be serialised by the
+	 * timeline). To be completely sure, and since we are required to
+	 * do relocations we are already stalling, disable the user's opt
+	 * of our synchronisation.
+	 */
+	vma->exec_entry->flags &= ~EXEC_OBJECT_ASYNC;
+
 	ret = relocate_entry(obj, reloc, cache, target_offset);
 	if (ret)
 		return ret;
@@ -678,7 +689,7 @@ i915_gem_execbuffer_relocate_vma(struct
 		do {
 			u64 offset = r->presumed_offset;
 
-			ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r, &cache);
+			ret = i915_gem_execbuffer_relocate_entry(vma, eb, r, &cache);
 			if (ret)
 				goto out;
 
@@ -726,7 +737,7 @@ i915_gem_execbuffer_relocate_vma_slow(st
 
 	reloc_cache_init(&cache, eb->i915);
 	for (i = 0; i < entry->relocation_count; i++) {
-		ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i], &cache);
+		ret = i915_gem_execbuffer_relocate_entry(vma, eb, &relocs[i], &cache);
 		if (ret)
 			break;
 	}
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpu/drm/i915/i915_vma.c linux-libre-4.12-gnu/drivers/gpu/drm/i915/i915_vma.c
--- linux-libre-4.12-rc7-gnu/drivers/gpu/drm/i915/i915_vma.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpu/drm/i915/i915_vma.c	2017-07-02 19:07:02.000000000 -0400
@@ -650,6 +650,11 @@ int i915_vma_unbind(struct i915_vma *vma
 				break;
 		}
 
+		if (!ret) {
+			ret = i915_gem_active_retire(&vma->last_fence,
+						     &vma->vm->i915->drm.struct_mutex);
+		}
+
 		__i915_vma_unpin(vma);
 		if (ret)
 			return ret;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c linux-libre-4.12-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
--- linux-libre-4.12-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c	2017-07-02 19:07:02.000000000 -0400
@@ -321,6 +321,7 @@ void vmw_cmdbuf_res_man_destroy(struct v
 	list_for_each_entry_safe(entry, next, &man->list, head)
 		vmw_cmdbuf_res_free(man, entry);
 
+	drm_ht_remove(&man->resources);
 	kfree(man);
 }
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/iommu/amd_iommu.c linux-libre-4.12-gnu/drivers/iommu/amd_iommu.c
--- linux-libre-4.12-rc7-gnu/drivers/iommu/amd_iommu.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/iommu/amd_iommu.c	2017-07-02 19:07:02.000000000 -0400
@@ -3879,11 +3879,9 @@ static void irte_ga_prepare(void *entry,
 			    u8 vector, u32 dest_apicid, int devid)
 {
 	struct irte_ga *irte = (struct irte_ga *) entry;
-	struct iommu_dev_data *dev_data = search_dev_data(devid);
 
 	irte->lo.val                      = 0;
 	irte->hi.val                      = 0;
-	irte->lo.fields_remap.guest_mode  = dev_data ? dev_data->use_vapic : 0;
 	irte->lo.fields_remap.int_type    = delivery_mode;
 	irte->lo.fields_remap.dm          = dest_mode;
 	irte->hi.fields.vector            = vector;
@@ -3939,10 +3937,10 @@ static void irte_ga_set_affinity(void *e
 	struct irte_ga *irte = (struct irte_ga *) entry;
 	struct iommu_dev_data *dev_data = search_dev_data(devid);
 
-	if (!dev_data || !dev_data->use_vapic) {
+	if (!dev_data || !dev_data->use_vapic ||
+	    !irte->lo.fields_remap.guest_mode) {
 		irte->hi.fields.vector = vector;
 		irte->lo.fields_remap.destination = dest_apicid;
-		irte->lo.fields_remap.guest_mode = 0;
 		modify_irte_ga(devid, index, irte, NULL);
 	}
 }
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/md/dm-raid.c linux-libre-4.12-gnu/drivers/md/dm-raid.c
--- linux-libre-4.12-rc7-gnu/drivers/md/dm-raid.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/md/dm-raid.c	2017-07-02 19:07:02.000000000 -0400
@@ -1927,7 +1927,7 @@ struct dm_raid_superblock {
 	/********************************************************************
 	 * BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
 	 *
-	 * FEATURE_FLAG_SUPPORTS_V190 in the features member indicates that those exist
+	 * FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
 	 */
 
 	__le32 flags; /* Flags defining array states for reshaping */
@@ -2092,6 +2092,11 @@ static void super_sync(struct mddev *mdd
 	sb->layout = cpu_to_le32(mddev->layout);
 	sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors);
 
+	/********************************************************************
+	 * BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
+	 *
+	 * FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
+	 */
 	sb->new_level = cpu_to_le32(mddev->new_level);
 	sb->new_layout = cpu_to_le32(mddev->new_layout);
 	sb->new_stripe_sectors = cpu_to_le32(mddev->new_chunk_sectors);
@@ -2438,8 +2443,14 @@ static int super_validate(struct raid_se
 	mddev->bitmap_info.default_offset = mddev->bitmap_info.offset;
 
 	if (!test_and_clear_bit(FirstUse, &rdev->flags)) {
-		/* Retrieve device size stored in superblock to be prepared for shrink */
-		rdev->sectors = le64_to_cpu(sb->sectors);
+		/*
+		 * Retrieve rdev size stored in superblock to be prepared for shrink.
+		 * Check extended superblock members are present otherwise the size
+		 * will not be set!
+		 */
+		if (le32_to_cpu(sb->compat_features) & FEATURE_FLAG_SUPPORTS_V190)
+			rdev->sectors = le64_to_cpu(sb->sectors);
+
 		rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset);
 		if (rdev->recovery_offset == MaxSector)
 			set_bit(In_sync, &rdev->flags);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/md/dm-thin.c linux-libre-4.12-gnu/drivers/md/dm-thin.c
--- linux-libre-4.12-rc7-gnu/drivers/md/dm-thin.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/md/dm-thin.c	2017-07-02 19:07:02.000000000 -0400
@@ -1094,6 +1094,19 @@ static void process_prepared_discard_pas
 		return;
 	}
 
+	/*
+	 * Increment the unmapped blocks.  This prevents a race between the
+	 * passdown io and reallocation of freed blocks.
+	 */
+	r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
+	if (r) {
+		metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
+		bio_io_error(m->bio);
+		cell_defer_no_holder(tc, m->cell);
+		mempool_free(m, pool->mapping_pool);
+		return;
+	}
+
 	discard_parent = bio_alloc(GFP_NOIO, 1);
 	if (!discard_parent) {
 		DMWARN("%s: unable to allocate top level discard bio for passdown. Skipping passdown.",
@@ -1114,19 +1127,6 @@ static void process_prepared_discard_pas
 			end_discard(&op, r);
 		}
 	}
-
-	/*
-	 * Increment the unmapped blocks.  This prevents a race between the
-	 * passdown io and reallocation of freed blocks.
-	 */
-	r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
-	if (r) {
-		metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
-		bio_io_error(m->bio);
-		cell_defer_no_holder(tc, m->cell);
-		mempool_free(m, pool->mapping_pool);
-		return;
-	}
 }
 
 static void process_prepared_discard_passdown_pt2(struct dm_thin_new_mapping *m)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/misc/cxl/context.c linux-libre-4.12-gnu/drivers/misc/cxl/context.c
--- linux-libre-4.12-rc7-gnu/drivers/misc/cxl/context.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/misc/cxl/context.c	2017-07-02 19:07:02.000000000 -0400
@@ -45,7 +45,7 @@ int cxl_context_init(struct cxl_context
 	mutex_init(&ctx->mapping_lock);
 	ctx->mapping = NULL;
 
-	if (cxl_is_psl8(afu)) {
+	if (cxl_is_power8()) {
 		spin_lock_init(&ctx->sste_lock);
 
 		/*
@@ -189,7 +189,7 @@ int cxl_context_iomap(struct cxl_context
 		if (start + len > ctx->afu->adapter->ps_size)
 			return -EINVAL;
 
-		if (cxl_is_psl9(ctx->afu)) {
+		if (cxl_is_power9()) {
 			/*
 			 * Make sure there is a valid problem state
 			 * area space for this AFU.
@@ -324,7 +324,7 @@ static void reclaim_ctx(struct rcu_head
 {
 	struct cxl_context *ctx = container_of(rcu, struct cxl_context, rcu);
 
-	if (cxl_is_psl8(ctx->afu))
+	if (cxl_is_power8())
 		free_page((u64)ctx->sstp);
 	if (ctx->ff_page)
 		__free_page(ctx->ff_page);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/misc/cxl/cxl.h linux-libre-4.12-gnu/drivers/misc/cxl/cxl.h
--- linux-libre-4.12-rc7-gnu/drivers/misc/cxl/cxl.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/misc/cxl/cxl.h	2017-07-02 19:07:02.000000000 -0400
@@ -357,6 +357,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_A
 #define CXL_PSL9_DSISR_An_PF_RGP  0x0000000000000090ULL  /* PTE not found (Radix Guest (parent)) 0b10010000 */
 #define CXL_PSL9_DSISR_An_PF_HRH  0x0000000000000094ULL  /* PTE not found (HPT/Radix Host)       0b10010100 */
 #define CXL_PSL9_DSISR_An_PF_STEG 0x000000000000009CULL  /* PTE not found (STEG VA)              0b10011100 */
+#define CXL_PSL9_DSISR_An_URTCH   0x00000000000000B4ULL  /* Unsupported Radix Tree Configuration 0b10110100 */
 
 /****** CXL_PSL_TFC_An ******************************************************/
 #define CXL_PSL_TFC_An_A  (1ull << (63-28)) /* Acknowledge non-translation fault */
@@ -844,24 +845,15 @@ static inline bool cxl_is_power8(void)
 
 static inline bool cxl_is_power9(void)
 {
-	/* intermediate solution */
-	if (!cxl_is_power8() &&
-	   (cpu_has_feature(CPU_FTRS_POWER9) ||
-	    cpu_has_feature(CPU_FTR_POWER9_DD1)))
-		return true;
-	return false;
-}
-
-static inline bool cxl_is_psl8(struct cxl_afu *afu)
-{
-	if (afu->adapter->caia_major == 1)
+	if (pvr_version_is(PVR_POWER9))
 		return true;
 	return false;
 }
 
-static inline bool cxl_is_psl9(struct cxl_afu *afu)
+static inline bool cxl_is_power9_dd1(void)
 {
-	if (afu->adapter->caia_major == 2)
+	if ((pvr_version_is(PVR_POWER9)) &&
+	    cpu_has_feature(CPU_FTR_POWER9_DD1))
 		return true;
 	return false;
 }
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/misc/cxl/fault.c linux-libre-4.12-gnu/drivers/misc/cxl/fault.c
--- linux-libre-4.12-rc7-gnu/drivers/misc/cxl/fault.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/misc/cxl/fault.c	2017-07-02 19:07:02.000000000 -0400
@@ -187,7 +187,7 @@ static struct mm_struct *get_mem_context
 
 static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr)
 {
-	if ((cxl_is_psl8(ctx->afu)) && (dsisr & CXL_PSL_DSISR_An_DS))
+	if ((cxl_is_power8() && (dsisr & CXL_PSL_DSISR_An_DS)))
 		return true;
 
 	return false;
@@ -195,16 +195,23 @@ static bool cxl_is_segment_miss(struct c
 
 static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr)
 {
-	if ((cxl_is_psl8(ctx->afu)) && (dsisr & CXL_PSL_DSISR_An_DM))
-		return true;
+	u64 crs; /* Translation Checkout Response Status */
 
-	if ((cxl_is_psl9(ctx->afu)) &&
-	   ((dsisr & CXL_PSL9_DSISR_An_CO_MASK) &
-		(CXL_PSL9_DSISR_An_PF_SLR | CXL_PSL9_DSISR_An_PF_RGC |
-		 CXL_PSL9_DSISR_An_PF_RGP | CXL_PSL9_DSISR_An_PF_HRH |
-		 CXL_PSL9_DSISR_An_PF_STEG)))
+	if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_An_DM))
 		return true;
 
+	if (cxl_is_power9()) {
+		crs = (dsisr & CXL_PSL9_DSISR_An_CO_MASK);
+		if ((crs == CXL_PSL9_DSISR_An_PF_SLR) ||
+		    (crs == CXL_PSL9_DSISR_An_PF_RGC) ||
+		    (crs == CXL_PSL9_DSISR_An_PF_RGP) ||
+		    (crs == CXL_PSL9_DSISR_An_PF_HRH) ||
+		    (crs == CXL_PSL9_DSISR_An_PF_STEG) ||
+		    (crs == CXL_PSL9_DSISR_An_URTCH)) {
+			return true;
+		}
+	}
+
 	return false;
 }
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/misc/cxl/main.c linux-libre-4.12-gnu/drivers/misc/cxl/main.c
--- linux-libre-4.12-rc7-gnu/drivers/misc/cxl/main.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/misc/cxl/main.c	2017-07-02 19:07:02.000000000 -0400
@@ -329,8 +329,15 @@ static int __init init_cxl(void)
 
 	cxl_debugfs_init();
 
-	if ((rc = register_cxl_calls(&cxl_calls)))
-		goto err;
+	/*
+	 * we don't register the callback on P9. slb callack is only
+	 * used for the PSL8 MMU and CX4.
+	 */
+	if (cxl_is_power8()) {
+		rc = register_cxl_calls(&cxl_calls);
+		if (rc)
+			goto err;
+	}
 
 	if (cpu_has_feature(CPU_FTR_HVMODE)) {
 		cxl_ops = &cxl_native_ops;
@@ -347,7 +354,8 @@ static int __init init_cxl(void)
 
 	return 0;
 err1:
-	unregister_cxl_calls(&cxl_calls);
+	if (cxl_is_power8())
+		unregister_cxl_calls(&cxl_calls);
 err:
 	cxl_debugfs_exit();
 	cxl_file_exit();
@@ -366,7 +374,8 @@ static void exit_cxl(void)
 
 	cxl_debugfs_exit();
 	cxl_file_exit();
-	unregister_cxl_calls(&cxl_calls);
+	if (cxl_is_power8())
+		unregister_cxl_calls(&cxl_calls);
 	idr_destroy(&cxl_adapter_idr);
 }
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/misc/cxl/native.c linux-libre-4.12-gnu/drivers/misc/cxl/native.c
--- linux-libre-4.12-rc7-gnu/drivers/misc/cxl/native.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/misc/cxl/native.c	2017-07-02 19:07:02.000000000 -0400
@@ -105,11 +105,16 @@ static int native_afu_reset(struct cxl_a
 			   CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
 			   false);
 
-	/* Re-enable any masked interrupts */
-	serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
-	serr &= ~CXL_PSL_SERR_An_IRQ_MASKS;
-	cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
-
+	/*
+	 * Re-enable any masked interrupts when the AFU is not
+	 * activated to avoid side effects after attaching a process
+	 * in dedicated mode.
+	 */
+	if (afu->current_mode == 0) {
+		serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
+		serr &= ~CXL_PSL_SERR_An_IRQ_MASKS;
+		cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
+	}
 
 	return rc;
 }
@@ -139,9 +144,9 @@ int cxl_psl_purge(struct cxl_afu *afu)
 
 	pr_devel("PSL purge request\n");
 
-	if (cxl_is_psl8(afu))
+	if (cxl_is_power8())
 		trans_fault = CXL_PSL_DSISR_TRANS;
-	if (cxl_is_psl9(afu))
+	if (cxl_is_power9())
 		trans_fault = CXL_PSL9_DSISR_An_TF;
 
 	if (!cxl_ops->link_ok(afu->adapter, afu)) {
@@ -603,7 +608,7 @@ static u64 calculate_sr(struct cxl_conte
 		if (!test_tsk_thread_flag(current, TIF_32BIT))
 			sr |= CXL_PSL_SR_An_SF;
 	}
-	if (cxl_is_psl9(ctx->afu)) {
+	if (cxl_is_power9()) {
 		if (radix_enabled())
 			sr |= CXL_PSL_SR_An_XLAT_ror;
 		else
@@ -1117,10 +1122,10 @@ static irqreturn_t native_handle_psl_sli
 
 static bool cxl_is_translation_fault(struct cxl_afu *afu, u64 dsisr)
 {
-	if ((cxl_is_psl8(afu)) && (dsisr & CXL_PSL_DSISR_TRANS))
+	if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_TRANS))
 		return true;
 
-	if ((cxl_is_psl9(afu)) && (dsisr & CXL_PSL9_DSISR_An_TF))
+	if ((cxl_is_power9()) && (dsisr & CXL_PSL9_DSISR_An_TF))
 		return true;
 
 	return false;
@@ -1194,10 +1199,10 @@ static void native_irq_wait(struct cxl_c
 		if (ph != ctx->pe)
 			return;
 		dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An);
-		if (cxl_is_psl8(ctx->afu) &&
+		if (cxl_is_power8() &&
 		   ((dsisr & CXL_PSL_DSISR_PENDING) == 0))
 			return;
-		if (cxl_is_psl9(ctx->afu) &&
+		if (cxl_is_power9() &&
 		   ((dsisr & CXL_PSL9_DSISR_PENDING) == 0))
 			return;
 		/*
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/misc/cxl/pci.c linux-libre-4.12-gnu/drivers/misc/cxl/pci.c
--- linux-libre-4.12-rc7-gnu/drivers/misc/cxl/pci.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/misc/cxl/pci.c	2017-07-02 19:07:02.000000000 -0400
@@ -436,7 +436,7 @@ static int init_implementation_adapter_r
 	/* nMMU_ID Defaults to: b’000001001’*/
 	xsl_dsnctl |= ((u64)0x09 << (63-28));
 
-	if (cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1)) {
+	if (!(cxl_is_power9_dd1())) {
 		/*
 		 * Used to identify CAPI packets which should be sorted into
 		 * the Non-Blocking queues by the PHB. This field should match
@@ -491,7 +491,7 @@ static int init_implementation_adapter_r
 	cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000003FFFF0000ULL);
 
 	/* Disable vc dd1 fix */
-	if ((cxl_is_power9() && cpu_has_feature(CPU_FTR_POWER9_DD1)))
+	if (cxl_is_power9_dd1())
 		cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0400000000000001ULL);
 
 	return 0;
@@ -1439,8 +1439,7 @@ int cxl_pci_reset(struct cxl *adapter)
 	 * The adapter is about to be reset, so ignore errors.
 	 * Not supported on P9 DD1
 	 */
-	if ((cxl_is_power8()) ||
-	    ((cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1))))
+	if ((cxl_is_power8()) || (!(cxl_is_power9_dd1())))
 		cxl_data_cache_flush(adapter);
 
 	/* pcie_warm_reset requests a fundamental pci reset which includes a
@@ -1750,7 +1749,6 @@ static const struct cxl_service_layer_op
 	.debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl9,
 	.debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl9,
 	.psl_irq_dump_registers = cxl_native_irq_dump_regs_psl9,
-	.err_irq_dump_registers = cxl_native_err_irq_dump_regs,
 	.debugfs_stop_trace = cxl_stop_trace_psl9,
 	.write_timebase_ctrl = write_timebase_ctrl_psl9,
 	.timebase_read = timebase_read_psl9,
@@ -1889,8 +1887,7 @@ static void cxl_pci_remove_adapter(struc
 	 * Flush adapter datacache as its about to be removed.
 	 * Not supported on P9 DD1.
 	 */
-	if ((cxl_is_power8()) ||
-	    ((cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1))))
+	if ((cxl_is_power8()) || (!(cxl_is_power9_dd1())))
 		cxl_data_cache_flush(adapter);
 
 	cxl_deconfigure_adapter(adapter);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/arcnet/arcnet.c linux-libre-4.12-gnu/drivers/net/arcnet/arcnet.c
--- linux-libre-4.12-rc7-gnu/drivers/net/arcnet/arcnet.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/arcnet/arcnet.c	2017-07-02 19:07:02.000000000 -0400
@@ -756,6 +756,7 @@ irqreturn_t arcnet_interrupt(int irq, vo
 	struct net_device *dev = dev_id;
 	struct arcnet_local *lp;
 	int recbuf, status, diagstatus, didsomething, boguscount;
+	unsigned long flags;
 	int retval = IRQ_NONE;
 
 	arc_printk(D_DURING, dev, "\n");
@@ -765,7 +766,7 @@ irqreturn_t arcnet_interrupt(int irq, vo
 	lp = netdev_priv(dev);
 	BUG_ON(!lp);
 
-	spin_lock(&lp->lock);
+	spin_lock_irqsave(&lp->lock, flags);
 
 	/* RESET flag was enabled - if device is not running, we must
 	 * clear it right away (but nothing else).
@@ -774,7 +775,7 @@ irqreturn_t arcnet_interrupt(int irq, vo
 		if (lp->hw.status(dev) & RESETflag)
 			lp->hw.command(dev, CFLAGScmd | RESETclear);
 		lp->hw.intmask(dev, 0);
-		spin_unlock(&lp->lock);
+		spin_unlock_irqrestore(&lp->lock, flags);
 		return retval;
 	}
 
@@ -998,7 +999,7 @@ irqreturn_t arcnet_interrupt(int irq, vo
 	udelay(1);
 	lp->hw.intmask(dev, lp->intmask);
 
-	spin_unlock(&lp->lock);
+	spin_unlock_irqrestore(&lp->lock, flags);
 	return retval;
 }
 EXPORT_SYMBOL(arcnet_interrupt);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/arcnet/capmode.c linux-libre-4.12-gnu/drivers/net/arcnet/capmode.c
--- linux-libre-4.12-rc7-gnu/drivers/net/arcnet/capmode.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/arcnet/capmode.c	2017-07-02 19:07:02.000000000 -0400
@@ -212,7 +212,7 @@ static int ack_tx(struct net_device *dev
 	ackpkt->soft.cap.proto = 0; /* using protocol 0 for acknowledge */
 	ackpkt->soft.cap.mes.ack = acked;
 
-	arc_printk(D_PROTO, dev, "Ackknowledge for cap packet %x.\n",
+	arc_printk(D_PROTO, dev, "Acknowledge for cap packet %x.\n",
 		   *((int *)&ackpkt->soft.cap.cookie[0]));
 
 	ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/arcnet/com20020.c linux-libre-4.12-gnu/drivers/net/arcnet/com20020.c
--- linux-libre-4.12-rc7-gnu/drivers/net/arcnet/com20020.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/arcnet/com20020.c	2017-07-02 19:07:02.000000000 -0400
@@ -246,8 +246,6 @@ int com20020_found(struct net_device *de
 		return -ENODEV;
 	}
 
-	dev->base_addr = ioaddr;
-
 	arc_printk(D_NORMAL, dev, "%s: station %02Xh found at %03lXh, IRQ %d.\n",
 		   lp->card_name, dev->dev_addr[0], dev->base_addr, dev->irq);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/arcnet/com20020-pci.c linux-libre-4.12-gnu/drivers/net/arcnet/com20020-pci.c
--- linux-libre-4.12-rc7-gnu/drivers/net/arcnet/com20020-pci.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/arcnet/com20020-pci.c	2017-07-02 19:07:02.000000000 -0400
@@ -135,6 +135,7 @@ static int com20020pci_probe(struct pci_
 	for (i = 0; i < ci->devcount; i++) {
 		struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
 		struct com20020_dev *card;
+		int dev_id_mask = 0xf;
 
 		dev = alloc_arcdev(device);
 		if (!dev) {
@@ -166,6 +167,7 @@ static int com20020pci_probe(struct pci_
 		arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND);
 		arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT);
 
+		SET_NETDEV_DEV(dev, &pdev->dev);
 		dev->base_addr = ioaddr;
 		dev->dev_addr[0] = node;
 		dev->irq = pdev->irq;
@@ -179,8 +181,8 @@ static int com20020pci_probe(struct pci_
 
 		/* Get the dev_id from the PLX rotary coder */
 		if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
-			dev->dev_id = 0xc;
-		dev->dev_id ^= inb(priv->misc + ci->rotary) >> 4;
+			dev_id_mask = 0x3;
+		dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
 
 		snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c linux-libre-4.12-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2017-06-30 15:05:45.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2017-07-02 21:51:19.000000000 -0400
@@ -12723,7 +12723,7 @@ static int bnx2x_set_mc_list(struct bnx2
 	} else {
 		/* If no mc addresses are required, flush the configuration */
 		rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL);
-		if (rc)
+		if (rc < 0)
 			BNX2X_ERR("Failed to clear multicast configuration %d\n",
 				  rc);
 	}
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-libre-4.12-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2017-07-02 19:07:02.000000000 -0400
@@ -1301,10 +1301,11 @@ static inline struct sk_buff *bnxt_tpa_e
 		cp_cons = NEXT_CMP(cp_cons);
 	}
 
-	if (unlikely(agg_bufs > MAX_SKB_FRAGS)) {
+	if (unlikely(agg_bufs > MAX_SKB_FRAGS || TPA_END_ERRORS(tpa_end1))) {
 		bnxt_abort_tpa(bp, bnapi, cp_cons, agg_bufs);
-		netdev_warn(bp->dev, "TPA frags %d exceeded MAX_SKB_FRAGS %d\n",
-			    agg_bufs, (int)MAX_SKB_FRAGS);
+		if (agg_bufs > MAX_SKB_FRAGS)
+			netdev_warn(bp->dev, "TPA frags %d exceeded MAX_SKB_FRAGS %d\n",
+				    agg_bufs, (int)MAX_SKB_FRAGS);
 		return NULL;
 	}
 
@@ -1562,6 +1563,45 @@ next_rx_no_prod:
 	return rc;
 }
 
+/* In netpoll mode, if we are using a combined completion ring, we need to
+ * discard the rx packets and recycle the buffers.
+ */
+static int bnxt_force_rx_discard(struct bnxt *bp, struct bnxt_napi *bnapi,
+				 u32 *raw_cons, u8 *event)
+{
+	struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
+	u32 tmp_raw_cons = *raw_cons;
+	struct rx_cmp_ext *rxcmp1;
+	struct rx_cmp *rxcmp;
+	u16 cp_cons;
+	u8 cmp_type;
+
+	cp_cons = RING_CMP(tmp_raw_cons);
+	rxcmp = (struct rx_cmp *)
+			&cpr->cp_desc_ring[CP_RING(cp_cons)][CP_IDX(cp_cons)];
+
+	tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+	cp_cons = RING_CMP(tmp_raw_cons);
+	rxcmp1 = (struct rx_cmp_ext *)
+			&cpr->cp_desc_ring[CP_RING(cp_cons)][CP_IDX(cp_cons)];
+
+	if (!RX_CMP_VALID(rxcmp1, tmp_raw_cons))
+		return -EBUSY;
+
+	cmp_type = RX_CMP_TYPE(rxcmp);
+	if (cmp_type == CMP_TYPE_RX_L2_CMP) {
+		rxcmp1->rx_cmp_cfa_code_errors_v2 |=
+			cpu_to_le32(RX_CMPL_ERRORS_CRC_ERROR);
+	} else if (cmp_type == CMP_TYPE_RX_L2_TPA_END_CMP) {
+		struct rx_tpa_end_cmp_ext *tpa_end1;
+
+		tpa_end1 = (struct rx_tpa_end_cmp_ext *)rxcmp1;
+		tpa_end1->rx_tpa_end_cmp_errors_v2 |=
+			cpu_to_le32(RX_TPA_END_CMP_ERRORS);
+	}
+	return bnxt_rx_pkt(bp, bnapi, raw_cons, event);
+}
+
 #define BNXT_GET_EVENT_PORT(data)	\
 	((data) &			\
 	 ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_PORT_ID_MASK)
@@ -1744,7 +1784,11 @@ static int bnxt_poll_work(struct bnxt *b
 			if (unlikely(tx_pkts > bp->tx_wake_thresh))
 				rx_pkts = budget;
 		} else if ((TX_CMP_TYPE(txcmp) & 0x30) == 0x10) {
-			rc = bnxt_rx_pkt(bp, bnapi, &raw_cons, &event);
+			if (likely(budget))
+				rc = bnxt_rx_pkt(bp, bnapi, &raw_cons, &event);
+			else
+				rc = bnxt_force_rx_discard(bp, bnapi, &raw_cons,
+							   &event);
 			if (likely(rc >= 0))
 				rx_pkts += rc;
 			else if (rc == -EBUSY)	/* partial completion */
@@ -6663,12 +6707,11 @@ static void bnxt_poll_controller(struct
 	struct bnxt *bp = netdev_priv(dev);
 	int i;
 
-	for (i = 0; i < bp->cp_nr_rings; i++) {
-		struct bnxt_irq *irq = &bp->irq_tbl[i];
+	/* Only process tx rings/combined rings in netpoll mode. */
+	for (i = 0; i < bp->tx_nr_rings; i++) {
+		struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
 
-		disable_irq(irq->vector);
-		irq->handler(irq->vector, bp->bnapi[i]);
-		enable_irq(irq->vector);
+		napi_schedule(&txr->bnapi->napi);
 	}
 }
 #endif
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.h linux-libre-4.12-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.h
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.h	2017-07-02 19:07:02.000000000 -0400
@@ -374,12 +374,16 @@ struct rx_tpa_end_cmp_ext {
 
 	__le32 rx_tpa_end_cmp_errors_v2;
 	#define RX_TPA_END_CMP_V2				(0x1 << 0)
-	#define RX_TPA_END_CMP_ERRORS				(0x7fff << 1)
+	#define RX_TPA_END_CMP_ERRORS				(0x3 << 1)
 	#define RX_TPA_END_CMPL_ERRORS_SHIFT			 1
 
 	u32 rx_tpa_end_cmp_start_opaque;
 };
 
+#define TPA_END_ERRORS(rx_tpa_end_ext)					\
+	((rx_tpa_end_ext)->rx_tpa_end_cmp_errors_v2 &			\
+	 cpu_to_le32(RX_TPA_END_CMP_ERRORS))
+
 #define DB_IDX_MASK						0xffffff
 #define DB_IDX_VALID						(0x1 << 26)
 #define DB_IRQ_DIS						(0x1 << 27)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/freescale/fman/Kconfig linux-libre-4.12-gnu/drivers/net/ethernet/freescale/fman/Kconfig
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/freescale/fman/Kconfig	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/freescale/fman/Kconfig	2017-07-02 19:07:02.000000000 -0400
@@ -2,6 +2,7 @@ config FSL_FMAN
 	tristate "FMan support"
 	depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
 	select GENERIC_ALLOCATOR
+	depends on HAS_DMA
 	select PHYLIB
 	default n
 	help
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c linux-libre-4.12-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c	2017-07-02 19:07:02.000000000 -0400
@@ -3334,6 +3334,9 @@ static int mlxsw_sp_inetaddr_vlan_event(
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(vlan_dev);
 	u16 vid = vlan_dev_vlan_id(vlan_dev);
 
+	if (netif_is_bridge_port(vlan_dev))
+		return 0;
+
 	if (mlxsw_sp_port_dev_check(real_dev))
 		return mlxsw_sp_inetaddr_vport_event(vlan_dev, real_dev, event,
 						     vid);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/rocker/rocker_ofdpa.c linux-libre-4.12-gnu/drivers/net/ethernet/rocker/rocker_ofdpa.c
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/rocker/rocker_ofdpa.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/rocker/rocker_ofdpa.c	2017-07-02 19:07:02.000000000 -0400
@@ -1505,8 +1505,8 @@ static int ofdpa_port_ipv4_nh(struct ofd
 		*index = entry->index;
 		resolved = false;
 	} else if (removing) {
-		ofdpa_neigh_del(trans, found);
 		*index = found->index;
+		ofdpa_neigh_del(trans, found);
 	} else if (updating) {
 		ofdpa_neigh_update(found, trans, NULL, false);
 		resolved = !is_zero_ether_addr(found->eth_dst);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/sfc/ef10.c linux-libre-4.12-gnu/drivers/net/ethernet/sfc/ef10.c
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/sfc/ef10.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/sfc/ef10.c	2017-07-02 19:07:02.000000000 -0400
@@ -4172,7 +4172,7 @@ found:
 	 * recipients
 	 */
 	if (is_mc_recip) {
-		MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN);
+		MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
 		unsigned int depth, i;
 
 		memset(inbuf, 0, sizeof(inbuf));
@@ -4320,7 +4320,7 @@ static int efx_ef10_filter_remove_intern
 			efx_ef10_filter_set_entry(table, filter_idx, NULL, 0);
 		} else {
 			efx_mcdi_display_error(efx, MC_CMD_FILTER_OP,
-					       MC_CMD_FILTER_OP_IN_LEN,
+					       MC_CMD_FILTER_OP_EXT_IN_LEN,
 					       NULL, 0, rc);
 		}
 	}
@@ -4453,7 +4453,7 @@ static s32 efx_ef10_filter_rfs_insert(st
 				      struct efx_filter_spec *spec)
 {
 	struct efx_ef10_filter_table *table = efx->filter_state;
-	MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN);
+	MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
 	struct efx_filter_spec *saved_spec;
 	unsigned int hash, i, depth = 1;
 	bool replacing = false;
@@ -4940,7 +4940,7 @@ not_restored:
 static void efx_ef10_filter_table_remove(struct efx_nic *efx)
 {
 	struct efx_ef10_filter_table *table = efx->filter_state;
-	MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN);
+	MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
 	struct efx_filter_spec *spec;
 	unsigned int filter_idx;
 	int rc;
@@ -5105,6 +5105,7 @@ static int efx_ef10_filter_insert_addr_l
 
 	/* Insert/renew filters */
 	for (i = 0; i < addr_count; i++) {
+		EFX_WARN_ON_PARANOID(ids[i] != EFX_EF10_FILTER_ID_INVALID);
 		efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
 		efx_filter_set_eth_local(&spec, vlan->vid, addr_list[i].addr);
 		rc = efx_ef10_filter_insert(efx, &spec, true);
@@ -5122,11 +5123,11 @@ static int efx_ef10_filter_insert_addr_l
 				}
 				return rc;
 			} else {
-				/* mark as not inserted, and carry on */
-				rc = EFX_EF10_FILTER_ID_INVALID;
+				/* keep invalid ID, and carry on */
 			}
+		} else {
+			ids[i] = efx_ef10_filter_get_unsafe_id(rc);
 		}
-		ids[i] = efx_ef10_filter_get_unsafe_id(rc);
 	}
 
 	if (multicast && rollback) {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/ethernet/ti/cpsw-common.c linux-libre-4.12-gnu/drivers/net/ethernet/ti/cpsw-common.c
--- linux-libre-4.12-rc7-gnu/drivers/net/ethernet/ti/cpsw-common.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/ethernet/ti/cpsw-common.c	2017-07-02 19:07:02.000000000 -0400
@@ -90,7 +90,7 @@ int ti_cm_get_macid(struct device *dev,
 	if (of_device_is_compatible(dev->of_node, "ti,dm816-emac"))
 		return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
 
-	if (of_machine_is_compatible("ti,am4372"))
+	if (of_machine_is_compatible("ti,am43"))
 		return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
 
 	if (of_machine_is_compatible("ti,dra7"))
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/hyperv/netvsc_drv.c linux-libre-4.12-gnu/drivers/net/hyperv/netvsc_drv.c
--- linux-libre-4.12-rc7-gnu/drivers/net/hyperv/netvsc_drv.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/hyperv/netvsc_drv.c	2017-07-02 19:07:02.000000000 -0400
@@ -776,7 +776,7 @@ static int netvsc_set_channels(struct ne
 	    channels->rx_count || channels->tx_count || channels->other_count)
 		return -EINVAL;
 
-	if (count > net->num_tx_queues || count > net->num_rx_queues)
+	if (count > net->num_tx_queues || count > VRSS_CHANNEL_MAX)
 		return -EINVAL;
 
 	if (!nvdev || nvdev->destroy)
@@ -1203,7 +1203,7 @@ static int netvsc_set_rxfh(struct net_de
 	rndis_dev = ndev->extension;
 	if (indir) {
 		for (i = 0; i < ITAB_NUM; i++)
-			if (indir[i] >= dev->num_rx_queues)
+			if (indir[i] >= VRSS_CHANNEL_MAX)
 				return -EINVAL;
 
 		for (i = 0; i < ITAB_NUM; i++)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/macvlan.c linux-libre-4.12-gnu/drivers/net/macvlan.c
--- linux-libre-4.12-rc7-gnu/drivers/net/macvlan.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/macvlan.c	2017-07-02 19:07:02.000000000 -0400
@@ -39,16 +39,20 @@
 #define MACVLAN_HASH_SIZE	(1<<MACVLAN_HASH_BITS)
 #define MACVLAN_BC_QUEUE_LEN	1000
 
+#define MACVLAN_F_PASSTHRU	1
+#define MACVLAN_F_ADDRCHANGE	2
+
 struct macvlan_port {
 	struct net_device	*dev;
 	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
 	struct list_head	vlans;
 	struct sk_buff_head	bc_queue;
 	struct work_struct	bc_work;
-	bool 			passthru;
+	u32			flags;
 	int			count;
 	struct hlist_head	vlan_source_hash[MACVLAN_HASH_SIZE];
 	DECLARE_BITMAP(mc_filter, MACVLAN_MC_FILTER_SZ);
+	unsigned char           perm_addr[ETH_ALEN];
 };
 
 struct macvlan_source_entry {
@@ -66,6 +70,31 @@ struct macvlan_skb_cb {
 
 static void macvlan_port_destroy(struct net_device *dev);
 
+static inline bool macvlan_passthru(const struct macvlan_port *port)
+{
+	return port->flags & MACVLAN_F_PASSTHRU;
+}
+
+static inline void macvlan_set_passthru(struct macvlan_port *port)
+{
+	port->flags |= MACVLAN_F_PASSTHRU;
+}
+
+static inline bool macvlan_addr_change(const struct macvlan_port *port)
+{
+	return port->flags & MACVLAN_F_ADDRCHANGE;
+}
+
+static inline void macvlan_set_addr_change(struct macvlan_port *port)
+{
+	port->flags |= MACVLAN_F_ADDRCHANGE;
+}
+
+static inline void macvlan_clear_addr_change(struct macvlan_port *port)
+{
+	port->flags &= ~MACVLAN_F_ADDRCHANGE;
+}
+
 /* Hash Ethernet address */
 static u32 macvlan_eth_hash(const unsigned char *addr)
 {
@@ -181,11 +210,12 @@ static void macvlan_hash_change_addr(str
 static bool macvlan_addr_busy(const struct macvlan_port *port,
 			      const unsigned char *addr)
 {
-	/* Test to see if the specified multicast address is
+	/* Test to see if the specified address is
 	 * currently in use by the underlying device or
 	 * another macvlan.
 	 */
-	if (ether_addr_equal_64bits(port->dev->dev_addr, addr))
+	if (!macvlan_passthru(port) && !macvlan_addr_change(port) &&
+	    ether_addr_equal_64bits(port->dev->dev_addr, addr))
 		return true;
 
 	if (macvlan_hash_lookup(port, addr))
@@ -445,7 +475,7 @@ static rx_handler_result_t macvlan_handl
 	}
 
 	macvlan_forward_source(skb, port, eth->h_source);
-	if (port->passthru)
+	if (macvlan_passthru(port))
 		vlan = list_first_or_null_rcu(&port->vlans,
 					      struct macvlan_dev, list);
 	else
@@ -574,7 +604,7 @@ static int macvlan_open(struct net_devic
 	struct net_device *lowerdev = vlan->lowerdev;
 	int err;
 
-	if (vlan->port->passthru) {
+	if (macvlan_passthru(vlan->port)) {
 		if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC)) {
 			err = dev_set_promiscuity(lowerdev, 1);
 			if (err < 0)
@@ -649,7 +679,7 @@ static int macvlan_stop(struct net_devic
 	dev_uc_unsync(lowerdev, dev);
 	dev_mc_unsync(lowerdev, dev);
 
-	if (vlan->port->passthru) {
+	if (macvlan_passthru(vlan->port)) {
 		if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
 			dev_set_promiscuity(lowerdev, -1);
 		goto hash_del;
@@ -672,6 +702,7 @@ static int macvlan_sync_address(struct n
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
+	struct macvlan_port *port = vlan->port;
 	int err;
 
 	if (!(dev->flags & IFF_UP)) {
@@ -682,7 +713,7 @@ static int macvlan_sync_address(struct n
 		if (macvlan_addr_busy(vlan->port, addr))
 			return -EBUSY;
 
-		if (!vlan->port->passthru) {
+		if (!macvlan_passthru(port)) {
 			err = dev_uc_add(lowerdev, addr);
 			if (err)
 				return err;
@@ -692,6 +723,15 @@ static int macvlan_sync_address(struct n
 
 		macvlan_hash_change_addr(vlan, addr);
 	}
+	if (macvlan_passthru(port) && !macvlan_addr_change(port)) {
+		/* Since addr_change isn't set, we are here due to lower
+		 * device change.  Save the lower-dev address so we can
+		 * restore it later.
+		 */
+		ether_addr_copy(vlan->port->perm_addr,
+				lowerdev->dev_addr);
+	}
+	macvlan_clear_addr_change(port);
 	return 0;
 }
 
@@ -703,7 +743,12 @@ static int macvlan_set_mac_address(struc
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
+	/* If the addresses are the same, this is a no-op */
+	if (ether_addr_equal(dev->dev_addr, addr->sa_data))
+		return 0;
+
 	if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
+		macvlan_set_addr_change(vlan->port);
 		dev_set_mac_address(vlan->lowerdev, addr);
 		return 0;
 	}
@@ -928,7 +973,7 @@ static int macvlan_fdb_add(struct ndmsg
 	/* Support unicast filter only on passthru devices.
 	 * Multicast filter should be allowed on all devices.
 	 */
-	if (!vlan->port->passthru && is_unicast_ether_addr(addr))
+	if (!macvlan_passthru(vlan->port) && is_unicast_ether_addr(addr))
 		return -EOPNOTSUPP;
 
 	if (flags & NLM_F_REPLACE)
@@ -952,7 +997,7 @@ static int macvlan_fdb_del(struct ndmsg
 	/* Support unicast filter only on passthru devices.
 	 * Multicast filter should be allowed on all devices.
 	 */
-	if (!vlan->port->passthru && is_unicast_ether_addr(addr))
+	if (!macvlan_passthru(vlan->port) && is_unicast_ether_addr(addr))
 		return -EOPNOTSUPP;
 
 	if (is_unicast_ether_addr(addr))
@@ -1120,8 +1165,8 @@ static int macvlan_port_create(struct ne
 	if (port == NULL)
 		return -ENOMEM;
 
-	port->passthru = false;
 	port->dev = dev;
+	ether_addr_copy(port->perm_addr, dev->dev_addr);
 	INIT_LIST_HEAD(&port->vlans);
 	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
 		INIT_HLIST_HEAD(&port->vlan_hash[i]);
@@ -1161,6 +1206,18 @@ static void macvlan_port_destroy(struct
 		kfree_skb(skb);
 	}
 
+	/* If the lower device address has been changed by passthru
+	 * macvlan, put it back.
+	 */
+	if (macvlan_passthru(port) &&
+	    !ether_addr_equal(port->dev->dev_addr, port->perm_addr)) {
+		struct sockaddr sa;
+
+		sa.sa_family = port->dev->type;
+		memcpy(&sa.sa_data, port->perm_addr, port->dev->addr_len);
+		dev_set_mac_address(port->dev, &sa);
+	}
+
 	kfree(port);
 }
 
@@ -1326,7 +1383,7 @@ int macvlan_common_newlink(struct net *s
 	port = macvlan_port_get_rtnl(lowerdev);
 
 	/* Only 1 macvlan device can be created in passthru mode */
-	if (port->passthru) {
+	if (macvlan_passthru(port)) {
 		/* The macvlan port must be not created this time,
 		 * still goto destroy_macvlan_port for readability.
 		 */
@@ -1352,7 +1409,7 @@ int macvlan_common_newlink(struct net *s
 			err = -EINVAL;
 			goto destroy_macvlan_port;
 		}
-		port->passthru = true;
+		macvlan_set_passthru(port);
 		eth_hw_addr_inherit(dev, lowerdev);
 	}
 
@@ -1434,7 +1491,7 @@ static int macvlan_changelink(struct net
 	if (data && data[IFLA_MACVLAN_FLAGS]) {
 		__u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
 		bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC;
-		if (vlan->port->passthru && promisc) {
+		if (macvlan_passthru(vlan->port) && promisc) {
 			int err;
 
 			if (flags & MACVLAN_FLAG_NOPROMISC)
@@ -1597,7 +1654,7 @@ static int macvlan_device_event(struct n
 		}
 		break;
 	case NETDEV_CHANGEADDR:
-		if (!port->passthru)
+		if (!macvlan_passthru(port))
 			return NOTIFY_DONE;
 
 		vlan = list_first_entry_or_null(&port->vlans,
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/phy/dp83640.c linux-libre-4.12-gnu/drivers/net/phy/dp83640.c
--- linux-libre-4.12-rc7-gnu/drivers/net/phy/dp83640.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/phy/dp83640.c	2017-07-02 19:07:02.000000000 -0400
@@ -908,7 +908,7 @@ static void decode_txts(struct dp83640_p
 	if (overflow) {
 		pr_debug("tx timestamp queue overflow, count %d\n", overflow);
 		while (skb) {
-			skb_complete_tx_timestamp(skb, NULL);
+			kfree_skb(skb);
 			skb = skb_dequeue(&dp83640->tx_queue);
 		}
 		return;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/phy/micrel.c linux-libre-4.12-gnu/drivers/net/phy/micrel.c
--- linux-libre-4.12-rc7-gnu/drivers/net/phy/micrel.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/phy/micrel.c	2017-07-02 19:07:02.000000000 -0400
@@ -619,6 +619,8 @@ static int ksz9031_read_status(struct ph
 	if ((regval & 0xFF) == 0xFF) {
 		phy_init_hw(phydev);
 		phydev->link = 0;
+		if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev))
+			phydev->drv->config_intr(phydev);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/usb/ax88179_178a.c linux-libre-4.12-gnu/drivers/net/usb/ax88179_178a.c
--- linux-libre-4.12-rc7-gnu/drivers/net/usb/ax88179_178a.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/usb/ax88179_178a.c	2017-07-02 19:07:02.000000000 -0400
@@ -1722,6 +1722,18 @@ static const struct driver_info lenovo_i
 	.tx_fixup = ax88179_tx_fixup,
 };
 
+static const struct driver_info belkin_info = {
+	.description = "Belkin USB Ethernet Adapter",
+	.bind	= ax88179_bind,
+	.unbind = ax88179_unbind,
+	.status = ax88179_status,
+	.link_reset = ax88179_link_reset,
+	.reset	= ax88179_reset,
+	.flags	= FLAG_ETHER | FLAG_FRAMING_AX,
+	.rx_fixup = ax88179_rx_fixup,
+	.tx_fixup = ax88179_tx_fixup,
+};
+
 static const struct usb_device_id products[] = {
 {
 	/* ASIX AX88179 10/100/1000 */
@@ -1751,6 +1763,10 @@ static const struct usb_device_id produc
 	/* Lenovo OneLinkDock Gigabit LAN */
 	USB_DEVICE(0x17ef, 0x304b),
 	.driver_info = (unsigned long)&lenovo_info,
+}, {
+	/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
+	USB_DEVICE(0x050d, 0x0128),
+	.driver_info = (unsigned long)&belkin_info,
 },
 	{ },
 };
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/veth.c linux-libre-4.12-gnu/drivers/net/veth.c
--- linux-libre-4.12-rc7-gnu/drivers/net/veth.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/veth.c	2017-07-02 19:07:02.000000000 -0400
@@ -383,7 +383,7 @@ static int veth_newlink(struct net *src_
 		tbp = tb;
 	}
 
-	if (tbp[IFLA_IFNAME]) {
+	if (ifmp && tbp[IFLA_IFNAME]) {
 		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
 		name_assign_type = NET_NAME_USER;
 	} else {
@@ -402,7 +402,7 @@ static int veth_newlink(struct net *src_
 		return PTR_ERR(peer);
 	}
 
-	if (tbp[IFLA_ADDRESS] == NULL)
+	if (!ifmp || !tbp[IFLA_ADDRESS])
 		eth_hw_addr_random(peer);
 
 	if (ifmp && (dev->ifindex != 0))
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/virtio_net.c linux-libre-4.12-gnu/drivers/net/virtio_net.c
--- linux-libre-4.12-rc7-gnu/drivers/net/virtio_net.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/virtio_net.c	2017-07-02 19:07:02.000000000 -0400
@@ -1797,6 +1797,7 @@ static void virtnet_freeze_down(struct v
 	flush_work(&vi->config_work);
 
 	netif_device_detach(vi->dev);
+	netif_tx_disable(vi->dev);
 	cancel_delayed_work_sync(&vi->refill);
 
 	if (netif_running(vi->dev)) {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/xen-netback/common.h linux-libre-4.12-gnu/drivers/net/xen-netback/common.h
--- linux-libre-4.12-rc7-gnu/drivers/net/xen-netback/common.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/xen-netback/common.h	2017-07-02 19:07:02.000000000 -0400
@@ -199,6 +199,7 @@ struct xenvif_queue { /* Per-queue data
 	unsigned long   remaining_credit;
 	struct timer_list credit_timeout;
 	u64 credit_window_start;
+	bool rate_limited;
 
 	/* Statistics */
 	struct xenvif_stats stats;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/xen-netback/interface.c linux-libre-4.12-gnu/drivers/net/xen-netback/interface.c
--- linux-libre-4.12-rc7-gnu/drivers/net/xen-netback/interface.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/xen-netback/interface.c	2017-07-02 19:07:02.000000000 -0400
@@ -106,7 +106,11 @@ static int xenvif_poll(struct napi_struc
 
 	if (work_done < budget) {
 		napi_complete_done(napi, work_done);
-		xenvif_napi_schedule_or_enable_events(queue);
+		/* If the queue is rate-limited, it shall be
+		 * rescheduled in the timer callback.
+		 */
+		if (likely(!queue->rate_limited))
+			xenvif_napi_schedule_or_enable_events(queue);
 	}
 
 	return work_done;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/net/xen-netback/netback.c linux-libre-4.12-gnu/drivers/net/xen-netback/netback.c
--- linux-libre-4.12-rc7-gnu/drivers/net/xen-netback/netback.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/net/xen-netback/netback.c	2017-07-02 19:07:02.000000000 -0400
@@ -180,6 +180,7 @@ static void tx_add_credit(struct xenvif_
 		max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */
 
 	queue->remaining_credit = min(max_credit, max_burst);
+	queue->rate_limited = false;
 }
 
 void xenvif_tx_credit_callback(unsigned long data)
@@ -686,8 +687,10 @@ static bool tx_credit_exceeded(struct xe
 		msecs_to_jiffies(queue->credit_usec / 1000);
 
 	/* Timer could already be pending in rare cases. */
-	if (timer_pending(&queue->credit_timeout))
+	if (timer_pending(&queue->credit_timeout)) {
+		queue->rate_limited = true;
 		return true;
+	}
 
 	/* Passed the point where we can replenish credit? */
 	if (time_after_eq64(now, next_credit)) {
@@ -702,6 +705,7 @@ static bool tx_credit_exceeded(struct xe
 		mod_timer(&queue->credit_timeout,
 			  next_credit);
 		queue->credit_window_start = next_credit;
+		queue->rate_limited = true;
 
 		return true;
 	}
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/nvme/host/pci.c linux-libre-4.12-gnu/drivers/nvme/host/pci.c
--- linux-libre-4.12-rc7-gnu/drivers/nvme/host/pci.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/nvme/host/pci.c	2017-07-02 19:07:02.000000000 -0400
@@ -1805,7 +1805,8 @@ static void nvme_dev_disable(struct nvme
 	if (pci_is_enabled(pdev)) {
 		u32 csts = readl(dev->bar + NVME_REG_CSTS);
 
-		if (dev->ctrl.state == NVME_CTRL_LIVE)
+		if (dev->ctrl.state == NVME_CTRL_LIVE ||
+		    dev->ctrl.state == NVME_CTRL_RESETTING)
 			nvme_start_freeze(&dev->ctrl);
 		dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) ||
 			pdev->error_state  != pci_channel_io_normal);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/drivers/pinctrl/pinctrl-rockchip.c linux-libre-4.12-gnu/drivers/pinctrl/pinctrl-rockchip.c
--- linux-libre-4.12-rc7-gnu/drivers/pinctrl/pinctrl-rockchip.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/drivers/pinctrl/pinctrl-rockchip.c	2017-07-02 19:07:02.000000000 -0400
@@ -143,9 +143,6 @@ struct rockchip_drv {
  * @gpio_chip: gpiolib chip
  * @grange: gpio range
  * @slock: spinlock for the gpio bank
- * @irq_lock: bus lock for irq chip
- * @new_irqs: newly configured irqs which must be muxed as GPIOs in
- *	irq_bus_sync_unlock()
  */
 struct rockchip_pin_bank {
 	void __iomem			*reg_base;
@@ -168,8 +165,6 @@ struct rockchip_pin_bank {
 	struct pinctrl_gpio_range	grange;
 	raw_spinlock_t			slock;
 	u32				toggle_edge_mode;
-	struct mutex			irq_lock;
-	u32				new_irqs;
 };
 
 #define PIN_BANK(id, pins, label)			\
@@ -2134,12 +2129,11 @@ static int rockchip_irq_set_type(struct
 	int ret;
 
 	/* make sure the pin is configured as gpio input */
-	ret = rockchip_verify_mux(bank, d->hwirq, RK_FUNC_GPIO);
+	ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
 	if (ret < 0)
 		return ret;
 
-	bank->new_irqs |= mask;
-
+	clk_enable(bank->clk);
 	raw_spin_lock_irqsave(&bank->slock, flags);
 
 	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
@@ -2197,6 +2191,7 @@ static int rockchip_irq_set_type(struct
 	default:
 		irq_gc_unlock(gc);
 		raw_spin_unlock_irqrestore(&bank->slock, flags);
+		clk_disable(bank->clk);
 		return -EINVAL;
 	}
 
@@ -2205,6 +2200,7 @@ static int rockchip_irq_set_type(struct
 
 	irq_gc_unlock(gc);
 	raw_spin_unlock_irqrestore(&bank->slock, flags);
+	clk_disable(bank->clk);
 
 	return 0;
 }
@@ -2248,34 +2244,6 @@ static void rockchip_irq_disable(struct
 	clk_disable(bank->clk);
 }
 
-static void rockchip_irq_bus_lock(struct irq_data *d)
-{
-	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-	struct rockchip_pin_bank *bank = gc->private;
-
-	clk_enable(bank->clk);
-	mutex_lock(&bank->irq_lock);
-}
-
-static void rockchip_irq_bus_sync_unlock(struct irq_data *d)
-{
-	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-	struct rockchip_pin_bank *bank = gc->private;
-
-	while (bank->new_irqs) {
-		unsigned int irq = __ffs(bank->new_irqs);
-		int ret;
-
-		ret = rockchip_set_mux(bank, irq, RK_FUNC_GPIO);
-		WARN_ON(ret < 0);
-
-		bank->new_irqs &= ~BIT(irq);
-	}
-
-	mutex_unlock(&bank->irq_lock);
-	clk_disable(bank->clk);
-}
-
 static int rockchip_interrupts_register(struct platform_device *pdev,
 						struct rockchip_pinctrl *info)
 {
@@ -2342,9 +2310,6 @@ static int rockchip_interrupts_register(
 		gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
 		gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
 		gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
-		gc->chip_types[0].chip.irq_bus_lock = rockchip_irq_bus_lock;
-		gc->chip_types[0].chip.irq_bus_sync_unlock =
-						rockchip_irq_bus_sync_unlock;
 		gc->wake_enabled = IRQ_MSK(bank->nr_pins);
 
 		irq_set_chained_handler_and_data(bank->irq,
@@ -2518,7 +2483,6 @@ static struct rockchip_pin_ctrl *rockchi
 		int bank_pins = 0;
 
 		raw_spin_lock_init(&bank->slock);
-		mutex_init(&bank->irq_lock);
 		bank->drvdata = d;
 		bank->pin_base = ctrl->nr_pins;
 		ctrl->nr_pins += bank->nr_pins;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/fs/block_dev.c linux-libre-4.12-gnu/fs/block_dev.c
--- linux-libre-4.12-rc7-gnu/fs/block_dev.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/fs/block_dev.c	2017-07-02 19:07:02.000000000 -0400
@@ -263,7 +263,10 @@ __blkdev_direct_IO_simple(struct kiocb *
 		kfree(vecs);
 
 	if (unlikely(bio.bi_error))
-		return bio.bi_error;
+		ret = bio.bi_error;
+
+	bio_uninit(&bio);
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/fs/nfs/callback_xdr.c linux-libre-4.12-gnu/fs/nfs/callback_xdr.c
--- linux-libre-4.12-rc7-gnu/fs/nfs/callback_xdr.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/fs/nfs/callback_xdr.c	2017-07-02 19:07:02.000000000 -0400
@@ -753,7 +753,6 @@ static void nfs4_callback_free_slot(stru
 	 * A single slot, so highest used slotid is either 0 or -1
 	 */
 	nfs4_free_slot(tbl, slot);
-	nfs4_slot_tbl_drain_complete(tbl);
 	spin_unlock(&tbl->slot_tbl_lock);
 }
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/fs/nfs/dir.c linux-libre-4.12-gnu/fs/nfs/dir.c
--- linux-libre-4.12-rc7-gnu/fs/nfs/dir.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/fs/nfs/dir.c	2017-07-02 19:07:02.000000000 -0400
@@ -1946,29 +1946,6 @@ nfs_link(struct dentry *old_dentry, stru
 }
 EXPORT_SYMBOL_GPL(nfs_link);
 
-static void
-nfs_complete_rename(struct rpc_task *task, struct nfs_renamedata *data)
-{
-	struct dentry *old_dentry = data->old_dentry;
-	struct dentry *new_dentry = data->new_dentry;
-	struct inode *old_inode = d_inode(old_dentry);
-	struct inode *new_inode = d_inode(new_dentry);
-
-	nfs_mark_for_revalidate(old_inode);
-
-	switch (task->tk_status) {
-	case 0:
-		if (new_inode != NULL)
-			nfs_drop_nlink(new_inode);
-		d_move(old_dentry, new_dentry);
-		nfs_set_verifier(new_dentry,
-					nfs_save_change_attribute(data->new_dir));
-		break;
-	case -ENOENT:
-		nfs_dentry_handle_enoent(old_dentry);
-	}
-}
-
 /*
  * RENAME
  * FIXME: Some nfsds, like the Linux user space nfsd, may generate a
@@ -1999,7 +1976,7 @@ int nfs_rename(struct inode *old_dir, st
 {
 	struct inode *old_inode = d_inode(old_dentry);
 	struct inode *new_inode = d_inode(new_dentry);
-	struct dentry *dentry = NULL;
+	struct dentry *dentry = NULL, *rehash = NULL;
 	struct rpc_task *task;
 	int error = -EBUSY;
 
@@ -2022,8 +1999,10 @@ int nfs_rename(struct inode *old_dir, st
 		 * To prevent any new references to the target during the
 		 * rename, we unhash the dentry in advance.
 		 */
-		if (!d_unhashed(new_dentry))
+		if (!d_unhashed(new_dentry)) {
 			d_drop(new_dentry);
+			rehash = new_dentry;
+		}
 
 		if (d_count(new_dentry) > 2) {
 			int err;
@@ -2040,6 +2019,7 @@ int nfs_rename(struct inode *old_dir, st
 				goto out;
 
 			new_dentry = dentry;
+			rehash = NULL;
 			new_inode = NULL;
 		}
 	}
@@ -2048,8 +2028,7 @@ int nfs_rename(struct inode *old_dir, st
 	if (new_inode != NULL)
 		NFS_PROTO(new_inode)->return_delegation(new_inode);
 
-	task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
-					nfs_complete_rename);
+	task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
 	if (IS_ERR(task)) {
 		error = PTR_ERR(task);
 		goto out;
@@ -2059,9 +2038,27 @@ int nfs_rename(struct inode *old_dir, st
 	if (error == 0)
 		error = task->tk_status;
 	rpc_put_task(task);
+	nfs_mark_for_revalidate(old_inode);
 out:
+	if (rehash)
+		d_rehash(rehash);
 	trace_nfs_rename_exit(old_dir, old_dentry,
 			new_dir, new_dentry, error);
+	if (!error) {
+		if (new_inode != NULL)
+			nfs_drop_nlink(new_inode);
+		/*
+		 * The d_move() should be here instead of in an async RPC completion
+		 * handler because we need the proper locks to move the dentry.  If
+		 * we're interrupted by a signal, the async RPC completion handler
+		 * should mark the directories for revalidation.
+		 */
+		d_move(old_dentry, new_dentry);
+		nfs_set_verifier(new_dentry,
+					nfs_save_change_attribute(new_dir));
+	} else if (error == -ENOENT)
+		nfs_dentry_handle_enoent(old_dentry);
+
 	/* new dentry created? */
 	if (dentry)
 		dput(dentry);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/fs/nfs/nfs4proc.c linux-libre-4.12-gnu/fs/nfs/nfs4proc.c
--- linux-libre-4.12-rc7-gnu/fs/nfs/nfs4proc.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/fs/nfs/nfs4proc.c	2017-07-02 19:07:02.000000000 -0400
@@ -2589,7 +2589,8 @@ static inline void nfs4_exclusive_attrse
 
 	/* Except MODE, it seems harmless of setting twice. */
 	if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
-		attrset[1] & FATTR4_WORD1_MODE)
+		(attrset[1] & FATTR4_WORD1_MODE ||
+		 attrset[2] & FATTR4_WORD2_MODE_UMASK))
 		sattr->ia_valid &= ~ATTR_MODE;
 
 	if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
@@ -8416,6 +8417,7 @@ static void nfs4_layoutget_release(void
 	size_t max_pages = max_response_pages(server);
 
 	dprintk("--> %s\n", __func__);
+	nfs4_sequence_free_slot(&lgp->res.seq_res);
 	nfs4_free_pages(lgp->args.layout.pages, max_pages);
 	pnfs_put_layout_hdr(NFS_I(inode)->layout);
 	put_nfs_open_context(lgp->args.ctx);
@@ -8490,7 +8492,6 @@ nfs4_proc_layoutget(struct nfs4_layoutge
 	/* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
 	if (status == 0 && lgp->res.layoutp->len)
 		lseg = pnfs_layout_process(lgp);
-	nfs4_sequence_free_slot(&lgp->res.seq_res);
 	rpc_put_task(task);
 	dprintk("<-- %s status=%d\n", __func__, status);
 	if (status)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/fs/nfs/nfs4state.c linux-libre-4.12-gnu/fs/nfs/nfs4state.c
--- linux-libre-4.12-rc7-gnu/fs/nfs/nfs4state.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/fs/nfs/nfs4state.c	2017-07-02 19:07:02.000000000 -0400
@@ -2134,6 +2134,8 @@ again:
 	put_rpccred(cred);
 	switch (status) {
 	case 0:
+	case -EINTR:
+	case -ERESTARTSYS:
 		break;
 	case -ETIMEDOUT:
 		if (clnt->cl_softrtry)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/fs/overlayfs/copy_up.c linux-libre-4.12-gnu/fs/overlayfs/copy_up.c
--- linux-libre-4.12-rc7-gnu/fs/overlayfs/copy_up.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/fs/overlayfs/copy_up.c	2017-07-02 19:07:02.000000000 -0400
@@ -330,15 +330,9 @@ static int ovl_copy_up_locked(struct den
 		.link = link
 	};
 
-	upper = lookup_one_len(dentry->d_name.name, upperdir,
-			       dentry->d_name.len);
-	err = PTR_ERR(upper);
-	if (IS_ERR(upper))
-		goto out;
-
 	err = security_inode_copy_up(dentry, &new_creds);
 	if (err < 0)
-		goto out1;
+		goto out;
 
 	if (new_creds)
 		old_creds = override_creds(new_creds);
@@ -362,7 +356,7 @@ static int ovl_copy_up_locked(struct den
 	}
 
 	if (err)
-		goto out2;
+		goto out;
 
 	if (S_ISREG(stat->mode)) {
 		struct path upperpath;
@@ -398,10 +392,23 @@ static int ovl_copy_up_locked(struct den
 	/*
 	 * Store identifier of lower inode in upper inode xattr to
 	 * allow lookup of the copy up origin inode.
+	 *
+	 * Don't set origin when we are breaking the association with a lower
+	 * hard link.
 	 */
-	err = ovl_set_origin(dentry, lowerpath->dentry, temp);
-	if (err)
+	if (S_ISDIR(stat->mode) || stat->nlink == 1) {
+		err = ovl_set_origin(dentry, lowerpath->dentry, temp);
+		if (err)
+			goto out_cleanup;
+	}
+
+	upper = lookup_one_len(dentry->d_name.name, upperdir,
+			       dentry->d_name.len);
+	if (IS_ERR(upper)) {
+		err = PTR_ERR(upper);
+		upper = NULL;
 		goto out_cleanup;
+	}
 
 	if (tmpfile)
 		err = ovl_do_link(temp, udir, upper, true);
@@ -416,17 +423,15 @@ static int ovl_copy_up_locked(struct den
 
 	/* Restore timestamps on parent (best effort) */
 	ovl_set_timestamps(upperdir, pstat);
-out2:
+out:
 	dput(temp);
-out1:
 	dput(upper);
-out:
 	return err;
 
 out_cleanup:
 	if (!tmpfile)
 		ovl_cleanup(wdir, temp);
-	goto out2;
+	goto out;
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/include/linux/bio.h linux-libre-4.12-gnu/include/linux/bio.h
--- linux-libre-4.12-rc7-gnu/include/linux/bio.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/include/linux/bio.h	2017-07-02 19:07:02.000000000 -0400
@@ -426,6 +426,7 @@ extern void bio_advance(struct bio *, un
 
 extern void bio_init(struct bio *bio, struct bio_vec *table,
 		     unsigned short max_vecs);
+extern void bio_uninit(struct bio *);
 extern void bio_reset(struct bio *);
 void bio_chain(struct bio *, struct bio *);
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/include/linux/hashtable.h linux-libre-4.12-gnu/include/linux/hashtable.h
--- linux-libre-4.12-rc7-gnu/include/linux/hashtable.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/include/linux/hashtable.h	2017-07-02 19:07:02.000000000 -0400
@@ -167,7 +167,6 @@ static inline void hash_del_rcu(struct h
 /**
  * hash_for_each_possible_rcu - iterate over all possible objects hashing to the
  * same bucket in an rcu enabled hashtable
- * in a rcu enabled hashtable
  * @name: hashtable to iterate
  * @obj: the type * to use as a loop cursor for each entry
  * @member: the name of the hlist_node within the struct
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/include/linux/moduleparam.h linux-libre-4.12-gnu/include/linux/moduleparam.h
--- linux-libre-4.12-rc7-gnu/include/linux/moduleparam.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/include/linux/moduleparam.h	2017-07-02 19:07:02.000000000 -0400
@@ -457,7 +457,7 @@ enum hwparam_type {
 	hwparam_ioport,		/* Module parameter configures an I/O port */
 	hwparam_iomem,		/* Module parameter configures an I/O mem address */
 	hwparam_ioport_or_iomem, /* Module parameter could be either, depending on other option */
-	hwparam_irq,		/* Module parameter configures an I/O port */
+	hwparam_irq,		/* Module parameter configures an IRQ */
 	hwparam_dma,		/* Module parameter configures a DMA channel */
 	hwparam_dma_addr,	/* Module parameter configures a DMA buffer address */
 	hwparam_other,		/* Module parameter configures some other value */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/include/net/xfrm.h linux-libre-4.12-gnu/include/net/xfrm.h
--- linux-libre-4.12-rc7-gnu/include/net/xfrm.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/include/net/xfrm.h	2017-07-02 19:07:02.000000000 -0400
@@ -1850,8 +1850,9 @@ static inline struct xfrm_offload *xfrm_
 }
 #endif
 
-#ifdef CONFIG_XFRM_OFFLOAD
 void __net_init xfrm_dev_init(void);
+
+#ifdef CONFIG_XFRM_OFFLOAD
 int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features);
 int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
 		       struct xfrm_user_offload *xuo);
@@ -1877,10 +1878,6 @@ static inline void xfrm_dev_state_free(s
 	}
 }
 #else
-static inline void __net_init xfrm_dev_init(void)
-{
-}
-
 static inline int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
 {
 	return 0;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/include/uapi/linux/a.out.h linux-libre-4.12-gnu/include/uapi/linux/a.out.h
--- linux-libre-4.12-rc7-gnu/include/uapi/linux/a.out.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/include/uapi/linux/a.out.h	2017-07-02 19:07:02.000000000 -0400
@@ -112,24 +112,7 @@ enum machine_type {
 #define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
 #endif
 
-/* Address of data segment in memory after it is loaded.
-   Note that it is up to you to define SEGMENT_SIZE
-   on machines not listed here.  */
-#if defined(vax) || defined(hp300) || defined(pyr)
-#define SEGMENT_SIZE page_size
-#endif
-#ifdef	sony
-#define	SEGMENT_SIZE	0x2000
-#endif	/* Sony.  */
-#ifdef is68k
-#define SEGMENT_SIZE 0x20000
-#endif
-#if defined(m68k) && defined(PORTAR)
-#define PAGE_SIZE 0x400
-#define SEGMENT_SIZE PAGE_SIZE
-#endif
-
-#ifdef linux
+/* Address of data segment in memory after it is loaded. */
 #ifndef __KERNEL__
 #include <unistd.h>
 #endif
@@ -142,7 +125,6 @@ enum machine_type {
 #endif
 #endif
 #endif
-#endif
 
 #define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
 
@@ -260,13 +242,7 @@ struct relocation_info
   unsigned int r_extern:1;
   /* Four bits that aren't used, but when writing an object file
      it is desirable to clear them.  */
-#ifdef NS32K
-  unsigned r_bsr:1;
-  unsigned r_disp:1;
-  unsigned r_pad:2;
-#else
   unsigned int r_pad:4;
-#endif
 };
 #endif /* no N_RELOCATION_INFO_DECLARED.  */
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/kernel/bpf/verifier.c linux-libre-4.12-gnu/kernel/bpf/verifier.c
--- linux-libre-4.12-rc7-gnu/kernel/bpf/verifier.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/kernel/bpf/verifier.c	2017-07-02 19:07:02.000000000 -0400
@@ -989,6 +989,11 @@ static int check_xadd(struct bpf_verifie
 	if (err)
 		return err;
 
+	if (is_pointer_value(env, insn->src_reg)) {
+		verbose("R%d leaks addr into mem\n", insn->src_reg);
+		return -EACCES;
+	}
+
 	/* check whether atomic_add can read the memory */
 	err = check_mem_access(env, insn->dst_reg, insn->off,
 			       BPF_SIZE(insn->code), BPF_READ, -1);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/kernel/trace/ftrace.c linux-libre-4.12-gnu/kernel/trace/ftrace.c
--- linux-libre-4.12-rc7-gnu/kernel/trace/ftrace.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/kernel/trace/ftrace.c	2017-07-02 19:07:02.000000000 -0400
@@ -4337,9 +4337,6 @@ static int ftrace_process_regex(struct f
 
 	command = strsep(&next, ":");
 
-	if (WARN_ON_ONCE(!tr))
-		return -EINVAL;
-
 	mutex_lock(&ftrace_cmd_mutex);
 	list_for_each_entry(p, &ftrace_commands, list) {
 		if (strcmp(p->name, command) == 0) {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/kernel/trace/trace.c linux-libre-4.12-gnu/kernel/trace/trace.c
--- linux-libre-4.12-rc7-gnu/kernel/trace/trace.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/kernel/trace/trace.c	2017-07-02 19:07:02.000000000 -0400
@@ -6881,6 +6881,9 @@ ftrace_trace_snapshot_callback(struct tr
 	char *number;
 	int ret;
 
+	if (!tr)
+		return -ENODEV;
+
 	/* hash funcs only work with set_ftrace_filter */
 	if (!enable)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/kernel/trace/trace_functions.c linux-libre-4.12-gnu/kernel/trace/trace_functions.c
--- linux-libre-4.12-rc7-gnu/kernel/trace/trace_functions.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/kernel/trace/trace_functions.c	2017-07-02 19:07:02.000000000 -0400
@@ -654,6 +654,9 @@ ftrace_trace_onoff_callback(struct trace
 {
 	struct ftrace_probe_ops *ops;
 
+	if (!tr)
+		return -ENODEV;
+
 	/* we register both traceon and traceoff to this callback */
 	if (strcmp(cmd, "traceon") == 0)
 		ops = param ? &traceon_count_probe_ops : &traceon_probe_ops;
@@ -670,6 +673,9 @@ ftrace_stacktrace_callback(struct trace_
 {
 	struct ftrace_probe_ops *ops;
 
+	if (!tr)
+		return -ENODEV;
+
 	ops = param ? &stacktrace_count_probe_ops : &stacktrace_probe_ops;
 
 	return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
@@ -682,6 +688,9 @@ ftrace_dump_callback(struct trace_array
 {
 	struct ftrace_probe_ops *ops;
 
+	if (!tr)
+		return -ENODEV;
+
 	ops = &dump_probe_ops;
 
 	/* Only dump once. */
@@ -695,6 +704,9 @@ ftrace_cpudump_callback(struct trace_arr
 {
 	struct ftrace_probe_ops *ops;
 
+	if (!tr)
+		return -ENODEV;
+
 	ops = &cpudump_probe_ops;
 
 	/* Only dump once. */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/kernel/trace/trace_kprobe.c linux-libre-4.12-gnu/kernel/trace/trace_kprobe.c
--- linux-libre-4.12-rc7-gnu/kernel/trace/trace_kprobe.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/kernel/trace/trace_kprobe.c	2017-07-02 19:07:02.000000000 -0400
@@ -707,20 +707,16 @@ static int create_trace_kprobe(int argc,
 		pr_info("Probe point is not specified.\n");
 		return -EINVAL;
 	}
-	if (isdigit(argv[1][0])) {
-		/* an address specified */
-		ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr);
-		if (ret) {
-			pr_info("Failed to parse address.\n");
-			return ret;
-		}
-	} else {
+
+	/* try to parse an address. if that fails, try to read the
+	 * input as a symbol. */
+	if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
 		/* a symbol specified */
 		symbol = argv[1];
 		/* TODO: support .init module functions */
 		ret = traceprobe_split_symbol_offset(symbol, &offset);
 		if (ret) {
-			pr_info("Failed to parse symbol.\n");
+			pr_info("Failed to parse either an address or a symbol.\n");
 			return ret;
 		}
 		if (offset && is_return &&
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/kernel/trace/trace_stack.c linux-libre-4.12-gnu/kernel/trace/trace_stack.c
--- linux-libre-4.12-rc7-gnu/kernel/trace/trace_stack.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/kernel/trace/trace_stack.c	2017-07-02 19:07:02.000000000 -0400
@@ -409,7 +409,9 @@ static const struct file_operations stac
 static int
 stack_trace_filter_open(struct inode *inode, struct file *file)
 {
-	return ftrace_regex_open(&trace_ops, FTRACE_ITER_FILTER,
+	struct ftrace_ops *ops = inode->i_private;
+
+	return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
 				 inode, file);
 }
 
@@ -476,7 +478,7 @@ static __init int stack_trace_init(void)
 			NULL, &stack_trace_fops);
 
 	trace_create_file("stack_trace_filter", 0444, d_tracer,
-			NULL, &stack_trace_filter_fops);
+			  &trace_ops, &stack_trace_filter_fops);
 
 	if (stack_trace_filter_buf[0])
 		ftrace_set_early_filter(&trace_ops, stack_trace_filter_buf, 1);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/MAINTAINERS linux-libre-4.12-gnu/MAINTAINERS
--- linux-libre-4.12-rc7-gnu/MAINTAINERS	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/MAINTAINERS	2017-07-02 19:07:02.000000000 -0400
@@ -2964,7 +2964,7 @@ F:	sound/pci/oxygen/
 
 C6X ARCHITECTURE
 M:	Mark Salter <msalter@redhat.com>
-M:	Aurelien Jacquiot <a-jacquiot@ti.com>
+M:	Aurelien Jacquiot <jacquiot.aurelien@gmail.com>
 L:	linux-c6x-dev@linux-c6x.org
 W:	http://www.linux-c6x.org/wiki/index.php/Main_Page
 S:	Maintained
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/Makefile linux-libre-4.12-gnu/Makefile
--- linux-libre-4.12-rc7-gnu/Makefile	2017-06-30 14:50:04.000000000 -0400
+++ linux-libre-4.12-gnu/Makefile	2017-07-02 21:33:26.000000000 -0400
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 12
 SUBLEVEL = 0
-EXTRAVERSION = -rc7-gnu
+EXTRAVERSION = -gnu
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/core/dev.c linux-libre-4.12-gnu/net/core/dev.c
--- linux-libre-4.12-rc7-gnu/net/core/dev.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/core/dev.c	2017-07-02 19:07:02.000000000 -0400
@@ -4767,6 +4767,13 @@ struct packet_offload *gro_find_complete
 }
 EXPORT_SYMBOL(gro_find_complete_by_type);
 
+static void napi_skb_free_stolen_head(struct sk_buff *skb)
+{
+	skb_dst_drop(skb);
+	secpath_reset(skb);
+	kmem_cache_free(skbuff_head_cache, skb);
+}
+
 static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
 {
 	switch (ret) {
@@ -4780,13 +4787,10 @@ static gro_result_t napi_skb_finish(gro_
 		break;
 
 	case GRO_MERGED_FREE:
-		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) {
-			skb_dst_drop(skb);
-			secpath_reset(skb);
-			kmem_cache_free(skbuff_head_cache, skb);
-		} else {
+		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
+			napi_skb_free_stolen_head(skb);
+		else
 			__kfree_skb(skb);
-		}
 		break;
 
 	case GRO_HELD:
@@ -4858,10 +4862,16 @@ static gro_result_t napi_frags_finish(st
 		break;
 
 	case GRO_DROP:
-	case GRO_MERGED_FREE:
 		napi_reuse_skb(napi, skb);
 		break;
 
+	case GRO_MERGED_FREE:
+		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
+			napi_skb_free_stolen_head(skb);
+		else
+			napi_reuse_skb(napi, skb);
+		break;
+
 	case GRO_MERGED:
 	case GRO_CONSUMED:
 		break;
@@ -7783,9 +7793,9 @@ struct rtnl_link_stats64 *dev_get_stats(
 	} else {
 		netdev_stats_to_stats64(storage, &dev->stats);
 	}
-	storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
-	storage->tx_dropped += atomic_long_read(&dev->tx_dropped);
-	storage->rx_nohandler += atomic_long_read(&dev->rx_nohandler);
+	storage->rx_dropped += (unsigned long)atomic_long_read(&dev->rx_dropped);
+	storage->tx_dropped += (unsigned long)atomic_long_read(&dev->tx_dropped);
+	storage->rx_nohandler += (unsigned long)atomic_long_read(&dev->rx_nohandler);
 	return storage;
 }
 EXPORT_SYMBOL(dev_get_stats);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv4/ip_output.c linux-libre-4.12-gnu/net/ipv4/ip_output.c
--- linux-libre-4.12-rc7-gnu/net/ipv4/ip_output.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv4/ip_output.c	2017-07-02 19:07:02.000000000 -0400
@@ -964,7 +964,8 @@ static int __ip_append_data(struct sock
 		csummode = CHECKSUM_PARTIAL;
 
 	cork->length += length;
-	if ((((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) &&
+	if ((((length + (skb ? skb->len : fragheaderlen)) > mtu) ||
+	     (skb && skb_is_gso(skb))) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
 	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
 	    (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv4/tcp.c linux-libre-4.12-gnu/net/ipv4/tcp.c
--- linux-libre-4.12-rc7-gnu/net/ipv4/tcp.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv4/tcp.c	2017-07-02 19:07:02.000000000 -0400
@@ -2330,6 +2330,8 @@ int tcp_disconnect(struct sock *sk, int
 	tcp_init_send_head(sk);
 	memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
 	__sk_dst_reset(sk);
+	dst_release(sk->sk_rx_dst);
+	sk->sk_rx_dst = NULL;
 	tcp_saved_syn_free(tp);
 
 	/* Clean up fastopen related fields */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/addrconf.c linux-libre-4.12-gnu/net/ipv6/addrconf.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/addrconf.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/addrconf.c	2017-07-02 19:07:02.000000000 -0400
@@ -3369,6 +3369,7 @@ static int addrconf_notify(struct notifi
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct netdev_notifier_changeupper_info *info;
 	struct inet6_dev *idev = __in6_dev_get(dev);
+	struct net *net = dev_net(dev);
 	int run_pending = 0;
 	int err;
 
@@ -3384,7 +3385,7 @@ static int addrconf_notify(struct notifi
 	case NETDEV_CHANGEMTU:
 		/* if MTU under IPV6_MIN_MTU stop IPv6 on this interface. */
 		if (dev->mtu < IPV6_MIN_MTU) {
-			addrconf_ifdown(dev, 1);
+			addrconf_ifdown(dev, dev != net->loopback_dev);
 			break;
 		}
 
@@ -3500,7 +3501,7 @@ static int addrconf_notify(struct notifi
 			 * IPV6_MIN_MTU stop IPv6 on this interface.
 			 */
 			if (dev->mtu < IPV6_MIN_MTU)
-				addrconf_ifdown(dev, 1);
+				addrconf_ifdown(dev, dev != net->loopback_dev);
 		}
 		break;
 
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/datagram.c linux-libre-4.12-gnu/net/ipv6/datagram.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/datagram.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/datagram.c	2017-07-02 19:07:02.000000000 -0400
@@ -250,8 +250,14 @@ ipv4_connected:
 	 */
 
 	err = ip6_datagram_dst_update(sk, true);
-	if (err)
+	if (err) {
+		/* Reset daddr and dport so that udp_v6_early_demux()
+		 * fails to find this socket
+		 */
+		memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr));
+		inet->inet_dport = 0;
 		goto out;
+	}
 
 	sk->sk_state = TCP_ESTABLISHED;
 	sk_set_txhash(sk);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/esp6_offload.c linux-libre-4.12-gnu/net/ipv6/esp6_offload.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/esp6_offload.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/esp6_offload.c	2017-07-02 19:07:02.000000000 -0400
@@ -30,6 +30,25 @@
 #include <net/ipv6.h>
 #include <linux/icmpv6.h>
 
+static __u16 esp6_nexthdr_esp_offset(struct ipv6hdr *ipv6_hdr, int nhlen)
+{
+	int off = sizeof(struct ipv6hdr);
+	struct ipv6_opt_hdr *exthdr;
+
+	if (likely(ipv6_hdr->nexthdr == NEXTHDR_ESP))
+		return offsetof(struct ipv6hdr, nexthdr);
+
+	while (off < nhlen) {
+		exthdr = (void *)ipv6_hdr + off;
+		if (exthdr->nexthdr == NEXTHDR_ESP)
+			return off;
+
+		off += ipv6_optlen(exthdr);
+	}
+
+	return 0;
+}
+
 static struct sk_buff **esp6_gro_receive(struct sk_buff **head,
 					 struct sk_buff *skb)
 {
@@ -38,6 +57,7 @@ static struct sk_buff **esp6_gro_receive
 	struct xfrm_state *x;
 	__be32 seq;
 	__be32 spi;
+	int nhoff;
 	int err;
 
 	skb_pull(skb, offset);
@@ -72,6 +92,11 @@ static struct sk_buff **esp6_gro_receive
 
 	xo->flags |= XFRM_GRO;
 
+	nhoff = esp6_nexthdr_esp_offset(ipv6_hdr(skb), offset);
+	if (!nhoff)
+		goto out;
+
+	IP6CB(skb)->nhoff = nhoff;
 	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
 	XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/ip6_output.c linux-libre-4.12-gnu/net/ipv6/ip6_output.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/ip6_output.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/ip6_output.c	2017-07-02 19:07:02.000000000 -0400
@@ -1390,7 +1390,7 @@ emsgsize:
 	 */
 
 	cork->length += length;
-	if ((((length + fragheaderlen) > mtu) ||
+	if ((((length + (skb ? skb->len : headersize)) > mtu) ||
 	     (skb && skb_is_gso(skb))) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
 	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/route.c linux-libre-4.12-gnu/net/ipv6/route.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/route.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/route.c	2017-07-02 19:07:02.000000000 -0400
@@ -3722,7 +3722,11 @@ static int ip6_route_dev_notify(struct n
 		net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
 		net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
 #endif
-	 } else if (event == NETDEV_UNREGISTER) {
+	 } else if (event == NETDEV_UNREGISTER &&
+		    dev->reg_state != NETREG_UNREGISTERED) {
+		/* NETDEV_UNREGISTER could be fired for multiple times by
+		 * netdev_wait_allrefs(). Make sure we only call this once.
+		 */
 		in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev);
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 		in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/sit.c linux-libre-4.12-gnu/net/ipv6/sit.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/sit.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/sit.c	2017-07-02 19:07:02.000000000 -0400
@@ -305,7 +305,7 @@ static int ipip6_tunnel_get_prl(struct i
 	 * we try harder to allocate.
 	 */
 	kp = (cmax <= 1 || capable(CAP_NET_ADMIN)) ?
-		kcalloc(cmax, sizeof(*kp), GFP_KERNEL) :
+		kcalloc(cmax, sizeof(*kp), GFP_KERNEL | __GFP_NOWARN) :
 		NULL;
 
 	rcu_read_lock();
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/udp.c linux-libre-4.12-gnu/net/ipv6/udp.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/udp.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/udp.c	2017-07-02 19:07:02.000000000 -0400
@@ -879,7 +879,8 @@ static struct sock *__udp6_lib_demux_loo
 	struct sock *sk;
 
 	udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
-		if (INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif))
+		if (sk->sk_state == TCP_ESTABLISHED &&
+		    INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif))
 			return sk;
 		/* Only check first socket in chain */
 		break;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/ipv6/xfrm6_input.c linux-libre-4.12-gnu/net/ipv6/xfrm6_input.c
--- linux-libre-4.12-rc7-gnu/net/ipv6/xfrm6_input.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/ipv6/xfrm6_input.c	2017-07-02 19:07:02.000000000 -0400
@@ -43,8 +43,8 @@ int xfrm6_transport_finish(struct sk_buf
 		return 1;
 #endif
 
-	ipv6_hdr(skb)->payload_len = htons(skb->len);
 	__skb_push(skb, skb->data - skb_network_header(skb));
+	ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 
 	if (xo && (xo->flags & XFRM_GRO)) {
 		skb_mac_header_rebuild(skb);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/key/af_key.c linux-libre-4.12-gnu/net/key/af_key.c
--- linux-libre-4.12-rc7-gnu/net/key/af_key.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/key/af_key.c	2017-07-02 19:07:02.000000000 -0400
@@ -1157,6 +1157,7 @@ static struct xfrm_state * pfkey_msg2xfr
 			goto out;
 	}
 
+	err = -ENOBUFS;
 	key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
 	if (sa->sadb_sa_auth) {
 		int keysize = 0;
@@ -1168,8 +1169,10 @@ static struct xfrm_state * pfkey_msg2xfr
 		if (key)
 			keysize = (key->sadb_key_bits + 7) / 8;
 		x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
-		if (!x->aalg)
+		if (!x->aalg) {
+			err = -ENOMEM;
 			goto out;
+		}
 		strcpy(x->aalg->alg_name, a->name);
 		x->aalg->alg_key_len = 0;
 		if (key) {
@@ -1188,8 +1191,10 @@ static struct xfrm_state * pfkey_msg2xfr
 				goto out;
 			}
 			x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
-			if (!x->calg)
+			if (!x->calg) {
+				err = -ENOMEM;
 				goto out;
+			}
 			strcpy(x->calg->alg_name, a->name);
 			x->props.calgo = sa->sadb_sa_encrypt;
 		} else {
@@ -1203,8 +1208,10 @@ static struct xfrm_state * pfkey_msg2xfr
 			if (key)
 				keysize = (key->sadb_key_bits + 7) / 8;
 			x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
-			if (!x->ealg)
+			if (!x->ealg) {
+				err = -ENOMEM;
 				goto out;
+			}
 			strcpy(x->ealg->alg_name, a->name);
 			x->ealg->alg_key_len = 0;
 			if (key) {
@@ -1249,8 +1256,10 @@ static struct xfrm_state * pfkey_msg2xfr
 		struct xfrm_encap_tmpl *natt;
 
 		x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
-		if (!x->encap)
+		if (!x->encap) {
+			err = -ENOMEM;
 			goto out;
+		}
 
 		natt = x->encap;
 		n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
@@ -2755,6 +2764,8 @@ static int pfkey_spdflush(struct sock *s
 	int err, err2;
 
 	err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, true);
+	if (!err)
+		xfrm_garbage_collect(net);
 	err2 = unicast_flush_resp(sk, hdr);
 	if (err || err2) {
 		if (err == -ESRCH) /* empty table - old silent behavior */
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/sched/sch_api.c linux-libre-4.12-gnu/net/sched/sch_api.c
--- linux-libre-4.12-rc7-gnu/net/sched/sch_api.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/sched/sch_api.c	2017-07-02 19:07:02.000000000 -0400
@@ -1019,7 +1019,8 @@ static struct Qdisc *qdisc_create(struct
 		return sch;
 	}
 	/* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
-	ops->destroy(sch);
+	if (ops->destroy)
+		ops->destroy(sch);
 err_out3:
 	dev_put(dev);
 	kfree((char *) sch - sch->padded);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/xfrm/Makefile linux-libre-4.12-gnu/net/xfrm/Makefile
--- linux-libre-4.12-rc7-gnu/net/xfrm/Makefile	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/xfrm/Makefile	2017-07-02 19:07:02.000000000 -0400
@@ -4,8 +4,7 @@
 
 obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \
 		      xfrm_input.o xfrm_output.o \
-		      xfrm_sysctl.o xfrm_replay.o
-obj-$(CONFIG_XFRM_OFFLOAD) += xfrm_device.o
+		      xfrm_sysctl.o xfrm_replay.o xfrm_device.o
 obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o
 obj-$(CONFIG_XFRM_ALGO) += xfrm_algo.o
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/xfrm/xfrm_device.c linux-libre-4.12-gnu/net/xfrm/xfrm_device.c
--- linux-libre-4.12-rc7-gnu/net/xfrm/xfrm_device.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/xfrm/xfrm_device.c	2017-07-02 19:07:02.000000000 -0400
@@ -22,6 +22,7 @@
 #include <net/xfrm.h>
 #include <linux/notifier.h>
 
+#ifdef CONFIG_XFRM_OFFLOAD
 int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
 {
 	int err;
@@ -137,6 +138,7 @@ ok:
 	return true;
 }
 EXPORT_SYMBOL_GPL(xfrm_dev_offload_ok);
+#endif
 
 int xfrm_dev_register(struct net_device *dev)
 {
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/xfrm/xfrm_policy.c linux-libre-4.12-gnu/net/xfrm/xfrm_policy.c
--- linux-libre-4.12-rc7-gnu/net/xfrm/xfrm_policy.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/xfrm/xfrm_policy.c	2017-07-02 19:07:02.000000000 -0400
@@ -1006,10 +1006,6 @@ int xfrm_policy_flush(struct net *net, u
 		err = -ESRCH;
 out:
 	spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
-
-	if (cnt)
-		xfrm_garbage_collect(net);
-
 	return err;
 }
 EXPORT_SYMBOL(xfrm_policy_flush);
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/net/xfrm/xfrm_user.c linux-libre-4.12-gnu/net/xfrm/xfrm_user.c
--- linux-libre-4.12-rc7-gnu/net/xfrm/xfrm_user.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/net/xfrm/xfrm_user.c	2017-07-02 19:07:02.000000000 -0400
@@ -2027,6 +2027,7 @@ static int xfrm_flush_policy(struct sk_b
 			return 0;
 		return err;
 	}
+	xfrm_garbage_collect(net);
 
 	c.data.type = type;
 	c.event = nlh->nlmsg_type;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/sound/pci/hda/hda_codec.h linux-libre-4.12-gnu/sound/pci/hda/hda_codec.h
--- linux-libre-4.12-rc7-gnu/sound/pci/hda/hda_codec.h	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/sound/pci/hda/hda_codec.h	2017-07-02 19:07:02.000000000 -0400
@@ -295,6 +295,8 @@ struct hda_codec {
 
 #define list_for_each_codec(c, bus) \
 	list_for_each_entry(c, &(bus)->core.codec_list, core.list)
+#define list_for_each_codec_safe(c, n, bus)				\
+	list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list)
 
 /* snd_hda_codec_read/write optional flags */
 #define HDA_RW_NO_RESPONSE_FALLBACK	(1 << 0)
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/sound/pci/hda/hda_controller.c linux-libre-4.12-gnu/sound/pci/hda/hda_controller.c
--- linux-libre-4.12-rc7-gnu/sound/pci/hda/hda_controller.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/sound/pci/hda/hda_controller.c	2017-07-02 19:07:02.000000000 -0400
@@ -1337,8 +1337,12 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs);
 /* configure each codec instance */
 int azx_codec_configure(struct azx *chip)
 {
-	struct hda_codec *codec;
-	list_for_each_codec(codec, &chip->bus) {
+	struct hda_codec *codec, *next;
+
+	/* use _safe version here since snd_hda_codec_configure() deregisters
+	 * the device upon error and deletes itself from the bus list.
+	 */
+	list_for_each_codec_safe(codec, next, &chip->bus) {
 		snd_hda_codec_configure(codec);
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/sound/pci/hda/hda_generic.c linux-libre-4.12-gnu/sound/pci/hda/hda_generic.c
--- linux-libre-4.12-rc7-gnu/sound/pci/hda/hda_generic.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/sound/pci/hda/hda_generic.c	2017-07-02 19:07:02.000000000 -0400
@@ -3174,6 +3174,7 @@ static int check_dyn_adc_switch(struct h
 						spec->input_paths[i][nums]);
 					spec->input_paths[i][nums] =
 						spec->input_paths[i][n];
+					spec->input_paths[i][n] = 0;
 				}
 			}
 			nums++;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/tools/perf/util/machine.c linux-libre-4.12-gnu/tools/perf/util/machine.c
--- linux-libre-4.12-rc7-gnu/tools/perf/util/machine.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/tools/perf/util/machine.c	2017-07-02 19:07:02.000000000 -0400
@@ -1209,10 +1209,12 @@ int machine__create_kernel_maps(struct m
 	 */
 	map_groups__fixup_end(&machine->kmaps);
 
-	if (machine__get_running_kernel_start(machine, &name, &addr)) {
-	} else if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) {
-		machine__destroy_kernel_maps(machine);
-		return -1;
+	if (!machine__get_running_kernel_start(machine, &name, &addr)) {
+		if (name &&
+		    maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) {
+			machine__destroy_kernel_maps(machine);
+			return -1;
+		}
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.12-rc7-gnu/tools/testing/selftests/bpf/test_verifier.c linux-libre-4.12-gnu/tools/testing/selftests/bpf/test_verifier.c
--- linux-libre-4.12-rc7-gnu/tools/testing/selftests/bpf/test_verifier.c	2017-06-25 21:30:05.000000000 -0400
+++ linux-libre-4.12-gnu/tools/testing/selftests/bpf/test_verifier.c	2017-07-02 19:07:02.000000000 -0400
@@ -3749,6 +3749,72 @@ static struct bpf_test tests[] = {
 		.errstr = "invalid bpf_context access",
 	},
 	{
+		"leak pointer into ctx 1",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
+				    offsetof(struct __sk_buff, cb[0])),
+			BPF_LD_MAP_FD(BPF_REG_2, 0),
+			BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
+				      offsetof(struct __sk_buff, cb[0])),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_map1 = { 2 },
+		.errstr_unpriv = "R2 leaks addr into mem",
+		.result_unpriv = REJECT,
+		.result = ACCEPT,
+	},
+	{
+		"leak pointer into ctx 2",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
+				    offsetof(struct __sk_buff, cb[0])),
+			BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
+				      offsetof(struct __sk_buff, cb[0])),
+			BPF_EXIT_INSN(),
+		},
+		.errstr_unpriv = "R10 leaks addr into mem",
+		.result_unpriv = REJECT,
+		.result = ACCEPT,
+	},
+	{
+		"leak pointer into ctx 3",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_LD_MAP_FD(BPF_REG_2, 0),
+			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
+				      offsetof(struct __sk_buff, cb[0])),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_map1 = { 1 },
+		.errstr_unpriv = "R2 leaks addr into ctx",
+		.result_unpriv = REJECT,
+		.result = ACCEPT,
+	},
+	{
+		"leak pointer into map val",
+		.insns = {
+			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_map_lookup_elem),
+			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
+			BPF_MOV64_IMM(BPF_REG_3, 0),
+			BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
+			BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_map1 = { 4 },
+		.errstr_unpriv = "R6 leaks addr into mem",
+		.result_unpriv = REJECT,
+		.result = ACCEPT,
+	},
+	{
 		"helper access to map: full range",
 		.insns = {
 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
