diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/include/asm/branch.h linux-libre-4.12.4-gnu/arch/mips/include/asm/branch.h
--- linux-libre-4.12.3-gnu/arch/mips/include/asm/branch.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/include/asm/branch.h	2017-07-27 18:10:39.000000000 -0400
@@ -74,10 +74,7 @@ static inline int compute_return_epc(str
 			return __microMIPS_compute_return_epc(regs);
 		if (cpu_has_mips16)
 			return __MIPS16e_compute_return_epc(regs);
-		return regs->cp0_epc;
-	}
-
-	if (!delay_slot(regs)) {
+	} else if (!delay_slot(regs)) {
 		regs->cp0_epc += 4;
 		return 0;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/branch.c linux-libre-4.12.4-gnu/arch/mips/kernel/branch.c
--- linux-libre-4.12.3-gnu/arch/mips/kernel/branch.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/branch.c	2017-07-27 18:10:39.000000000 -0400
@@ -399,7 +399,7 @@ int __MIPS16e_compute_return_epc(struct
  *
  * @regs:	Pointer to pt_regs
  * @insn:	branch instruction to decode
- * @returns:	-EFAULT on error and forces SIGBUS, and on success
+ * @returns:	-EFAULT on error and forces SIGILL, and on success
  *		returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
  *		evaluating the branch.
  *
@@ -431,7 +431,7 @@ int __compute_return_epc_for_insn(struct
 			/* Fall through */
 		case jr_op:
 			if (NO_R6EMU && insn.r_format.func == jr_op)
-				goto sigill_r6;
+				goto sigill_r2r6;
 			regs->cp0_epc = regs->regs[insn.r_format.rs];
 			break;
 		}
@@ -446,7 +446,7 @@ int __compute_return_epc_for_insn(struct
 		switch (insn.i_format.rt) {
 		case bltzl_op:
 			if (NO_R6EMU)
-				goto sigill_r6;
+				goto sigill_r2r6;
 		case bltz_op:
 			if ((long)regs->regs[insn.i_format.rs] < 0) {
 				epc = epc + 4 + (insn.i_format.simmediate << 2);
@@ -459,7 +459,7 @@ int __compute_return_epc_for_insn(struct
 
 		case bgezl_op:
 			if (NO_R6EMU)
-				goto sigill_r6;
+				goto sigill_r2r6;
 		case bgez_op:
 			if ((long)regs->regs[insn.i_format.rs] >= 0) {
 				epc = epc + 4 + (insn.i_format.simmediate << 2);
@@ -473,10 +473,8 @@ int __compute_return_epc_for_insn(struct
 		case bltzal_op:
 		case bltzall_op:
 			if (NO_R6EMU && (insn.i_format.rs ||
-			    insn.i_format.rt == bltzall_op)) {
-				ret = -SIGILL;
-				break;
-			}
+			    insn.i_format.rt == bltzall_op))
+				goto sigill_r2r6;
 			regs->regs[31] = epc + 8;
 			/*
 			 * OK we are here either because we hit a NAL
@@ -507,10 +505,8 @@ int __compute_return_epc_for_insn(struct
 		case bgezal_op:
 		case bgezall_op:
 			if (NO_R6EMU && (insn.i_format.rs ||
-			    insn.i_format.rt == bgezall_op)) {
-				ret = -SIGILL;
-				break;
-			}
+			    insn.i_format.rt == bgezall_op))
+				goto sigill_r2r6;
 			regs->regs[31] = epc + 8;
 			/*
 			 * OK we are here either because we hit a BAL
@@ -556,6 +552,7 @@ int __compute_return_epc_for_insn(struct
 	/*
 	 * These are unconditional and in j_format.
 	 */
+	case jalx_op:
 	case jal_op:
 		regs->regs[31] = regs->cp0_epc + 8;
 	case j_op:
@@ -573,7 +570,7 @@ int __compute_return_epc_for_insn(struct
 	 */
 	case beql_op:
 		if (NO_R6EMU)
-			goto sigill_r6;
+			goto sigill_r2r6;
 	case beq_op:
 		if (regs->regs[insn.i_format.rs] ==
 		    regs->regs[insn.i_format.rt]) {
@@ -587,7 +584,7 @@ int __compute_return_epc_for_insn(struct
 
 	case bnel_op:
 		if (NO_R6EMU)
-			goto sigill_r6;
+			goto sigill_r2r6;
 	case bne_op:
 		if (regs->regs[insn.i_format.rs] !=
 		    regs->regs[insn.i_format.rt]) {
@@ -601,7 +598,7 @@ int __compute_return_epc_for_insn(struct
 
 	case blezl_op: /* not really i_format */
 		if (!insn.i_format.rt && NO_R6EMU)
-			goto sigill_r6;
+			goto sigill_r2r6;
 	case blez_op:
 		/*
 		 * Compact branches for R6 for the
@@ -636,7 +633,7 @@ int __compute_return_epc_for_insn(struct
 
 	case bgtzl_op:
 		if (!insn.i_format.rt && NO_R6EMU)
-			goto sigill_r6;
+			goto sigill_r2r6;
 	case bgtz_op:
 		/*
 		 * Compact branches for R6 for the
@@ -774,35 +771,27 @@ int __compute_return_epc_for_insn(struct
 #else
 	case bc6_op:
 		/* Only valid for MIPS R6 */
-		if (!cpu_has_mips_r6) {
-			ret = -SIGILL;
-			break;
-		}
+		if (!cpu_has_mips_r6)
+			goto sigill_r6;
 		regs->cp0_epc += 8;
 		break;
 	case balc6_op:
-		if (!cpu_has_mips_r6) {
-			ret = -SIGILL;
-			break;
-		}
+		if (!cpu_has_mips_r6)
+			goto sigill_r6;
 		/* Compact branch: BALC */
 		regs->regs[31] = epc + 4;
 		epc += 4 + (insn.i_format.simmediate << 2);
 		regs->cp0_epc = epc;
 		break;
 	case pop66_op:
-		if (!cpu_has_mips_r6) {
-			ret = -SIGILL;
-			break;
-		}
+		if (!cpu_has_mips_r6)
+			goto sigill_r6;
 		/* Compact branch: BEQZC || JIC */
 		regs->cp0_epc += 8;
 		break;
 	case pop76_op:
-		if (!cpu_has_mips_r6) {
-			ret = -SIGILL;
-			break;
-		}
+		if (!cpu_has_mips_r6)
+			goto sigill_r6;
 		/* Compact branch: BNEZC || JIALC */
 		if (!insn.i_format.rs) {
 			/* JIALC: set $31/ra */
@@ -814,10 +803,8 @@ int __compute_return_epc_for_insn(struct
 	case pop10_op:
 	case pop30_op:
 		/* Only valid for MIPS R6 */
-		if (!cpu_has_mips_r6) {
-			ret = -SIGILL;
-			break;
-		}
+		if (!cpu_has_mips_r6)
+			goto sigill_r6;
 		/*
 		 * Compact branches:
 		 * bovc, beqc, beqzalc, bnvc, bnec, bnezlac
@@ -831,11 +818,17 @@ int __compute_return_epc_for_insn(struct
 	return ret;
 
 sigill_dsp:
-	printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
-	force_sig(SIGBUS, current);
+	pr_info("%s: DSP branch but not DSP ASE - sending SIGILL.\n",
+		current->comm);
+	force_sig(SIGILL, current);
+	return -EFAULT;
+sigill_r2r6:
+	pr_info("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n",
+		current->comm);
+	force_sig(SIGILL, current);
 	return -EFAULT;
 sigill_r6:
-	pr_info("%s: R2 branch but r2-to-r6 emulator is not preset - sending SIGILL.\n",
+	pr_info("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n",
 		current->comm);
 	force_sig(SIGILL, current);
 	return -EFAULT;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/proc.c linux-libre-4.12.4-gnu/arch/mips/kernel/proc.c
--- linux-libre-4.12.3-gnu/arch/mips/kernel/proc.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/proc.c	2017-07-27 18:10:39.000000000 -0400
@@ -83,7 +83,7 @@ static int show_cpuinfo(struct seq_file
 	}
 
 	seq_printf(m, "isa\t\t\t:"); 
-	if (cpu_has_mips_r1)
+	if (cpu_has_mips_1)
 		seq_printf(m, " mips1");
 	if (cpu_has_mips_2)
 		seq_printf(m, "%s", " mips2");
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/ptrace.c linux-libre-4.12.4-gnu/arch/mips/kernel/ptrace.c
--- linux-libre-4.12.3-gnu/arch/mips/kernel/ptrace.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/ptrace.c	2017-07-27 18:10:39.000000000 -0400
@@ -895,7 +895,7 @@ asmlinkage void syscall_trace_leave(stru
 	audit_syscall_exit(regs);
 
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
-		trace_sys_exit(regs, regs->regs[2]);
+		trace_sys_exit(regs, regs_return_value(regs));
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, 0);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/scall32-o32.S linux-libre-4.12.4-gnu/arch/mips/kernel/scall32-o32.S
--- linux-libre-4.12.3-gnu/arch/mips/kernel/scall32-o32.S	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/scall32-o32.S	2017-07-27 18:10:39.000000000 -0400
@@ -371,7 +371,7 @@ EXPORT(sys_call_table)
 	PTR	sys_writev
 	PTR	sys_cacheflush
 	PTR	sys_cachectl
-	PTR	sys_sysmips
+	PTR	__sys_sysmips
 	PTR	sys_ni_syscall			/* 4150 */
 	PTR	sys_getsid
 	PTR	sys_fdatasync
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/scall64-64.S linux-libre-4.12.4-gnu/arch/mips/kernel/scall64-64.S
--- linux-libre-4.12.3-gnu/arch/mips/kernel/scall64-64.S	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/scall64-64.S	2017-07-27 18:10:39.000000000 -0400
@@ -311,7 +311,7 @@ EXPORT(sys_call_table)
 	PTR	sys_sched_getaffinity
 	PTR	sys_cacheflush
 	PTR	sys_cachectl
-	PTR	sys_sysmips
+	PTR	__sys_sysmips
 	PTR	sys_io_setup			/* 5200 */
 	PTR	sys_io_destroy
 	PTR	sys_io_getevents
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/scall64-n32.S linux-libre-4.12.4-gnu/arch/mips/kernel/scall64-n32.S
--- linux-libre-4.12.3-gnu/arch/mips/kernel/scall64-n32.S	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/scall64-n32.S	2017-07-27 18:10:39.000000000 -0400
@@ -302,7 +302,7 @@ EXPORT(sysn32_call_table)
 	PTR	compat_sys_sched_getaffinity
 	PTR	sys_cacheflush
 	PTR	sys_cachectl
-	PTR	sys_sysmips
+	PTR	__sys_sysmips
 	PTR	compat_sys_io_setup			/* 6200 */
 	PTR	sys_io_destroy
 	PTR	compat_sys_io_getevents
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/scall64-o32.S linux-libre-4.12.4-gnu/arch/mips/kernel/scall64-o32.S
--- linux-libre-4.12.3-gnu/arch/mips/kernel/scall64-o32.S	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/scall64-o32.S	2017-07-27 18:10:39.000000000 -0400
@@ -371,7 +371,7 @@ EXPORT(sys32_call_table)
 	PTR	compat_sys_writev
 	PTR	sys_cacheflush
 	PTR	sys_cachectl
-	PTR	sys_sysmips
+	PTR	__sys_sysmips
 	PTR	sys_ni_syscall			/* 4150 */
 	PTR	sys_getsid
 	PTR	sys_fdatasync
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/kernel/syscall.c linux-libre-4.12.4-gnu/arch/mips/kernel/syscall.c
--- linux-libre-4.12.3-gnu/arch/mips/kernel/syscall.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/kernel/syscall.c	2017-07-27 18:10:39.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/sched/task_stack.h>
 
 #include <asm/asm.h>
+#include <asm/asm-eva.h>
 #include <asm/branch.h>
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
@@ -131,10 +132,12 @@ static inline int mips_atomic_set(unsign
 		__asm__ __volatile__ (
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
 		"	li	%[err], 0				\n"
-		"1:	ll	%[old], (%[addr])			\n"
+		"1:							\n"
+		user_ll("%[old]", "(%[addr])")
 		"	move	%[tmp], %[new]				\n"
-		"2:	sc	%[tmp], (%[addr])			\n"
-		"	bnez	%[tmp], 4f				\n"
+		"2:							\n"
+		user_sc("%[tmp]", "(%[addr])")
+		"	beqz	%[tmp], 4f				\n"
 		"3:							\n"
 		"	.insn						\n"
 		"	.subsection 2					\n"
@@ -192,6 +195,12 @@ static inline int mips_atomic_set(unsign
 	unreachable();
 }
 
+/*
+ * mips_atomic_set() normally returns directly via syscall_exit potentially
+ * clobbering static registers, so be sure to preserve them.
+ */
+save_static_function(sys_sysmips);
+
 SYSCALL_DEFINE3(sysmips, long, cmd, long, arg1, long, arg2)
 {
 	switch (cmd) {
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/mips/math-emu/cp1emu.c linux-libre-4.12.4-gnu/arch/mips/math-emu/cp1emu.c
--- linux-libre-4.12.3-gnu/arch/mips/math-emu/cp1emu.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/mips/math-emu/cp1emu.c	2017-07-27 18:10:39.000000000 -0400
@@ -2524,6 +2524,35 @@ dcopuop:
 	return 0;
 }
 
+/*
+ * Emulate FPU instructions.
+ *
+ * If we use FPU hardware, then we have been typically called to handle
+ * an unimplemented operation, such as where an operand is a NaN or
+ * denormalized.  In that case exit the emulation loop after a single
+ * iteration so as to let hardware execute any subsequent instructions.
+ *
+ * If we have no FPU hardware or it has been disabled, then continue
+ * emulating floating-point instructions until one of these conditions
+ * has occurred:
+ *
+ * - a non-FPU instruction has been encountered,
+ *
+ * - an attempt to emulate has ended with a signal,
+ *
+ * - the ISA mode has been switched.
+ *
+ * We need to terminate the emulation loop if we got switched to the
+ * MIPS16 mode, whether supported or not, so that we do not attempt
+ * to emulate a MIPS16 instruction as a regular MIPS FPU instruction.
+ * Similarly if we got switched to the microMIPS mode and only the
+ * regular MIPS mode is supported, so that we do not attempt to emulate
+ * a microMIPS instruction as a regular MIPS FPU instruction.  Or if
+ * we got switched to the regular MIPS mode and only the microMIPS mode
+ * is supported, so that we do not attempt to emulate a regular MIPS
+ * instruction that should cause an Address Error exception instead.
+ * For simplicity we always terminate upon an ISA mode switch.
+ */
 int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 	int has_fpu, void *__user *fault_addr)
 {
@@ -2609,6 +2638,15 @@ int fpu_emulator_cop1Handler(struct pt_r
 			break;
 		if (sig)
 			break;
+		/*
+		 * We have to check for the ISA bit explicitly here,
+		 * because `get_isa16_mode' may return 0 if support
+		 * for code compression has been globally disabled,
+		 * or otherwise we may produce the wrong signal or
+		 * even proceed successfully where we must not.
+		 */
+		if ((xcp->cp0_epc ^ prevepc) & 0x1)
+			break;
 
 		cond_resched();
 	} while (xcp->cp0_epc > prevepc);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/include/asm/atomic.h linux-libre-4.12.4-gnu/arch/powerpc/include/asm/atomic.h
--- linux-libre-4.12.3-gnu/arch/powerpc/include/asm/atomic.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/include/asm/atomic.h	2017-07-27 18:10:39.000000000 -0400
@@ -560,7 +560,7 @@ static __inline__ int atomic64_add_unles
  * Atomically increments @v by 1, so long as @v is non-zero.
  * Returns non-zero if @v was non-zero, and zero otherwise.
  */
-static __inline__ long atomic64_inc_not_zero(atomic64_t *v)
+static __inline__ int atomic64_inc_not_zero(atomic64_t *v)
 {
 	long t1, t2;
 
@@ -579,7 +579,7 @@ static __inline__ long atomic64_inc_not_
 	: "r" (&v->counter)
 	: "cc", "xer", "memory");
 
-	return t1;
+	return t1 != 0;
 }
 
 #endif /* __powerpc64__ */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/include/asm/reg.h linux-libre-4.12.4-gnu/arch/powerpc/include/asm/reg.h
--- linux-libre-4.12.3-gnu/arch/powerpc/include/asm/reg.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/include/asm/reg.h	2017-07-27 18:10:39.000000000 -0400
@@ -1303,7 +1303,7 @@ static inline void msr_check_and_clear(u
 				"	.llong 0\n"			\
 				".previous"				\
 			: "=r" (rval) \
-			: "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL)); \
+			: "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \
 			rval;})
 #else
 #define mftb()		({unsigned long rval;	\
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/lib/sstep.c linux-libre-4.12.4-gnu/arch/powerpc/lib/sstep.c
--- linux-libre-4.12.3-gnu/arch/powerpc/lib/sstep.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/lib/sstep.c	2017-07-27 18:10:39.000000000 -0400
@@ -683,8 +683,10 @@ int analyse_instr(struct instruction_op
 	case 19:
 		switch ((instr >> 1) & 0x3ff) {
 		case 0:		/* mcrf */
-			rd = (instr >> 21) & 0x1c;
-			ra = (instr >> 16) & 0x1c;
+			rd = 7 - ((instr >> 23) & 0x7);
+			ra = 7 - ((instr >> 18) & 0x7);
+			rd *= 4;
+			ra *= 4;
 			val = (regs->ccr >> ra) & 0xf;
 			regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
 			goto instr_done;
@@ -964,6 +966,19 @@ int analyse_instr(struct instruction_op
 #endif
 
 		case 19:	/* mfcr */
+			if ((instr >> 20) & 1) {
+				imm = 0xf0000000UL;
+				for (sh = 0; sh < 8; ++sh) {
+					if (instr & (0x80000 >> sh)) {
+						regs->gpr[rd] = regs->ccr & imm;
+						break;
+					}
+					imm >>= 4;
+				}
+
+				goto instr_done;
+			}
+
 			regs->gpr[rd] = regs->ccr;
 			regs->gpr[rd] &= 0xffffffffUL;
 			goto instr_done;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/mm/mmu_context_book3s64.c linux-libre-4.12.4-gnu/arch/powerpc/mm/mmu_context_book3s64.c
--- linux-libre-4.12.3-gnu/arch/powerpc/mm/mmu_context_book3s64.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/mm/mmu_context_book3s64.c	2017-07-27 18:10:39.000000000 -0400
@@ -223,9 +223,15 @@ void destroy_context(struct mm_struct *m
 	mm->context.cop_lockp = NULL;
 #endif /* CONFIG_PPC_ICSWX */
 
-	if (radix_enabled())
-		process_tb[mm->context.id].prtb1 = 0;
-	else
+	if (radix_enabled()) {
+		/*
+		 * Radix doesn't have a valid bit in the process table
+		 * entries. However we know that at least P9 implementation
+		 * will avoid caching an entry with an invalid RTS field,
+		 * and 0 is invalid. So this will do.
+		 */
+		process_tb[mm->context.id].prtb0 = 0;
+	} else
 		subpage_prot_free(mm);
 	destroy_pagetable_page(mm);
 	__destroy_context(mm->context.id);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/mm/pgtable-radix.c linux-libre-4.12.4-gnu/arch/powerpc/mm/pgtable-radix.c
--- linux-libre-4.12.3-gnu/arch/powerpc/mm/pgtable-radix.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/mm/pgtable-radix.c	2017-07-27 18:10:39.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/mmu.h>
 #include <asm/firmware.h>
 #include <asm/powernv.h>
+#include <asm/sections.h>
 
 #include <trace/events/thp.h>
 
@@ -121,7 +122,8 @@ static inline void __meminit print_mappi
 static int __meminit create_physical_mapping(unsigned long start,
 					     unsigned long end)
 {
-	unsigned long addr, mapping_size = 0;
+	unsigned long vaddr, addr, mapping_size = 0;
+	pgprot_t prot;
 
 	start = _ALIGN_UP(start, PAGE_SIZE);
 	for (addr = start; addr < end; addr += mapping_size) {
@@ -145,8 +147,15 @@ static int __meminit create_physical_map
 			start = addr;
 		}
 
-		rc = radix__map_kernel_page((unsigned long)__va(addr), addr,
-					    PAGE_KERNEL_X, mapping_size);
+		vaddr = (unsigned long)__va(addr);
+
+		if (overlaps_kernel_text(vaddr, vaddr + mapping_size) ||
+		    overlaps_interrupt_vector_text(vaddr, vaddr + mapping_size))
+			prot = PAGE_KERNEL_X;
+		else
+			prot = PAGE_KERNEL;
+
+		rc = radix__map_kernel_page(vaddr, addr, prot, mapping_size);
 		if (rc)
 			return rc;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/perf/isa207-common.c linux-libre-4.12.4-gnu/arch/powerpc/perf/isa207-common.c
--- linux-libre-4.12.3-gnu/arch/powerpc/perf/isa207-common.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/perf/isa207-common.c	2017-07-27 18:10:39.000000000 -0400
@@ -90,13 +90,15 @@ static void mmcra_sdar_mode(u64 event, u
 	 *	MMCRA[SDAR_MODE] will be set to 0b01
 	 * For rest
 	 *	MMCRA[SDAR_MODE] will be set from event code.
+	 *      If sdar_mode from event is zero, default to 0b01. Hardware
+	 *      requires that we set a non-zero value.
 	 */
 	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
 		if (is_event_marked(event) || (*mmcra & MMCRA_SAMPLE_ENABLE))
 			*mmcra &= MMCRA_SDAR_MODE_NO_UPDATES;
-		else if (!cpu_has_feature(CPU_FTR_POWER9_DD1))
+		else if (!cpu_has_feature(CPU_FTR_POWER9_DD1) && p9_SDAR_MODE(event))
 			*mmcra |=  p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT;
-		else if (cpu_has_feature(CPU_FTR_POWER9_DD1))
+		else
 			*mmcra |= MMCRA_SDAR_MODE_TLB;
 	} else
 		*mmcra |= MMCRA_SDAR_MODE_TLB;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/powerpc/platforms/pseries/lpar.c linux-libre-4.12.4-gnu/arch/powerpc/platforms/pseries/lpar.c
--- linux-libre-4.12.3-gnu/arch/powerpc/platforms/pseries/lpar.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/powerpc/platforms/pseries/lpar.c	2017-07-27 18:10:39.000000000 -0400
@@ -301,7 +301,7 @@ static long pSeries_lpar_hpte_updatepp(u
 				       int ssize, unsigned long inv_flags)
 {
 	unsigned long lpar_rc;
-	unsigned long flags = (newpp & 7) | H_AVPN;
+	unsigned long flags;
 	unsigned long want_v;
 
 	want_v = hpte_encode_avpn(vpn, psize, ssize);
@@ -309,6 +309,11 @@ static long pSeries_lpar_hpte_updatepp(u
 	pr_devel("    update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
 		 want_v, slot, flags, psize);
 
+	flags = (newpp & 7) | H_AVPN;
+	if (mmu_has_feature(MMU_FTR_KERNEL_RO))
+		/* Move pp0 into bit 8 (IBM 55) */
+		flags |= (newpp & HPTE_R_PP0) >> 55;
+
 	lpar_rc = plpar_pte_protect(flags, slot, want_v);
 
 	if (lpar_rc == H_NOT_FOUND) {
@@ -380,6 +385,10 @@ static void pSeries_lpar_hpte_updatebolt
 	BUG_ON(slot == -1);
 
 	flags = newpp & 7;
+	if (mmu_has_feature(MMU_FTR_KERNEL_RO))
+		/* Move pp0 into bit 8 (IBM 55) */
+		flags |= (newpp & HPTE_R_PP0) >> 55;
+
 	lpar_rc = plpar_pte_protect(flags, slot, 0);
 
 	BUG_ON(lpar_rc != H_SUCCESS);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/s390/include/asm/syscall.h linux-libre-4.12.4-gnu/arch/s390/include/asm/syscall.h
--- linux-libre-4.12.3-gnu/arch/s390/include/asm/syscall.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/s390/include/asm/syscall.h	2017-07-27 18:10:39.000000000 -0400
@@ -64,6 +64,12 @@ static inline void syscall_get_arguments
 {
 	unsigned long mask = -1UL;
 
+	/*
+	 * No arguments for this syscall, there's nothing to do.
+	 */
+	if (!n)
+		return;
+
 	BUG_ON(i + n > 6);
 #ifdef CONFIG_COMPAT
 	if (test_tsk_thread_flag(task, TIF_31BIT))
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/x86/include/asm/xen/hypercall.h linux-libre-4.12.4-gnu/arch/x86/include/asm/xen/hypercall.h
--- linux-libre-4.12.3-gnu/arch/x86/include/asm/xen/hypercall.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/x86/include/asm/xen/hypercall.h	2017-07-27 18:10:39.000000000 -0400
@@ -43,6 +43,7 @@
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/smap.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/sched.h>
@@ -214,10 +215,12 @@ privcmd_call(unsigned call,
 	__HYPERCALL_DECLS;
 	__HYPERCALL_5ARG(a1, a2, a3, a4, a5);
 
+	stac();
 	asm volatile("call *%[call]"
 		     : __HYPERCALL_5PARAM
 		     : [call] "a" (&hypercall_page[call])
 		     : __HYPERCALL_CLOBBER5);
+	clac();
 
 	return (long)__res;
 }
@@ -476,7 +479,11 @@ static inline int
 HYPERVISOR_dm_op(
 	domid_t dom, unsigned int nr_bufs, void *bufs)
 {
-	return _hypercall3(int, dm_op, dom, nr_bufs, bufs);
+	int ret;
+	stac();
+	ret = _hypercall3(int, dm_op, dom, nr_bufs, bufs);
+	clac();
+	return ret;
 }
 
 static inline void
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/x86/kernel/acpi/boot.c linux-libre-4.12.4-gnu/arch/x86/kernel/acpi/boot.c
--- linux-libre-4.12.3-gnu/arch/x86/kernel/acpi/boot.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/x86/kernel/acpi/boot.c	2017-07-27 18:10:39.000000000 -0400
@@ -347,6 +347,14 @@ static void __init mp_override_legacy_ir
 	struct mpc_intsrc mp_irq;
 
 	/*
+	 * Check bus_irq boundary.
+	 */
+	if (bus_irq >= NR_IRQS_LEGACY) {
+		pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq);
+		return;
+	}
+
+	/*
 	 * Convert 'gsi' to 'ioapic.pin'.
 	 */
 	ioapic = mp_find_ioapic(gsi);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/x86/kernel/apic/io_apic.c linux-libre-4.12.4-gnu/arch/x86/kernel/apic/io_apic.c
--- linux-libre-4.12.3-gnu/arch/x86/kernel/apic/io_apic.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/x86/kernel/apic/io_apic.c	2017-07-27 18:10:39.000000000 -0400
@@ -2115,7 +2115,7 @@ static inline void __init check_timer(vo
 			int idx;
 			idx = find_irq_entry(apic1, pin1, mp_INT);
 			if (idx != -1 && irq_trigger(idx))
-				unmask_ioapic_irq(irq_get_chip_data(0));
+				unmask_ioapic_irq(irq_get_irq_data(0));
 		}
 		irq_domain_deactivate_irq(irq_data);
 		irq_domain_activate_irq(irq_data);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/x86/pci/fixup.c linux-libre-4.12.4-gnu/arch/x86/pci/fixup.c
--- linux-libre-4.12.3-gnu/arch/x86/pci/fixup.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/x86/pci/fixup.c	2017-07-27 18:10:39.000000000 -0400
@@ -571,3 +571,35 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IN
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_invalid_bar);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_invalid_bar);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_invalid_bar);
+
+/*
+ * Apple MacBook Pro: Avoid [mem 0x7fa00000-0x7fbfffff]
+ *
+ * Using the [mem 0x7fa00000-0x7fbfffff] region, e.g., by assigning it to
+ * the 00:1c.0 Root Port, causes a conflict with [io 0x1804], which is used
+ * for soft poweroff and suspend-to-RAM.
+ *
+ * As far as we know, this is related to the address space, not to the Root
+ * Port itself.  Attaching the quirk to the Root Port is a convenience, but
+ * it could probably also be a standalone DMI quirk.
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=103211
+ */
+static void quirk_apple_mbp_poweroff(struct pci_dev *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+
+	if ((!dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,4") &&
+	     !dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,5")) ||
+	    pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x1c, 0))
+		return;
+
+	res = request_mem_region(0x7fa00000, 0x200000,
+				 "MacBook Pro poweroff workaround");
+	if (res)
+		dev_info(dev, "claimed %s %pR\n", res->name, res);
+	else
+		dev_info(dev, "can't work around MacBook Pro poweroff issue\n");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/arch/x86/xen/smp_pv.c linux-libre-4.12.4-gnu/arch/x86/xen/smp_pv.c
--- linux-libre-4.12.3-gnu/arch/x86/xen/smp_pv.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/arch/x86/xen/smp_pv.c	2017-07-27 18:10:39.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/irq_work.h>
 #include <linux/tick.h>
 #include <linux/nmi.h>
+#include <linux/cpuhotplug.h>
 
 #include <asm/paravirt.h>
 #include <asm/desc.h>
@@ -417,7 +418,7 @@ static void xen_pv_play_dead(void) /* us
 	 */
 	tick_nohz_idle_enter();
 
-	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+	cpuhp_online_idle(CPUHP_AP_ONLINE_IDLE);
 }
 
 #else /* !CONFIG_HOTPLUG_CPU */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/acpi/ec.c linux-libre-4.12.4-gnu/drivers/acpi/ec.c
--- linux-libre-4.12.3-gnu/drivers/acpi/ec.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/acpi/ec.c	2017-07-27 18:10:39.000000000 -0400
@@ -147,7 +147,7 @@ static unsigned int ec_storm_threshold
 module_param(ec_storm_threshold, uint, 0644);
 MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm");
 
-static bool ec_freeze_events __read_mostly = true;
+static bool ec_freeze_events __read_mostly = false;
 module_param(ec_freeze_events, bool, 0644);
 MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume");
 
@@ -1812,24 +1812,6 @@ error:
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int acpi_ec_suspend_noirq(struct device *dev)
-{
-	struct acpi_ec *ec =
-		acpi_driver_data(to_acpi_device(dev));
-
-	acpi_ec_enter_noirq(ec);
-	return 0;
-}
-
-static int acpi_ec_resume_noirq(struct device *dev)
-{
-	struct acpi_ec *ec =
-		acpi_driver_data(to_acpi_device(dev));
-
-	acpi_ec_leave_noirq(ec);
-	return 0;
-}
-
 static int acpi_ec_suspend(struct device *dev)
 {
 	struct acpi_ec *ec =
@@ -1851,7 +1833,6 @@ static int acpi_ec_resume(struct device
 #endif
 
 static const struct dev_pm_ops acpi_ec_pm = {
-	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, acpi_ec_resume_noirq)
 	SET_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend, acpi_ec_resume)
 };
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/acpi/nfit/core.c linux-libre-4.12.4-gnu/drivers/acpi/nfit/core.c
--- linux-libre-4.12.3-gnu/drivers/acpi/nfit/core.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/acpi/nfit/core.c	2017-07-27 18:10:39.000000000 -0400
@@ -3043,6 +3043,8 @@ static struct acpi_driver acpi_nfit_driv
 
 static __init int nfit_init(void)
 {
+	int ret;
+
 	BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40);
 	BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56);
 	BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48);
@@ -3070,8 +3072,14 @@ static __init int nfit_init(void)
 		return -ENOMEM;
 
 	nfit_mce_register();
+	ret = acpi_bus_register_driver(&acpi_nfit_driver);
+	if (ret) {
+		nfit_mce_unregister();
+		destroy_workqueue(nfit_wq);
+	}
+
+	return ret;
 
-	return acpi_bus_register_driver(&acpi_nfit_driver);
 }
 
 static __exit void nfit_exit(void)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/base/power/domain.c linux-libre-4.12.4-gnu/drivers/base/power/domain.c
--- linux-libre-4.12.3-gnu/drivers/base/power/domain.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/base/power/domain.c	2017-07-27 18:10:39.000000000 -0400
@@ -1168,8 +1168,6 @@ static struct generic_pm_domain_data *ge
 
 	spin_unlock_irq(&dev->power.lock);
 
-	dev_pm_domain_set(dev, &genpd->domain);
-
 	return gpd_data;
 
  err_free:
@@ -1183,8 +1181,6 @@ static struct generic_pm_domain_data *ge
 static void genpd_free_dev_data(struct device *dev,
 				struct generic_pm_domain_data *gpd_data)
 {
-	dev_pm_domain_set(dev, NULL);
-
 	spin_lock_irq(&dev->power.lock);
 
 	dev->power.subsys_data->domain_data = NULL;
@@ -1221,6 +1217,8 @@ static int genpd_add_device(struct gener
 	if (ret)
 		goto out;
 
+	dev_pm_domain_set(dev, &genpd->domain);
+
 	genpd->device_count++;
 	genpd->max_off_time_changed = true;
 
@@ -1282,6 +1280,8 @@ static int genpd_remove_device(struct ge
 	if (genpd->detach_dev)
 		genpd->detach_dev(genpd, dev);
 
+	dev_pm_domain_set(dev, NULL);
+
 	list_del_init(&pdd->list_node);
 
 	genpd_unlock(genpd);
@@ -1393,7 +1393,7 @@ EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain
 int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 			      struct generic_pm_domain *subdomain)
 {
-	struct gpd_link *link;
+	struct gpd_link *l, *link;
 	int ret = -EINVAL;
 
 	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
@@ -1409,7 +1409,7 @@ int pm_genpd_remove_subdomain(struct gen
 		goto out;
 	}
 
-	list_for_each_entry(link, &genpd->master_links, master_node) {
+	list_for_each_entry_safe(link, l, &genpd->master_links, master_node) {
 		if (link->slave != subdomain)
 			continue;
 
@@ -1780,12 +1780,12 @@ EXPORT_SYMBOL_GPL(of_genpd_add_provider_
  */
 void of_genpd_del_provider(struct device_node *np)
 {
-	struct of_genpd_provider *cp;
+	struct of_genpd_provider *cp, *tmp;
 	struct generic_pm_domain *gpd;
 
 	mutex_lock(&gpd_list_lock);
 	mutex_lock(&of_genpd_mutex);
-	list_for_each_entry(cp, &of_genpd_providers, link) {
+	list_for_each_entry_safe(cp, tmp, &of_genpd_providers, link) {
 		if (cp->node == np) {
 			/*
 			 * For each PM domain associated with the
@@ -1925,14 +1925,14 @@ EXPORT_SYMBOL_GPL(of_genpd_add_subdomain
  */
 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 {
-	struct generic_pm_domain *gpd, *genpd = ERR_PTR(-ENOENT);
+	struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT);
 	int ret;
 
 	if (IS_ERR_OR_NULL(np))
 		return ERR_PTR(-EINVAL);
 
 	mutex_lock(&gpd_list_lock);
-	list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+	list_for_each_entry_safe(gpd, tmp, &gpd_list, gpd_list_node) {
 		if (gpd->provider == &np->fwnode) {
 			ret = genpd_remove(gpd);
 			genpd = ret ? ERR_PTR(ret) : gpd;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/char/ipmi/ipmi_msghandler.c linux-libre-4.12.4-gnu/drivers/char/ipmi/ipmi_msghandler.c
--- linux-libre-4.12.3-gnu/drivers/char/ipmi/ipmi_msghandler.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/char/ipmi/ipmi_msghandler.c	2017-07-27 18:10:39.000000000 -0400
@@ -3878,6 +3878,9 @@ static void smi_recv_tasklet(unsigned lo
 	 * because the lower layer is allowed to hold locks while calling
 	 * message delivery.
 	 */
+
+	rcu_read_lock();
+
 	if (!run_to_completion)
 		spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
 	if (intf->curr_msg == NULL && !intf->in_shutdown) {
@@ -3900,6 +3903,8 @@ static void smi_recv_tasklet(unsigned lo
 	if (newmsg)
 		intf->handlers->sender(intf->send_info, newmsg);
 
+	rcu_read_unlock();
+
 	handle_new_recv_msgs(intf);
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/char/ipmi/ipmi_ssif.c linux-libre-4.12.4-gnu/drivers/char/ipmi/ipmi_ssif.c
--- linux-libre-4.12.3-gnu/drivers/char/ipmi/ipmi_ssif.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/char/ipmi/ipmi_ssif.c	2017-07-27 18:10:39.000000000 -0400
@@ -761,6 +761,11 @@ static void msg_done_handler(struct ssif
 			       result, len, data[2]);
 		} else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2
 			   || data[1] != IPMI_GET_MSG_FLAGS_CMD) {
+			/*
+			 * Don't abort here, maybe it was a queued
+			 * response to a previous command.
+			 */
+			ipmi_ssif_unlock_cond(ssif_info, flags);
 			pr_warn(PFX "Invalid response getting flags: %x %x\n",
 				data[0], data[1]);
 		} else {
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/cpufreq/intel_pstate.c linux-libre-4.12.4-gnu/drivers/cpufreq/intel_pstate.c
--- linux-libre-4.12.3-gnu/drivers/cpufreq/intel_pstate.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/cpufreq/intel_pstate.c	2017-07-27 18:10:39.000000000 -0400
@@ -225,6 +225,9 @@ struct global_params {
  * @vid:		Stores VID limits for this CPU
  * @pid:		Stores PID parameters for this CPU
  * @last_sample_time:	Last Sample time
+ * @aperf_mperf_shift:	Number of clock cycles after aperf, merf is incremented
+ *			This shift is a multiplier to mperf delta to
+ *			calculate CPU busy.
  * @prev_aperf:		Last APERF value read from APERF MSR
  * @prev_mperf:		Last MPERF value read from MPERF MSR
  * @prev_tsc:		Last timestamp counter (TSC) value
@@ -261,6 +264,7 @@ struct cpudata {
 
 	u64	last_update;
 	u64	last_sample_time;
+	u64	aperf_mperf_shift;
 	u64	prev_aperf;
 	u64	prev_mperf;
 	u64	prev_tsc;
@@ -323,6 +327,7 @@ struct pstate_funcs {
 	int (*get_min)(void);
 	int (*get_turbo)(void);
 	int (*get_scaling)(void);
+	int (*get_aperf_mperf_shift)(void);
 	u64 (*get_val)(struct cpudata*, int pstate);
 	void (*get_vid)(struct cpudata *);
 	void (*update_util)(struct update_util_data *data, u64 time,
@@ -1485,6 +1490,11 @@ static u64 core_get_val(struct cpudata *
 	return val;
 }
 
+static int knl_get_aperf_mperf_shift(void)
+{
+	return 10;
+}
+
 static int knl_get_turbo_pstate(void)
 {
 	u64 value;
@@ -1543,6 +1553,9 @@ static void intel_pstate_get_cpu_pstates
 	cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling;
 	cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
 
+	if (pstate_funcs.get_aperf_mperf_shift)
+		cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift();
+
 	if (pstate_funcs.get_vid)
 		pstate_funcs.get_vid(cpu);
 
@@ -1619,7 +1632,8 @@ static inline int32_t get_target_pstate_
 	if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE)
 		return cpu->pstate.turbo_pstate;
 
-	busy_frac = div_fp(sample->mperf, sample->tsc);
+	busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift,
+			   sample->tsc);
 
 	boost = cpu->iowait_boost;
 	cpu->iowait_boost >>= 1;
@@ -1681,7 +1695,8 @@ static inline int32_t get_target_pstate_
 		sample_ratio = div_fp(pid_params.sample_rate_ns, duration_ns);
 		perf_scaled = mul_fp(perf_scaled, sample_ratio);
 	} else {
-		sample_ratio = div_fp(100 * cpu->sample.mperf, cpu->sample.tsc);
+		sample_ratio = div_fp(100 * (cpu->sample.mperf << cpu->aperf_mperf_shift),
+				      cpu->sample.tsc);
 		if (sample_ratio < int_tofp(1))
 			perf_scaled = 0;
 	}
@@ -1824,6 +1839,7 @@ static const struct pstate_funcs knl_fun
 	.get_max_physical = core_get_max_pstate_physical,
 	.get_min = core_get_min_pstate,
 	.get_turbo = knl_get_turbo_pstate,
+	.get_aperf_mperf_shift = knl_get_aperf_mperf_shift,
 	.get_scaling = core_get_scaling,
 	.get_val = core_get_val,
 	.update_util = intel_pstate_update_util_pid,
@@ -2408,6 +2424,7 @@ static void __init copy_cpu_funcs(struct
 	pstate_funcs.get_val   = funcs->get_val;
 	pstate_funcs.get_vid   = funcs->get_vid;
 	pstate_funcs.update_util = funcs->update_util;
+	pstate_funcs.get_aperf_mperf_shift = funcs->get_aperf_mperf_shift;
 
 	intel_pstate_use_acpi_profile();
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/dax/device.c linux-libre-4.12.4-gnu/drivers/dax/device.c
--- linux-libre-4.12.3-gnu/drivers/dax/device.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/dax/device.c	2017-07-27 18:10:39.000000000 -0400
@@ -528,7 +528,8 @@ static void dev_dax_release(struct devic
 	struct dax_region *dax_region = dev_dax->region;
 	struct dax_device *dax_dev = dev_dax->dax_dev;
 
-	ida_simple_remove(&dax_region->ida, dev_dax->id);
+	if (dev_dax->id >= 0)
+		ida_simple_remove(&dax_region->ida, dev_dax->id);
 	dax_region_put(dax_region);
 	put_dax(dax_dev);
 	kfree(dev_dax);
@@ -558,7 +559,7 @@ static void unregister_dev_dax(void *dev
 }
 
 struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
-		struct resource *res, int count)
+		int id, struct resource *res, int count)
 {
 	struct device *parent = dax_region->dev;
 	struct dax_device *dax_dev;
@@ -586,10 +587,16 @@ struct dev_dax *devm_create_dev_dax(stru
 	if (i < count)
 		goto err_id;
 
-	dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
-	if (dev_dax->id < 0) {
-		rc = dev_dax->id;
-		goto err_id;
+	if (id < 0) {
+		id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
+		dev_dax->id = id;
+		if (id < 0) {
+			rc = id;
+			goto err_id;
+		}
+	} else {
+		/* region provider owns @id lifetime */
+		dev_dax->id = -1;
 	}
 
 	/*
@@ -619,7 +626,7 @@ struct dev_dax *devm_create_dev_dax(stru
 	dev->parent = parent;
 	dev->groups = dax_attribute_groups;
 	dev->release = dev_dax_release;
-	dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
+	dev_set_name(dev, "dax%d.%d", dax_region->id, id);
 
 	rc = cdev_device_add(cdev, dev);
 	if (rc) {
@@ -635,7 +642,8 @@ struct dev_dax *devm_create_dev_dax(stru
 	return dev_dax;
 
  err_dax:
-	ida_simple_remove(&dax_region->ida, dev_dax->id);
+	if (dev_dax->id >= 0)
+		ida_simple_remove(&dax_region->ida, dev_dax->id);
  err_id:
 	kfree(dev_dax);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/dax/device-dax.h linux-libre-4.12.4-gnu/drivers/dax/device-dax.h
--- linux-libre-4.12.3-gnu/drivers/dax/device-dax.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/dax/device-dax.h	2017-07-27 18:10:39.000000000 -0400
@@ -21,5 +21,5 @@ struct dax_region *alloc_dax_region(stru
 		int region_id, struct resource *res, unsigned int align,
 		void *addr, unsigned long flags);
 struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
-		struct resource *res, int count);
+		int id, struct resource *res, int count);
 #endif /* __DEVICE_DAX_H__ */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/dax/pmem.c linux-libre-4.12.4-gnu/drivers/dax/pmem.c
--- linux-libre-4.12.3-gnu/drivers/dax/pmem.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/dax/pmem.c	2017-07-27 18:10:39.000000000 -0400
@@ -58,13 +58,12 @@ static void dax_pmem_percpu_kill(void *d
 
 static int dax_pmem_probe(struct device *dev)
 {
-	int rc;
 	void *addr;
 	struct resource res;
+	int rc, id, region_id;
 	struct nd_pfn_sb *pfn_sb;
 	struct dev_dax *dev_dax;
 	struct dax_pmem *dax_pmem;
-	struct nd_region *nd_region;
 	struct nd_namespace_io *nsio;
 	struct dax_region *dax_region;
 	struct nd_namespace_common *ndns;
@@ -123,14 +122,17 @@ static int dax_pmem_probe(struct device
 	/* adjust the dax_region resource to the start of data */
 	res.start += le64_to_cpu(pfn_sb->dataoff);
 
-	nd_region = to_nd_region(dev->parent);
-	dax_region = alloc_dax_region(dev, nd_region->id, &res,
+	rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
+	if (rc != 2)
+		return -EINVAL;
+
+	dax_region = alloc_dax_region(dev, region_id, &res,
 			le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
 	if (!dax_region)
 		return -ENOMEM;
 
 	/* TODO: support for subdividing a dax region... */
-	dev_dax = devm_create_dev_dax(dax_region, &res, 1);
+	dev_dax = devm_create_dev_dax(dax_region, id, &res, 1);
 
 	/* child dev_dax instances now own the lifetime of the dax_region */
 	dax_region_put(dax_region);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c	2017-07-21 05:01:09.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c	2017-07-27 21:28:56.000000000 -0400
@@ -838,6 +838,12 @@ static int amdgpu_cgs_get_active_display
 		return -EINVAL;
 
 	mode_info = info->mode_info;
+	if (mode_info) {
+		/* if the displays are off, vblank time is max */
+		mode_info->vblank_time_us = 0xffffffff;
+		/* always set the reference clock */
+		mode_info->ref_clock = adev->clock.spll.reference_freq;
+	}
 
 	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
 		list_for_each_entry(crtc,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c	2017-07-27 18:10:39.000000000 -0400
@@ -208,7 +208,8 @@ static void amdgpu_pp_late_fini(void *ha
 	if (adev->pp_enabled && adev->pm.dpm_enabled)
 		amdgpu_pm_sysfs_fini(adev);
 
-	amd_powerplay_destroy(adev->powerplay.pp_handle);
+	if (adev->pp_enabled)
+		amd_powerplay_destroy(adev->powerplay.pp_handle);
 }
 
 static int amdgpu_pp_suspend(void *handle)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c	2017-07-27 18:10:39.000000000 -0400
@@ -319,14 +319,11 @@ static int psp_load_fw(struct amdgpu_dev
 {
 	int ret;
 	struct psp_context *psp = &adev->psp;
-	struct psp_gfx_cmd_resp *cmd;
 
-	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
-	if (!cmd)
+	psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+	if (!psp->cmd)
 		return -ENOMEM;
 
-	psp->cmd = cmd;
-
 	ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
 				      AMDGPU_GEM_DOMAIN_GTT,
 				      &psp->fw_pri_bo,
@@ -365,8 +362,6 @@ static int psp_load_fw(struct amdgpu_dev
 	if (ret)
 		goto failed_mem;
 
-	kfree(cmd);
-
 	return 0;
 
 failed_mem:
@@ -376,7 +371,8 @@ failed_mem1:
 	amdgpu_bo_free_kernel(&psp->fw_pri_bo,
 			      &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
 failed:
-	kfree(cmd);
+	kfree(psp->cmd);
+	psp->cmd = NULL;
 	return ret;
 }
 
@@ -436,6 +432,9 @@ static int psp_hw_fini(void *handle)
 		amdgpu_bo_free_kernel(&psp->fence_buf_bo,
 				      &psp->fence_buf_mc_addr, &psp->fence_buf);
 
+	kfree(psp->cmd);
+	psp->cmd = NULL;
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c	2017-07-27 18:10:39.000000000 -0400
@@ -1462,6 +1462,9 @@ static ssize_t amdgpu_ttm_vram_read(stru
 	if (size & 0x3 || *pos & 0x3)
 		return -EINVAL;
 
+	if (*pos >= adev->mc.mc_vram_size)
+		return -ENXIO;
+
 	while (size) {
 		unsigned long flags;
 		uint32_t value;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c	2017-07-21 05:00:14.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c	2017-07-27 21:28:10.000000000 -0400
@@ -1855,46 +1855,7 @@ static int gfx_v8_0_gpu_early_init(struc
 		adev->gfx.config.max_tile_pipes = 2;
 		adev->gfx.config.max_sh_per_se = 1;
 		adev->gfx.config.max_backends_per_se = 2;
-
-		switch (adev->pdev->revision) {
-		case 0xc4:
-		case 0x84:
-		case 0xc8:
-		case 0xcc:
-		case 0xe1:
-		case 0xe3:
-			/* B10 */
-			adev->gfx.config.max_cu_per_sh = 8;
-			break;
-		case 0xc5:
-		case 0x81:
-		case 0x85:
-		case 0xc9:
-		case 0xcd:
-		case 0xe2:
-		case 0xe4:
-			/* B8 */
-			adev->gfx.config.max_cu_per_sh = 6;
-			break;
-		case 0xc6:
-		case 0xca:
-		case 0xce:
-		case 0x88:
-		case 0xe6:
-			/* B6 */
-			adev->gfx.config.max_cu_per_sh = 6;
-			break;
-		case 0xc7:
-		case 0x87:
-		case 0xcb:
-		case 0xe5:
-		case 0x89:
-		default:
-			/* B4 */
-			adev->gfx.config.max_cu_per_sh = 4;
-			break;
-		}
-
+		adev->gfx.config.max_cu_per_sh = 8;
 		adev->gfx.config.max_texture_channel_caches = 2;
 		adev->gfx.config.max_gprs = 256;
 		adev->gfx.config.max_gs_threads = 32;
@@ -1911,35 +1872,7 @@ static int gfx_v8_0_gpu_early_init(struc
 		adev->gfx.config.max_tile_pipes = 2;
 		adev->gfx.config.max_sh_per_se = 1;
 		adev->gfx.config.max_backends_per_se = 1;
-
-		switch (adev->pdev->revision) {
-		case 0x80:
-		case 0x81:
-		case 0xc0:
-		case 0xc1:
-		case 0xc2:
-		case 0xc4:
-		case 0xc8:
-		case 0xc9:
-		case 0xd6:
-		case 0xda:
-		case 0xe9:
-		case 0xea:
-			adev->gfx.config.max_cu_per_sh = 3;
-			break;
-		case 0x83:
-		case 0xd0:
-		case 0xd1:
-		case 0xd2:
-		case 0xd4:
-		case 0xdb:
-		case 0xe1:
-		case 0xe2:
-		default:
-			adev->gfx.config.max_cu_per_sh = 2;
-			break;
-		}
-
+		adev->gfx.config.max_cu_per_sh = 3;
 		adev->gfx.config.max_texture_channel_caches = 2;
 		adev->gfx.config.max_gprs = 256;
 		adev->gfx.config.max_gs_threads = 16;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c	2017-07-27 18:10:39.000000000 -0400
@@ -1224,6 +1224,12 @@ static int cz_hwmgr_backend_fini(struct
 		phm_destroy_table(hwmgr, &(hwmgr->disable_dynamic_state_management));
 		phm_destroy_table(hwmgr, &(hwmgr->power_down_asic));
 		phm_destroy_table(hwmgr, &(hwmgr->setup_asic));
+
+		if (NULL != hwmgr->dyn_state.vddc_dep_on_dal_pwrl) {
+			kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
+			hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
+		}
+
 		kfree(hwmgr->backend);
 		hwmgr->backend = NULL;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/drm_dp_mst_topology.c linux-libre-4.12.4-gnu/drivers/gpu/drm/drm_dp_mst_topology.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/drm_dp_mst_topology.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/drm_dp_mst_topology.c	2017-07-27 18:10:39.000000000 -0400
@@ -330,6 +330,13 @@ static bool drm_dp_sideband_msg_build(st
 			return false;
 		}
 
+		/*
+		 * ignore out-of-order messages or messages that are part of a
+		 * failed transaction
+		 */
+		if (!recv_hdr.somt && !msg->have_somt)
+			return false;
+
 		/* get length contained in this portion */
 		msg->curchunk_len = recv_hdr.msg_len;
 		msg->curchunk_hdrlen = hdrlen;
@@ -2164,7 +2171,7 @@ out_unlock:
 }
 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
 
-static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
+static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
 {
 	int len;
 	u8 replyblock[32];
@@ -2179,12 +2186,12 @@ static void drm_dp_get_one_sb_msg(struct
 			       replyblock, len);
 	if (ret != len) {
 		DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
-		return;
+		return false;
 	}
 	ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
 	if (!ret) {
 		DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
-		return;
+		return false;
 	}
 	replylen = msg->curchunk_len + msg->curchunk_hdrlen;
 
@@ -2196,21 +2203,32 @@ static void drm_dp_get_one_sb_msg(struct
 		ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,
 				    replyblock, len);
 		if (ret != len) {
-			DRM_DEBUG_KMS("failed to read a chunk\n");
+			DRM_DEBUG_KMS("failed to read a chunk (len %d, ret %d)\n",
+				      len, ret);
+			return false;
 		}
+
 		ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
-		if (ret == false)
+		if (!ret) {
 			DRM_DEBUG_KMS("failed to build sideband msg\n");
+			return false;
+		}
+
 		curreply += len;
 		replylen -= len;
 	}
+	return true;
 }
 
 static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
 {
 	int ret = 0;
 
-	drm_dp_get_one_sb_msg(mgr, false);
+	if (!drm_dp_get_one_sb_msg(mgr, false)) {
+		memset(&mgr->down_rep_recv, 0,
+		       sizeof(struct drm_dp_sideband_msg_rx));
+		return 0;
+	}
 
 	if (mgr->down_rep_recv.have_eomt) {
 		struct drm_dp_sideband_msg_tx *txmsg;
@@ -2266,7 +2284,12 @@ static int drm_dp_mst_handle_down_rep(st
 static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
 {
 	int ret = 0;
-	drm_dp_get_one_sb_msg(mgr, true);
+
+	if (!drm_dp_get_one_sb_msg(mgr, true)) {
+		memset(&mgr->up_req_recv, 0,
+		       sizeof(struct drm_dp_sideband_msg_rx));
+		return 0;
+	}
 
 	if (mgr->up_req_recv.have_eomt) {
 		struct drm_dp_sideband_msg_req_body msg;
@@ -2318,7 +2341,9 @@ static int drm_dp_mst_handle_up_req(stru
 			DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
 		}
 
-		drm_dp_put_mst_branch_device(mstb);
+		if (mstb)
+			drm_dp_put_mst_branch_device(mstb);
+
 		memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
 	}
 	return ret;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/drm_framebuffer.c linux-libre-4.12.4-gnu/drivers/gpu/drm/drm_framebuffer.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/drm_framebuffer.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/drm_framebuffer.c	2017-07-27 18:10:39.000000000 -0400
@@ -832,6 +832,7 @@ unlock:
 		drm_atomic_clean_old_fb(dev, plane_mask, ret);
 
 	if (ret == -EDEADLK) {
+		drm_atomic_state_clear(state);
 		drm_modeset_backoff(&ctx);
 		goto retry;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.c linux-libre-4.12.4-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.c	2017-07-27 18:10:39.000000000 -0400
@@ -495,6 +495,7 @@ static struct drm_driver etnaviv_drm_dri
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_export   = drm_gem_prime_export,
 	.gem_prime_import   = drm_gem_prime_import,
+	.gem_prime_res_obj  = etnaviv_gem_prime_res_obj,
 	.gem_prime_pin      = etnaviv_gem_prime_pin,
 	.gem_prime_unpin    = etnaviv_gem_prime_unpin,
 	.gem_prime_get_sg_table = etnaviv_gem_prime_get_sg_table,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.h linux-libre-4.12.4-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.h
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/etnaviv/etnaviv_drv.h	2017-07-27 18:10:39.000000000 -0400
@@ -80,6 +80,7 @@ void *etnaviv_gem_prime_vmap(struct drm_
 void etnaviv_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
 int etnaviv_gem_prime_mmap(struct drm_gem_object *obj,
 			   struct vm_area_struct *vma);
+struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj);
 struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
 	struct dma_buf_attachment *attach, struct sg_table *sg);
 int etnaviv_gem_prime_pin(struct drm_gem_object *obj);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c linux-libre-4.12.4-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c	2017-07-27 18:10:39.000000000 -0400
@@ -150,3 +150,10 @@ fail:
 
 	return ERR_PTR(ret);
 }
+
+struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+	struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
+
+	return etnaviv_obj->resv;
+}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/gvt/kvmgt.c linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/gvt/kvmgt.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/gvt/kvmgt.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/gvt/kvmgt.c	2017-07-27 18:10:39.000000000 -0400
@@ -232,16 +232,20 @@ static void gvt_cache_destroy(struct int
 	struct device *dev = mdev_dev(vgpu->vdev.mdev);
 	unsigned long gfn;
 
-	mutex_lock(&vgpu->vdev.cache_lock);
-	while ((node = rb_first(&vgpu->vdev.cache))) {
+	for (;;) {
+		mutex_lock(&vgpu->vdev.cache_lock);
+		node = rb_first(&vgpu->vdev.cache);
+		if (!node) {
+			mutex_unlock(&vgpu->vdev.cache_lock);
+			break;
+		}
 		dma = rb_entry(node, struct gvt_dma, node);
 		gvt_dma_unmap_iova(vgpu, dma->iova);
 		gfn = dma->gfn;
-
-		vfio_unpin_pages(dev, &gfn, 1);
 		__gvt_cache_remove_entry(vgpu, dma);
+		mutex_unlock(&vgpu->vdev.cache_lock);
+		vfio_unpin_pages(dev, &gfn, 1);
 	}
-	mutex_unlock(&vgpu->vdev.cache_lock);
 }
 
 static struct intel_vgpu_type *intel_gvt_find_vgpu_type(struct intel_gvt *gvt,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/i915_debugfs.c linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/i915_debugfs.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/i915_debugfs.c	2017-07-27 18:10:39.000000000 -0400
@@ -3018,7 +3018,7 @@ static void intel_connector_info(struct
 			   connector->display_info.cea_rev);
 	}
 
-	if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST)
+	if (!intel_encoder)
 		return;
 
 	switch (connector->connector_type) {
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/i915_drv.c linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/i915_drv.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/i915_drv.c	2017-07-27 18:10:39.000000000 -0400
@@ -1087,10 +1087,12 @@ static int i915_driver_init_hw(struct dr
 	 * and the registers being closely associated.
 	 *
 	 * According to chipset errata, on the 965GM, MSI interrupts may
-	 * be lost or delayed, but we use them anyways to avoid
-	 * stuck interrupts on some machines.
+	 * be lost or delayed, and was defeatured. MSI interrupts seem to
+	 * get lost on g4x as well, and interrupt delivery seems to stay
+	 * properly dead afterwards. So we'll just disable them for all
+	 * pre-gen5 chipsets.
 	 */
-	if (!IS_I945G(dev_priv) && !IS_I945GM(dev_priv)) {
+	if (INTEL_GEN(dev_priv) >= 5) {
 		if (pci_enable_msi(pdev) < 0)
 			DRM_DEBUG_DRIVER("can't enable MSI");
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/i915_perf.c linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/i915_perf.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/i915_perf.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/i915_perf.c	2017-07-27 18:10:39.000000000 -0400
@@ -1210,10 +1210,6 @@ static int i915_oa_stream_init(struct i9
 			return ret;
 	}
 
-	ret = alloc_oa_buffer(dev_priv);
-	if (ret)
-		goto err_oa_buf_alloc;
-
 	/* PRM - observability performance counters:
 	 *
 	 *   OACONTROL, performance counter enable, note:
@@ -1229,6 +1225,10 @@ static int i915_oa_stream_init(struct i9
 	intel_runtime_pm_get(dev_priv);
 	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
+	ret = alloc_oa_buffer(dev_priv);
+	if (ret)
+		goto err_oa_buf_alloc;
+
 	ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv);
 	if (ret)
 		goto err_enable;
@@ -1240,11 +1240,11 @@ static int i915_oa_stream_init(struct i9
 	return 0;
 
 err_enable:
-	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
-	intel_runtime_pm_put(dev_priv);
 	free_oa_buffer(dev_priv);
 
 err_oa_buf_alloc:
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+	intel_runtime_pm_put(dev_priv);
 	if (stream->ctx)
 		oa_put_render_ctx_id(stream);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/intel_cdclk.c linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/intel_cdclk.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/intel_cdclk.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/intel_cdclk.c	2017-07-27 18:10:39.000000000 -0400
@@ -491,6 +491,14 @@ static void vlv_set_cdclk(struct drm_i91
 	int cdclk = cdclk_state->cdclk;
 	u32 val, cmd;
 
+	/* There are cases where we can end up here with power domains
+	 * off and a CDCLK frequency other than the minimum, like when
+	 * issuing a modeset without actually changing any display after
+	 * a system suspend.  So grab the PIPE-A domain, which covers
+	 * the HW blocks needed for the following programming.
+	 */
+	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
 	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
 		cmd = 2;
 	else if (cdclk == 266667)
@@ -549,6 +557,8 @@ static void vlv_set_cdclk(struct drm_i91
 	intel_update_cdclk(dev_priv);
 
 	vlv_program_pfi_credits(dev_priv);
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
 }
 
 static void chv_set_cdclk(struct drm_i915_private *dev_priv,
@@ -568,6 +578,14 @@ static void chv_set_cdclk(struct drm_i91
 		return;
 	}
 
+	/* There are cases where we can end up here with power domains
+	 * off and a CDCLK frequency other than the minimum, like when
+	 * issuing a modeset without actually changing any display after
+	 * a system suspend.  So grab the PIPE-A domain, which covers
+	 * the HW blocks needed for the following programming.
+	 */
+	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
 	/*
 	 * Specs are full of misinformation, but testing on actual
 	 * hardware has shown that we just need to write the desired
@@ -590,6 +608,8 @@ static void chv_set_cdclk(struct drm_i91
 	intel_update_cdclk(dev_priv);
 
 	vlv_program_pfi_credits(dev_priv);
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
 }
 
 static int bdw_calc_cdclk(int max_pixclk)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/intel_fbdev.c linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/intel_fbdev.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/i915/intel_fbdev.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/i915/intel_fbdev.c	2017-07-27 18:10:39.000000000 -0400
@@ -535,13 +535,14 @@ static void intel_fbdev_destroy(struct i
 
 	drm_fb_helper_fini(&ifbdev->helper);
 
-	if (ifbdev->fb) {
+	if (ifbdev->vma) {
 		mutex_lock(&ifbdev->helper.dev->struct_mutex);
 		intel_unpin_fb_vma(ifbdev->vma);
 		mutex_unlock(&ifbdev->helper.dev->struct_mutex);
+	}
 
+	if (ifbdev->fb)
 		drm_framebuffer_remove(&ifbdev->fb->base);
-	}
 
 	kfree(ifbdev);
 }
@@ -765,7 +766,7 @@ void intel_fbdev_set_suspend(struct drm_
 	struct intel_fbdev *ifbdev = dev_priv->fbdev;
 	struct fb_info *info;
 
-	if (!ifbdev || !ifbdev->fb)
+	if (!ifbdev || !ifbdev->vma)
 		return;
 
 	info = ifbdev->helper.fbdev;
@@ -812,7 +813,7 @@ void intel_fbdev_output_poll_changed(str
 {
 	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
 
-	if (ifbdev && ifbdev->fb)
+	if (ifbdev && ifbdev->vma)
 		drm_fb_helper_hotplug_event(&ifbdev->helper);
 }
 
@@ -824,7 +825,7 @@ void intel_fbdev_restore_mode(struct drm
 		return;
 
 	intel_fbdev_sync(ifbdev);
-	if (!ifbdev->fb)
+	if (!ifbdev->vma)
 		return;
 
 	if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/imx/parallel-display.c linux-libre-4.12.4-gnu/drivers/gpu/drm/imx/parallel-display.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/imx/parallel-display.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/imx/parallel-display.c	2017-07-27 18:10:39.000000000 -0400
@@ -237,7 +237,7 @@ static int imx_pd_bind(struct device *de
 
 	/* port@1 is the output port */
 	ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel, &imxpd->bridge);
-	if (ret)
+	if (ret && ret != -ENODEV)
 		return ret;
 
 	imxpd->dev = dev;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/radeon/atombios_encoders.c linux-libre-4.12.4-gnu/drivers/gpu/drm/radeon/atombios_encoders.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/radeon/atombios_encoders.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/radeon/atombios_encoders.c	2017-07-27 18:10:39.000000000 -0400
@@ -31,6 +31,7 @@
 #include "radeon_asic.h"
 #include "atom.h"
 #include <linux/backlight.h>
+#include <linux/dmi.h>
 
 extern int atom_debug;
 
@@ -2184,9 +2185,17 @@ int radeon_atom_pick_dig_encoder(struct
 		goto assigned;
 	}
 
-	/* on DCE32 and encoder can driver any block so just crtc id */
+	/*
+	 * On DCE32 any encoder can drive any block so usually just use crtc id,
+	 * but Apple thinks different at least on iMac10,1, so there use linkb,
+	 * otherwise the internal eDP panel will stay dark.
+	 */
 	if (ASIC_IS_DCE32(rdev)) {
-		enc_idx = radeon_crtc->crtc_id;
+		if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1"))
+			enc_idx = (dig->linkb) ? 1 : 0;
+		else
+			enc_idx = radeon_crtc->crtc_id;
+
 		goto assigned;
 	}
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/radeon/ci_dpm.c linux-libre-4.12.4-gnu/drivers/gpu/drm/radeon/ci_dpm.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/radeon/ci_dpm.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/radeon/ci_dpm.c	2017-07-27 18:10:39.000000000 -0400
@@ -782,6 +782,12 @@ bool ci_dpm_vblank_too_short(struct rade
 	if (r600_dpm_get_vrefresh(rdev) > 120)
 		return true;
 
+	/* disable mclk switching if the refresh is >120Hz, even if the
+        * blanking period would allow it
+        */
+	if (r600_dpm_get_vrefresh(rdev) > 120)
+		return true;
+
 	if (vblank_time < switch_limit)
 		return true;
 	else
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/gpu/drm/ttm/ttm_bo.c linux-libre-4.12.4-gnu/drivers/gpu/drm/ttm/ttm_bo.c
--- linux-libre-4.12.3-gnu/drivers/gpu/drm/ttm/ttm_bo.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/gpu/drm/ttm/ttm_bo.c	2017-07-27 18:10:39.000000000 -0400
@@ -1353,7 +1353,6 @@ int ttm_bo_clean_mm(struct ttm_bo_device
 		       mem_type);
 		return ret;
 	}
-	dma_fence_put(man->move);
 
 	man->use_type = false;
 	man->has_type = false;
@@ -1369,6 +1368,9 @@ int ttm_bo_clean_mm(struct ttm_bo_device
 		ret = (*man->func->takedown)(man);
 	}
 
+	dma_fence_put(man->move);
+	man->move = NULL;
+
 	return ret;
 }
 EXPORT_SYMBOL(ttm_bo_clean_mm);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/hid/hid-multitouch.c linux-libre-4.12.4-gnu/drivers/hid/hid-multitouch.c
--- linux-libre-4.12.3-gnu/drivers/hid/hid-multitouch.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/hid/hid-multitouch.c	2017-07-27 18:10:39.000000000 -0400
@@ -595,16 +595,6 @@ static int mt_touch_input_mapping(struct
 	return 0;
 }
 
-static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi,
-		struct hid_field *field, struct hid_usage *usage,
-		unsigned long **bit, int *max)
-{
-	if (usage->type == EV_KEY || usage->type == EV_ABS)
-		set_bit(usage->type, hi->input->evbit);
-
-	return -1;
-}
-
 static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
 {
 	__s32 quirks = td->mtclass.quirks;
@@ -905,8 +895,10 @@ static int mt_input_mapped(struct hid_de
 		return 0;
 
 	if (field->application == HID_DG_TOUCHSCREEN ||
-	    field->application == HID_DG_TOUCHPAD)
-		return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
+	    field->application == HID_DG_TOUCHPAD) {
+		/* We own these mappings, tell hid-input to ignore them */
+		return -1;
+	}
 
 	/* let hid-core decide for the others */
 	return 0;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/hv/channel.c linux-libre-4.12.4-gnu/drivers/hv/channel.c
--- linux-libre-4.12.3-gnu/drivers/hv/channel.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/hv/channel.c	2017-07-27 18:10:39.000000000 -0400
@@ -606,6 +606,8 @@ static int vmbus_close_internal(struct v
 		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 
 out:
+	/* re-enable tasklet for use on re-open */
+	tasklet_enable(&channel->callback_event);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/infiniband/core/addr.c linux-libre-4.12.4-gnu/drivers/infiniband/core/addr.c
--- linux-libre-4.12.3-gnu/drivers/infiniband/core/addr.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/infiniband/core/addr.c	2017-07-27 18:10:39.000000000 -0400
@@ -510,6 +510,11 @@ static int addr_resolve(struct sockaddr
 	struct dst_entry *dst;
 	int ret;
 
+	if (!addr->net) {
+		pr_warn_ratelimited("%s: missing namespace\n", __func__);
+		return -EINVAL;
+	}
+
 	if (src_in->sa_family == AF_INET) {
 		struct rtable *rt = NULL;
 		const struct sockaddr_in *dst_in4 =
@@ -547,7 +552,6 @@ static int addr_resolve(struct sockaddr
 	}
 
 	addr->bound_dev_if = ndev->ifindex;
-	addr->net = dev_net(ndev);
 	dev_put(ndev);
 
 	return ret;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/infiniband/core/cma.c linux-libre-4.12.4-gnu/drivers/infiniband/core/cma.c
--- linux-libre-4.12.3-gnu/drivers/infiniband/core/cma.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/infiniband/core/cma.c	2017-07-27 18:10:39.000000000 -0400
@@ -1044,6 +1044,8 @@ int rdma_init_qp_attr(struct rdma_cm_id
 		} else
 			ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
 						 qp_attr_mask);
+		qp_attr->port_num = id_priv->id.port_num;
+		*qp_attr_mask |= IB_QP_PORT;
 	} else
 		ret = -ENOSYS;
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/infiniband/core/uverbs_cmd.c linux-libre-4.12.4-gnu/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-4.12.3-gnu/drivers/infiniband/core/uverbs_cmd.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/infiniband/core/uverbs_cmd.c	2017-07-27 18:10:39.000000000 -0400
@@ -1931,7 +1931,8 @@ static int modify_qp(struct ib_uverbs_fi
 		goto out;
 	}
 
-	if (!rdma_is_port_valid(qp->device, cmd->base.port_num)) {
+	if ((cmd->base.attr_mask & IB_QP_PORT) &&
+	    !rdma_is_port_valid(qp->device, cmd->base.port_num)) {
 		ret = -EINVAL;
 		goto release_qp;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/infiniband/hw/mlx5/mr.c linux-libre-4.12.4-gnu/drivers/infiniband/hw/mlx5/mr.c
--- linux-libre-4.12.3-gnu/drivers/infiniband/hw/mlx5/mr.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/infiniband/hw/mlx5/mr.c	2017-07-27 18:10:39.000000000 -0400
@@ -1779,7 +1779,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr
 	mr->ndescs = sg_nents;
 
 	for_each_sg(sgl, sg, sg_nents, i) {
-		if (unlikely(i > mr->max_descs))
+		if (unlikely(i >= mr->max_descs))
 			break;
 		klms[i].va = cpu_to_be64(sg_dma_address(sg) + sg_offset);
 		klms[i].bcount = cpu_to_be32(sg_dma_len(sg) - sg_offset);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/infiniband/ulp/iser/iscsi_iser.c linux-libre-4.12.4-gnu/drivers/infiniband/ulp/iser/iscsi_iser.c
--- linux-libre-4.12.3-gnu/drivers/infiniband/ulp/iser/iscsi_iser.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/infiniband/ulp/iser/iscsi_iser.c	2017-07-27 18:10:39.000000000 -0400
@@ -83,6 +83,7 @@ static struct scsi_host_template iscsi_i
 static struct iscsi_transport iscsi_iser_transport;
 static struct scsi_transport_template *iscsi_iser_scsi_transport;
 static struct workqueue_struct *release_wq;
+static DEFINE_MUTEX(unbind_iser_conn_mutex);
 struct iser_global ig;
 
 int iser_debug_level = 0;
@@ -550,12 +551,14 @@ iscsi_iser_conn_stop(struct iscsi_cls_co
 	 */
 	if (iser_conn) {
 		mutex_lock(&iser_conn->state_mutex);
+		mutex_lock(&unbind_iser_conn_mutex);
 		iser_conn_terminate(iser_conn);
 		iscsi_conn_stop(cls_conn, flag);
 
 		/* unbind */
 		iser_conn->iscsi_conn = NULL;
 		conn->dd_data = NULL;
+		mutex_unlock(&unbind_iser_conn_mutex);
 
 		complete(&iser_conn->stop_completion);
 		mutex_unlock(&iser_conn->state_mutex);
@@ -977,13 +980,21 @@ static int iscsi_iser_slave_alloc(struct
 	struct iser_conn *iser_conn;
 	struct ib_device *ib_dev;
 
+	mutex_lock(&unbind_iser_conn_mutex);
+
 	session = starget_to_session(scsi_target(sdev))->dd_data;
 	iser_conn = session->leadconn->dd_data;
+	if (!iser_conn) {
+		mutex_unlock(&unbind_iser_conn_mutex);
+		return -ENOTCONN;
+	}
 	ib_dev = iser_conn->ib_conn.device->ib_device;
 
 	if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
 		blk_queue_virt_boundary(sdev->request_queue, ~MASK_4K);
 
+	mutex_unlock(&unbind_iser_conn_mutex);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/infiniband/ulp/isert/ib_isert.c linux-libre-4.12.4-gnu/drivers/infiniband/ulp/isert/ib_isert.c
--- linux-libre-4.12.3-gnu/drivers/infiniband/ulp/isert/ib_isert.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/infiniband/ulp/isert/ib_isert.c	2017-07-27 18:10:39.000000000 -0400
@@ -1452,7 +1452,7 @@ static void
 isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
 {
 	struct isert_conn *isert_conn = wc->qp->qp_context;
-	struct ib_device *ib_dev = isert_conn->cm_id->device;
+	struct ib_device *ib_dev = isert_conn->device->ib_device;
 
 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
 		isert_print_wc(wc, "login recv");
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/input/serio/i8042.c linux-libre-4.12.4-gnu/drivers/input/serio/i8042.c
--- linux-libre-4.12.3-gnu/drivers/input/serio/i8042.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/input/serio/i8042.c	2017-07-27 18:10:39.000000000 -0400
@@ -436,8 +436,10 @@ static int i8042_start(struct serio *ser
 {
 	struct i8042_port *port = serio->port_data;
 
+	spin_lock_irq(&i8042_lock);
 	port->exists = true;
-	mb();
+	spin_unlock_irq(&i8042_lock);
+
 	return 0;
 }
 
@@ -450,16 +452,20 @@ static void i8042_stop(struct serio *ser
 {
 	struct i8042_port *port = serio->port_data;
 
+	spin_lock_irq(&i8042_lock);
 	port->exists = false;
+	port->serio = NULL;
+	spin_unlock_irq(&i8042_lock);
 
 	/*
+	 * We need to make sure that interrupt handler finishes using
+	 * our serio port before we return from this function.
 	 * We synchronize with both AUX and KBD IRQs because there is
 	 * a (very unlikely) chance that AUX IRQ is raised for KBD port
 	 * and vice versa.
 	 */
 	synchronize_irq(I8042_AUX_IRQ);
 	synchronize_irq(I8042_KBD_IRQ);
-	port->serio = NULL;
 }
 
 /*
@@ -576,7 +582,7 @@ static irqreturn_t i8042_interrupt(int i
 
 	spin_unlock_irqrestore(&i8042_lock, flags);
 
-	if (likely(port->exists && !filtered))
+	if (likely(serio && !filtered))
 		serio_interrupt(serio, data, dfl);
 
  out:
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/iommu/arm-smmu.c linux-libre-4.12.4-gnu/drivers/iommu/arm-smmu.c
--- linux-libre-4.12.3-gnu/drivers/iommu/arm-smmu.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/iommu/arm-smmu.c	2017-07-27 18:10:39.000000000 -0400
@@ -312,6 +312,14 @@ enum arm_smmu_implementation {
 	CAVIUM_SMMUV2,
 };
 
+/* Until ACPICA headers cover IORT rev. C */
+#ifndef ACPI_IORT_SMMU_CORELINK_MMU401
+#define ACPI_IORT_SMMU_CORELINK_MMU401	0x4
+#endif
+#ifndef ACPI_IORT_SMMU_CAVIUM_THUNDERX
+#define ACPI_IORT_SMMU_CAVIUM_THUNDERX	0x5
+#endif
+
 struct arm_smmu_s2cr {
 	struct iommu_group		*group;
 	int				count;
@@ -2073,6 +2081,10 @@ static int acpi_smmu_get_data(u32 model,
 		smmu->version = ARM_SMMU_V1;
 		smmu->model = GENERIC_SMMU;
 		break;
+	case ACPI_IORT_SMMU_CORELINK_MMU401:
+		smmu->version = ARM_SMMU_V1_64K;
+		smmu->model = GENERIC_SMMU;
+		break;
 	case ACPI_IORT_SMMU_V2:
 		smmu->version = ARM_SMMU_V2;
 		smmu->model = GENERIC_SMMU;
@@ -2081,6 +2093,10 @@ static int acpi_smmu_get_data(u32 model,
 		smmu->version = ARM_SMMU_V2;
 		smmu->model = ARM_MMU500;
 		break;
+	case ACPI_IORT_SMMU_CAVIUM_THUNDERX:
+		smmu->version = ARM_SMMU_V2;
+		smmu->model = CAVIUM_SMMUV2;
+		break;
 	default:
 		ret = -ENODEV;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/dm-raid.c linux-libre-4.12.4-gnu/drivers/md/dm-raid.c
--- linux-libre-4.12.3-gnu/drivers/md/dm-raid.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/dm-raid.c	2017-07-27 18:10:39.000000000 -0400
@@ -1571,7 +1571,7 @@ static sector_t __rdev_sectors(struct ra
 			return rdev->sectors;
 	}
 
-	BUG(); /* Constructor ensures we got some. */
+	return 0;
 }
 
 /* Calculate the sectors per device and per array used for @rs */
@@ -2941,7 +2941,7 @@ static int raid_ctr(struct dm_target *ti
 	bool resize;
 	struct raid_type *rt;
 	unsigned int num_raid_params, num_raid_devs;
-	sector_t calculated_dev_sectors;
+	sector_t calculated_dev_sectors, rdev_sectors;
 	struct raid_set *rs = NULL;
 	const char *arg;
 	struct rs_layout rs_layout;
@@ -3017,7 +3017,14 @@ static int raid_ctr(struct dm_target *ti
 	if (r)
 		goto bad;
 
-	resize = calculated_dev_sectors != __rdev_sectors(rs);
+	rdev_sectors = __rdev_sectors(rs);
+	if (!rdev_sectors) {
+		ti->error = "Invalid rdev size";
+		r = -EINVAL;
+		goto bad;
+	}
+
+	resize = calculated_dev_sectors != rdev_sectors;
 
 	INIT_WORK(&rs->md.event_work, do_table_event);
 	ti->private = rs;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/faulty.c linux-libre-4.12.4-gnu/drivers/md/faulty.c
--- linux-libre-4.12.3-gnu/drivers/md/faulty.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/faulty.c	2017-07-27 18:10:39.000000000 -0400
@@ -170,7 +170,7 @@ static void add_sector(struct faulty_con
 		conf->nfaults = n+1;
 }
 
-static void faulty_make_request(struct mddev *mddev, struct bio *bio)
+static bool faulty_make_request(struct mddev *mddev, struct bio *bio)
 {
 	struct faulty_conf *conf = mddev->private;
 	int failit = 0;
@@ -182,7 +182,7 @@ static void faulty_make_request(struct m
 			 * just fail immediately
 			 */
 			bio_io_error(bio);
-			return;
+			return true;
 		}
 
 		if (check_sector(conf, bio->bi_iter.bi_sector,
@@ -224,6 +224,7 @@ static void faulty_make_request(struct m
 		bio->bi_bdev = conf->rdev->bdev;
 
 	generic_make_request(bio);
+	return true;
 }
 
 static void faulty_status(struct seq_file *seq, struct mddev *mddev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/linear.c linux-libre-4.12.4-gnu/drivers/md/linear.c
--- linux-libre-4.12.3-gnu/drivers/md/linear.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/linear.c	2017-07-27 18:10:39.000000000 -0400
@@ -245,7 +245,7 @@ static void linear_free(struct mddev *md
 	kfree(conf);
 }
 
-static void linear_make_request(struct mddev *mddev, struct bio *bio)
+static bool linear_make_request(struct mddev *mddev, struct bio *bio)
 {
 	char b[BDEVNAME_SIZE];
 	struct dev_info *tmp_dev;
@@ -254,7 +254,7 @@ static void linear_make_request(struct m
 
 	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
 		md_flush_request(mddev, bio);
-		return;
+		return true;
 	}
 
 	tmp_dev = which_dev(mddev, bio_sector);
@@ -292,7 +292,7 @@ static void linear_make_request(struct m
 		mddev_check_write_zeroes(mddev, bio);
 		generic_make_request(bio);
 	}
-	return;
+	return true;
 
 out_of_bounds:
 	pr_err("md/linear:%s: make_request: Sector %llu out of bounds on dev %s: %llu sectors, offset %llu\n",
@@ -302,6 +302,7 @@ out_of_bounds:
 	       (unsigned long long)tmp_dev->rdev->sectors,
 	       (unsigned long long)start_sector);
 	bio_io_error(bio);
+	return true;
 }
 
 static void linear_status (struct seq_file *seq, struct mddev *mddev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/md.c linux-libre-4.12.4-gnu/drivers/md/md.c
--- linux-libre-4.12.3-gnu/drivers/md/md.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/md.c	2017-07-27 18:10:39.000000000 -0400
@@ -277,7 +277,7 @@ static blk_qc_t md_make_request(struct r
 		bio_endio(bio);
 		return BLK_QC_T_NONE;
 	}
-	smp_rmb(); /* Ensure implications of  'active' are visible */
+check_suspended:
 	rcu_read_lock();
 	if (mddev->suspended) {
 		DEFINE_WAIT(__wait);
@@ -302,7 +302,11 @@ static blk_qc_t md_make_request(struct r
 	sectors = bio_sectors(bio);
 	/* bio could be mergeable after passing to underlayer */
 	bio->bi_opf &= ~REQ_NOMERGE;
-	mddev->pers->make_request(mddev, bio);
+	if (!mddev->pers->make_request(mddev, bio)) {
+		atomic_dec(&mddev->active_io);
+		wake_up(&mddev->sb_wait);
+		goto check_suspended;
+	}
 
 	cpu = part_stat_lock();
 	part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
@@ -327,6 +331,7 @@ void mddev_suspend(struct mddev *mddev)
 	if (mddev->suspended++)
 		return;
 	synchronize_rcu();
+	wake_up(&mddev->sb_wait);
 	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
 	mddev->pers->quiesce(mddev, 1);
 
@@ -7950,12 +7955,14 @@ EXPORT_SYMBOL(md_done_sync);
  * If we need to update some array metadata (e.g. 'active' flag
  * in superblock) before writing, schedule a superblock update
  * and wait for it to complete.
+ * A return value of 'false' means that the write wasn't recorded
+ * and cannot proceed as the array is being suspend.
  */
-void md_write_start(struct mddev *mddev, struct bio *bi)
+bool md_write_start(struct mddev *mddev, struct bio *bi)
 {
 	int did_change = 0;
 	if (bio_data_dir(bi) != WRITE)
-		return;
+		return true;
 
 	BUG_ON(mddev->ro == 1);
 	if (mddev->ro == 2) {
@@ -7987,7 +7994,12 @@ void md_write_start(struct mddev *mddev,
 	if (did_change)
 		sysfs_notify_dirent_safe(mddev->sysfs_state);
 	wait_event(mddev->sb_wait,
-		   !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
+		   !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) && !mddev->suspended);
+	if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) {
+		percpu_ref_put(&mddev->writes_pending);
+		return false;
+	}
+	return true;
 }
 EXPORT_SYMBOL(md_write_start);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/md.h linux-libre-4.12.4-gnu/drivers/md/md.h
--- linux-libre-4.12.3-gnu/drivers/md/md.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/md.h	2017-07-27 18:10:39.000000000 -0400
@@ -510,7 +510,7 @@ struct md_personality
 	int level;
 	struct list_head list;
 	struct module *owner;
-	void (*make_request)(struct mddev *mddev, struct bio *bio);
+	bool (*make_request)(struct mddev *mddev, struct bio *bio);
 	int (*run)(struct mddev *mddev);
 	void (*free)(struct mddev *mddev, void *priv);
 	void (*status)(struct seq_file *seq, struct mddev *mddev);
@@ -649,7 +649,7 @@ extern void md_wakeup_thread(struct md_t
 extern void md_check_recovery(struct mddev *mddev);
 extern void md_reap_sync_thread(struct mddev *mddev);
 extern int mddev_init_writes_pending(struct mddev *mddev);
-extern void md_write_start(struct mddev *mddev, struct bio *bi);
+extern bool md_write_start(struct mddev *mddev, struct bio *bi);
 extern void md_write_inc(struct mddev *mddev, struct bio *bi);
 extern void md_write_end(struct mddev *mddev);
 extern void md_done_sync(struct mddev *mddev, int blocks, int ok);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/multipath.c linux-libre-4.12.4-gnu/drivers/md/multipath.c
--- linux-libre-4.12.3-gnu/drivers/md/multipath.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/multipath.c	2017-07-27 18:10:39.000000000 -0400
@@ -106,7 +106,7 @@ static void multipath_end_request(struct
 	rdev_dec_pending(rdev, conf->mddev);
 }
 
-static void multipath_make_request(struct mddev *mddev, struct bio * bio)
+static bool multipath_make_request(struct mddev *mddev, struct bio * bio)
 {
 	struct mpconf *conf = mddev->private;
 	struct multipath_bh * mp_bh;
@@ -114,7 +114,7 @@ static void multipath_make_request(struc
 
 	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
 		md_flush_request(mddev, bio);
-		return;
+		return true;
 	}
 
 	mp_bh = mempool_alloc(conf->pool, GFP_NOIO);
@@ -126,7 +126,7 @@ static void multipath_make_request(struc
 	if (mp_bh->path < 0) {
 		bio_io_error(bio);
 		mempool_free(mp_bh, conf->pool);
-		return;
+		return true;
 	}
 	multipath = conf->multipaths + mp_bh->path;
 
@@ -141,7 +141,7 @@ static void multipath_make_request(struc
 	mddev_check_writesame(mddev, &mp_bh->bio);
 	mddev_check_write_zeroes(mddev, &mp_bh->bio);
 	generic_make_request(&mp_bh->bio);
-	return;
+	return true;
 }
 
 static void multipath_status(struct seq_file *seq, struct mddev *mddev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/raid0.c linux-libre-4.12.4-gnu/drivers/md/raid0.c
--- linux-libre-4.12.3-gnu/drivers/md/raid0.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/raid0.c	2017-07-27 18:10:39.000000000 -0400
@@ -548,7 +548,7 @@ static void raid0_handle_discard(struct
 	bio_endio(bio);
 }
 
-static void raid0_make_request(struct mddev *mddev, struct bio *bio)
+static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
 {
 	struct strip_zone *zone;
 	struct md_rdev *tmp_dev;
@@ -559,12 +559,12 @@ static void raid0_make_request(struct md
 
 	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
 		md_flush_request(mddev, bio);
-		return;
+		return true;
 	}
 
 	if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
 		raid0_handle_discard(mddev, bio);
-		return;
+		return true;
 	}
 
 	bio_sector = bio->bi_iter.bi_sector;
@@ -599,6 +599,7 @@ static void raid0_make_request(struct md
 	mddev_check_writesame(mddev, bio);
 	mddev_check_write_zeroes(mddev, bio);
 	generic_make_request(bio);
+	return true;
 }
 
 static void raid0_status(struct seq_file *seq, struct mddev *mddev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/raid10.c linux-libre-4.12.4-gnu/drivers/md/raid10.c
--- linux-libre-4.12.3-gnu/drivers/md/raid10.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/raid10.c	2017-07-27 18:10:39.000000000 -0400
@@ -1303,8 +1303,6 @@ static void raid10_write_request(struct
 	sector_t sectors;
 	int max_sectors;
 
-	md_write_start(mddev, bio);
-
 	/*
 	 * Register the new request and wait if the reconstruction
 	 * thread has put up a bar for new requests.
@@ -1525,7 +1523,7 @@ static void __make_request(struct mddev
 		raid10_write_request(mddev, bio, r10_bio);
 }
 
-static void raid10_make_request(struct mddev *mddev, struct bio *bio)
+static bool raid10_make_request(struct mddev *mddev, struct bio *bio)
 {
 	struct r10conf *conf = mddev->private;
 	sector_t chunk_mask = (conf->geo.chunk_mask & conf->prev.chunk_mask);
@@ -1534,9 +1532,12 @@ static void raid10_make_request(struct m
 
 	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
 		md_flush_request(mddev, bio);
-		return;
+		return true;
 	}
 
+	if (!md_write_start(mddev, bio))
+		return false;
+
 	/*
 	 * If this request crosses a chunk boundary, we need to split
 	 * it.
@@ -1553,6 +1554,7 @@ static void raid10_make_request(struct m
 
 	/* In case raid10d snuck in to freeze_array */
 	wake_up(&conf->wait_barrier);
+	return true;
 }
 
 static void raid10_status(struct seq_file *seq, struct mddev *mddev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/raid1.c linux-libre-4.12.4-gnu/drivers/md/raid1.c
--- linux-libre-4.12.3-gnu/drivers/md/raid1.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/raid1.c	2017-07-27 18:10:39.000000000 -0400
@@ -1321,7 +1321,6 @@ static void raid1_write_request(struct m
 	 * Continue immediately if no resync is active currently.
 	 */
 
-	md_write_start(mddev, bio); /* wait on superblock update early */
 
 	if ((bio_end_sector(bio) > mddev->suspend_lo &&
 	    bio->bi_iter.bi_sector < mddev->suspend_hi) ||
@@ -1335,7 +1334,7 @@ static void raid1_write_request(struct m
 		 */
 		DEFINE_WAIT(w);
 		for (;;) {
-			flush_signals(current);
+			sigset_t full, old;
 			prepare_to_wait(&conf->wait_barrier,
 					&w, TASK_INTERRUPTIBLE);
 			if (bio_end_sector(bio) <= mddev->suspend_lo ||
@@ -1345,7 +1344,10 @@ static void raid1_write_request(struct m
 				     bio->bi_iter.bi_sector,
 				     bio_end_sector(bio))))
 				break;
+			sigfillset(&full);
+			sigprocmask(SIG_BLOCK, &full, &old);
 			schedule();
+			sigprocmask(SIG_SETMASK, &old, NULL);
 		}
 		finish_wait(&conf->wait_barrier, &w);
 	}
@@ -1550,13 +1552,13 @@ static void raid1_write_request(struct m
 	wake_up(&conf->wait_barrier);
 }
 
-static void raid1_make_request(struct mddev *mddev, struct bio *bio)
+static bool raid1_make_request(struct mddev *mddev, struct bio *bio)
 {
 	sector_t sectors;
 
 	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
 		md_flush_request(mddev, bio);
-		return;
+		return true;
 	}
 
 	/*
@@ -1571,8 +1573,12 @@ static void raid1_make_request(struct md
 
 	if (bio_data_dir(bio) == READ)
 		raid1_read_request(mddev, bio, sectors, NULL);
-	else
+	else {
+		if (!md_write_start(mddev,bio))
+			return false;
 		raid1_write_request(mddev, bio, sectors);
+	}
+	return true;
 }
 
 static void raid1_status(struct seq_file *seq, struct mddev *mddev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/md/raid5.c linux-libre-4.12.4-gnu/drivers/md/raid5.c
--- linux-libre-4.12.3-gnu/drivers/md/raid5.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/md/raid5.c	2017-07-27 18:10:39.000000000 -0400
@@ -5479,7 +5479,6 @@ static void make_discard_request(struct
 	last_sector = bi->bi_iter.bi_sector + (bi->bi_iter.bi_size>>9);
 
 	bi->bi_next = NULL;
-	md_write_start(mddev, bi);
 
 	stripe_sectors = conf->chunk_sectors *
 		(conf->raid_disks - conf->max_degraded);
@@ -5549,11 +5548,10 @@ static void make_discard_request(struct
 		release_stripe_plug(mddev, sh);
 	}
 
-	md_write_end(mddev);
 	bio_endio(bi);
 }
 
-static void raid5_make_request(struct mddev *mddev, struct bio * bi)
+static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
 {
 	struct r5conf *conf = mddev->private;
 	int dd_idx;
@@ -5569,10 +5567,10 @@ static void raid5_make_request(struct md
 		int ret = r5l_handle_flush_request(conf->log, bi);
 
 		if (ret == 0)
-			return;
+			return true;
 		if (ret == -ENODEV) {
 			md_flush_request(mddev, bi);
-			return;
+			return true;
 		}
 		/* ret == -EAGAIN, fallback */
 		/*
@@ -5582,6 +5580,8 @@ static void raid5_make_request(struct md
 		do_flush = bi->bi_opf & REQ_PREFLUSH;
 	}
 
+	if (!md_write_start(mddev, bi))
+		return false;
 	/*
 	 * If array is degraded, better not do chunk aligned read because
 	 * later we might have to read it again in order to reconstruct
@@ -5591,18 +5591,18 @@ static void raid5_make_request(struct md
 	    mddev->reshape_position == MaxSector) {
 		bi = chunk_aligned_read(mddev, bi);
 		if (!bi)
-			return;
+			return true;
 	}
 
 	if (unlikely(bio_op(bi) == REQ_OP_DISCARD)) {
 		make_discard_request(mddev, bi);
-		return;
+		md_write_end(mddev);
+		return true;
 	}
 
 	logical_sector = bi->bi_iter.bi_sector & ~((sector_t)STRIPE_SECTORS-1);
 	last_sector = bio_end_sector(bi);
 	bi->bi_next = NULL;
-	md_write_start(mddev, bi);
 
 	prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
@@ -5693,12 +5693,15 @@ static void raid5_make_request(struct md
 				 * userspace, we want an interruptible
 				 * wait.
 				 */
-				flush_signals(current);
 				prepare_to_wait(&conf->wait_for_overlap,
 						&w, TASK_INTERRUPTIBLE);
 				if (logical_sector >= mddev->suspend_lo &&
 				    logical_sector < mddev->suspend_hi) {
+					sigset_t full, old;
+					sigfillset(&full);
+					sigprocmask(SIG_BLOCK, &full, &old);
 					schedule();
+					sigprocmask(SIG_SETMASK, &old, NULL);
 					do_prepare = true;
 				}
 				goto retry;
@@ -5740,6 +5743,7 @@ static void raid5_make_request(struct md
 	if (rw == WRITE)
 		md_write_end(mddev);
 	bio_endio(bi);
+	return true;
 }
 
 static sector_t raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks);
@@ -7947,12 +7951,10 @@ static void end_reshape(struct r5conf *c
 {
 
 	if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
-		struct md_rdev *rdev;
 
 		spin_lock_irq(&conf->device_lock);
 		conf->previous_raid_disks = conf->raid_disks;
-		rdev_for_each(rdev, conf->mddev)
-			rdev->data_offset = rdev->new_data_offset;
+		md_finish_reshape(conf->mddev);
 		smp_wmb();
 		conf->reshape_progress = MaxSector;
 		conf->mddev->reshape_position = MaxSector;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/pci/cx88/cx88-cards.c linux-libre-4.12.4-gnu/drivers/media/pci/cx88/cx88-cards.c
--- linux-libre-4.12.3-gnu/drivers/media/pci/cx88/cx88-cards.c	2017-07-21 05:08:10.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/pci/cx88/cx88-cards.c	2017-07-27 21:34:34.000000000 -0400
@@ -3681,7 +3681,14 @@ struct cx88_core *cx88_core_create(struc
 	core->nr = nr;
 	sprintf(core->name, "cx88[%d]", core->nr);
 
-	core->tvnorm = V4L2_STD_NTSC_M;
+	/*
+	 * Note: Setting initial standard here would cause first call to
+	 * cx88_set_tvnorm() to return without programming any registers.  Leave
+	 * it blank for at this point and it will get set later in
+	 * cx8800_initdev()
+	 */
+	core->tvnorm  = 0;
+
 	core->width   = 320;
 	core->height  = 240;
 	core->field   = V4L2_FIELD_INTERLACED;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/pci/cx88/cx88-video.c linux-libre-4.12.4-gnu/drivers/media/pci/cx88/cx88-video.c
--- linux-libre-4.12.3-gnu/drivers/media/pci/cx88/cx88-video.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/pci/cx88/cx88-video.c	2017-07-27 18:10:39.000000000 -0400
@@ -1435,7 +1435,7 @@ static int cx8800_initdev(struct pci_dev
 
 	/* initial device configuration */
 	mutex_lock(&core->lock);
-	cx88_set_tvnorm(core, core->tvnorm);
+	cx88_set_tvnorm(core, V4L2_STD_NTSC_M);
 	v4l2_ctrl_handler_setup(&core->video_hdl);
 	v4l2_ctrl_handler_setup(&core->audio_hdl);
 	cx88_video_mux(core, 0);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/platform/s5p-jpeg/jpeg-core.c linux-libre-4.12.4-gnu/drivers/media/platform/s5p-jpeg/jpeg-core.c
--- linux-libre-4.12.3-gnu/drivers/media/platform/s5p-jpeg/jpeg-core.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/platform/s5p-jpeg/jpeg-core.c	2017-07-27 18:10:39.000000000 -0400
@@ -1099,10 +1099,10 @@ static bool s5p_jpeg_parse_hdr(struct s5
 			       struct s5p_jpeg_ctx *ctx)
 {
 	int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
-	unsigned int height, width, word, subsampling = 0, sos = 0, sof = 0,
-		     sof_len = 0;
-	unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER],
-		     dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
+	unsigned int height = 0, width = 0, word, subsampling = 0;
+	unsigned int sos = 0, sof = 0, sof_len = 0;
+	unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER];
+	unsigned int dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
 	long length;
 	struct s5p_jpeg_buffer jpeg_buffer;
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/rc/imon.c linux-libre-4.12.4-gnu/drivers/media/rc/imon.c
--- linux-libre-4.12.3-gnu/drivers/media/rc/imon.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/rc/imon.c	2017-07-27 18:10:39.000000000 -0400
@@ -1722,7 +1722,7 @@ static void imon_incoming_scancode(struc
 	if (kc == KEY_KEYBOARD && !ictx->release_code) {
 		ictx->last_keycode = kc;
 		if (!nomouse) {
-			ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
+			ictx->pad_mouse = !ictx->pad_mouse;
 			dev_dbg(dev, "toggling to %s mode\n",
 				ictx->pad_mouse ? "mouse" : "keyboard");
 			spin_unlock_irqrestore(&ictx->kc_lock, flags);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/rc/rc-main.c linux-libre-4.12.4-gnu/drivers/media/rc/rc-main.c
--- linux-libre-4.12.3-gnu/drivers/media/rc/rc-main.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/rc/rc-main.c	2017-07-27 18:10:39.000000000 -0400
@@ -1703,6 +1703,16 @@ static int rc_setup_rx_device(struct rc_
 	if (dev->close)
 		dev->input_dev->close = ir_close;
 
+	dev->input_dev->dev.parent = &dev->dev;
+	memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
+	dev->input_dev->phys = dev->input_phys;
+	dev->input_dev->name = dev->input_name;
+
+	/* rc_open will be called here */
+	rc = input_register_device(dev->input_dev);
+	if (rc)
+		goto out_table;
+
 	/*
 	 * Default delay of 250ms is too short for some protocols, especially
 	 * since the timeout is currently set to 250ms. Increase it to 500ms,
@@ -1718,16 +1728,6 @@ static int rc_setup_rx_device(struct rc_
 	 */
 	dev->input_dev->rep[REP_PERIOD] = 125;
 
-	dev->input_dev->dev.parent = &dev->dev;
-	memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
-	dev->input_dev->phys = dev->input_phys;
-	dev->input_dev->name = dev->input_name;
-
-	/* rc_open will be called here */
-	rc = input_register_device(dev->input_dev);
-	if (rc)
-		goto out_table;
-
 	return 0;
 
 out_table:
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c linux-libre-4.12.4-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c
--- linux-libre-4.12.3-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c	2017-07-27 18:10:39.000000000 -0400
@@ -24,9 +24,6 @@
 #include "lgdt3305.h"
 #include "lg2160.h"
 
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  64
-
 int dvb_usb_mxl111sf_debug;
 module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
@@ -55,27 +52,34 @@ MODULE_PARM_DESC(rfswitch, "force rf swi
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
+int mxl111sf_ctrl_msg(struct mxl111sf_state *state,
 		      u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
+	struct dvb_usb_device *d = state->d;
 	int wo = (rbuf == NULL || rlen == 0); /* write-only */
 	int ret;
-	u8 sndbuf[MAX_XFER_SIZE];
 
-	if (1 + wlen > sizeof(sndbuf)) {
+	if (1 + wlen > MXL_MAX_XFER_SIZE) {
 		pr_warn("%s: len=%d is too big!\n", __func__, wlen);
 		return -EOPNOTSUPP;
 	}
 
 	pr_debug("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
 
-	memset(sndbuf, 0, 1+wlen);
+	mutex_lock(&state->msg_lock);
+	memset(state->sndbuf, 0, 1+wlen);
+	memset(state->rcvbuf, 0, rlen);
 
-	sndbuf[0] = cmd;
-	memcpy(&sndbuf[1], wbuf, wlen);
+	state->sndbuf[0] = cmd;
+	memcpy(&state->sndbuf[1], wbuf, wlen);
+
+	ret = (wo) ? dvb_usbv2_generic_write(d, state->sndbuf, 1+wlen) :
+		dvb_usbv2_generic_rw(d, state->sndbuf, 1+wlen, state->rcvbuf,
+				     rlen);
+
+	memcpy(rbuf, state->rcvbuf, rlen);
+	mutex_unlock(&state->msg_lock);
 
-	ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
-		dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
 	mxl_fail(ret);
 
 	return ret;
@@ -91,7 +95,7 @@ int mxl111sf_read_reg(struct mxl111sf_st
 	u8 buf[2];
 	int ret;
 
-	ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
+	ret = mxl111sf_ctrl_msg(state, MXL_CMD_REG_READ, &addr, 1, buf, 2);
 	if (mxl_fail(ret)) {
 		mxl_debug("error reading reg: 0x%02x", addr);
 		goto fail;
@@ -117,7 +121,7 @@ int mxl111sf_write_reg(struct mxl111sf_s
 
 	pr_debug("W: (0x%02x, 0x%02x)\n", addr, data);
 
-	ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
+	ret = mxl111sf_ctrl_msg(state, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
 	if (mxl_fail(ret))
 		pr_err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
 	return ret;
@@ -926,6 +930,8 @@ static int mxl111sf_init(struct dvb_usb_
 		  .len = sizeof(eeprom), .buf = eeprom },
 	};
 
+	mutex_init(&state->msg_lock);
+
 	ret = get_chip_info(state);
 	if (mxl_fail(ret))
 		pr_err("failed to get chip info during probe");
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.h linux-libre-4.12.4-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.h
--- linux-libre-4.12.3-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.h	2017-07-27 18:10:39.000000000 -0400
@@ -19,6 +19,9 @@
 #include <media/tveeprom.h>
 #include <media/media-entity.h>
 
+/* Max transfer size done by I2C transfer functions */
+#define MXL_MAX_XFER_SIZE  64
+
 #define MXL_EP1_REG_READ     1
 #define MXL_EP2_REG_WRITE    2
 #define MXL_EP3_INTERRUPT    3
@@ -86,6 +89,9 @@ struct mxl111sf_state {
 	struct mutex fe_lock;
 	u8 num_frontends;
 	struct mxl111sf_adap_state adap_state[3];
+	u8 sndbuf[MXL_MAX_XFER_SIZE];
+	u8 rcvbuf[MXL_MAX_XFER_SIZE];
+	struct mutex msg_lock;
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
 	struct media_entity tuner;
 	struct media_pad tuner_pads[2];
@@ -108,7 +114,7 @@ int mxl111sf_ctrl_program_regs(struct mx
 
 /* needed for hardware i2c functions in mxl111sf-i2c.c:
  * mxl111sf_i2c_send_data / mxl111sf_i2c_get_data */
-int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
+int mxl111sf_ctrl_msg(struct mxl111sf_state *state,
 		      u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen);
 
 #define mxl_printk(kern, fmt, arg...) \
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c linux-libre-4.12.4-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
--- linux-libre-4.12.3-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c	2017-07-27 18:10:39.000000000 -0400
@@ -316,7 +316,7 @@ fail:
 static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
 				  u8 index, u8 *wdata)
 {
-	int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
+	int ret = mxl111sf_ctrl_msg(state, wdata[0],
 				    &wdata[1], 25, NULL, 0);
 	mxl_fail(ret);
 
@@ -326,7 +326,7 @@ static int mxl111sf_i2c_send_data(struct
 static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
 				 u8 index, u8 *wdata, u8 *rdata)
 {
-	int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
+	int ret = mxl111sf_ctrl_msg(state, wdata[0],
 				    &wdata[1], 25, rdata, 24);
 	mxl_fail(ret);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/misc/enclosure.c linux-libre-4.12.4-gnu/drivers/misc/enclosure.c
--- linux-libre-4.12.3-gnu/drivers/misc/enclosure.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/misc/enclosure.c	2017-07-27 18:10:39.000000000 -0400
@@ -375,6 +375,7 @@ int enclosure_add_device(struct enclosur
 			 struct device *dev)
 {
 	struct enclosure_component *cdev;
+	int err;
 
 	if (!edev || component >= edev->components)
 		return -EINVAL;
@@ -384,12 +385,17 @@ int enclosure_add_device(struct enclosur
 	if (cdev->dev == dev)
 		return -EEXIST;
 
-	if (cdev->dev)
+	if (cdev->dev) {
 		enclosure_remove_links(cdev);
-
-	put_device(cdev->dev);
+		put_device(cdev->dev);
+	}
 	cdev->dev = get_device(dev);
-	return enclosure_add_links(cdev);
+	err = enclosure_add_links(cdev);
+	if (err) {
+		put_device(cdev->dev);
+		cdev->dev = NULL;
+	}
+	return err;
 }
 EXPORT_SYMBOL_GPL(enclosure_add_device);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/mtd/nand/tango_nand.c linux-libre-4.12.4-gnu/drivers/mtd/nand/tango_nand.c
--- linux-libre-4.12.3-gnu/drivers/mtd/nand/tango_nand.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/mtd/nand/tango_nand.c	2017-07-27 18:10:39.000000000 -0400
@@ -340,7 +340,7 @@ static void aux_write(struct nand_chip *
 
 	if (!*buf) {
 		/* skip over "len" bytes */
-		chip->cmdfunc(mtd, NAND_CMD_SEQIN, *pos, -1);
+		chip->cmdfunc(mtd, NAND_CMD_RNDIN, *pos, -1);
 	} else {
 		tango_write_buf(mtd, *buf, len);
 		*buf += len;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c linux-libre-4.12.4-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c
--- linux-libre-4.12.3-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c	2017-07-27 18:10:39.000000000 -0400
@@ -257,6 +257,7 @@ static s32 igb_init_phy_params_82575(str
 	}
 
 	/* Set phy->phy_addr and phy->id. */
+	igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, 0);
 	ret_val = igb_get_phy_id_82575(hw);
 	if (ret_val)
 		return ret_val;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c linux-libre-4.12.4-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c
--- linux-libre-4.12.3-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c	2017-07-27 18:10:39.000000000 -0400
@@ -1821,8 +1821,6 @@ static void ar9003_hw_spectral_scan_wait
 static void ar9003_hw_tx99_start(struct ath_hw *ah, u32 qnum)
 {
 	REG_SET_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR);
-	REG_SET_BIT(ah, 0x9864, 0x7f000);
-	REG_SET_BIT(ah, 0x9924, 0x7f00fe);
 	REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
 	REG_WRITE(ah, AR_CR, AR_CR_RXD);
 	REG_WRITE(ah, AR_DLCL_IFS(qnum), 0);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/wireless/ath/ath9k/rng.c linux-libre-4.12.4-gnu/drivers/net/wireless/ath/ath9k/rng.c
--- linux-libre-4.12.3-gnu/drivers/net/wireless/ath/ath9k/rng.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/wireless/ath/ath9k/rng.c	2017-07-27 18:10:39.000000000 -0400
@@ -120,6 +120,8 @@ void ath9k_rng_start(struct ath_softc *s
 
 void ath9k_rng_stop(struct ath_softc *sc)
 {
-	if (sc->rng_task)
+	if (sc->rng_task) {
 		kthread_stop(sc->rng_task);
+		sc->rng_task = NULL;
+	}
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/wireless/ath/ath9k/tx99.c linux-libre-4.12.4-gnu/drivers/net/wireless/ath/ath9k/tx99.c
--- linux-libre-4.12.3-gnu/drivers/net/wireless/ath/ath9k/tx99.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/wireless/ath/ath9k/tx99.c	2017-07-27 18:10:39.000000000 -0400
@@ -189,22 +189,27 @@ static ssize_t write_file_tx99(struct fi
 	if (strtobool(buf, &start))
 		return -EINVAL;
 
+	mutex_lock(&sc->mutex);
+
 	if (start == sc->tx99_state) {
 		if (!start)
-			return count;
+			goto out;
 		ath_dbg(common, XMIT, "Resetting TX99\n");
 		ath9k_tx99_deinit(sc);
 	}
 
 	if (!start) {
 		ath9k_tx99_deinit(sc);
-		return count;
+		goto out;
 	}
 
 	r = ath9k_tx99_init(sc);
-	if (r)
+	if (r) {
+		mutex_unlock(&sc->mutex);
 		return r;
-
+	}
+out:
+	mutex_unlock(&sc->mutex);
 	return count;
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c linux-libre-4.12.4-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
--- linux-libre-4.12.3-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c	2017-07-27 18:10:39.000000000 -0400
@@ -1974,14 +1974,32 @@ static void iwl_mvm_bss_info_changed_sta
 			WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false),
 				  "Failed to update SF upon disassociation\n");
 
-			/* remove AP station now that the MAC is unassoc */
-			ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
-			if (ret)
-				IWL_ERR(mvm, "failed to remove AP station\n");
+			/*
+			 * If we get an assert during the connection (after the
+			 * station has been added, but before the vif is set
+			 * to associated), mac80211 will re-add the station and
+			 * then configure the vif. Since the vif is not
+			 * associated, we would remove the station here and
+			 * this would fail the recovery.
+			 */
+			if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
+				      &mvm->status)) {
+				/*
+				 * Remove AP station now that
+				 * the MAC is unassoc
+				 */
+				ret = iwl_mvm_rm_sta_id(mvm, vif,
+							mvmvif->ap_sta_id);
+				if (ret)
+					IWL_ERR(mvm,
+						"failed to remove AP station\n");
+
+				if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
+					mvm->d0i3_ap_sta_id =
+						IWL_MVM_INVALID_STA;
+				mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
+			}
 
-			if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
-				mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
-			mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
 			/* remove quota for this interface */
 			ret = iwl_mvm_update_quotas(mvm, false, NULL);
 			if (ret)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c linux-libre-4.12.4-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c
--- linux-libre-4.12.3-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c	2017-07-27 18:10:39.000000000 -0400
@@ -2964,10 +2964,8 @@ struct wireless_dev *mwifiex_add_virtual
 	if (!dev) {
 		mwifiex_dbg(adapter, ERROR,
 			    "no memory available for netdevice\n");
-		memset(&priv->wdev, 0, sizeof(priv->wdev));
-		priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
-		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-		return ERR_PTR(-ENOMEM);
+		ret = -ENOMEM;
+		goto err_alloc_netdev;
 	}
 
 	mwifiex_init_priv_params(priv, dev);
@@ -2976,11 +2974,11 @@ struct wireless_dev *mwifiex_add_virtual
 	ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
 			       HostCmd_ACT_GEN_SET, 0, NULL, true);
 	if (ret)
-		return ERR_PTR(ret);
+		goto err_set_bss_mode;
 
 	ret = mwifiex_sta_init_cmd(priv, false, false);
 	if (ret)
-		return ERR_PTR(ret);
+		goto err_sta_init;
 
 	mwifiex_setup_ht_caps(&wiphy->bands[NL80211_BAND_2GHZ]->ht_cap, priv);
 	if (adapter->is_hw_11ac_capable)
@@ -3011,31 +3009,14 @@ struct wireless_dev *mwifiex_add_virtual
 
 	SET_NETDEV_DEV(dev, adapter->dev);
 
-	/* Register network device */
-	if (register_netdevice(dev)) {
-		mwifiex_dbg(adapter, ERROR,
-			    "cannot register virtual network device\n");
-		free_netdev(dev);
-		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-		priv->netdev = NULL;
-		memset(&priv->wdev, 0, sizeof(priv->wdev));
-		priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
-		return ERR_PTR(-EFAULT);
-	}
-
 	priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC%s",
 						  WQ_HIGHPRI |
 						  WQ_MEM_RECLAIM |
 						  WQ_UNBOUND, 1, name);
 	if (!priv->dfs_cac_workqueue) {
-		mwifiex_dbg(adapter, ERROR,
-			    "cannot register virtual network device\n");
-		free_netdev(dev);
-		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-		priv->netdev = NULL;
-		memset(&priv->wdev, 0, sizeof(priv->wdev));
-		priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
-		return ERR_PTR(-ENOMEM);
+		mwifiex_dbg(adapter, ERROR, "cannot alloc DFS CAC queue\n");
+		ret = -ENOMEM;
+		goto err_alloc_cac;
 	}
 
 	INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
@@ -3044,16 +3025,9 @@ struct wireless_dev *mwifiex_add_virtual
 						      WQ_HIGHPRI | WQ_UNBOUND |
 						      WQ_MEM_RECLAIM, 1, name);
 	if (!priv->dfs_chan_sw_workqueue) {
-		mwifiex_dbg(adapter, ERROR,
-			    "cannot register virtual network device\n");
-		free_netdev(dev);
-		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-		priv->netdev = NULL;
-		memset(&priv->wdev, 0, sizeof(priv->wdev));
-		priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
-		destroy_workqueue(priv->dfs_cac_workqueue);
-		priv->dfs_cac_workqueue = NULL;
-		return ERR_PTR(-ENOMEM);
+		mwifiex_dbg(adapter, ERROR, "cannot alloc DFS channel sw queue\n");
+		ret = -ENOMEM;
+		goto err_alloc_chsw;
 	}
 
 	INIT_DELAYED_WORK(&priv->dfs_chan_sw_work,
@@ -3061,6 +3035,13 @@ struct wireless_dev *mwifiex_add_virtual
 
 	sema_init(&priv->async_sem, 1);
 
+	/* Register network device */
+	if (register_netdevice(dev)) {
+		mwifiex_dbg(adapter, ERROR, "cannot register network device\n");
+		ret = -EFAULT;
+		goto err_reg_netdev;
+	}
+
 	mwifiex_dbg(adapter, INFO,
 		    "info: %s: Marvell 802.11 Adapter\n", dev->name);
 
@@ -3081,11 +3062,29 @@ struct wireless_dev *mwifiex_add_virtual
 		adapter->curr_iface_comb.p2p_intf++;
 		break;
 	default:
+		/* This should be dead code; checked above */
 		mwifiex_dbg(adapter, ERROR, "type not supported\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	return &priv->wdev;
+
+err_reg_netdev:
+	destroy_workqueue(priv->dfs_chan_sw_workqueue);
+	priv->dfs_chan_sw_workqueue = NULL;
+err_alloc_chsw:
+	destroy_workqueue(priv->dfs_cac_workqueue);
+	priv->dfs_cac_workqueue = NULL;
+err_alloc_cac:
+	free_netdev(dev);
+	priv->netdev = NULL;
+err_sta_init:
+err_set_bss_mode:
+err_alloc_netdev:
+	memset(&priv->wdev, 0, sizeof(priv->wdev));
+	priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
+	priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/net/wireless/ti/wlcore/spi.c linux-libre-4.12.4-gnu/drivers/net/wireless/ti/wlcore/spi.c
--- linux-libre-4.12.3-gnu/drivers/net/wireless/ti/wlcore/spi.c	2017-07-21 05:42:01.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/net/wireless/ti/wlcore/spi.c	2017-07-27 22:01:45.000000000 -0400
@@ -70,10 +70,10 @@
 #define WSPI_MAX_CHUNK_SIZE    4092
 
 /*
- * wl18xx driver aggregation buffer size is (13 * PAGE_SIZE) compared to
- * (4 * PAGE_SIZE) for wl12xx, so use the larger buffer needed for wl18xx
+ * wl18xx driver aggregation buffer size is (13 * 4K) compared to
+ * (4 * 4K) for wl12xx, so use the larger buffer needed for wl18xx
  */
-#define SPI_AGGR_BUFFER_SIZE (13 * PAGE_SIZE)
+#define SPI_AGGR_BUFFER_SIZE (13 * SZ_4K)
 
 /* Maximum number of SPI write chunks */
 #define WSPI_MAX_NUM_OF_CHUNKS \
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nfc/nfcmrvl/fw_dnld.c linux-libre-4.12.4-gnu/drivers/nfc/nfcmrvl/fw_dnld.c
--- linux-libre-4.12.3-gnu/drivers/nfc/nfcmrvl/fw_dnld.c	2017-07-21 05:28:17.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nfc/nfcmrvl/fw_dnld.c	2017-07-27 21:50:39.000000000 -0400
@@ -458,7 +458,7 @@ int	nfcmrvl_fw_dnld_init(struct nfcmrvl_
 
 	INIT_WORK(&priv->fw_dnld.rx_work, fw_dnld_rx_work);
 	snprintf(name, sizeof(name), "%s_nfcmrvl_fw_dnld_rx_wq",
-		 dev_name(priv->dev));
+		 dev_name(&priv->ndev->nfc_dev->dev));
 	priv->fw_dnld.rx_wq = create_singlethread_workqueue(name);
 	if (!priv->fw_dnld.rx_wq)
 		return -ENOMEM;
@@ -495,6 +495,7 @@ int nfcmrvl_fw_dnld_start(struct nci_dev
 {
 	struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
 	struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld;
+	int res;
 
 	if (!priv->support_fw_dnld)
 		return -ENOTSUPP;
@@ -510,7 +511,9 @@ int nfcmrvl_fw_dnld_start(struct nci_dev
 	 */
 
 	/* Retrieve FW binary */
-	if (reject_firmware(&fw_dnld->fw, firmware_name, priv->dev) < 0) {
+	res = reject_firmware(&fw_dnld->fw, firmware_name,
+			       &ndev->nfc_dev->dev);
+	if (res < 0) {
 		nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name);
 		return -ENOENT;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nfc/nfcmrvl/main.c linux-libre-4.12.4-gnu/drivers/nfc/nfcmrvl/main.c
--- linux-libre-4.12.3-gnu/drivers/nfc/nfcmrvl/main.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nfc/nfcmrvl/main.c	2017-07-27 18:10:39.000000000 -0400
@@ -124,12 +124,13 @@ struct nfcmrvl_private *nfcmrvl_nci_regi
 	memcpy(&priv->config, pdata, sizeof(*pdata));
 
 	if (priv->config.reset_n_io) {
-		rc = devm_gpio_request_one(dev,
-					   priv->config.reset_n_io,
-					   GPIOF_OUT_INIT_LOW,
-					   "nfcmrvl_reset_n");
-		if (rc < 0)
+		rc = gpio_request_one(priv->config.reset_n_io,
+				      GPIOF_OUT_INIT_LOW,
+				      "nfcmrvl_reset_n");
+		if (rc < 0) {
+			priv->config.reset_n_io = 0;
 			nfc_err(dev, "failed to request reset_n io\n");
+		}
 	}
 
 	if (phy == NFCMRVL_PHY_SPI) {
@@ -154,7 +155,13 @@ struct nfcmrvl_private *nfcmrvl_nci_regi
 	if (!priv->ndev) {
 		nfc_err(dev, "nci_allocate_device failed\n");
 		rc = -ENOMEM;
-		goto error;
+		goto error_free_gpio;
+	}
+
+	rc = nfcmrvl_fw_dnld_init(priv);
+	if (rc) {
+		nfc_err(dev, "failed to initialize FW download %d\n", rc);
+		goto error_free_dev;
 	}
 
 	nci_set_drvdata(priv->ndev, priv);
@@ -162,24 +169,22 @@ struct nfcmrvl_private *nfcmrvl_nci_regi
 	rc = nci_register_device(priv->ndev);
 	if (rc) {
 		nfc_err(dev, "nci_register_device failed %d\n", rc);
-		goto error_free_dev;
+		goto error_fw_dnld_deinit;
 	}
 
 	/* Ensure that controller is powered off */
 	nfcmrvl_chip_halt(priv);
 
-	rc = nfcmrvl_fw_dnld_init(priv);
-	if (rc) {
-		nfc_err(dev, "failed to initialize FW download %d\n", rc);
-		goto error_free_dev;
-	}
-
 	nfc_info(dev, "registered with nci successfully\n");
 	return priv;
 
+error_fw_dnld_deinit:
+	nfcmrvl_fw_dnld_deinit(priv);
 error_free_dev:
 	nci_free_device(priv->ndev);
-error:
+error_free_gpio:
+	if (priv->config.reset_n_io)
+		gpio_free(priv->config.reset_n_io);
 	kfree(priv);
 	return ERR_PTR(rc);
 }
@@ -195,7 +200,7 @@ void nfcmrvl_nci_unregister_dev(struct n
 	nfcmrvl_fw_dnld_deinit(priv);
 
 	if (priv->config.reset_n_io)
-		devm_gpio_free(priv->dev, priv->config.reset_n_io);
+		gpio_free(priv->config.reset_n_io);
 
 	nci_unregister_device(ndev);
 	nci_free_device(ndev);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nfc/nfcmrvl/uart.c linux-libre-4.12.4-gnu/drivers/nfc/nfcmrvl/uart.c
--- linux-libre-4.12.3-gnu/drivers/nfc/nfcmrvl/uart.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nfc/nfcmrvl/uart.c	2017-07-27 18:10:39.000000000 -0400
@@ -109,6 +109,7 @@ static int nfcmrvl_nci_uart_open(struct
 	struct nfcmrvl_private *priv;
 	struct nfcmrvl_platform_data *pdata = NULL;
 	struct nfcmrvl_platform_data config;
+	struct device *dev = nu->tty->dev;
 
 	/*
 	 * Platform data cannot be used here since usually it is already used
@@ -116,9 +117,8 @@ static int nfcmrvl_nci_uart_open(struct
 	 * and check if DT entries were added.
 	 */
 
-	if (nu->tty->dev->parent && nu->tty->dev->parent->of_node)
-		if (nfcmrvl_uart_parse_dt(nu->tty->dev->parent->of_node,
-					  &config) == 0)
+	if (dev && dev->parent && dev->parent->of_node)
+		if (nfcmrvl_uart_parse_dt(dev->parent->of_node, &config) == 0)
 			pdata = &config;
 
 	if (!pdata) {
@@ -131,7 +131,7 @@ static int nfcmrvl_nci_uart_open(struct
 	}
 
 	priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_UART, nu, &uart_ops,
-					nu->tty->dev, pdata);
+					dev, pdata);
 	if (IS_ERR(priv))
 		return PTR_ERR(priv);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nvdimm/btt.c linux-libre-4.12.4-gnu/drivers/nvdimm/btt.c
--- linux-libre-4.12.3-gnu/drivers/nvdimm/btt.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nvdimm/btt.c	2017-07-27 18:10:39.000000000 -0400
@@ -1248,10 +1248,13 @@ static int btt_rw_page(struct block_devi
 		struct page *page, bool is_write)
 {
 	struct btt *btt = bdev->bd_disk->private_data;
+	int rc;
 
-	btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector);
-	page_endio(page, is_write, 0);
-	return 0;
+	rc = btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector);
+	if (rc == 0)
+		page_endio(page, is_write, 0);
+
+	return rc;
 }
 
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nvdimm/claim.c linux-libre-4.12.4-gnu/drivers/nvdimm/claim.c
--- linux-libre-4.12.3-gnu/drivers/nvdimm/claim.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nvdimm/claim.c	2017-07-27 18:10:39.000000000 -0400
@@ -260,8 +260,7 @@ static int nsio_rw_bytes(struct nd_names
 		 * work around this collision.
 		 */
 		if (IS_ALIGNED(offset, 512) && IS_ALIGNED(size, 512)
-				&& !(flags & NVDIMM_IO_ATOMIC)
-				&& !ndns->claim) {
+				&& !(flags & NVDIMM_IO_ATOMIC)) {
 			long cleared;
 
 			cleared = nvdimm_clear_poison(&ndns->dev,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nvdimm/core.c linux-libre-4.12.4-gnu/drivers/nvdimm/core.c
--- linux-libre-4.12.3-gnu/drivers/nvdimm/core.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nvdimm/core.c	2017-07-27 18:10:39.000000000 -0400
@@ -421,14 +421,15 @@ static void set_badblock(struct badblock
 static void __add_badblock_range(struct badblocks *bb, u64 ns_offset, u64 len)
 {
 	const unsigned int sector_size = 512;
-	sector_t start_sector;
+	sector_t start_sector, end_sector;
 	u64 num_sectors;
 	u32 rem;
 
 	start_sector = div_u64(ns_offset, sector_size);
-	num_sectors = div_u64_rem(len, sector_size, &rem);
+	end_sector = div_u64_rem(ns_offset + len, sector_size, &rem);
 	if (rem)
-		num_sectors++;
+		end_sector++;
+	num_sectors = end_sector - start_sector;
 
 	if (unlikely(num_sectors > (u64)INT_MAX)) {
 		u64 remaining = num_sectors;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/nvme/host/rdma.c linux-libre-4.12.4-gnu/drivers/nvme/host/rdma.c
--- linux-libre-4.12.3-gnu/drivers/nvme/host/rdma.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/nvme/host/rdma.c	2017-07-27 18:10:39.000000000 -0400
@@ -88,7 +88,7 @@ enum nvme_rdma_queue_flags {
 
 struct nvme_rdma_queue {
 	struct nvme_rdma_qe	*rsp_ring;
-	u8			sig_count;
+	atomic_t		sig_count;
 	int			queue_size;
 	size_t			cmnd_capsule_len;
 	struct nvme_rdma_ctrl	*ctrl;
@@ -553,6 +553,7 @@ static int nvme_rdma_init_queue(struct n
 		queue->cmnd_capsule_len = sizeof(struct nvme_command);
 
 	queue->queue_size = queue_size;
+	atomic_set(&queue->sig_count, 0);
 
 	queue->cm_id = rdma_create_id(&init_net, nvme_rdma_cm_handler, queue,
 			RDMA_PS_TCP, IB_QPT_RC);
@@ -1040,17 +1041,16 @@ static void nvme_rdma_send_done(struct i
 		nvme_rdma_wr_error(cq, wc, "SEND");
 }
 
-static inline int nvme_rdma_queue_sig_limit(struct nvme_rdma_queue *queue)
+/*
+ * We want to signal completion at least every queue depth/2.  This returns the
+ * largest power of two that is not above half of (queue size + 1) to optimize
+ * (avoid divisions).
+ */
+static inline bool nvme_rdma_queue_sig_limit(struct nvme_rdma_queue *queue)
 {
-	int sig_limit;
+	int limit = 1 << ilog2((queue->queue_size + 1) / 2);
 
-	/*
-	 * We signal completion every queue depth/2 and also handle the
-	 * degenerated case of a  device with queue_depth=1, where we
-	 * would need to signal every message.
-	 */
-	sig_limit = max(queue->queue_size / 2, 1);
-	return (++queue->sig_count % sig_limit) == 0;
+	return (atomic_inc_return(&queue->sig_count) & (limit - 1)) == 0;
 }
 
 static int nvme_rdma_post_send(struct nvme_rdma_queue *queue,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/pci/host/pcie-rockchip.c linux-libre-4.12.4-gnu/drivers/pci/host/pcie-rockchip.c
--- linux-libre-4.12.3-gnu/drivers/pci/host/pcie-rockchip.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/pci/host/pcie-rockchip.c	2017-07-27 18:10:39.000000000 -0400
@@ -139,6 +139,7 @@
 		 PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \
 		 PCIE_CORE_INT_MMVC)
 
+#define PCIE_RC_CONFIG_NORMAL_BASE	0x800000
 #define PCIE_RC_CONFIG_BASE		0xa00000
 #define PCIE_RC_CONFIG_RID_CCR		(PCIE_RC_CONFIG_BASE + 0x08)
 #define   PCIE_RC_CONFIG_SCC_SHIFT		16
@@ -295,7 +296,9 @@ static int rockchip_pcie_valid_device(st
 static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip,
 				     int where, int size, u32 *val)
 {
-	void __iomem *addr = rockchip->apb_base + PCIE_RC_CONFIG_BASE + where;
+	void __iomem *addr;
+
+	addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + where;
 
 	if (!IS_ALIGNED((uintptr_t)addr, size)) {
 		*val = 0;
@@ -319,11 +322,13 @@ static int rockchip_pcie_wr_own_conf(str
 				     int where, int size, u32 val)
 {
 	u32 mask, tmp, offset;
+	void __iomem *addr;
 
 	offset = where & ~0x3;
+	addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + offset;
 
 	if (size == 4) {
-		writel(val, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset);
+		writel(val, addr);
 		return PCIBIOS_SUCCESSFUL;
 	}
 
@@ -334,9 +339,9 @@ static int rockchip_pcie_wr_own_conf(str
 	 * corrupt RW1C bits in adjacent registers.  But the hardware
 	 * doesn't support smaller writes.
 	 */
-	tmp = readl(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset) & mask;
+	tmp = readl(addr) & mask;
 	tmp |= val << ((where & 0x3) * 8);
-	writel(tmp, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset);
+	writel(tmp, addr);
 
 	return PCIBIOS_SUCCESSFUL;
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/pci/host/vmd.c linux-libre-4.12.4-gnu/drivers/pci/host/vmd.c
--- linux-libre-4.12.3-gnu/drivers/pci/host/vmd.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/pci/host/vmd.c	2017-07-27 18:10:39.000000000 -0400
@@ -733,10 +733,10 @@ static void vmd_remove(struct pci_dev *d
 	struct vmd_dev *vmd = pci_get_drvdata(dev);
 
 	vmd_detach_resources(vmd);
-	vmd_cleanup_srcu(vmd);
 	sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
 	pci_stop_root_bus(vmd->bus);
 	pci_remove_root_bus(vmd->bus);
+	vmd_cleanup_srcu(vmd);
 	vmd_teardown_dma_ops(vmd);
 	irq_domain_remove(vmd->irq_domain);
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/pci/msi.c linux-libre-4.12.4-gnu/drivers/pci/msi.c
--- linux-libre-4.12.3-gnu/drivers/pci/msi.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/pci/msi.c	2017-07-27 18:10:39.000000000 -0400
@@ -1058,7 +1058,7 @@ static int __pci_enable_msi_range(struct
 
 	for (;;) {
 		if (affd) {
-			nvec = irq_calc_affinity_vectors(nvec, affd);
+			nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
 			if (nvec < minvec)
 				return -ENOSPC;
 		}
@@ -1097,7 +1097,7 @@ static int __pci_enable_msix_range(struc
 
 	for (;;) {
 		if (affd) {
-			nvec = irq_calc_affinity_vectors(nvec, affd);
+			nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
 			if (nvec < minvec)
 				return -ENOSPC;
 		}
@@ -1165,16 +1165,6 @@ int pci_alloc_irq_vectors_affinity(struc
 	if (flags & PCI_IRQ_AFFINITY) {
 		if (!affd)
 			affd = &msi_default_affd;
-
-		if (affd->pre_vectors + affd->post_vectors > min_vecs)
-			return -EINVAL;
-
-		/*
-		 * If there aren't any vectors left after applying the pre/post
-		 * vectors don't bother with assigning affinity.
-		 */
-		if (affd->pre_vectors + affd->post_vectors == min_vecs)
-			affd = NULL;
 	} else {
 		if (WARN_ON(affd))
 			affd = NULL;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/pci/pci-driver.c linux-libre-4.12.4-gnu/drivers/pci/pci-driver.c
--- linux-libre-4.12.3-gnu/drivers/pci/pci-driver.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/pci/pci-driver.c	2017-07-27 18:10:39.000000000 -0400
@@ -964,6 +964,7 @@ static int pci_pm_thaw_noirq(struct devi
 		return pci_legacy_resume_early(dev);
 
 	pci_update_current_state(pci_dev, PCI_D0);
+	pci_restore_state(pci_dev);
 
 	if (drv && drv->pm && drv->pm->thaw_noirq)
 		error = drv->pm->thaw_noirq(dev);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/scsi/qla2xxx/qla_init.c linux-libre-4.12.4-gnu/drivers/scsi/qla2xxx/qla_init.c
--- linux-libre-4.12.3-gnu/drivers/scsi/qla2xxx/qla_init.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/scsi/qla2xxx/qla_init.c	2017-07-27 18:10:39.000000000 -0400
@@ -2946,7 +2946,8 @@ qla24xx_update_fw_options(scsi_qla_host_
 	}
 
 	/* Move PUREX, ABTS RX & RIDA to ATIOQ */
-	if (ql2xmvasynctoatio) {
+	if (ql2xmvasynctoatio &&
+	    (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
 		if (qla_tgt_mode_enabled(vha) ||
 		    qla_dual_mode_enabled(vha))
 			ha->fw_options[2] |= BIT_11;
@@ -2958,7 +2959,9 @@ qla24xx_update_fw_options(scsi_qla_host_
 		"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
 		__func__, ha->fw_options[1], ha->fw_options[2],
 		ha->fw_options[3], vha->host->active_mode);
-	qla2x00_set_fw_options(vha, ha->fw_options);
+
+	if (ha->fw_options[1] || ha->fw_options[2] || ha->fw_options[3])
+		qla2x00_set_fw_options(vha, ha->fw_options);
 
 	/* Update Serial Link options. */
 	if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/scsi/scsi_lib.c linux-libre-4.12.4-gnu/drivers/scsi/scsi_lib.c
--- linux-libre-4.12.3-gnu/drivers/scsi/scsi_lib.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/scsi/scsi_lib.c	2017-07-27 18:10:39.000000000 -0400
@@ -45,23 +45,23 @@ static struct kmem_cache *scsi_sense_isa
 static DEFINE_MUTEX(scsi_sense_cache_mutex);
 
 static inline struct kmem_cache *
-scsi_select_sense_cache(struct Scsi_Host *shost)
+scsi_select_sense_cache(bool unchecked_isa_dma)
 {
-	return shost->unchecked_isa_dma ?
-		scsi_sense_isadma_cache : scsi_sense_cache;
+	return unchecked_isa_dma ? scsi_sense_isadma_cache : scsi_sense_cache;
 }
 
-static void scsi_free_sense_buffer(struct Scsi_Host *shost,
-		unsigned char *sense_buffer)
+static void scsi_free_sense_buffer(bool unchecked_isa_dma,
+				   unsigned char *sense_buffer)
 {
-	kmem_cache_free(scsi_select_sense_cache(shost), sense_buffer);
+	kmem_cache_free(scsi_select_sense_cache(unchecked_isa_dma),
+			sense_buffer);
 }
 
-static unsigned char *scsi_alloc_sense_buffer(struct Scsi_Host *shost,
+static unsigned char *scsi_alloc_sense_buffer(bool unchecked_isa_dma,
 	gfp_t gfp_mask, int numa_node)
 {
-	return kmem_cache_alloc_node(scsi_select_sense_cache(shost), gfp_mask,
-			numa_node);
+	return kmem_cache_alloc_node(scsi_select_sense_cache(unchecked_isa_dma),
+				     gfp_mask, numa_node);
 }
 
 int scsi_init_sense_cache(struct Scsi_Host *shost)
@@ -69,7 +69,7 @@ int scsi_init_sense_cache(struct Scsi_Ho
 	struct kmem_cache *cache;
 	int ret = 0;
 
-	cache = scsi_select_sense_cache(shost);
+	cache = scsi_select_sense_cache(shost->unchecked_isa_dma);
 	if (cache)
 		return 0;
 
@@ -1138,6 +1138,7 @@ void scsi_init_command(struct scsi_devic
 {
 	void *buf = cmd->sense_buffer;
 	void *prot = cmd->prot_sdb;
+	unsigned int unchecked_isa_dma = cmd->flags & SCMD_UNCHECKED_ISA_DMA;
 	unsigned long flags;
 
 	/* zero out the cmd, except for the embedded scsi_request */
@@ -1147,6 +1148,7 @@ void scsi_init_command(struct scsi_devic
 	cmd->device = dev;
 	cmd->sense_buffer = buf;
 	cmd->prot_sdb = prot;
+	cmd->flags = unchecked_isa_dma;
 	INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
 	cmd->jiffies_at_alloc = jiffies;
 
@@ -1847,6 +1849,7 @@ static int scsi_mq_prep_fn(struct reques
 	struct scsi_device *sdev = req->q->queuedata;
 	struct Scsi_Host *shost = sdev->host;
 	unsigned char *sense_buf = cmd->sense_buffer;
+	unsigned int unchecked_isa_dma = cmd->flags & SCMD_UNCHECKED_ISA_DMA;
 	struct scatterlist *sg;
 
 	/* zero out the cmd, except for the embedded scsi_request */
@@ -1858,6 +1861,7 @@ static int scsi_mq_prep_fn(struct reques
 	cmd->request = req;
 	cmd->device = sdev;
 	cmd->sense_buffer = sense_buf;
+	cmd->flags = unchecked_isa_dma;
 
 	cmd->tag = req->tag;
 
@@ -2004,10 +2008,13 @@ static int scsi_init_request(struct blk_
 		unsigned int hctx_idx, unsigned int numa_node)
 {
 	struct Scsi_Host *shost = set->driver_data;
+	const bool unchecked_isa_dma = shost->unchecked_isa_dma;
 	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
 
-	cmd->sense_buffer =
-		scsi_alloc_sense_buffer(shost, GFP_KERNEL, numa_node);
+	if (unchecked_isa_dma)
+		cmd->flags |= SCMD_UNCHECKED_ISA_DMA;
+	cmd->sense_buffer = scsi_alloc_sense_buffer(unchecked_isa_dma,
+						    GFP_KERNEL, numa_node);
 	if (!cmd->sense_buffer)
 		return -ENOMEM;
 	cmd->req.sense = cmd->sense_buffer;
@@ -2017,10 +2024,10 @@ static int scsi_init_request(struct blk_
 static void scsi_exit_request(struct blk_mq_tag_set *set, struct request *rq,
 		unsigned int hctx_idx)
 {
-	struct Scsi_Host *shost = set->driver_data;
 	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
 
-	scsi_free_sense_buffer(shost, cmd->sense_buffer);
+	scsi_free_sense_buffer(cmd->flags & SCMD_UNCHECKED_ISA_DMA,
+			       cmd->sense_buffer);
 }
 
 static int scsi_map_queues(struct blk_mq_tag_set *set)
@@ -2093,11 +2100,15 @@ EXPORT_SYMBOL_GPL(__scsi_init_queue);
 static int scsi_init_rq(struct request_queue *q, struct request *rq, gfp_t gfp)
 {
 	struct Scsi_Host *shost = q->rq_alloc_data;
+	const bool unchecked_isa_dma = shost->unchecked_isa_dma;
 	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
 
 	memset(cmd, 0, sizeof(*cmd));
 
-	cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp, NUMA_NO_NODE);
+	if (unchecked_isa_dma)
+		cmd->flags |= SCMD_UNCHECKED_ISA_DMA;
+	cmd->sense_buffer = scsi_alloc_sense_buffer(unchecked_isa_dma, gfp,
+						    NUMA_NO_NODE);
 	if (!cmd->sense_buffer)
 		goto fail;
 	cmd->req.sense = cmd->sense_buffer;
@@ -2111,19 +2122,19 @@ static int scsi_init_rq(struct request_q
 	return 0;
 
 fail_free_sense:
-	scsi_free_sense_buffer(shost, cmd->sense_buffer);
+	scsi_free_sense_buffer(unchecked_isa_dma, cmd->sense_buffer);
 fail:
 	return -ENOMEM;
 }
 
 static void scsi_exit_rq(struct request_queue *q, struct request *rq)
 {
-	struct Scsi_Host *shost = q->rq_alloc_data;
 	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
 
 	if (cmd->prot_sdb)
 		kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
-	scsi_free_sense_buffer(shost, cmd->sense_buffer);
+	scsi_free_sense_buffer(cmd->flags & SCMD_UNCHECKED_ISA_DMA,
+			       cmd->sense_buffer);
 }
 
 struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/scsi/scsi_scan.c linux-libre-4.12.4-gnu/drivers/scsi/scsi_scan.c
--- linux-libre-4.12.3-gnu/drivers/scsi/scsi_scan.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/scsi/scsi_scan.c	2017-07-27 18:10:39.000000000 -0400
@@ -384,11 +384,12 @@ static void scsi_target_reap_ref_release
 		= container_of(kref, struct scsi_target, reap_ref);
 
 	/*
-	 * if we get here and the target is still in the CREATED state that
+	 * if we get here and the target is still in a CREATED state that
 	 * means it was allocated but never made visible (because a scan
 	 * turned up no LUNs), so don't call device_del() on it.
 	 */
-	if (starget->state != STARGET_CREATED) {
+	if ((starget->state != STARGET_CREATED) &&
+	    (starget->state != STARGET_CREATED_REMOVE)) {
 		transport_remove_device(&starget->dev);
 		device_del(&starget->dev);
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/scsi/scsi_sysfs.c linux-libre-4.12.4-gnu/drivers/scsi/scsi_sysfs.c
--- linux-libre-4.12.3-gnu/drivers/scsi/scsi_sysfs.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/scsi/scsi_sysfs.c	2017-07-27 18:10:39.000000000 -0400
@@ -1370,11 +1370,15 @@ restart:
 	spin_lock_irqsave(shost->host_lock, flags);
 	list_for_each_entry(starget, &shost->__targets, siblings) {
 		if (starget->state == STARGET_DEL ||
-		    starget->state == STARGET_REMOVE)
+		    starget->state == STARGET_REMOVE ||
+		    starget->state == STARGET_CREATED_REMOVE)
 			continue;
 		if (starget->dev.parent == dev || &starget->dev == dev) {
 			kref_get(&starget->reap_ref);
-			starget->state = STARGET_REMOVE;
+			if (starget->state == STARGET_CREATED)
+				starget->state = STARGET_CREATED_REMOVE;
+			else
+				starget->state = STARGET_REMOVE;
 			spin_unlock_irqrestore(shost->host_lock, flags);
 			__scsi_remove_target(starget);
 			scsi_target_reap(starget);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/scsi/virtio_scsi.c linux-libre-4.12.4-gnu/drivers/scsi/virtio_scsi.c
--- linux-libre-4.12.3-gnu/drivers/scsi/virtio_scsi.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/scsi/virtio_scsi.c	2017-07-27 18:10:39.000000000 -0400
@@ -796,6 +796,16 @@ static int virtscsi_map_queues(struct Sc
 	return blk_mq_virtio_map_queues(&shost->tag_set, vscsi->vdev, 2);
 }
 
+/*
+ * The host guarantees to respond to each command, although I/O
+ * latencies might be higher than on bare metal.  Reset the timer
+ * unconditionally to give the host a chance to perform EH.
+ */
+static enum blk_eh_timer_return virtscsi_eh_timed_out(struct scsi_cmnd *scmnd)
+{
+	return BLK_EH_RESET_TIMER;
+}
+
 static struct scsi_host_template virtscsi_host_template_single = {
 	.module = THIS_MODULE,
 	.name = "Virtio SCSI HBA",
@@ -806,6 +816,7 @@ static struct scsi_host_template virtscs
 	.change_queue_depth = virtscsi_change_queue_depth,
 	.eh_abort_handler = virtscsi_abort,
 	.eh_device_reset_handler = virtscsi_device_reset,
+	.eh_timed_out = virtscsi_eh_timed_out,
 	.slave_alloc = virtscsi_device_alloc,
 
 	.can_queue = 1024,
@@ -826,6 +837,8 @@ static struct scsi_host_template virtscs
 	.change_queue_depth = virtscsi_change_queue_depth,
 	.eh_abort_handler = virtscsi_abort,
 	.eh_device_reset_handler = virtscsi_device_reset,
+	.eh_timed_out = virtscsi_eh_timed_out,
+	.slave_alloc = virtscsi_device_alloc,
 
 	.can_queue = 1024,
 	.dma_boundary = UINT_MAX,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/spi/spi-atmel.c linux-libre-4.12.4-gnu/drivers/spi/spi-atmel.c
--- linux-libre-4.12.3-gnu/drivers/spi/spi-atmel.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/spi/spi-atmel.c	2017-07-27 18:10:39.000000000 -0400
@@ -269,6 +269,7 @@ struct atmel_spi_caps {
 	bool	is_spi2;
 	bool	has_wdrbt;
 	bool	has_dma_support;
+	bool	has_pdc_support;
 };
 
 /*
@@ -1426,7 +1427,28 @@ static void atmel_get_caps(struct atmel_
 
 	as->caps.is_spi2 = version > 0x121;
 	as->caps.has_wdrbt = version >= 0x210;
+#ifdef CONFIG_SOC_SAM_V4_V5
+	/*
+	 * Atmel SoCs based on ARM9 (SAM9x) cores should not use spi_map_buf()
+	 * since this later function tries to map buffers with dma_map_sg()
+	 * even if they have not been allocated inside DMA-safe areas.
+	 * On SoCs based on Cortex A5 (SAMA5Dx), it works anyway because for
+	 * those ARM cores, the data cache follows the PIPT model.
+	 * Also the L2 cache controller of SAMA5D2 uses the PIPT model too.
+	 * In case of PIPT caches, there cannot be cache aliases.
+	 * However on ARM9 cores, the data cache follows the VIVT model, hence
+	 * the cache aliases issue can occur when buffers are allocated from
+	 * DMA-unsafe areas, by vmalloc() for instance, where cache coherency is
+	 * not taken into account or at least not handled completely (cache
+	 * lines of aliases are not invalidated).
+	 * This is not a theorical issue: it was reproduced when trying to mount
+	 * a UBI file-system on a at91sam9g35ek board.
+	 */
+	as->caps.has_dma_support = false;
+#else
 	as->caps.has_dma_support = version >= 0x212;
+#endif
+	as->caps.has_pdc_support = version < 0x212;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1567,7 +1589,7 @@ static int atmel_spi_probe(struct platfo
 		} else if (ret == -EPROBE_DEFER) {
 			return ret;
 		}
-	} else {
+	} else if (as->caps.has_pdc_support) {
 		as->use_pdc = true;
 	}
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/spmi/spmi.c linux-libre-4.12.4-gnu/drivers/spmi/spmi.c
--- linux-libre-4.12.3-gnu/drivers/spmi/spmi.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/spmi/spmi.c	2017-07-27 18:10:39.000000000 -0400
@@ -365,11 +365,23 @@ static int spmi_drv_remove(struct device
 	return 0;
 }
 
+static int spmi_drv_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	int ret;
+
+	ret = of_device_uevent_modalias(dev, env);
+	if (ret != -ENODEV)
+		return ret;
+
+	return 0;
+}
+
 static struct bus_type spmi_bus_type = {
 	.name		= "spmi",
 	.match		= spmi_device_match,
 	.probe		= spmi_drv_probe,
 	.remove		= spmi_drv_remove,
+	.uevent		= spmi_drv_uevent,
 };
 
 /**
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/staging/comedi/drivers/ni_mio_common.c linux-libre-4.12.4-gnu/drivers/staging/comedi/drivers/ni_mio_common.c
--- linux-libre-4.12.3-gnu/drivers/staging/comedi/drivers/ni_mio_common.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/staging/comedi/drivers/ni_mio_common.c	2017-07-27 18:10:39.000000000 -0400
@@ -3116,8 +3116,7 @@ static void ni_ao_cmd_set_update(struct
 		/* following line: 2-1 per STC */
 		ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG);
 		ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG);
-		/* following line: N-1 per STC */
-		ni_stc_writel(dev, trigvar - 1, NISTC_AO_UI_LOADA_REG);
+		ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG);
 	} else { /* TRIG_EXT */
 		/* FIXME:  assert scan_begin_arg != 0, ret failure otherwise */
 		devpriv->ao_cmd2  |= NISTC_AO_CMD2_BC_GATE_ENA;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c linux-libre-4.12.4-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
--- linux-libre-4.12.3-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c	2017-07-27 18:10:39.000000000 -0400
@@ -1640,8 +1640,13 @@ kiblnd_send(struct lnet_ni *ni, void *pr
 	ibmsg = tx->tx_msg;
 	ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
 
-	copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, IBLND_MSG_SIZE,
-		       &from);
+	rc = copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, payload_nob,
+			    &from);
+	if (rc != payload_nob) {
+		kiblnd_pool_free_node(&tx->tx_pool->tpo_pool, &tx->tx_list);
+		return -EFAULT;
+	}
+
 	nob = offsetof(struct kib_immediate_msg, ibim_payload[payload_nob]);
 	kiblnd_init_tx_msg(ni, tx, IBLND_MSG_IMMEDIATE, nob);
 
@@ -1741,8 +1746,14 @@ kiblnd_recv(struct lnet_ni *ni, void *pr
 			break;
 		}
 
-		copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload,
-			     IBLND_MSG_SIZE, to);
+		rc = copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload, rlen,
+				  to);
+		if (rc != rlen) {
+			rc = -EFAULT;
+			break;
+		}
+
+		rc = 0;
 		lnet_finalize(ni, lntmsg, 0);
 		break;
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c linux-libre-4.12.4-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c
--- linux-libre-4.12.3-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c	2017-07-27 18:10:39.000000000 -0400
@@ -43,6 +43,7 @@ static struct usb_device_id rtw_usb_id_t
 	{USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
 	{USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
 	{USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
+	{USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
 	{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
 	{}	/* Terminating entry */
 };
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/staging/sm750fb/sm750.c linux-libre-4.12.4-gnu/drivers/staging/sm750fb/sm750.c
--- linux-libre-4.12.3-gnu/drivers/staging/sm750fb/sm750.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/staging/sm750fb/sm750.c	2017-07-27 18:10:39.000000000 -0400
@@ -1053,6 +1053,26 @@ release_fb:
 	return err;
 }
 
+static int lynxfb_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+	struct apertures_struct *ap;
+	bool primary = false;
+
+	ap = alloc_apertures(1);
+	if (!ap)
+		return -ENOMEM;
+
+	ap->ranges[0].base = pci_resource_start(pdev, 0);
+	ap->ranges[0].size = pci_resource_len(pdev, 0);
+#ifdef CONFIG_X86
+	primary = pdev->resource[PCI_ROM_RESOURCE].flags &
+					IORESOURCE_ROM_SHADOW;
+#endif
+	remove_conflicting_framebuffers(ap, "sm750_fb1", primary);
+	kfree(ap);
+	return 0;
+}
+
 static int lynxfb_pci_probe(struct pci_dev *pdev,
 			    const struct pci_device_id *ent)
 {
@@ -1061,6 +1081,10 @@ static int lynxfb_pci_probe(struct pci_d
 	int fbidx;
 	int err;
 
+	err = lynxfb_kick_out_firmware_fb(pdev);
+	if (err)
+		return err;
+
 	/* enable device */
 	err = pcim_enable_device(pdev);
 	if (err)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_configfs.c linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_configfs.c
--- linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_configfs.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_configfs.c	2017-07-27 18:10:39.000000000 -0400
@@ -781,6 +781,7 @@ DEF_TPG_ATTRIB(default_erl);
 DEF_TPG_ATTRIB(t10_pi);
 DEF_TPG_ATTRIB(fabric_prot_type);
 DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
+DEF_TPG_ATTRIB(login_keys_workaround);
 
 static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
 	&iscsi_tpg_attrib_attr_authentication,
@@ -796,6 +797,7 @@ static struct configfs_attribute *lio_ta
 	&iscsi_tpg_attrib_attr_t10_pi,
 	&iscsi_tpg_attrib_attr_fabric_prot_type,
 	&iscsi_tpg_attrib_attr_tpg_enabled_sendtargets,
+	&iscsi_tpg_attrib_attr_login_keys_workaround,
 	NULL,
 };
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_nego.c linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_nego.c
--- linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_nego.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_nego.c	2017-07-27 18:10:39.000000000 -0400
@@ -886,7 +886,8 @@ static int iscsi_target_handle_csg_zero(
 			SENDER_TARGET,
 			login->rsp_buf,
 			&login->rsp_length,
-			conn->param_list);
+			conn->param_list,
+			conn->tpg->tpg_attrib.login_keys_workaround);
 	if (ret < 0)
 		return -1;
 
@@ -956,7 +957,8 @@ static int iscsi_target_handle_csg_one(s
 			SENDER_TARGET,
 			login->rsp_buf,
 			&login->rsp_length,
-			conn->param_list);
+			conn->param_list,
+			conn->tpg->tpg_attrib.login_keys_workaround);
 	if (ret < 0) {
 		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 				ISCSI_LOGIN_STATUS_INIT_ERR);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_parameters.c linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_parameters.c
--- linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_parameters.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_parameters.c	2017-07-27 18:10:39.000000000 -0400
@@ -765,7 +765,8 @@ static int iscsi_check_for_auth_key(char
 	return 0;
 }
 
-static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
+static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param,
+						    bool keys_workaround)
 {
 	if (IS_TYPE_BOOL_AND(param)) {
 		if (!strcmp(param->value, NO))
@@ -773,19 +774,31 @@ static void iscsi_check_proposer_for_opt
 	} else if (IS_TYPE_BOOL_OR(param)) {
 		if (!strcmp(param->value, YES))
 			SET_PSTATE_REPLY_OPTIONAL(param);
-		 /*
-		  * Required for gPXE iSCSI boot client
-		  */
-		if (!strcmp(param->name, IMMEDIATEDATA))
-			SET_PSTATE_REPLY_OPTIONAL(param);
+
+		if (keys_workaround) {
+			/*
+			 * Required for gPXE iSCSI boot client
+			 */
+			if (!strcmp(param->name, IMMEDIATEDATA))
+				SET_PSTATE_REPLY_OPTIONAL(param);
+		}
 	} else if (IS_TYPE_NUMBER(param)) {
 		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
 			SET_PSTATE_REPLY_OPTIONAL(param);
-		/*
-		 * Required for gPXE iSCSI boot client
-		 */
-		if (!strcmp(param->name, MAXCONNECTIONS))
-			SET_PSTATE_REPLY_OPTIONAL(param);
+
+		if (keys_workaround) {
+			/*
+			 * Required for Mellanox Flexboot PXE boot ROM
+			 */
+			if (!strcmp(param->name, FIRSTBURSTLENGTH))
+				SET_PSTATE_REPLY_OPTIONAL(param);
+
+			/*
+			 * Required for gPXE iSCSI boot client
+			 */
+			if (!strcmp(param->name, MAXCONNECTIONS))
+				SET_PSTATE_REPLY_OPTIONAL(param);
+		}
 	} else if (IS_PHASE_DECLARATIVE(param))
 		SET_PSTATE_REPLY_OPTIONAL(param);
 }
@@ -1422,7 +1435,8 @@ int iscsi_encode_text_output(
 	u8 sender,
 	char *textbuf,
 	u32 *length,
-	struct iscsi_param_list *param_list)
+	struct iscsi_param_list *param_list,
+	bool keys_workaround)
 {
 	char *output_buf = NULL;
 	struct iscsi_extra_response *er;
@@ -1458,7 +1472,8 @@ int iscsi_encode_text_output(
 			*length += 1;
 			output_buf = textbuf + *length;
 			SET_PSTATE_PROPOSER(param);
-			iscsi_check_proposer_for_optional_reply(param);
+			iscsi_check_proposer_for_optional_reply(param,
+							        keys_workaround);
 			pr_debug("Sending key: %s=%s\n",
 				param->name, param->value);
 		}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_parameters.h linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_parameters.h
--- linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_parameters.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_parameters.h	2017-07-27 18:10:39.000000000 -0400
@@ -46,7 +46,7 @@ extern int iscsi_extract_key_value(char
 extern int iscsi_update_param_value(struct iscsi_param *, char *);
 extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
 extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
-			struct iscsi_param_list *);
+			struct iscsi_param_list *, bool);
 extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
 extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *,
 			struct iscsi_param_list *);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_tpg.c linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_tpg.c
--- linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_tpg.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_tpg.c	2017-07-27 18:10:39.000000000 -0400
@@ -227,6 +227,7 @@ static void iscsit_set_default_tpg_attri
 	a->t10_pi = TA_DEFAULT_T10_PI;
 	a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
 	a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
+	a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
 }
 
 int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
@@ -899,3 +900,21 @@ int iscsit_ta_tpg_enabled_sendtargets(
 
 	return 0;
 }
+
+int iscsit_ta_login_keys_workaround(
+	struct iscsi_portal_group *tpg,
+	u32 flag)
+{
+	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
+
+	if ((flag != 0) && (flag != 1)) {
+		pr_err("Illegal value %d\n", flag);
+		return -EINVAL;
+	}
+
+	a->login_keys_workaround = flag;
+	pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ",
+		tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF");
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_tpg.h linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_tpg.h
--- linux-libre-4.12.3-gnu/drivers/target/iscsi/iscsi_target_tpg.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/iscsi/iscsi_target_tpg.h	2017-07-27 18:10:39.000000000 -0400
@@ -48,5 +48,6 @@ extern int iscsit_ta_default_erl(struct
 extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32);
 extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32);
 extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32);
+extern int iscsit_ta_login_keys_workaround(struct iscsi_portal_group *, u32);
 
 #endif /* ISCSI_TARGET_TPG_H */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/target/target_core_transport.c linux-libre-4.12.4-gnu/drivers/target/target_core_transport.c
--- linux-libre-4.12.3-gnu/drivers/target/target_core_transport.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/target/target_core_transport.c	2017-07-27 18:10:39.000000000 -0400
@@ -730,6 +730,15 @@ void target_complete_cmd(struct se_cmd *
 	if (cmd->transport_state & CMD_T_ABORTED ||
 	    cmd->transport_state & CMD_T_STOP) {
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+		/*
+		 * If COMPARE_AND_WRITE was stopped by __transport_wait_for_tasks(),
+		 * release se_device->caw_sem obtained by sbc_compare_and_write()
+		 * since target_complete_ok_work() or target_complete_failure_work()
+		 * won't be called to invoke the normal CAW completion callbacks.
+		 */
+		if (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) {
+			up(&dev->caw_sem);
+		}
 		complete_all(&cmd->t_transport_stop_comp);
 		return;
 	} else if (!success) {
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/thermal/cpu_cooling.c linux-libre-4.12.4-gnu/drivers/thermal/cpu_cooling.c
--- linux-libre-4.12.3-gnu/drivers/thermal/cpu_cooling.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/thermal/cpu_cooling.c	2017-07-27 18:10:39.000000000 -0400
@@ -153,8 +153,10 @@ unsigned long cpufreq_cooling_get_level(
 	mutex_lock(&cooling_list_lock);
 	list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
 		if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) {
+			unsigned long level = get_level(cpufreq_dev, freq);
+
 			mutex_unlock(&cooling_list_lock);
-			return get_level(cpufreq_dev, freq);
+			return level;
 		}
 	}
 	mutex_unlock(&cooling_list_lock);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/thermal/max77620_thermal.c linux-libre-4.12.4-gnu/drivers/thermal/max77620_thermal.c
--- linux-libre-4.12.3-gnu/drivers/thermal/max77620_thermal.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/thermal/max77620_thermal.c	2017-07-27 18:10:39.000000000 -0400
@@ -104,8 +104,6 @@ static int max77620_thermal_probe(struct
 		return -EINVAL;
 	}
 
-	pdev->dev.of_node = pdev->dev.parent->of_node;
-
 	mtherm->dev = &pdev->dev;
 	mtherm->rmap = dev_get_regmap(pdev->dev.parent, NULL);
 	if (!mtherm->rmap) {
@@ -113,6 +111,14 @@ static int max77620_thermal_probe(struct
 		return -ENODEV;
 	}
 
+	/*
+	 * Drop any current reference to a device-tree node and get a
+	 * reference to the parent's node which will be balanced on reprobe or
+	 * on platform-device release.
+	 */
+	of_node_put(pdev->dev.of_node);
+	pdev->dev.of_node = of_node_get(pdev->dev.parent->of_node);
+
 	mtherm->tz_device = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
 				mtherm, &max77620_thermal_ops);
 	if (IS_ERR(mtherm->tz_device)) {
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/tty/serial/sh-sci.c linux-libre-4.12.4-gnu/drivers/tty/serial/sh-sci.c
--- linux-libre-4.12.3-gnu/drivers/tty/serial/sh-sci.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/tty/serial/sh-sci.c	2017-07-27 18:10:39.000000000 -0400
@@ -1085,10 +1085,12 @@ static ssize_t rx_trigger_store(struct d
 {
 	struct uart_port *port = dev_get_drvdata(dev);
 	struct sci_port *sci = to_sci_port(port);
+	int ret;
 	long r;
 
-	if (kstrtol(buf, 0, &r) == -EINVAL)
-		return -EINVAL;
+	ret = kstrtol(buf, 0, &r);
+	if (ret)
+		return ret;
 
 	sci->rx_trigger = scif_set_rtrg(port, r);
 	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
@@ -1116,10 +1118,12 @@ static ssize_t rx_fifo_timeout_store(str
 {
 	struct uart_port *port = dev_get_drvdata(dev);
 	struct sci_port *sci = to_sci_port(port);
+	int ret;
 	long r;
 
-	if (kstrtol(buf, 0, &r) == -EINVAL)
-		return -EINVAL;
+	ret = kstrtol(buf, 0, &r);
+	if (ret)
+		return ret;
 	sci->rx_fifo_timeout = r;
 	scif_set_rtrg(port, 1);
 	if (r > 0)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/tty/serial/st-asc.c linux-libre-4.12.4-gnu/drivers/tty/serial/st-asc.c
--- linux-libre-4.12.3-gnu/drivers/tty/serial/st-asc.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/tty/serial/st-asc.c	2017-07-27 18:10:39.000000000 -0400
@@ -758,6 +758,7 @@ static int asc_init_port(struct asc_port
 	if (IS_ERR(ascport->pinctrl)) {
 		ret = PTR_ERR(ascport->pinctrl);
 		dev_err(&pdev->dev, "Failed to get Pinctrl: %d\n", ret);
+		return ret;
 	}
 
 	ascport->states[DEFAULT] =
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/class/cdc-acm.c linux-libre-4.12.4-gnu/drivers/usb/class/cdc-acm.c
--- linux-libre-4.12.3-gnu/drivers/usb/class/cdc-acm.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/class/cdc-acm.c	2017-07-27 18:10:39.000000000 -0400
@@ -1829,6 +1829,9 @@ static const struct usb_device_id acm_id
 	{ USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},
+	{ USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
+	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+	},
 
 	{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
 	.driver_info = CLEAR_HALT_CONDITIONS,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/pci-quirks.c linux-libre-4.12.4-gnu/drivers/usb/host/pci-quirks.c
--- linux-libre-4.12.3-gnu/drivers/usb/host/pci-quirks.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/pci-quirks.c	2017-07-27 18:10:39.000000000 -0400
@@ -77,6 +77,16 @@
 #define USB_INTEL_USB3_PSSEN   0xD8
 #define USB_INTEL_USB3PRM      0xDC
 
+/* ASMEDIA quirk use */
+#define ASMT_DATA_WRITE0_REG	0xF8
+#define ASMT_DATA_WRITE1_REG	0xFC
+#define ASMT_CONTROL_REG	0xE0
+#define ASMT_CONTROL_WRITE_BIT	0x02
+#define ASMT_WRITEREG_CMD	0x10423
+#define ASMT_FLOWCTL_ADDR	0xFA30
+#define ASMT_FLOWCTL_DATA	0xBA
+#define ASMT_PSEUDO_DATA	0
+
 /*
  * amd_chipset_gen values represent AMD different chipset generations
  */
@@ -412,6 +422,50 @@ void usb_amd_quirk_pll_disable(void)
 }
 EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable);
 
+static int usb_asmedia_wait_write(struct pci_dev *pdev)
+{
+	unsigned long retry_count;
+	unsigned char value;
+
+	for (retry_count = 1000; retry_count > 0; --retry_count) {
+
+		pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
+
+		if (value == 0xff) {
+			dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
+			return -EIO;
+		}
+
+		if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
+			return 0;
+
+		usleep_range(40, 60);
+	}
+
+	dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
+	return -ETIMEDOUT;
+}
+
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
+{
+	if (usb_asmedia_wait_write(pdev) != 0)
+		return;
+
+	/* send command and address to device */
+	pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
+	pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
+	pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+
+	if (usb_asmedia_wait_write(pdev) != 0)
+		return;
+
+	/* send data to device */
+	pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
+	pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
+	pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+}
+EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
+
 void usb_amd_quirk_pll_enable(void)
 {
 	usb_amd_quirk_pll(0);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/pci-quirks.h linux-libre-4.12.4-gnu/drivers/usb/host/pci-quirks.h
--- linux-libre-4.12.3-gnu/drivers/usb/host/pci-quirks.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/pci-quirks.h	2017-07-27 18:10:39.000000000 -0400
@@ -11,6 +11,7 @@ bool usb_amd_prefetch_quirk(void);
 void usb_amd_dev_put(void);
 void usb_amd_quirk_pll_disable(void);
 void usb_amd_quirk_pll_enable(void);
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
 void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
 void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
 void sb800_prefetch(struct device *dev, int on);
@@ -18,6 +19,7 @@ void sb800_prefetch(struct device *dev,
 struct pci_dev;
 static inline void usb_amd_quirk_pll_disable(void) {}
 static inline void usb_amd_quirk_pll_enable(void) {}
+static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
 static inline void usb_amd_dev_put(void) {}
 static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
 static inline void sb800_prefetch(struct device *dev, int on) {}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/xhci.c linux-libre-4.12.4-gnu/drivers/usb/host/xhci.c
--- linux-libre-4.12.3-gnu/drivers/usb/host/xhci.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/xhci.c	2017-07-27 18:10:39.000000000 -0400
@@ -198,6 +198,9 @@ int xhci_reset(struct xhci_hcd *xhci)
 	if (ret)
 		return ret;
 
+	if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL)
+		usb_asmedia_modifyflowcontrol(to_pci_dev(xhci_to_hcd(xhci)->self.controller));
+
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			 "Wait for controller to be ready for doorbell rings");
 	/*
@@ -622,8 +625,10 @@ int xhci_run(struct usb_hcd *hcd)
 		if (!command)
 			return -ENOMEM;
 
-		xhci_queue_vendor_command(xhci, command, 0, 0, 0,
+		ret = xhci_queue_vendor_command(xhci, command, 0, 0, 0,
 				TRB_TYPE(TRB_NEC_GET_FW));
+		if (ret)
+			xhci_free_command(xhci, command);
 	}
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			"Finished xhci_run for USB2 roothub");
@@ -1085,6 +1090,9 @@ int xhci_resume(struct xhci_hcd *xhci, b
 	if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
 		compliance_mode_recovery_timer_init(xhci);
 
+	if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL)
+		usb_asmedia_modifyflowcontrol(to_pci_dev(hcd->self.controller));
+
 	/* Re-enable port polling. */
 	xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
 	set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/xhci.h linux-libre-4.12.4-gnu/drivers/usb/host/xhci.h
--- linux-libre-4.12.3-gnu/drivers/usb/host/xhci.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/xhci.h	2017-07-27 18:10:39.000000000 -0400
@@ -1820,6 +1820,7 @@ struct xhci_hcd {
 #define XHCI_BROKEN_PORT_PED	(1 << 25)
 #define XHCI_LIMIT_ENDPOINT_INTERVAL_7	(1 << 26)
 #define XHCI_U2_DISABLE_WAKE	(1 << 27)
+#define XHCI_ASMEDIA_MODIFY_FLOWCONTROL	(1 << 28)
 
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/xhci-hub.c linux-libre-4.12.4-gnu/drivers/usb/host/xhci-hub.c
--- linux-libre-4.12.3-gnu/drivers/usb/host/xhci-hub.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/xhci-hub.c	2017-07-27 18:10:39.000000000 -0400
@@ -603,12 +603,14 @@ static int xhci_enter_test_mode(struct x
 
 	/* Disable all Device Slots */
 	xhci_dbg(xhci, "Disable all slots\n");
+	spin_unlock_irqrestore(&xhci->lock, *flags);
 	for (i = 1; i <= HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
 		retval = xhci_disable_slot(xhci, NULL, i);
 		if (retval)
 			xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n",
 				 i, retval);
 	}
+	spin_lock_irqsave(&xhci->lock, *flags);
 	/* Put all ports to the Disable state by clear PP */
 	xhci_dbg(xhci, "Disable all port (PP = 0)\n");
 	/* Power off USB3 ports*/
@@ -897,6 +899,9 @@ static u32 xhci_get_port_status(struct u
 			clear_bit(wIndex, &bus_state->resuming_ports);
 
 			set_bit(wIndex, &bus_state->rexit_ports);
+
+			xhci_test_and_clear_bit(xhci, port_array, wIndex,
+						PORT_PLC);
 			xhci_set_link_state(xhci, port_array, wIndex,
 					XDEV_U0);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/xhci-pci.c linux-libre-4.12.4-gnu/drivers/usb/host/xhci-pci.c
--- linux-libre-4.12.3-gnu/drivers/usb/host/xhci-pci.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/xhci-pci.c	2017-07-27 18:10:39.000000000 -0400
@@ -59,6 +59,8 @@
 #define PCI_DEVICE_ID_AMD_PROMONTORYA_2			0x43bb
 #define PCI_DEVICE_ID_AMD_PROMONTORYA_1			0x43bc
 
+#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI		0x1142
+
 static const char hcd_name[] = "xhci_hcd";
 
 static struct hc_driver __read_mostly xhci_pci_hc_driver;
@@ -217,6 +219,10 @@ static void xhci_pci_quirks(struct devic
 			pdev->device == 0x1142)
 		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 
+	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
+		xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL;
+
 	if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
 		xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/host/xhci-ring.c linux-libre-4.12.4-gnu/drivers/usb/host/xhci-ring.c
--- linux-libre-4.12.3-gnu/drivers/usb/host/xhci-ring.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/host/xhci-ring.c	2017-07-27 18:10:39.000000000 -0400
@@ -845,13 +845,16 @@ static void xhci_kill_endpoint_urbs(stru
 			(ep->ep_state & EP_GETTING_NO_STREAMS)) {
 		int stream_id;
 
-		for (stream_id = 0; stream_id < ep->stream_info->num_streams;
+		for (stream_id = 1; stream_id < ep->stream_info->num_streams;
 				stream_id++) {
+			ring = ep->stream_info->stream_rings[stream_id];
+			if (!ring)
+				continue;
+
 			xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 					"Killing URBs for slot ID %u, ep index %u, stream %u",
-					slot_id, ep_index, stream_id + 1);
-			xhci_kill_ring_urbs(xhci,
-					ep->stream_info->stream_rings[stream_id]);
+					slot_id, ep_index, stream_id);
+			xhci_kill_ring_urbs(xhci, ring);
 		}
 	} else {
 		ring = ep->ring;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/renesas_usbhs/common.c linux-libre-4.12.4-gnu/drivers/usb/renesas_usbhs/common.c
--- linux-libre-4.12.3-gnu/drivers/usb/renesas_usbhs/common.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/renesas_usbhs/common.c	2017-07-27 18:10:39.000000000 -0400
@@ -752,8 +752,10 @@ static int usbhsc_resume(struct device *
 	struct usbhs_priv *priv = dev_get_drvdata(dev);
 	struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 
-	if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
+	if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
 		usbhsc_power_ctrl(priv, 1);
+		usbhs_mod_autonomy_mode(priv);
+	}
 
 	usbhs_platform_call(priv, phy_reset, pdev);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/renesas_usbhs/mod_gadget.c linux-libre-4.12.4-gnu/drivers/usb/renesas_usbhs/mod_gadget.c
--- linux-libre-4.12.3-gnu/drivers/usb/renesas_usbhs/mod_gadget.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/renesas_usbhs/mod_gadget.c	2017-07-27 18:10:39.000000000 -0400
@@ -37,6 +37,7 @@ struct usbhsg_gpriv;
 struct usbhsg_uep {
 	struct usb_ep		 ep;
 	struct usbhs_pipe	*pipe;
+	spinlock_t		lock;	/* protect the pipe */
 
 	char ep_name[EP_NAME_SIZE];
 
@@ -636,10 +637,16 @@ usbhsg_ep_enable_end:
 static int usbhsg_ep_disable(struct usb_ep *ep)
 {
 	struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
-	struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
+	struct usbhs_pipe *pipe;
+	unsigned long flags;
+	int ret = 0;
 
-	if (!pipe)
-		return -EINVAL;
+	spin_lock_irqsave(&uep->lock, flags);
+	pipe = usbhsg_uep_to_pipe(uep);
+	if (!pipe) {
+		ret = -EINVAL;
+		goto out;
+	}
 
 	usbhsg_pipe_disable(uep);
 	usbhs_pipe_free(pipe);
@@ -647,6 +654,9 @@ static int usbhsg_ep_disable(struct usb_
 	uep->pipe->mod_private	= NULL;
 	uep->pipe		= NULL;
 
+out:
+	spin_unlock_irqrestore(&uep->lock, flags);
+
 	return 0;
 }
 
@@ -696,8 +706,11 @@ static int usbhsg_ep_dequeue(struct usb_
 {
 	struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
 	struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
-	struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
+	struct usbhs_pipe *pipe;
+	unsigned long flags;
 
+	spin_lock_irqsave(&uep->lock, flags);
+	pipe = usbhsg_uep_to_pipe(uep);
 	if (pipe)
 		usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
 
@@ -706,6 +719,7 @@ static int usbhsg_ep_dequeue(struct usb_
 	 * even if the pipe is NULL.
 	 */
 	usbhsg_queue_pop(uep, ureq, -ECONNRESET);
+	spin_unlock_irqrestore(&uep->lock, flags);
 
 	return 0;
 }
@@ -852,10 +866,10 @@ static int usbhsg_try_stop(struct usbhs_
 {
 	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
 	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
-	struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
+	struct usbhsg_uep *uep;
 	struct device *dev = usbhs_priv_to_dev(priv);
 	unsigned long flags;
-	int ret = 0;
+	int ret = 0, i;
 
 	/********************  spin lock ********************/
 	usbhs_lock(priv, flags);
@@ -887,7 +901,9 @@ static int usbhsg_try_stop(struct usbhs_
 	usbhs_sys_set_test_mode(priv, 0);
 	usbhs_sys_function_ctrl(priv, 0);
 
-	usbhsg_ep_disable(&dcp->ep);
+	/* disable all eps */
+	usbhsg_for_each_uep_with_dcp(uep, gpriv, i)
+		usbhsg_ep_disable(&uep->ep);
 
 	dev_dbg(dev, "stop gadget\n");
 
@@ -1069,6 +1085,7 @@ int usbhs_mod_gadget_probe(struct usbhs_
 		ret = -ENOMEM;
 		goto usbhs_mod_gadget_probe_err_gpriv;
 	}
+	spin_lock_init(&uep->lock);
 
 	gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
 	dev_info(dev, "%stransceiver found\n",
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/usb/storage/isd200.c linux-libre-4.12.4-gnu/drivers/usb/storage/isd200.c
--- linux-libre-4.12.3-gnu/drivers/usb/storage/isd200.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/usb/storage/isd200.c	2017-07-27 18:10:39.000000000 -0400
@@ -1529,8 +1529,11 @@ static void isd200_ata_command(struct sc
 
 	/* Make sure driver was initialized */
 
-	if (us->extra == NULL)
+	if (us->extra == NULL) {
 		usb_stor_dbg(us, "ERROR Driver not initialized\n");
+		srb->result = DID_ERROR << 16;
+		return;
+	}
 
 	scsi_set_resid(srb, 0);
 	/* scsi_bufflen might change in protocol translation to ata */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/vfio/vfio.c linux-libre-4.12.4-gnu/drivers/vfio/vfio.c
--- linux-libre-4.12.3-gnu/drivers/vfio/vfio.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/vfio/vfio.c	2017-07-27 18:10:39.000000000 -0400
@@ -423,6 +423,34 @@ static void vfio_group_put(struct vfio_g
 	kref_put_mutex(&group->kref, vfio_group_release, &vfio.group_lock);
 }
 
+struct vfio_group_put_work {
+	struct work_struct work;
+	struct vfio_group *group;
+};
+
+static void vfio_group_put_bg(struct work_struct *work)
+{
+	struct vfio_group_put_work *do_work;
+
+	do_work = container_of(work, struct vfio_group_put_work, work);
+
+	vfio_group_put(do_work->group);
+	kfree(do_work);
+}
+
+static void vfio_group_schedule_put(struct vfio_group *group)
+{
+	struct vfio_group_put_work *do_work;
+
+	do_work = kmalloc(sizeof(*do_work), GFP_KERNEL);
+	if (WARN_ON(!do_work))
+		return;
+
+	INIT_WORK(&do_work->work, vfio_group_put_bg);
+	do_work->group = group;
+	schedule_work(&do_work->work);
+}
+
 /* Assume group_lock or group reference is held */
 static void vfio_group_get(struct vfio_group *group)
 {
@@ -762,7 +790,14 @@ static int vfio_iommu_group_notifier(str
 		break;
 	}
 
-	vfio_group_put(group);
+	/*
+	 * If we're the last reference to the group, the group will be
+	 * released, which includes unregistering the iommu group notifier.
+	 * We hold a read-lock on that notifier list, unregistering needs
+	 * a write-lock... deadlock.  Release our reference asynchronously
+	 * to avoid that situation.
+	 */
+	vfio_group_schedule_put(group);
 	return NOTIFY_OK;
 }
 
@@ -1140,15 +1175,11 @@ static long vfio_fops_unl_ioctl(struct f
 		ret = vfio_ioctl_set_iommu(container, arg);
 		break;
 	default:
-		down_read(&container->group_lock);
-
 		driver = container->iommu_driver;
 		data = container->iommu_data;
 
 		if (driver) /* passthrough all unrecognized ioctls */
 			ret = driver->ops->ioctl(data, cmd, arg);
-
-		up_read(&container->group_lock);
 	}
 
 	return ret;
@@ -1202,15 +1233,11 @@ static ssize_t vfio_fops_read(struct fil
 	struct vfio_iommu_driver *driver;
 	ssize_t ret = -EINVAL;
 
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->read))
 		ret = driver->ops->read(container->iommu_data,
 					buf, count, ppos);
 
-	up_read(&container->group_lock);
-
 	return ret;
 }
 
@@ -1221,15 +1248,11 @@ static ssize_t vfio_fops_write(struct fi
 	struct vfio_iommu_driver *driver;
 	ssize_t ret = -EINVAL;
 
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->write))
 		ret = driver->ops->write(container->iommu_data,
 					 buf, count, ppos);
 
-	up_read(&container->group_lock);
-
 	return ret;
 }
 
@@ -1239,14 +1262,10 @@ static int vfio_fops_mmap(struct file *f
 	struct vfio_iommu_driver *driver;
 	int ret = -EINVAL;
 
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->mmap))
 		ret = driver->ops->mmap(container->iommu_data, vma);
 
-	up_read(&container->group_lock);
-
 	return ret;
 }
 
@@ -1741,6 +1760,15 @@ void vfio_group_put_external_user(struct
 }
 EXPORT_SYMBOL_GPL(vfio_group_put_external_user);
 
+bool vfio_external_group_match_file(struct vfio_group *test_group,
+				    struct file *filep)
+{
+	struct vfio_group *group = filep->private_data;
+
+	return (filep->f_op == &vfio_group_fops) && (group == test_group);
+}
+EXPORT_SYMBOL_GPL(vfio_external_group_match_file);
+
 int vfio_external_user_iommu_id(struct vfio_group *group)
 {
 	return iommu_group_id(group->iommu_group);
@@ -1949,8 +1977,6 @@ int vfio_pin_pages(struct device *dev, u
 		goto err_pin_pages;
 
 	container = group->container;
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->pin_pages))
 		ret = driver->ops->pin_pages(container->iommu_data, user_pfn,
@@ -1958,7 +1984,6 @@ int vfio_pin_pages(struct device *dev, u
 	else
 		ret = -ENOTTY;
 
-	up_read(&container->group_lock);
 	vfio_group_try_dissolve_container(group);
 
 err_pin_pages:
@@ -1998,8 +2023,6 @@ int vfio_unpin_pages(struct device *dev,
 		goto err_unpin_pages;
 
 	container = group->container;
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->unpin_pages))
 		ret = driver->ops->unpin_pages(container->iommu_data, user_pfn,
@@ -2007,7 +2030,6 @@ int vfio_unpin_pages(struct device *dev,
 	else
 		ret = -ENOTTY;
 
-	up_read(&container->group_lock);
 	vfio_group_try_dissolve_container(group);
 
 err_unpin_pages:
@@ -2029,8 +2051,6 @@ static int vfio_register_iommu_notifier(
 		return -EINVAL;
 
 	container = group->container;
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->register_notifier))
 		ret = driver->ops->register_notifier(container->iommu_data,
@@ -2038,7 +2058,6 @@ static int vfio_register_iommu_notifier(
 	else
 		ret = -ENOTTY;
 
-	up_read(&container->group_lock);
 	vfio_group_try_dissolve_container(group);
 
 	return ret;
@@ -2056,8 +2075,6 @@ static int vfio_unregister_iommu_notifie
 		return -EINVAL;
 
 	container = group->container;
-	down_read(&container->group_lock);
-
 	driver = container->iommu_driver;
 	if (likely(driver && driver->ops->unregister_notifier))
 		ret = driver->ops->unregister_notifier(container->iommu_data,
@@ -2065,7 +2082,6 @@ static int vfio_unregister_iommu_notifie
 	else
 		ret = -ENOTTY;
 
-	up_read(&container->group_lock);
 	vfio_group_try_dissolve_container(group);
 
 	return ret;
@@ -2083,7 +2099,6 @@ static int vfio_register_group_notifier(
 					unsigned long *events,
 					struct notifier_block *nb)
 {
-	struct vfio_container *container;
 	int ret;
 	bool set_kvm = false;
 
@@ -2101,9 +2116,6 @@ static int vfio_register_group_notifier(
 	if (ret)
 		return -EINVAL;
 
-	container = group->container;
-	down_read(&container->group_lock);
-
 	ret = blocking_notifier_chain_register(&group->notifier, nb);
 
 	/*
@@ -2114,7 +2126,6 @@ static int vfio_register_group_notifier(
 		blocking_notifier_call_chain(&group->notifier,
 					VFIO_GROUP_NOTIFY_SET_KVM, group->kvm);
 
-	up_read(&container->group_lock);
 	vfio_group_try_dissolve_container(group);
 
 	return ret;
@@ -2123,19 +2134,14 @@ static int vfio_register_group_notifier(
 static int vfio_unregister_group_notifier(struct vfio_group *group,
 					 struct notifier_block *nb)
 {
-	struct vfio_container *container;
 	int ret;
 
 	ret = vfio_group_add_container_user(group);
 	if (ret)
 		return -EINVAL;
 
-	container = group->container;
-	down_read(&container->group_lock);
-
 	ret = blocking_notifier_chain_unregister(&group->notifier, nb);
 
-	up_read(&container->group_lock);
 	vfio_group_try_dissolve_container(group);
 
 	return ret;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/drivers/xen/xen-scsiback.c linux-libre-4.12.4-gnu/drivers/xen/xen-scsiback.c
--- linux-libre-4.12.3-gnu/drivers/xen/xen-scsiback.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/drivers/xen/xen-scsiback.c	2017-07-27 18:10:39.000000000 -0400
@@ -134,9 +134,7 @@ struct vscsibk_pend {
 	struct page *pages[VSCSI_MAX_GRANTS];
 
 	struct se_cmd se_cmd;
-};
 
-struct scsiback_tmr {
 	atomic_t tmr_complete;
 	wait_queue_head_t tmr_wait;
 };
@@ -599,26 +597,20 @@ static void scsiback_device_action(struc
 	struct scsiback_tpg *tpg = pending_req->v2p->tpg;
 	struct scsiback_nexus *nexus = tpg->tpg_nexus;
 	struct se_cmd *se_cmd = &pending_req->se_cmd;
-	struct scsiback_tmr *tmr;
 	u64 unpacked_lun = pending_req->v2p->lun;
 	int rc, err = FAILED;
 
-	tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL);
-	if (!tmr) {
-		target_put_sess_cmd(se_cmd);
-		goto err;
-	}
-
-	init_waitqueue_head(&tmr->tmr_wait);
+	init_waitqueue_head(&pending_req->tmr_wait);
 
 	rc = target_submit_tmr(&pending_req->se_cmd, nexus->tvn_se_sess,
 			       &pending_req->sense_buffer[0],
-			       unpacked_lun, tmr, act, GFP_KERNEL,
+			       unpacked_lun, NULL, act, GFP_KERNEL,
 			       tag, TARGET_SCF_ACK_KREF);
 	if (rc)
 		goto err;
 
-	wait_event(tmr->tmr_wait, atomic_read(&tmr->tmr_complete));
+	wait_event(pending_req->tmr_wait,
+		   atomic_read(&pending_req->tmr_complete));
 
 	err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
 		SUCCESS : FAILED;
@@ -626,9 +618,8 @@ static void scsiback_device_action(struc
 	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
 	transport_generic_free_cmd(&pending_req->se_cmd, 1);
 	return;
+
 err:
-	if (tmr)
-		kfree(tmr);
 	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
 }
 
@@ -1389,12 +1380,6 @@ static int scsiback_check_stop_free(stru
 static void scsiback_release_cmd(struct se_cmd *se_cmd)
 {
 	struct se_session *se_sess = se_cmd->se_sess;
-	struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
-
-	if (se_tmr && se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) {
-		struct scsiback_tmr *tmr = se_tmr->fabric_tmr_ptr;
-		kfree(tmr);
-	}
 
 	percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
 }
@@ -1455,11 +1440,11 @@ static int scsiback_queue_status(struct
 
 static void scsiback_queue_tm_rsp(struct se_cmd *se_cmd)
 {
-	struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
-	struct scsiback_tmr *tmr = se_tmr->fabric_tmr_ptr;
+	struct vscsibk_pend *pending_req = container_of(se_cmd,
+				struct vscsibk_pend, se_cmd);
 
-	atomic_set(&tmr->tmr_complete, 1);
-	wake_up(&tmr->tmr_wait);
+	atomic_set(&pending_req->tmr_complete, 1);
+	wake_up(&pending_req->tmr_wait);
 }
 
 static void scsiback_aborted_task(struct se_cmd *se_cmd)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/btrfs/acl.c linux-libre-4.12.4-gnu/fs/btrfs/acl.c
--- linux-libre-4.12.3-gnu/fs/btrfs/acl.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/btrfs/acl.c	2017-07-27 18:10:39.000000000 -0400
@@ -78,12 +78,6 @@ static int __btrfs_set_acl(struct btrfs_
 	switch (type) {
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
-		if (acl) {
-			ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
-			if (ret)
-				return ret;
-		}
-		ret = 0;
 		break;
 	case ACL_TYPE_DEFAULT:
 		if (!S_ISDIR(inode->i_mode))
@@ -119,6 +113,13 @@ out:
 
 int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
+	int ret;
+
+	if (type == ACL_TYPE_ACCESS && acl) {
+		ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+		if (ret)
+			return ret;
+	}
 	return __btrfs_set_acl(NULL, inode, acl, type);
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/btrfs/disk-io.c linux-libre-4.12.4-gnu/fs/btrfs/disk-io.c
--- linux-libre-4.12.3-gnu/fs/btrfs/disk-io.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/btrfs/disk-io.c	2017-07-27 18:10:39.000000000 -0400
@@ -1255,9 +1255,9 @@ void clean_tree_block(struct btrfs_fs_in
 		btrfs_assert_tree_locked(buf);
 
 		if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) {
-			__percpu_counter_add(&fs_info->dirty_metadata_bytes,
-					     -buf->len,
-					     fs_info->dirty_metadata_batch);
+			percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
+						 -buf->len,
+						 fs_info->dirty_metadata_batch);
 			/* ugh, clear_extent_buffer_dirty needs to lock the page */
 			btrfs_set_lock_blocking(buf);
 			clear_extent_buffer_dirty(buf);
@@ -4049,9 +4049,9 @@ void btrfs_mark_buffer_dirty(struct exte
 			buf->start, transid, fs_info->generation);
 	was_dirty = set_extent_buffer_dirty(buf);
 	if (!was_dirty)
-		__percpu_counter_add(&fs_info->dirty_metadata_bytes,
-				     buf->len,
-				     fs_info->dirty_metadata_batch);
+		percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
+					 buf->len,
+					 fs_info->dirty_metadata_batch);
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
 	if (btrfs_header_level(buf) == 0 && check_leaf(root, buf)) {
 		btrfs_print_leaf(fs_info, buf);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/btrfs/extent_io.c linux-libre-4.12.4-gnu/fs/btrfs/extent_io.c
--- linux-libre-4.12.3-gnu/fs/btrfs/extent_io.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/btrfs/extent_io.c	2017-07-27 18:10:39.000000000 -0400
@@ -3597,9 +3597,9 @@ lock_extent_buffer_for_io(struct extent_
 		set_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
 		spin_unlock(&eb->refs_lock);
 		btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
-		__percpu_counter_add(&fs_info->dirty_metadata_bytes,
-				     -eb->len,
-				     fs_info->dirty_metadata_batch);
+		percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
+					 -eb->len,
+					 fs_info->dirty_metadata_batch);
 		ret = 1;
 	} else {
 		spin_unlock(&eb->refs_lock);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/btrfs/file.c linux-libre-4.12.4-gnu/fs/btrfs/file.c
--- linux-libre-4.12.3-gnu/fs/btrfs/file.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/btrfs/file.c	2017-07-27 18:10:39.000000000 -0400
@@ -2390,10 +2390,13 @@ out:
  */
 static int find_first_non_hole(struct inode *inode, u64 *start, u64 *len)
 {
+	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 	struct extent_map *em;
 	int ret = 0;
 
-	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, *start, *len, 0);
+	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0,
+			      round_down(*start, fs_info->sectorsize),
+			      round_up(*len, fs_info->sectorsize), 0);
 	if (IS_ERR(em))
 		return PTR_ERR(em);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/btrfs/inode.c linux-libre-4.12.4-gnu/fs/btrfs/inode.c
--- linux-libre-4.12.3-gnu/fs/btrfs/inode.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/btrfs/inode.c	2017-07-27 18:10:39.000000000 -0400
@@ -1766,8 +1766,8 @@ static void btrfs_set_bit_hook(struct in
 		if (btrfs_is_testing(fs_info))
 			return;
 
-		__percpu_counter_add(&fs_info->delalloc_bytes, len,
-				     fs_info->delalloc_batch);
+		percpu_counter_add_batch(&fs_info->delalloc_bytes, len,
+					 fs_info->delalloc_batch);
 		spin_lock(&BTRFS_I(inode)->lock);
 		BTRFS_I(inode)->delalloc_bytes += len;
 		if (*bits & EXTENT_DEFRAG)
@@ -1840,8 +1840,8 @@ static void btrfs_clear_bit_hook(struct
 					&inode->vfs_inode,
 					state->start, len);
 
-		__percpu_counter_add(&fs_info->delalloc_bytes, -len,
-				     fs_info->delalloc_batch);
+		percpu_counter_add_batch(&fs_info->delalloc_bytes, -len,
+					 fs_info->delalloc_batch);
 		spin_lock(&inode->lock);
 		inode->delalloc_bytes -= len;
 		if (do_list && inode->delalloc_bytes == 0 &&
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/btrfs/send.c linux-libre-4.12.4-gnu/fs/btrfs/send.c
--- linux-libre-4.12.3-gnu/fs/btrfs/send.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/btrfs/send.c	2017-07-27 18:10:39.000000000 -0400
@@ -5190,15 +5190,12 @@ static int is_extent_unchanged(struct se
 			goto out;
 		}
 
-		right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
 		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
 			right_len = btrfs_file_extent_inline_len(eb, slot, ei);
 			right_len = PAGE_ALIGN(right_len);
 		} else {
 			right_len = btrfs_file_extent_num_bytes(eb, ei);
 		}
-		right_offset = btrfs_file_extent_offset(eb, ei);
-		right_gen = btrfs_file_extent_generation(eb, ei);
 
 		/*
 		 * Are we at extent 8? If yes, we know the extent is changed.
@@ -5223,6 +5220,10 @@ static int is_extent_unchanged(struct se
 			goto out;
 		}
 
+		right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
+		right_offset = btrfs_file_extent_offset(eb, ei);
+		right_gen = btrfs_file_extent_generation(eb, ei);
+
 		left_offset_fixed = left_offset;
 		if (key.offset < ekey->offset) {
 			/* Fix the right offset for 2a and 7. */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ceph/dir.c linux-libre-4.12.4-gnu/fs/ceph/dir.c
--- linux-libre-4.12.3-gnu/fs/ceph/dir.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ceph/dir.c	2017-07-27 18:10:39.000000000 -0400
@@ -271,6 +271,11 @@ out:
 		if (ret < 0)
 			err = ret;
 		dput(last);
+		/* last_name no longer match cache index */
+		if (fi->readdir_cache_idx >= 0) {
+			fi->readdir_cache_idx = -1;
+			fi->dir_release_count = 0;
+		}
 	}
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/cifs/cifsglob.h linux-libre-4.12.4-gnu/fs/cifs/cifsglob.h
--- linux-libre-4.12.3-gnu/fs/cifs/cifsglob.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/cifs/cifsglob.h	2017-07-27 18:10:39.000000000 -0400
@@ -367,6 +367,8 @@ struct smb_version_operations {
 	unsigned int (*calc_smb_size)(void *);
 	/* check for STATUS_PENDING and process it in a positive case */
 	bool (*is_status_pending)(char *, struct TCP_Server_Info *, int);
+	/* check for STATUS_NETWORK_SESSION_EXPIRED */
+	bool (*is_session_expired)(char *);
 	/* send oplock break response */
 	int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *,
 			       struct cifsInodeInfo *);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/cifs/cifssmb.c linux-libre-4.12.4-gnu/fs/cifs/cifssmb.c
--- linux-libre-4.12.3-gnu/fs/cifs/cifssmb.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/cifs/cifssmb.c	2017-07-27 18:10:39.000000000 -0400
@@ -1460,6 +1460,13 @@ cifs_readv_receive(struct TCP_Server_Inf
 		return length;
 	server->total_read += length;
 
+	if (server->ops->is_session_expired &&
+	    server->ops->is_session_expired(buf)) {
+		cifs_reconnect(server);
+		wake_up(&server->response_q);
+		return -1;
+	}
+
 	if (server->ops->is_status_pending &&
 	    server->ops->is_status_pending(buf, server, 0)) {
 		cifs_discard_remaining_data(server);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/cifs/connect.c linux-libre-4.12.4-gnu/fs/cifs/connect.c
--- linux-libre-4.12.3-gnu/fs/cifs/connect.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/cifs/connect.c	2017-07-27 18:10:39.000000000 -0400
@@ -812,6 +812,13 @@ cifs_handle_standard(struct TCP_Server_I
 		cifs_dump_mem("Bad SMB: ", buf,
 			min_t(unsigned int, server->total_read, 48));
 
+	if (server->ops->is_session_expired &&
+	    server->ops->is_session_expired(buf)) {
+		cifs_reconnect(server);
+		wake_up(&server->response_q);
+		return -1;
+	}
+
 	if (server->ops->is_status_pending &&
 	    server->ops->is_status_pending(buf, server, length))
 		return -1;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/cifs/smb2ops.c linux-libre-4.12.4-gnu/fs/cifs/smb2ops.c
--- linux-libre-4.12.3-gnu/fs/cifs/smb2ops.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/cifs/smb2ops.c	2017-07-27 18:10:39.000000000 -0400
@@ -1036,6 +1036,18 @@ smb2_is_status_pending(char *buf, struct
 	return true;
 }
 
+static bool
+smb2_is_session_expired(char *buf)
+{
+	struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
+
+	if (shdr->Status != STATUS_NETWORK_SESSION_EXPIRED)
+		return false;
+
+	cifs_dbg(FYI, "Session expired\n");
+	return true;
+}
+
 static int
 smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
 		     struct cifsInodeInfo *cinode)
@@ -2058,6 +2070,13 @@ handle_read_data(struct TCP_Server_Info
 		return -ENOTSUPP;
 	}
 
+	if (server->ops->is_session_expired &&
+	    server->ops->is_session_expired(buf)) {
+		cifs_reconnect(server);
+		wake_up(&server->response_q);
+		return -1;
+	}
+
 	if (server->ops->is_status_pending &&
 			server->ops->is_status_pending(buf, server, 0))
 		return -1;
@@ -2375,6 +2394,7 @@ struct smb_version_operations smb20_oper
 	.close_dir = smb2_close_dir,
 	.calc_smb_size = smb2_calc_size,
 	.is_status_pending = smb2_is_status_pending,
+	.is_session_expired = smb2_is_session_expired,
 	.oplock_response = smb2_oplock_response,
 	.queryfs = smb2_queryfs,
 	.mand_lock = smb2_mand_lock,
@@ -2458,6 +2478,7 @@ struct smb_version_operations smb21_oper
 	.close_dir = smb2_close_dir,
 	.calc_smb_size = smb2_calc_size,
 	.is_status_pending = smb2_is_status_pending,
+	.is_session_expired = smb2_is_session_expired,
 	.oplock_response = smb2_oplock_response,
 	.queryfs = smb2_queryfs,
 	.mand_lock = smb2_mand_lock,
@@ -2543,6 +2564,7 @@ struct smb_version_operations smb30_oper
 	.close_dir = smb2_close_dir,
 	.calc_smb_size = smb2_calc_size,
 	.is_status_pending = smb2_is_status_pending,
+	.is_session_expired = smb2_is_session_expired,
 	.oplock_response = smb2_oplock_response,
 	.queryfs = smb2_queryfs,
 	.mand_lock = smb2_mand_lock,
@@ -2638,6 +2660,7 @@ struct smb_version_operations smb311_ope
 	.close_dir = smb2_close_dir,
 	.calc_smb_size = smb2_calc_size,
 	.is_status_pending = smb2_is_status_pending,
+	.is_session_expired = smb2_is_session_expired,
 	.oplock_response = smb2_oplock_response,
 	.queryfs = smb2_queryfs,
 	.mand_lock = smb2_mand_lock,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ext2/acl.c linux-libre-4.12.4-gnu/fs/ext2/acl.c
--- linux-libre-4.12.3-gnu/fs/ext2/acl.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ext2/acl.c	2017-07-27 18:10:39.000000000 -0400
@@ -175,11 +175,8 @@ ext2_get_acl(struct inode *inode, int ty
 	return acl;
 }
 
-/*
- * inode->i_mutex: down
- */
-int
-ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+static int
+__ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
 	int name_index;
 	void *value = NULL;
@@ -189,13 +186,6 @@ ext2_set_acl(struct inode *inode, struct
 	switch(type) {
 		case ACL_TYPE_ACCESS:
 			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
-			if (acl) {
-				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
-				if (error)
-					return error;
-				inode->i_ctime = current_time(inode);
-				mark_inode_dirty(inode);
-			}
 			break;
 
 		case ACL_TYPE_DEFAULT:
@@ -222,6 +212,24 @@ ext2_set_acl(struct inode *inode, struct
 }
 
 /*
+ * inode->i_mutex: down
+ */
+int
+ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+	int error;
+
+	if (type == ACL_TYPE_ACCESS && acl) {
+		error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+		if (error)
+			return error;
+		inode->i_ctime = current_time(inode);
+		mark_inode_dirty(inode);
+	}
+	return __ext2_set_acl(inode, acl, type);
+}
+
+/*
  * Initialize the ACLs of a new inode. Called from ext2_new_inode.
  *
  * dir->i_mutex: down
@@ -238,12 +246,12 @@ ext2_init_acl(struct inode *inode, struc
 		return error;
 
 	if (default_acl) {
-		error = ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+		error = __ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
 		posix_acl_release(default_acl);
 	}
 	if (acl) {
 		if (!error)
-			error = ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
+			error = __ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
 		posix_acl_release(acl);
 	}
 	return error;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/acl.c linux-libre-4.12.4-gnu/fs/f2fs/acl.c
--- linux-libre-4.12.3-gnu/fs/f2fs/acl.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/acl.c	2017-07-27 18:10:39.000000000 -0400
@@ -211,7 +211,7 @@ static int __f2fs_set_acl(struct inode *
 	switch (type) {
 	case ACL_TYPE_ACCESS:
 		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
-		if (acl) {
+		if (acl && !ipage) {
 			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
 			if (error)
 				return error;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/checkpoint.c linux-libre-4.12.4-gnu/fs/f2fs/checkpoint.c
--- linux-libre-4.12.3-gnu/fs/f2fs/checkpoint.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/checkpoint.c	2017-07-27 18:10:39.000000000 -0400
@@ -1051,8 +1051,9 @@ static void update_ckpt_flags(struct f2f
 {
 	unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num;
 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
+	unsigned long flags;
 
-	spin_lock(&sbi->cp_lock);
+	spin_lock_irqsave(&sbi->cp_lock, flags);
 
 	if ((cpc->reason & CP_UMOUNT) &&
 			le32_to_cpu(ckpt->cp_pack_total_block_count) >
@@ -1083,14 +1084,14 @@ static void update_ckpt_flags(struct f2f
 	/* set this flag to activate crc|cp_ver for recovery */
 	__set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG);
 
-	spin_unlock(&sbi->cp_lock);
+	spin_unlock_irqrestore(&sbi->cp_lock, flags);
 }
 
 static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 {
 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
 	struct f2fs_nm_info *nm_i = NM_I(sbi);
-	unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num;
+	unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num, flags;
 	block_t start_blk;
 	unsigned int data_sum_blocks, orphan_blocks;
 	__u32 crc32 = 0;
@@ -1132,12 +1133,12 @@ static int do_checkpoint(struct f2fs_sb_
 
 	/* 2 cp  + n data seg summary + orphan inode blocks */
 	data_sum_blocks = npages_for_summary_flush(sbi, false);
-	spin_lock(&sbi->cp_lock);
+	spin_lock_irqsave(&sbi->cp_lock, flags);
 	if (data_sum_blocks < NR_CURSEG_DATA_TYPE)
 		__set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
 	else
 		__clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
-	spin_unlock(&sbi->cp_lock);
+	spin_unlock_irqrestore(&sbi->cp_lock, flags);
 
 	orphan_blocks = GET_ORPHAN_BLOCKS(orphan_num);
 	ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks +
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/f2fs.h linux-libre-4.12.4-gnu/fs/f2fs/f2fs.h
--- linux-libre-4.12.3-gnu/fs/f2fs/f2fs.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/f2fs.h	2017-07-27 18:10:39.000000000 -0400
@@ -1228,9 +1228,11 @@ static inline void __set_ckpt_flags(stru
 
 static inline void set_ckpt_flags(struct f2fs_sb_info *sbi, unsigned int f)
 {
-	spin_lock(&sbi->cp_lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sbi->cp_lock, flags);
 	__set_ckpt_flags(F2FS_CKPT(sbi), f);
-	spin_unlock(&sbi->cp_lock);
+	spin_unlock_irqrestore(&sbi->cp_lock, flags);
 }
 
 static inline void __clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
@@ -1244,22 +1246,26 @@ static inline void __clear_ckpt_flags(st
 
 static inline void clear_ckpt_flags(struct f2fs_sb_info *sbi, unsigned int f)
 {
-	spin_lock(&sbi->cp_lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sbi->cp_lock, flags);
 	__clear_ckpt_flags(F2FS_CKPT(sbi), f);
-	spin_unlock(&sbi->cp_lock);
+	spin_unlock_irqrestore(&sbi->cp_lock, flags);
 }
 
 static inline void disable_nat_bits(struct f2fs_sb_info *sbi, bool lock)
 {
+	unsigned long flags;
+
 	set_sbi_flag(sbi, SBI_NEED_FSCK);
 
 	if (lock)
-		spin_lock(&sbi->cp_lock);
+		spin_lock_irqsave(&sbi->cp_lock, flags);
 	__clear_ckpt_flags(F2FS_CKPT(sbi), CP_NAT_BITS_FLAG);
 	kfree(NM_I(sbi)->nat_bits);
 	NM_I(sbi)->nat_bits = NULL;
 	if (lock)
-		spin_unlock(&sbi->cp_lock);
+		spin_unlock_irqrestore(&sbi->cp_lock, flags);
 }
 
 static inline bool enabled_nat_bits(struct f2fs_sb_info *sbi,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/file.c linux-libre-4.12.4-gnu/fs/f2fs/file.c
--- linux-libre-4.12.3-gnu/fs/f2fs/file.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/file.c	2017-07-27 18:10:39.000000000 -0400
@@ -1493,6 +1493,7 @@ static int f2fs_ioc_setflags(struct file
 
 	inode->i_ctime = current_time(inode);
 	f2fs_set_inode_flags(inode);
+	f2fs_mark_inode_dirty_sync(inode, false);
 
 	inode_unlock(inode);
 out:
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/gc.c linux-libre-4.12.4-gnu/fs/f2fs/gc.c
--- linux-libre-4.12.3-gnu/fs/f2fs/gc.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/gc.c	2017-07-27 18:10:39.000000000 -0400
@@ -32,13 +32,14 @@ static int gc_thread_func(void *data)
 
 	wait_ms = gc_th->min_sleep_time;
 
+	set_freezable();
 	do {
+		wait_event_interruptible_timeout(*wq,
+				kthread_should_stop() || freezing(current),
+				msecs_to_jiffies(wait_ms));
+
 		if (try_to_freeze())
 			continue;
-		else
-			wait_event_interruptible_timeout(*wq,
-						kthread_should_stop(),
-						msecs_to_jiffies(wait_ms));
 		if (kthread_should_stop())
 			break;
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/inode.c linux-libre-4.12.4-gnu/fs/f2fs/inode.c
--- linux-libre-4.12.3-gnu/fs/f2fs/inode.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/inode.c	2017-07-27 18:10:39.000000000 -0400
@@ -44,7 +44,6 @@ void f2fs_set_inode_flags(struct inode *
 		new_fl |= S_DIRSYNC;
 	inode_set_flags(inode, new_fl,
 			S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
-	f2fs_mark_inode_dirty_sync(inode, false);
 }
 
 static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
@@ -226,6 +225,7 @@ make_now:
 		ret = -EIO;
 		goto bad_inode;
 	}
+	f2fs_set_inode_flags(inode);
 	unlock_new_inode(inode);
 	trace_f2fs_iget(inode);
 	return inode;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/segment.c linux-libre-4.12.4-gnu/fs/f2fs/segment.c
--- linux-libre-4.12.3-gnu/fs/f2fs/segment.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/segment.c	2017-07-27 18:10:39.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/kthread.h>
 #include <linux/swap.h>
 #include <linux/timer.h>
+#include <linux/freezer.h>
 
 #include "f2fs.h"
 #include "segment.h"
@@ -751,7 +752,7 @@ static void f2fs_submit_discard_endio(st
 
 	dc->error = bio->bi_error;
 	dc->state = D_DONE;
-	complete(&dc->wait);
+	complete_all(&dc->wait);
 	bio_put(bio);
 }
 
@@ -1060,18 +1061,24 @@ static int issue_discard_thread(void *da
 	struct f2fs_sb_info *sbi = data;
 	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
 	wait_queue_head_t *q = &dcc->discard_wait_queue;
-repeat:
-	if (kthread_should_stop())
-		return 0;
 
-	__issue_discard_cmd(sbi, true);
-	__wait_discard_cmd(sbi, true);
+	set_freezable();
 
-	congestion_wait(BLK_RW_SYNC, HZ/50);
+	do {
+		wait_event_interruptible(*q, kthread_should_stop() ||
+					freezing(current) ||
+					atomic_read(&dcc->discard_cmd_cnt));
+		if (try_to_freeze())
+			continue;
+		if (kthread_should_stop())
+			return 0;
 
-	wait_event_interruptible(*q, kthread_should_stop() ||
-				atomic_read(&dcc->discard_cmd_cnt));
-	goto repeat;
+		__issue_discard_cmd(sbi, true);
+		__wait_discard_cmd(sbi, true);
+
+		congestion_wait(BLK_RW_SYNC, HZ/50);
+	} while (!kthread_should_stop());
+	return 0;
 }
 
 #ifdef CONFIG_BLK_DEV_ZONED
@@ -1322,7 +1329,8 @@ find_next:
 					sbi->blocks_per_seg, cur_pos);
 			len = next_pos - cur_pos;
 
-			if (force && len < cpc->trim_minlen)
+			if (f2fs_sb_mounted_blkzoned(sbi->sb) ||
+			    (force && len < cpc->trim_minlen))
 				goto skip;
 
 			f2fs_issue_discard(sbi, entry->start_blkaddr + cur_pos,
@@ -2455,6 +2463,8 @@ static int read_normal_summaries(struct
 
 static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 {
+	struct f2fs_journal *sit_j = CURSEG_I(sbi, CURSEG_COLD_DATA)->journal;
+	struct f2fs_journal *nat_j = CURSEG_I(sbi, CURSEG_HOT_DATA)->journal;
 	int type = CURSEG_HOT_DATA;
 	int err;
 
@@ -2481,6 +2491,11 @@ static int restore_curseg_summaries(stru
 			return err;
 	}
 
+	/* sanity check for summary blocks */
+	if (nats_in_cursum(nat_j) > NAT_JOURNAL_ENTRIES ||
+			sits_in_cursum(sit_j) > SIT_JOURNAL_ENTRIES)
+		return -EINVAL;
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/f2fs/super.c linux-libre-4.12.4-gnu/fs/f2fs/super.c
--- linux-libre-4.12.3-gnu/fs/f2fs/super.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/f2fs/super.c	2017-07-27 18:10:39.000000000 -0400
@@ -1521,6 +1521,8 @@ int sanity_check_ckpt(struct f2fs_sb_inf
 	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
 	unsigned int ovp_segments, reserved_segments;
+	unsigned int main_segs, blocks_per_seg;
+	int i;
 
 	total = le32_to_cpu(raw_super->segment_count);
 	fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
@@ -1542,6 +1544,20 @@ int sanity_check_ckpt(struct f2fs_sb_inf
 		return 1;
 	}
 
+	main_segs = le32_to_cpu(raw_super->segment_count_main);
+	blocks_per_seg = sbi->blocks_per_seg;
+
+	for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
+		if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs ||
+			le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg)
+			return 1;
+	}
+	for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) {
+		if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs ||
+			le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg)
+			return 1;
+	}
+
 	if (unlikely(f2fs_cp_error(sbi))) {
 		f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck");
 		return 1;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/fs-writeback.c linux-libre-4.12.4-gnu/fs/fs-writeback.c
--- linux-libre-4.12.3-gnu/fs/fs-writeback.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/fs-writeback.c	2017-07-27 18:10:39.000000000 -0400
@@ -380,8 +380,8 @@ static void inode_switch_wbs_work_fn(str
 		struct page *page = radix_tree_deref_slot_protected(slot,
 							&mapping->tree_lock);
 		if (likely(page) && PageDirty(page)) {
-			__dec_wb_stat(old_wb, WB_RECLAIMABLE);
-			__inc_wb_stat(new_wb, WB_RECLAIMABLE);
+			dec_wb_stat(old_wb, WB_RECLAIMABLE);
+			inc_wb_stat(new_wb, WB_RECLAIMABLE);
 		}
 	}
 
@@ -391,8 +391,8 @@ static void inode_switch_wbs_work_fn(str
 							&mapping->tree_lock);
 		if (likely(page)) {
 			WARN_ON_ONCE(!PageWriteback(page));
-			__dec_wb_stat(old_wb, WB_WRITEBACK);
-			__inc_wb_stat(new_wb, WB_WRITEBACK);
+			dec_wb_stat(old_wb, WB_WRITEBACK);
+			inc_wb_stat(new_wb, WB_WRITEBACK);
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/hfsplus/posix_acl.c linux-libre-4.12.4-gnu/fs/hfsplus/posix_acl.c
--- linux-libre-4.12.3-gnu/fs/hfsplus/posix_acl.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/hfsplus/posix_acl.c	2017-07-27 18:10:39.000000000 -0400
@@ -51,8 +51,8 @@ struct posix_acl *hfsplus_get_posix_acl(
 	return acl;
 }
 
-int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
-		int type)
+static int __hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
+				   int type)
 {
 	int err;
 	char *xattr_name;
@@ -64,12 +64,6 @@ int hfsplus_set_posix_acl(struct inode *
 	switch (type) {
 	case ACL_TYPE_ACCESS:
 		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
-		if (acl) {
-			err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
-			if (err)
-				return err;
-		}
-		err = 0;
 		break;
 
 	case ACL_TYPE_DEFAULT:
@@ -105,6 +99,18 @@ end_set_acl:
 	return err;
 }
 
+int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+	int err;
+
+	if (type == ACL_TYPE_ACCESS && acl) {
+		err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+		if (err)
+			return err;
+	}
+	return __hfsplus_set_posix_acl(inode, acl, type);
+}
+
 int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
 {
 	int err = 0;
@@ -122,15 +128,15 @@ int hfsplus_init_posix_acl(struct inode
 		return err;
 
 	if (default_acl) {
-		err = hfsplus_set_posix_acl(inode, default_acl,
-					    ACL_TYPE_DEFAULT);
+		err = __hfsplus_set_posix_acl(inode, default_acl,
+					      ACL_TYPE_DEFAULT);
 		posix_acl_release(default_acl);
 	}
 
 	if (acl) {
 		if (!err)
-			err = hfsplus_set_posix_acl(inode, acl,
-						    ACL_TYPE_ACCESS);
+			err = __hfsplus_set_posix_acl(inode, acl,
+						      ACL_TYPE_ACCESS);
 		posix_acl_release(acl);
 	}
 	return err;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/nfs/dir.c linux-libre-4.12.4-gnu/fs/nfs/dir.c
--- linux-libre-4.12.3-gnu/fs/nfs/dir.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/nfs/dir.c	2017-07-27 18:10:39.000000000 -0400
@@ -1115,11 +1115,13 @@ static int nfs_lookup_revalidate(struct
 	/* Force a full look up iff the parent directory has changed */
 	if (!nfs_is_exclusive_create(dir, flags) &&
 	    nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU)) {
-
-		if (nfs_lookup_verify_inode(inode, flags)) {
+		error = nfs_lookup_verify_inode(inode, flags);
+		if (error) {
 			if (flags & LOOKUP_RCU)
 				return -ECHILD;
-			goto out_zap_parent;
+			if (error == -ESTALE)
+				goto out_zap_parent;
+			goto out_error;
 		}
 		nfs_advise_use_readdirplus(dir);
 		goto out_valid;
@@ -1144,8 +1146,10 @@ static int nfs_lookup_revalidate(struct
 	trace_nfs_lookup_revalidate_enter(dir, dentry, flags);
 	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
 	trace_nfs_lookup_revalidate_exit(dir, dentry, flags, error);
-	if (error)
+	if (error == -ESTALE || error == -ENOENT)
 		goto out_bad;
+	if (error)
+		goto out_error;
 	if (nfs_compare_fh(NFS_FH(inode), fhandle))
 		goto out_bad;
 	if ((error = nfs_refresh_inode(inode, fattr)) != 0)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/nfs/filelayout/filelayout.c linux-libre-4.12.4-gnu/fs/nfs/filelayout/filelayout.c
--- linux-libre-4.12.3-gnu/fs/nfs/filelayout/filelayout.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/nfs/filelayout/filelayout.c	2017-07-27 18:10:39.000000000 -0400
@@ -172,6 +172,7 @@ static int filelayout_async_handle_error
 	case -NFS4ERR_RETRY_UNCACHED_REP:
 		break;
 	/* Invalidate Layout errors */
+	case -NFS4ERR_ACCESS:
 	case -NFS4ERR_PNFS_NO_LAYOUT:
 	case -ESTALE:           /* mapped NFS4ERR_STALE */
 	case -EBADHANDLE:       /* mapped NFS4ERR_BADHANDLE */
@@ -202,10 +203,10 @@ static int filelayout_async_handle_error
 			task->tk_status);
 		nfs4_mark_deviceid_unavailable(devid);
 		pnfs_error_mark_layout_for_return(inode, lseg);
+		pnfs_set_lo_fail(lseg);
 		rpc_wake_up(&tbl->slot_tbl_waitq);
 		/* fall through */
 	default:
-		pnfs_set_lo_fail(lseg);
 reset:
 		dprintk("%s Retry through MDS. Error %d\n", __func__,
 			task->tk_status);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/nfs/inode.c linux-libre-4.12.4-gnu/fs/nfs/inode.c
--- linux-libre-4.12.3-gnu/fs/nfs/inode.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/nfs/inode.c	2017-07-27 18:10:39.000000000 -0400
@@ -1315,9 +1315,9 @@ static int nfs_check_inode_attributes(st
 		return 0;
 	/* Has the inode gone and changed behind our back? */
 	if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
-		return -EIO;
+		return -ESTALE;
 	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
-		return -EIO;
+		return -ESTALE;
 
 	if (!nfs_file_has_buffered_writers(nfsi)) {
 		/* Verify a few of the more important attributes */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/nfs/pagelist.c linux-libre-4.12.4-gnu/fs/nfs/pagelist.c
--- linux-libre-4.12.3-gnu/fs/nfs/pagelist.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/nfs/pagelist.c	2017-07-27 18:10:39.000000000 -0400
@@ -779,6 +779,7 @@ int nfs_generic_pgio(struct nfs_pageio_d
 	gfp_t gfp_flags = GFP_KERNEL;
 
 	pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count);
+	pg_array->npages = pagecount;
 
 	if (pagecount <= ARRAY_SIZE(pg_array->page_array))
 		pg_array->pagevec = pg_array->page_array;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/overlayfs/dir.c linux-libre-4.12.4-gnu/fs/overlayfs/dir.c
--- linux-libre-4.12.3-gnu/fs/overlayfs/dir.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/overlayfs/dir.c	2017-07-27 18:10:39.000000000 -0400
@@ -478,17 +478,30 @@ out_cleanup:
 }
 
 static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
-			      struct cattr *attr, struct dentry *hardlink)
+			      struct cattr *attr, struct dentry *hardlink,
+			      bool origin)
 {
 	int err;
 	const struct cred *old_cred;
 	struct cred *override_cred;
+	struct dentry *parent = dentry->d_parent;
 
-	err = ovl_copy_up(dentry->d_parent);
+	err = ovl_copy_up(parent);
 	if (err)
 		return err;
 
 	old_cred = ovl_override_creds(dentry->d_sb);
+
+	/*
+	 * When linking a file with copy up origin into a new parent, mark the
+	 * new parent dir "impure".
+	 */
+	if (origin) {
+		err = ovl_set_impure(parent, ovl_dentry_upper(parent));
+		if (err)
+			goto out_revert_creds;
+	}
+
 	err = -ENOMEM;
 	override_cred = prepare_creds();
 	if (override_cred) {
@@ -547,7 +560,7 @@ static int ovl_create_object(struct dent
 	inode_init_owner(inode, dentry->d_parent->d_inode, mode);
 	attr.mode = inode->i_mode;
 
-	err = ovl_create_or_link(dentry, inode, &attr, NULL);
+	err = ovl_create_or_link(dentry, inode, &attr, NULL, false);
 	if (err)
 		iput(inode);
 
@@ -601,7 +614,8 @@ static int ovl_link(struct dentry *old,
 	inode = d_inode(old);
 	ihold(inode);
 
-	err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old));
+	err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old),
+				 ovl_type_origin(old));
 	if (err)
 		iput(inode);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/overlayfs/super.c linux-libre-4.12.4-gnu/fs/overlayfs/super.c
--- linux-libre-4.12.3-gnu/fs/overlayfs/super.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/overlayfs/super.c	2017-07-27 18:10:39.000000000 -0400
@@ -946,6 +946,7 @@ static int ovl_fill_super(struct super_b
 	else
 		sb->s_d_op = &ovl_dentry_operations;
 
+	err = -ENOMEM;
 	ufs->creator_cred = cred = prepare_creds();
 	if (!cred)
 		goto out_put_lower_mnt;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/pstore/platform.c linux-libre-4.12.4-gnu/fs/pstore/platform.c
--- linux-libre-4.12.3-gnu/fs/pstore/platform.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/pstore/platform.c	2017-07-27 18:10:39.000000000 -0400
@@ -770,8 +770,11 @@ static void decompress_record(struct pst
 	int unzipped_len;
 	char *decompressed;
 
+	if (!record->compressed)
+		return;
+
 	/* Only PSTORE_TYPE_DMESG support compression. */
-	if (!record->compressed || record->type != PSTORE_TYPE_DMESG) {
+	if (record->type != PSTORE_TYPE_DMESG) {
 		pr_warn("ignored compressed record type %d\n", record->type);
 		return;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/reiserfs/xattr_acl.c linux-libre-4.12.4-gnu/fs/reiserfs/xattr_acl.c
--- linux-libre-4.12.3-gnu/fs/reiserfs/xattr_acl.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/reiserfs/xattr_acl.c	2017-07-27 18:10:39.000000000 -0400
@@ -37,7 +37,14 @@ reiserfs_set_acl(struct inode *inode, st
 	error = journal_begin(&th, inode->i_sb, jcreate_blocks);
 	reiserfs_write_unlock(inode->i_sb);
 	if (error == 0) {
+		if (type == ACL_TYPE_ACCESS && acl) {
+			error = posix_acl_update_mode(inode, &inode->i_mode,
+						      &acl);
+			if (error)
+				goto unlock;
+		}
 		error = __reiserfs_set_acl(&th, inode, type, acl);
+unlock:
 		reiserfs_write_lock(inode->i_sb);
 		error2 = journal_end(&th);
 		reiserfs_write_unlock(inode->i_sb);
@@ -241,11 +248,6 @@ __reiserfs_set_acl(struct reiserfs_trans
 	switch (type) {
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
-		if (acl) {
-			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
-			if (error)
-				return error;
-		}
 		break;
 	case ACL_TYPE_DEFAULT:
 		name = XATTR_NAME_POSIX_ACL_DEFAULT;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ubifs/dir.c linux-libre-4.12.4-gnu/fs/ubifs/dir.c
--- linux-libre-4.12.3-gnu/fs/ubifs/dir.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ubifs/dir.c	2017-07-27 18:10:39.000000000 -0400
@@ -143,6 +143,7 @@ struct inode *ubifs_new_inode(struct ubi
 	case S_IFBLK:
 	case S_IFCHR:
 		inode->i_op  = &ubifs_file_inode_operations;
+		encrypted = false;
 		break;
 	default:
 		BUG();
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ubifs/journal.c linux-libre-4.12.4-gnu/fs/ubifs/journal.c
--- linux-libre-4.12.3-gnu/fs/ubifs/journal.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ubifs/journal.c	2017-07-27 18:10:39.000000000 -0400
@@ -574,7 +574,7 @@ int ubifs_jnl_update(struct ubifs_info *
 	/* Make sure to also account for extended attributes */
 	len += host_ui->data_len;
 
-	dent = kmalloc(len, GFP_NOFS);
+	dent = kzalloc(len, GFP_NOFS);
 	if (!dent)
 		return -ENOMEM;
 
@@ -967,7 +967,7 @@ int ubifs_jnl_xrename(struct ubifs_info
 	if (twoparents)
 		len += plen;
 
-	dent1 = kmalloc(len, GFP_NOFS);
+	dent1 = kzalloc(len, GFP_NOFS);
 	if (!dent1)
 		return -ENOMEM;
 
@@ -984,6 +984,7 @@ int ubifs_jnl_xrename(struct ubifs_info
 	dent1->nlen = cpu_to_le16(fname_len(snd_nm));
 	memcpy(dent1->name, fname_name(snd_nm), fname_len(snd_nm));
 	dent1->name[fname_len(snd_nm)] = '\0';
+	set_dent_cookie(c, dent1);
 	zero_dent_node_unused(dent1);
 	ubifs_prep_grp_node(c, dent1, dlen1, 0);
 
@@ -996,6 +997,7 @@ int ubifs_jnl_xrename(struct ubifs_info
 	dent2->nlen = cpu_to_le16(fname_len(fst_nm));
 	memcpy(dent2->name, fname_name(fst_nm), fname_len(fst_nm));
 	dent2->name[fname_len(fst_nm)] = '\0';
+	set_dent_cookie(c, dent2);
 	zero_dent_node_unused(dent2);
 	ubifs_prep_grp_node(c, dent2, dlen2, 0);
 
@@ -1117,7 +1119,7 @@ int ubifs_jnl_rename(struct ubifs_info *
 	len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8);
 	if (move)
 		len += plen;
-	dent = kmalloc(len, GFP_NOFS);
+	dent = kzalloc(len, GFP_NOFS);
 	if (!dent)
 		return -ENOMEM;
 
@@ -1500,7 +1502,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_
 	hlen = host_ui->data_len + UBIFS_INO_NODE_SZ;
 	len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8);
 
-	xent = kmalloc(len, GFP_NOFS);
+	xent = kzalloc(len, GFP_NOFS);
 	if (!xent)
 		return -ENOMEM;
 
@@ -1607,7 +1609,7 @@ int ubifs_jnl_change_xattr(struct ubifs_
 	aligned_len1 = ALIGN(len1, 8);
 	aligned_len = aligned_len1 + ALIGN(len2, 8);
 
-	ino = kmalloc(aligned_len, GFP_NOFS);
+	ino = kzalloc(aligned_len, GFP_NOFS);
 	if (!ino)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ubifs/tnc.c linux-libre-4.12.4-gnu/fs/ubifs/tnc.c
--- linux-libre-4.12.3-gnu/fs/ubifs/tnc.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ubifs/tnc.c	2017-07-27 18:10:39.000000000 -0400
@@ -2802,6 +2802,8 @@ int ubifs_tnc_remove_ino(struct ubifs_in
 		dbg_tnc("xent '%s', ino %lu", xent->name,
 			(unsigned long)xattr_inum);
 
+		ubifs_evict_xattr_inode(c, xattr_inum);
+
 		fname_name(&nm) = xent->name;
 		fname_len(&nm) = le16_to_cpu(xent->nlen);
 		err = ubifs_tnc_remove_nm(c, &key1, &nm);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ubifs/ubifs.h linux-libre-4.12.4-gnu/fs/ubifs/ubifs.h
--- linux-libre-4.12.3-gnu/fs/ubifs/ubifs.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ubifs/ubifs.h	2017-07-27 18:10:39.000000000 -0400
@@ -1757,6 +1757,7 @@ int ubifs_xattr_set(struct inode *host,
 		    size_t size, int flags);
 ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
 			size_t size);
+void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum);
 
 #ifdef CONFIG_UBIFS_FS_SECURITY
 extern int ubifs_init_security(struct inode *dentry, struct inode *inode,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/ubifs/xattr.c linux-libre-4.12.4-gnu/fs/ubifs/xattr.c
--- linux-libre-4.12.3-gnu/fs/ubifs/xattr.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/ubifs/xattr.c	2017-07-27 18:10:39.000000000 -0400
@@ -513,6 +513,28 @@ out_cancel:
 	return err;
 }
 
+/**
+ * ubifs_evict_xattr_inode - Evict an xattr inode.
+ * @c: UBIFS file-system description object
+ * @xattr_inum: xattr inode number
+ *
+ * When an inode that hosts xattrs is being removed we have to make sure
+ * that cached inodes of the xattrs also get removed from the inode cache
+ * otherwise we'd waste memory. This function looks up an inode from the
+ * inode cache and clears the link counter such that iput() will evict
+ * the inode.
+ */
+void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum)
+{
+	struct inode *inode;
+
+	inode = ilookup(c->vfs_sb, xattr_inum);
+	if (inode) {
+		clear_nlink(inode);
+		iput(inode);
+	}
+}
+
 static int ubifs_xattr_remove(struct inode *host, const char *name)
 {
 	struct inode *inode;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/udf/file.c linux-libre-4.12.4-gnu/fs/udf/file.c
--- linux-libre-4.12.3-gnu/fs/udf/file.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/udf/file.c	2017-07-27 18:10:39.000000000 -0400
@@ -43,10 +43,15 @@ static void __udf_adinicb_readpage(struc
 	struct inode *inode = page->mapping->host;
 	char *kaddr;
 	struct udf_inode_info *iinfo = UDF_I(inode);
+	loff_t isize = i_size_read(inode);
 
+	/*
+	 * We have to be careful here as truncate can change i_size under us.
+	 * So just sample it once and use the same value everywhere.
+	 */
 	kaddr = kmap_atomic(page);
-	memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size);
-	memset(kaddr + inode->i_size, 0, PAGE_SIZE - inode->i_size);
+	memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, isize);
+	memset(kaddr + isize, 0, PAGE_SIZE - isize);
 	flush_dcache_page(page);
 	SetPageUptodate(page);
 	kunmap_atomic(kaddr);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/udf/inode.c linux-libre-4.12.4-gnu/fs/udf/inode.c
--- linux-libre-4.12.3-gnu/fs/udf/inode.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/udf/inode.c	2017-07-27 18:10:39.000000000 -0400
@@ -1222,8 +1222,8 @@ int udf_setsize(struct inode *inode, lof
 			return err;
 		}
 set_size:
-		truncate_setsize(inode, newsize);
 		up_write(&iinfo->i_data_sem);
+		truncate_setsize(inode, newsize);
 	} else {
 		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
 			down_write(&iinfo->i_data_sem);
@@ -1240,9 +1240,9 @@ set_size:
 					  udf_get_block);
 		if (err)
 			return err;
+		truncate_setsize(inode, newsize);
 		down_write(&iinfo->i_data_sem);
 		udf_clear_extent_cache(inode);
-		truncate_setsize(inode, newsize);
 		udf_truncate_extents(inode);
 		up_write(&iinfo->i_data_sem);
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/xfs/xfs_acl.c linux-libre-4.12.4-gnu/fs/xfs/xfs_acl.c
--- linux-libre-4.12.3-gnu/fs/xfs/xfs_acl.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/xfs/xfs_acl.c	2017-07-27 18:10:39.000000000 -0400
@@ -170,8 +170,8 @@ xfs_get_acl(struct inode *inode, int typ
 	return acl;
 }
 
-STATIC int
-__xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+int
+__xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
 	struct xfs_inode *ip = XFS_I(inode);
 	unsigned char *ea_name;
@@ -268,5 +268,5 @@ xfs_set_acl(struct inode *inode, struct
 	}
 
  set_acl:
-	return __xfs_set_acl(inode, type, acl);
+	return __xfs_set_acl(inode, acl, type);
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/xfs/xfs_acl.h linux-libre-4.12.4-gnu/fs/xfs/xfs_acl.h
--- linux-libre-4.12.3-gnu/fs/xfs/xfs_acl.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/xfs/xfs_acl.h	2017-07-27 18:10:39.000000000 -0400
@@ -24,6 +24,7 @@ struct posix_acl;
 #ifdef CONFIG_XFS_POSIX_ACL
 extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
 extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+extern int __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
 #else
 static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
 {
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/xfs/xfs_iops.c linux-libre-4.12.4-gnu/fs/xfs/xfs_iops.c
--- linux-libre-4.12.3-gnu/fs/xfs/xfs_iops.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/xfs/xfs_iops.c	2017-07-27 18:10:39.000000000 -0400
@@ -190,12 +190,12 @@ xfs_generic_create(
 
 #ifdef CONFIG_XFS_POSIX_ACL
 	if (default_acl) {
-		error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+		error = __xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
 		if (error)
 			goto out_cleanup_inode;
 	}
 	if (acl) {
-		error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS);
+		error = __xfs_set_acl(inode, acl, ACL_TYPE_ACCESS);
 		if (error)
 			goto out_cleanup_inode;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/fs/xfs/xfs_mount.c linux-libre-4.12.4-gnu/fs/xfs/xfs_mount.c
--- linux-libre-4.12.3-gnu/fs/xfs/xfs_mount.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/fs/xfs/xfs_mount.c	2017-07-27 18:10:39.000000000 -0400
@@ -1209,7 +1209,7 @@ xfs_mod_icount(
 	struct xfs_mount	*mp,
 	int64_t			delta)
 {
-	__percpu_counter_add(&mp->m_icount, delta, XFS_ICOUNT_BATCH);
+	percpu_counter_add_batch(&mp->m_icount, delta, XFS_ICOUNT_BATCH);
 	if (__percpu_counter_compare(&mp->m_icount, 0, XFS_ICOUNT_BATCH) < 0) {
 		ASSERT(0);
 		percpu_counter_add(&mp->m_icount, -delta);
@@ -1288,7 +1288,7 @@ xfs_mod_fdblocks(
 	else
 		batch = XFS_FDBLOCKS_BATCH;
 
-	__percpu_counter_add(&mp->m_fdblocks, delta, batch);
+	percpu_counter_add_batch(&mp->m_fdblocks, delta, batch);
 	if (__percpu_counter_compare(&mp->m_fdblocks, mp->m_alloc_set_aside,
 				     XFS_FDBLOCKS_BATCH) >= 0) {
 		/* we had space! */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/backing-dev.h linux-libre-4.12.4-gnu/include/linux/backing-dev.h
--- linux-libre-4.12.3-gnu/include/linux/backing-dev.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/backing-dev.h	2017-07-27 18:10:39.000000000 -0400
@@ -66,37 +66,17 @@ static inline bool bdi_has_dirty_io(stru
 static inline void __add_wb_stat(struct bdi_writeback *wb,
 				 enum wb_stat_item item, s64 amount)
 {
-	__percpu_counter_add(&wb->stat[item], amount, WB_STAT_BATCH);
-}
-
-static inline void __inc_wb_stat(struct bdi_writeback *wb,
-				 enum wb_stat_item item)
-{
-	__add_wb_stat(wb, item, 1);
+	percpu_counter_add_batch(&wb->stat[item], amount, WB_STAT_BATCH);
 }
 
 static inline void inc_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
 {
-	unsigned long flags;
-
-	local_irq_save(flags);
-	__inc_wb_stat(wb, item);
-	local_irq_restore(flags);
-}
-
-static inline void __dec_wb_stat(struct bdi_writeback *wb,
-				 enum wb_stat_item item)
-{
-	__add_wb_stat(wb, item, -1);
+	__add_wb_stat(wb, item, 1);
 }
 
 static inline void dec_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
 {
-	unsigned long flags;
-
-	local_irq_save(flags);
-	__dec_wb_stat(wb, item);
-	local_irq_restore(flags);
+	__add_wb_stat(wb, item, -1);
 }
 
 static inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/blk-cgroup.h linux-libre-4.12.4-gnu/include/linux/blk-cgroup.h
--- linux-libre-4.12.3-gnu/include/linux/blk-cgroup.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/blk-cgroup.h	2017-07-27 18:10:39.000000000 -0400
@@ -518,7 +518,7 @@ static inline void blkg_stat_exit(struct
  */
 static inline void blkg_stat_add(struct blkg_stat *stat, uint64_t val)
 {
-	__percpu_counter_add(&stat->cpu_cnt, val, BLKG_STAT_CPU_BATCH);
+	percpu_counter_add_batch(&stat->cpu_cnt, val, BLKG_STAT_CPU_BATCH);
 }
 
 /**
@@ -597,14 +597,14 @@ static inline void blkg_rwstat_add(struc
 	else
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_READ];
 
-	__percpu_counter_add(cnt, val, BLKG_STAT_CPU_BATCH);
+	percpu_counter_add_batch(cnt, val, BLKG_STAT_CPU_BATCH);
 
 	if (op_is_sync(op))
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_SYNC];
 	else
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_ASYNC];
 
-	__percpu_counter_add(cnt, val, BLKG_STAT_CPU_BATCH);
+	percpu_counter_add_batch(cnt, val, BLKG_STAT_CPU_BATCH);
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/init_task.h linux-libre-4.12.4-gnu/include/linux/init_task.h
--- linux-libre-4.12.3-gnu/include/linux/init_task.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/init_task.h	2017-07-27 18:10:39.000000000 -0400
@@ -170,9 +170,9 @@ extern struct cred init_cred;
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
 # define INIT_VTIME(tsk)						\
-	.vtime_seqcount = SEQCNT_ZERO(tsk.vtime_seqcount),	\
-	.vtime_snap = 0,				\
-	.vtime_snap_whence = VTIME_SYS,
+	.vtime.seqcount = SEQCNT_ZERO(tsk.vtime.seqcount),		\
+	.vtime.starttime = 0,						\
+	.vtime.state = VTIME_SYS,
 #else
 # define INIT_VTIME(tsk)
 #endif
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/interrupt.h linux-libre-4.12.4-gnu/include/linux/interrupt.h
--- linux-libre-4.12.3-gnu/include/linux/interrupt.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/interrupt.h	2017-07-27 18:10:39.000000000 -0400
@@ -291,7 +291,7 @@ extern int
 irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
 
 struct cpumask *irq_create_affinity_masks(int nvec, const struct irq_affinity *affd);
-int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd);
+int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd);
 
 #else /* CONFIG_SMP */
 
@@ -331,7 +331,7 @@ irq_create_affinity_masks(int nvec, cons
 }
 
 static inline int
-irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
+irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd)
 {
 	return maxvec;
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/mman.h linux-libre-4.12.4-gnu/include/linux/mman.h
--- linux-libre-4.12.3-gnu/include/linux/mman.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/mman.h	2017-07-27 18:10:39.000000000 -0400
@@ -22,7 +22,7 @@ unsigned long vm_memory_committed(void);
 
 static inline void vm_acct_memory(long pages)
 {
-	__percpu_counter_add(&vm_committed_as, pages, vm_committed_as_batch);
+	percpu_counter_add_batch(&vm_committed_as, pages, vm_committed_as_batch);
 }
 
 static inline void vm_unacct_memory(long pages)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/percpu_counter.h linux-libre-4.12.4-gnu/include/linux/percpu_counter.h
--- linux-libre-4.12.3-gnu/include/linux/percpu_counter.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/percpu_counter.h	2017-07-27 18:10:39.000000000 -0400
@@ -39,7 +39,8 @@ int __percpu_counter_init(struct percpu_
 
 void percpu_counter_destroy(struct percpu_counter *fbc);
 void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
-void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
+void percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount,
+			      s32 batch);
 s64 __percpu_counter_sum(struct percpu_counter *fbc);
 int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch);
 
@@ -50,7 +51,7 @@ static inline int percpu_counter_compare
 
 static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
 {
-	__percpu_counter_add(fbc, amount, percpu_counter_batch);
+	percpu_counter_add_batch(fbc, amount, percpu_counter_batch);
 }
 
 static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
@@ -136,7 +137,7 @@ percpu_counter_add(struct percpu_counter
 }
 
 static inline void
-__percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
+percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount, s32 batch)
 {
 	percpu_counter_add(fbc, amount);
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/sched.h linux-libre-4.12.4-gnu/include/linux/sched.h
--- linux-libre-4.12.3-gnu/include/linux/sched.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/sched.h	2017-07-27 18:10:39.000000000 -0400
@@ -223,6 +223,24 @@ struct task_cputime {
 #define prof_exp			stime
 #define sched_exp			sum_exec_runtime
 
+enum vtime_state {
+	/* Task is sleeping or running in a CPU with VTIME inactive: */
+	VTIME_INACTIVE = 0,
+	/* Task runs in userspace in a CPU with VTIME active: */
+	VTIME_USER,
+	/* Task runs in kernelspace in a CPU with VTIME active: */
+	VTIME_SYS,
+};
+
+struct vtime {
+	seqcount_t		seqcount;
+	unsigned long long	starttime;
+	enum vtime_state	state;
+	u64			utime;
+	u64			stime;
+	u64			gtime;
+};
+
 struct sched_info {
 #ifdef CONFIG_SCHED_INFO
 	/* Cumulative counters: */
@@ -670,16 +688,7 @@ struct task_struct {
 	u64				gtime;
 	struct prev_cputime		prev_cputime;
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
-	seqcount_t			vtime_seqcount;
-	unsigned long long		vtime_snap;
-	enum {
-		/* Task is sleeping or running in a CPU with VTIME inactive: */
-		VTIME_INACTIVE = 0,
-		/* Task runs in userspace in a CPU with VTIME active: */
-		VTIME_USER,
-		/* Task runs in kernelspace in a CPU with VTIME active: */
-		VTIME_SYS,
-	} vtime_snap_whence;
+	struct vtime			vtime;
 #endif
 
 #ifdef CONFIG_NO_HZ_FULL
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/vfio.h linux-libre-4.12.4-gnu/include/linux/vfio.h
--- linux-libre-4.12.3-gnu/include/linux/vfio.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/vfio.h	2017-07-27 18:10:39.000000000 -0400
@@ -97,6 +97,8 @@ extern void vfio_unregister_iommu_driver
  */
 extern struct vfio_group *vfio_group_get_external_user(struct file *filep);
 extern void vfio_group_put_external_user(struct vfio_group *group);
+extern bool vfio_external_group_match_file(struct vfio_group *group,
+					   struct file *filep);
 extern int vfio_external_user_iommu_id(struct vfio_group *group);
 extern long vfio_external_check_extension(struct vfio_group *group,
 					  unsigned long arg);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/linux/vtime.h linux-libre-4.12.4-gnu/include/linux/vtime.h
--- linux-libre-4.12.3-gnu/include/linux/vtime.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/linux/vtime.h	2017-07-27 18:10:39.000000000 -0400
@@ -67,19 +67,12 @@ static inline void vtime_account_system(
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
 extern void arch_vtime_task_switch(struct task_struct *tsk);
-extern void vtime_account_user(struct task_struct *tsk);
 extern void vtime_user_enter(struct task_struct *tsk);
-
-static inline void vtime_user_exit(struct task_struct *tsk)
-{
-	vtime_account_user(tsk);
-}
-
+extern void vtime_user_exit(struct task_struct *tsk);
 extern void vtime_guest_enter(struct task_struct *tsk);
 extern void vtime_guest_exit(struct task_struct *tsk);
 extern void vtime_init_idle(struct task_struct *tsk, int cpu);
 #else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN  */
-static inline void vtime_account_user(struct task_struct *tsk) { }
 static inline void vtime_user_enter(struct task_struct *tsk) { }
 static inline void vtime_user_exit(struct task_struct *tsk) { }
 static inline void vtime_guest_enter(struct task_struct *tsk) { }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/net/inet_frag.h linux-libre-4.12.4-gnu/include/net/inet_frag.h
--- linux-libre-4.12.3-gnu/include/net/inet_frag.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/net/inet_frag.h	2017-07-27 18:10:39.000000000 -0400
@@ -154,12 +154,12 @@ static inline int frag_mem_limit(struct
 
 static inline void sub_frag_mem_limit(struct netns_frags *nf, int i)
 {
-	__percpu_counter_add(&nf->mem, -i, frag_percpu_counter_batch);
+	percpu_counter_add_batch(&nf->mem, -i, frag_percpu_counter_batch);
 }
 
 static inline void add_frag_mem_limit(struct netns_frags *nf, int i)
 {
-	__percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch);
+	percpu_counter_add_batch(&nf->mem, i, frag_percpu_counter_batch);
 }
 
 static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/scsi/scsi_cmnd.h linux-libre-4.12.4-gnu/include/scsi/scsi_cmnd.h
--- linux-libre-4.12.3-gnu/include/scsi/scsi_cmnd.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/scsi/scsi_cmnd.h	2017-07-27 18:10:39.000000000 -0400
@@ -56,6 +56,7 @@ struct scsi_pointer {
 
 /* for scmd->flags */
 #define SCMD_TAGGED		(1 << 0)
+#define SCMD_UNCHECKED_ISA_DMA	(1 << 1)
 
 struct scsi_cmnd {
 	struct scsi_request req;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/scsi/scsi_device.h linux-libre-4.12.4-gnu/include/scsi/scsi_device.h
--- linux-libre-4.12.3-gnu/include/scsi/scsi_device.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/scsi/scsi_device.h	2017-07-27 18:10:39.000000000 -0400
@@ -248,6 +248,7 @@ enum scsi_target_state {
 	STARGET_CREATED = 1,
 	STARGET_RUNNING,
 	STARGET_REMOVE,
+	STARGET_CREATED_REMOVE,
 	STARGET_DEL,
 };
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/include/target/iscsi/iscsi_target_core.h linux-libre-4.12.4-gnu/include/target/iscsi/iscsi_target_core.h
--- linux-libre-4.12.3-gnu/include/target/iscsi/iscsi_target_core.h	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/include/target/iscsi/iscsi_target_core.h	2017-07-27 18:10:39.000000000 -0400
@@ -66,6 +66,14 @@ struct sock;
 #define TA_DEFAULT_FABRIC_PROT_TYPE	0
 /* TPG status needs to be enabled to return sendtargets discovery endpoint info */
 #define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1
+/*
+ * Used to control the sending of keys with optional to respond state bit,
+ * as a workaround for non RFC compliant initiators,that do not propose,
+ * nor respond to specific keys required for login to complete.
+ *
+ * See iscsi_check_proposer_for_optional_reply() for more details.
+ */
+#define TA_DEFAULT_LOGIN_KEYS_WORKAROUND 1
 
 #define ISCSI_IOV_DATA_BUFFER		5
 
@@ -769,6 +777,7 @@ struct iscsi_tpg_attrib {
 	u8			t10_pi;
 	u32			fabric_prot_type;
 	u32			tpg_enabled_sendtargets;
+	u32			login_keys_workaround;
 	struct iscsi_portal_group *tpg;
 };
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/cpu.c linux-libre-4.12.4-gnu/kernel/cpu.c
--- linux-libre-4.12.3-gnu/kernel/cpu.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/cpu.c	2017-07-27 18:10:39.000000000 -0400
@@ -346,11 +346,26 @@ EXPORT_SYMBOL_GPL(cpu_hotplug_enable);
 
 /* Notifier wrappers for transitioning to state machine */
 
+static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st);
+
 static int bringup_wait_for_ap(unsigned int cpu)
 {
 	struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
 
+	/* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */
 	wait_for_completion(&st->done);
+	if (WARN_ON_ONCE((!cpu_online(cpu))))
+		return -ECANCELED;
+
+	/* Unpark the stopper thread and the hotplug thread of the target cpu */
+	stop_machine_unpark(cpu);
+	kthread_unpark(st->thread);
+
+	/* Should we go further up ? */
+	if (st->target > CPUHP_AP_ONLINE_IDLE) {
+		__cpuhp_kick_ap_work(st);
+		wait_for_completion(&st->done);
+	}
 	return st->result;
 }
 
@@ -371,9 +386,7 @@ static int bringup_cpu(unsigned int cpu)
 	irq_unlock_sparse();
 	if (ret)
 		return ret;
-	ret = bringup_wait_for_ap(cpu);
-	BUG_ON(!cpu_online(cpu));
-	return ret;
+	return bringup_wait_for_ap(cpu);
 }
 
 /*
@@ -859,31 +872,20 @@ void notify_cpu_starting(unsigned int cp
 }
 
 /*
- * Called from the idle task. We need to set active here, so we can kick off
- * the stopper thread and unpark the smpboot threads. If the target state is
- * beyond CPUHP_AP_ONLINE_IDLE we kick cpuhp thread and let it bring up the
- * cpu further.
+ * Called from the idle task. Wake up the controlling task which brings the
+ * stopper and the hotplug thread of the upcoming CPU up and then delegates
+ * the rest of the online bringup to the hotplug thread.
  */
 void cpuhp_online_idle(enum cpuhp_state state)
 {
 	struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
-	unsigned int cpu = smp_processor_id();
 
 	/* Happens for the boot cpu */
 	if (state != CPUHP_AP_ONLINE_IDLE)
 		return;
 
 	st->state = CPUHP_AP_ONLINE_IDLE;
-
-	/* Unpark the stopper thread and the hotplug thread of this cpu */
-	stop_machine_unpark(cpu);
-	kthread_unpark(st->thread);
-
-	/* Should we go further up ? */
-	if (st->target > CPUHP_AP_ONLINE_IDLE)
-		__cpuhp_kick_ap_work(st);
-	else
-		complete(&st->done);
+	complete(&st->done);
 }
 
 /* Requires cpu_add_remove_lock to be held */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/events/core.c linux-libre-4.12.4-gnu/kernel/events/core.c
--- linux-libre-4.12.3-gnu/kernel/events/core.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/events/core.c	2017-07-27 18:10:39.000000000 -0400
@@ -1456,6 +1456,13 @@ static enum event_type_t get_event_type(
 
 	lockdep_assert_held(&ctx->lock);
 
+	/*
+	 * It's 'group type', really, because if our group leader is
+	 * pinned, so are we.
+	 */
+	if (event->group_leader != event)
+		event = event->group_leader;
+
 	event_type = event->attr.pinned ? EVENT_PINNED : EVENT_FLEXIBLE;
 	if (!ctx->task)
 		event_type |= EVENT_CPU;
@@ -7316,21 +7323,6 @@ int perf_event_account_interrupt(struct
 	return __perf_event_account_interrupt(event, 1);
 }
 
-static bool sample_is_allowed(struct perf_event *event, struct pt_regs *regs)
-{
-	/*
-	 * Due to interrupt latency (AKA "skid"), we may enter the
-	 * kernel before taking an overflow, even if the PMU is only
-	 * counting user events.
-	 * To avoid leaking information to userspace, we must always
-	 * reject kernel samples when exclude_kernel is set.
-	 */
-	if (event->attr.exclude_kernel && !user_mode(regs))
-		return false;
-
-	return true;
-}
-
 /*
  * Generic event overflow handling, sampling.
  */
@@ -7352,12 +7344,6 @@ static int __perf_event_overflow(struct
 	ret = __perf_event_account_interrupt(event, throttle);
 
 	/*
-	 * For security, drop the skid kernel samples if necessary.
-	 */
-	if (!sample_is_allowed(event, regs))
-		return ret;
-
-	/*
 	 * XXX event_limit might not quite work as expected on inherited
 	 * events
 	 */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/fork.c linux-libre-4.12.4-gnu/kernel/fork.c
--- linux-libre-4.12.3-gnu/kernel/fork.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/fork.c	2017-07-27 18:10:39.000000000 -0400
@@ -205,19 +205,17 @@ static unsigned long *alloc_thread_stack
 	void *stack;
 	int i;
 
-	local_irq_disable();
 	for (i = 0; i < NR_CACHED_STACKS; i++) {
-		struct vm_struct *s = this_cpu_read(cached_stacks[i]);
+		struct vm_struct *s;
+
+		s = this_cpu_xchg(cached_stacks[i], NULL);
 
 		if (!s)
 			continue;
-		this_cpu_write(cached_stacks[i], NULL);
 
 		tsk->stack_vm_area = s;
-		local_irq_enable();
 		return s->addr;
 	}
-	local_irq_enable();
 
 	stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE,
 				     VMALLOC_START, VMALLOC_END,
@@ -245,19 +243,15 @@ static inline void free_thread_stack(str
 {
 #ifdef CONFIG_VMAP_STACK
 	if (task_stack_vm_area(tsk)) {
-		unsigned long flags;
 		int i;
 
-		local_irq_save(flags);
 		for (i = 0; i < NR_CACHED_STACKS; i++) {
-			if (this_cpu_read(cached_stacks[i]))
+			if (this_cpu_cmpxchg(cached_stacks[i],
+					NULL, tsk->stack_vm_area) != NULL)
 				continue;
 
-			this_cpu_write(cached_stacks[i], tsk->stack_vm_area);
-			local_irq_restore(flags);
 			return;
 		}
-		local_irq_restore(flags);
 
 		vfree_atomic(tsk->stack);
 		return;
@@ -1637,9 +1631,9 @@ static __latent_entropy struct task_stru
 	prev_cputime_init(&p->prev_cputime);
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
-	seqcount_init(&p->vtime_seqcount);
-	p->vtime_snap = 0;
-	p->vtime_snap_whence = VTIME_INACTIVE;
+	seqcount_init(&p->vtime.seqcount);
+	p->vtime.starttime = 0;
+	p->vtime.state = VTIME_INACTIVE;
 #endif
 
 #if defined(SPLIT_RSS_COUNTING)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/irq/affinity.c linux-libre-4.12.4-gnu/kernel/irq/affinity.c
--- linux-libre-4.12.3-gnu/kernel/irq/affinity.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/irq/affinity.c	2017-07-27 18:10:39.000000000 -0400
@@ -66,6 +66,13 @@ irq_create_affinity_masks(int nvecs, con
 	struct cpumask *masks;
 	cpumask_var_t nmsk;
 
+	/*
+	 * If there aren't any vectors left after applying the pre/post
+	 * vectors don't bother with assigning affinity.
+	 */
+	if (!affv)
+		return NULL;
+
 	if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL))
 		return NULL;
 
@@ -140,15 +147,19 @@ out:
 
 /**
  * irq_calc_affinity_vectors - Calculate the optimal number of vectors
+ * @minvec:	The minimum number of vectors available
  * @maxvec:	The maximum number of vectors available
  * @affd:	Description of the affinity requirements
  */
-int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
+int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd)
 {
 	int resv = affd->pre_vectors + affd->post_vectors;
 	int vecs = maxvec - resv;
 	int cpus;
 
+	if (resv > minvec)
+		return 0;
+
 	/* Stabilize the cpumasks */
 	get_online_cpus();
 	cpus = cpumask_weight(cpu_online_mask);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/sched/cputime.c linux-libre-4.12.4-gnu/kernel/sched/cputime.c
--- linux-libre-4.12.3-gnu/kernel/sched/cputime.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/sched/cputime.c	2017-07-27 18:10:39.000000000 -0400
@@ -679,20 +679,21 @@ void thread_group_cputime_adjusted(struc
 #endif /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
-static u64 vtime_delta(struct task_struct *tsk)
+static u64 vtime_delta(struct vtime *vtime)
 {
-	unsigned long now = READ_ONCE(jiffies);
+	unsigned long long clock;
 
-	if (time_before(now, (unsigned long)tsk->vtime_snap))
+	clock = sched_clock();
+	if (clock < vtime->starttime)
 		return 0;
 
-	return jiffies_to_nsecs(now - tsk->vtime_snap);
+	return clock - vtime->starttime;
 }
 
-static u64 get_vtime_delta(struct task_struct *tsk)
+static u64 get_vtime_delta(struct vtime *vtime)
 {
-	unsigned long now = READ_ONCE(jiffies);
-	u64 delta, other;
+	u64 delta = vtime_delta(vtime);
+	u64 other;
 
 	/*
 	 * Unlike tick based timing, vtime based timing never has lost
@@ -701,104 +702,138 @@ static u64 get_vtime_delta(struct task_s
 	 * elapsed time. Limit account_other_time to prevent rounding
 	 * errors from causing elapsed vtime to go negative.
 	 */
-	delta = jiffies_to_nsecs(now - tsk->vtime_snap);
 	other = account_other_time(delta);
-	WARN_ON_ONCE(tsk->vtime_snap_whence == VTIME_INACTIVE);
-	tsk->vtime_snap = now;
+	WARN_ON_ONCE(vtime->state == VTIME_INACTIVE);
+	vtime->starttime += delta;
 
 	return delta - other;
 }
 
-static void __vtime_account_system(struct task_struct *tsk)
+static void __vtime_account_system(struct task_struct *tsk,
+				   struct vtime *vtime)
 {
-	account_system_time(tsk, irq_count(), get_vtime_delta(tsk));
+	vtime->stime += get_vtime_delta(vtime);
+	if (vtime->stime >= TICK_NSEC) {
+		account_system_time(tsk, irq_count(), vtime->stime);
+		vtime->stime = 0;
+	}
+}
+
+static void vtime_account_guest(struct task_struct *tsk,
+				struct vtime *vtime)
+{
+	vtime->gtime += get_vtime_delta(vtime);
+	if (vtime->gtime >= TICK_NSEC) {
+		account_guest_time(tsk, vtime->gtime);
+		vtime->gtime = 0;
+	}
 }
 
 void vtime_account_system(struct task_struct *tsk)
 {
-	if (!vtime_delta(tsk))
+	struct vtime *vtime = &tsk->vtime;
+
+	if (!vtime_delta(vtime))
 		return;
 
-	write_seqcount_begin(&tsk->vtime_seqcount);
-	__vtime_account_system(tsk);
-	write_seqcount_end(&tsk->vtime_seqcount);
+	write_seqcount_begin(&vtime->seqcount);
+	/* We might have scheduled out from guest path */
+	if (current->flags & PF_VCPU)
+		vtime_account_guest(tsk, vtime);
+	else
+		__vtime_account_system(tsk, vtime);
+	write_seqcount_end(&vtime->seqcount);
 }
 
-void vtime_account_user(struct task_struct *tsk)
+void vtime_user_enter(struct task_struct *tsk)
 {
-	write_seqcount_begin(&tsk->vtime_seqcount);
-	tsk->vtime_snap_whence = VTIME_SYS;
-	if (vtime_delta(tsk))
-		account_user_time(tsk, get_vtime_delta(tsk));
-	write_seqcount_end(&tsk->vtime_seqcount);
+	struct vtime *vtime = &tsk->vtime;
+
+	write_seqcount_begin(&vtime->seqcount);
+	__vtime_account_system(tsk, vtime);
+	vtime->state = VTIME_USER;
+	write_seqcount_end(&vtime->seqcount);
 }
 
-void vtime_user_enter(struct task_struct *tsk)
+void vtime_user_exit(struct task_struct *tsk)
 {
-	write_seqcount_begin(&tsk->vtime_seqcount);
-	if (vtime_delta(tsk))
-		__vtime_account_system(tsk);
-	tsk->vtime_snap_whence = VTIME_USER;
-	write_seqcount_end(&tsk->vtime_seqcount);
+	struct vtime *vtime = &tsk->vtime;
+
+	write_seqcount_begin(&vtime->seqcount);
+	vtime->utime += get_vtime_delta(vtime);
+	if (vtime->utime >= TICK_NSEC) {
+		account_user_time(tsk, vtime->utime);
+		vtime->utime = 0;
+	}
+	vtime->state = VTIME_SYS;
+	write_seqcount_end(&vtime->seqcount);
 }
 
 void vtime_guest_enter(struct task_struct *tsk)
 {
+	struct vtime *vtime = &tsk->vtime;
 	/*
 	 * The flags must be updated under the lock with
-	 * the vtime_snap flush and update.
+	 * the vtime_starttime flush and update.
 	 * That enforces a right ordering and update sequence
 	 * synchronization against the reader (task_gtime())
 	 * that can thus safely catch up with a tickless delta.
 	 */
-	write_seqcount_begin(&tsk->vtime_seqcount);
-	if (vtime_delta(tsk))
-		__vtime_account_system(tsk);
+	write_seqcount_begin(&vtime->seqcount);
+	__vtime_account_system(tsk, vtime);
 	current->flags |= PF_VCPU;
-	write_seqcount_end(&tsk->vtime_seqcount);
+	write_seqcount_end(&vtime->seqcount);
 }
 EXPORT_SYMBOL_GPL(vtime_guest_enter);
 
 void vtime_guest_exit(struct task_struct *tsk)
 {
-	write_seqcount_begin(&tsk->vtime_seqcount);
-	__vtime_account_system(tsk);
+	struct vtime *vtime = &tsk->vtime;
+
+	write_seqcount_begin(&vtime->seqcount);
+	vtime_account_guest(tsk, vtime);
 	current->flags &= ~PF_VCPU;
-	write_seqcount_end(&tsk->vtime_seqcount);
+	write_seqcount_end(&vtime->seqcount);
 }
 EXPORT_SYMBOL_GPL(vtime_guest_exit);
 
 void vtime_account_idle(struct task_struct *tsk)
 {
-	account_idle_time(get_vtime_delta(tsk));
+	account_idle_time(get_vtime_delta(&tsk->vtime));
 }
 
 void arch_vtime_task_switch(struct task_struct *prev)
 {
-	write_seqcount_begin(&prev->vtime_seqcount);
-	prev->vtime_snap_whence = VTIME_INACTIVE;
-	write_seqcount_end(&prev->vtime_seqcount);
+	struct vtime *vtime = &prev->vtime;
 
-	write_seqcount_begin(&current->vtime_seqcount);
-	current->vtime_snap_whence = VTIME_SYS;
-	current->vtime_snap = jiffies;
-	write_seqcount_end(&current->vtime_seqcount);
+	write_seqcount_begin(&vtime->seqcount);
+	vtime->state = VTIME_INACTIVE;
+	write_seqcount_end(&vtime->seqcount);
+
+	vtime = &current->vtime;
+
+	write_seqcount_begin(&vtime->seqcount);
+	vtime->state = VTIME_SYS;
+	vtime->starttime = sched_clock();
+	write_seqcount_end(&vtime->seqcount);
 }
 
 void vtime_init_idle(struct task_struct *t, int cpu)
 {
+	struct vtime *vtime = &t->vtime;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	write_seqcount_begin(&t->vtime_seqcount);
-	t->vtime_snap_whence = VTIME_SYS;
-	t->vtime_snap = jiffies;
-	write_seqcount_end(&t->vtime_seqcount);
+	write_seqcount_begin(&vtime->seqcount);
+	vtime->state = VTIME_SYS;
+	vtime->starttime = sched_clock();
+	write_seqcount_end(&vtime->seqcount);
 	local_irq_restore(flags);
 }
 
 u64 task_gtime(struct task_struct *t)
 {
+	struct vtime *vtime = &t->vtime;
 	unsigned int seq;
 	u64 gtime;
 
@@ -806,13 +841,13 @@ u64 task_gtime(struct task_struct *t)
 		return t->gtime;
 
 	do {
-		seq = read_seqcount_begin(&t->vtime_seqcount);
+		seq = read_seqcount_begin(&vtime->seqcount);
 
 		gtime = t->gtime;
-		if (t->vtime_snap_whence == VTIME_SYS && t->flags & PF_VCPU)
-			gtime += vtime_delta(t);
+		if (vtime->state == VTIME_SYS && t->flags & PF_VCPU)
+			gtime += vtime->gtime + vtime_delta(vtime);
 
-	} while (read_seqcount_retry(&t->vtime_seqcount, seq));
+	} while (read_seqcount_retry(&vtime->seqcount, seq));
 
 	return gtime;
 }
@@ -824,8 +859,9 @@ u64 task_gtime(struct task_struct *t)
  */
 void task_cputime(struct task_struct *t, u64 *utime, u64 *stime)
 {
-	u64 delta;
+	struct vtime *vtime = &t->vtime;
 	unsigned int seq;
+	u64 delta;
 
 	if (!vtime_accounting_enabled()) {
 		*utime = t->utime;
@@ -834,25 +870,25 @@ void task_cputime(struct task_struct *t,
 	}
 
 	do {
-		seq = read_seqcount_begin(&t->vtime_seqcount);
+		seq = read_seqcount_begin(&vtime->seqcount);
 
 		*utime = t->utime;
 		*stime = t->stime;
 
 		/* Task is sleeping, nothing to add */
-		if (t->vtime_snap_whence == VTIME_INACTIVE || is_idle_task(t))
+		if (vtime->state == VTIME_INACTIVE || is_idle_task(t))
 			continue;
 
-		delta = vtime_delta(t);
+		delta = vtime_delta(vtime);
 
 		/*
 		 * Task runs either in user or kernel space, add pending nohz time to
 		 * the right place.
 		 */
-		if (t->vtime_snap_whence == VTIME_USER || t->flags & PF_VCPU)
-			*utime += delta;
-		else if (t->vtime_snap_whence == VTIME_SYS)
-			*stime += delta;
-	} while (read_seqcount_retry(&t->vtime_seqcount, seq));
+		if (vtime->state == VTIME_USER || t->flags & PF_VCPU)
+			*utime += vtime->utime + delta;
+		else if (vtime->state == VTIME_SYS)
+			*stime += vtime->stime + delta;
+	} while (read_seqcount_retry(&vtime->seqcount, seq));
 }
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/sched/fair.c linux-libre-4.12.4-gnu/kernel/sched/fair.c
--- linux-libre-4.12.3-gnu/kernel/sched/fair.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/sched/fair.c	2017-07-27 18:10:39.000000000 -0400
@@ -6619,10 +6619,10 @@ int can_migrate_task(struct task_struct
 		 * our sched_group. We may want to revisit it if we couldn't
 		 * meet load balance goals by pulling other tasks on src_cpu.
 		 *
-		 * Also avoid computing new_dst_cpu if we have already computed
-		 * one in current iteration.
+		 * Avoid computing new_dst_cpu for NEWLY_IDLE or if we have
+		 * already computed one in current iteration.
 		 */
-		if (!env->dst_grpmask || (env->flags & LBF_DST_PINNED))
+		if (env->idle == CPU_NEWLY_IDLE || (env->flags & LBF_DST_PINNED))
 			return 0;
 
 		/* Prevent to re-select dst_cpu via env's cpus */
@@ -7973,14 +7973,7 @@ static int load_balance(int this_cpu, st
 		.tasks		= LIST_HEAD_INIT(env.tasks),
 	};
 
-	/*
-	 * For NEWLY_IDLE load_balancing, we don't need to consider
-	 * other cpus in our group
-	 */
-	if (idle == CPU_NEWLY_IDLE)
-		env.dst_grpmask = NULL;
-
-	cpumask_copy(cpus, cpu_active_mask);
+	cpumask_and(cpus, sched_domain_span(sd), cpu_active_mask);
 
 	schedstat_inc(sd->lb_count[idle]);
 
@@ -8102,7 +8095,15 @@ more_balance:
 		/* All tasks on this runqueue were pinned by CPU affinity */
 		if (unlikely(env.flags & LBF_ALL_PINNED)) {
 			cpumask_clear_cpu(cpu_of(busiest), cpus);
-			if (!cpumask_empty(cpus)) {
+			/*
+			 * Attempting to continue load balancing at the current
+			 * sched_domain level only makes sense if there are
+			 * active CPUs remaining as possible busiest CPUs to
+			 * pull load from which are not contained within the
+			 * destination group that is receiving any migrated
+			 * load.
+			 */
+			if (!cpumask_subset(cpus, env.dst_grpmask)) {
 				env.loop = 0;
 				env.loop_break = sched_nr_migrate_break;
 				goto redo;
@@ -8398,6 +8399,13 @@ static int active_load_balance_cpu_stop(
 			.src_cpu	= busiest_rq->cpu,
 			.src_rq		= busiest_rq,
 			.idle		= CPU_IDLE,
+			/*
+			 * can_migrate_task() doesn't need to compute new_dst_cpu
+			 * for active balancing. Since we have CPU_IDLE, but no
+			 * @dst_grpmask we need to make that test go away with lying
+			 * about DST_PINNED.
+			 */
+			.flags		= LBF_DST_PINNED,
 		};
 
 		schedstat_inc(sd->alb_count);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/time/alarmtimer.c linux-libre-4.12.4-gnu/kernel/time/alarmtimer.c
--- linux-libre-4.12.3-gnu/kernel/time/alarmtimer.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/time/alarmtimer.c	2017-07-27 18:10:39.000000000 -0400
@@ -665,7 +665,7 @@ static int alarm_timer_set(struct k_itim
 	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
 	 * mopped up later.
 	 */
-	if (timr->it.alarm.interval < TICK_NSEC)
+	if (timr->it.alarm.interval && timr->it.alarm.interval < TICK_NSEC)
 		timr->it.alarm.interval = TICK_NSEC;
 
 	exp = timespec64_to_ktime(new_setting->it_value);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/trace/ftrace.c linux-libre-4.12.4-gnu/kernel/trace/ftrace.c
--- linux-libre-4.12.3-gnu/kernel/trace/ftrace.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/trace/ftrace.c	2017-07-27 18:10:39.000000000 -0400
@@ -3665,7 +3665,7 @@ match_records(struct ftrace_hash *hash,
 	int exclude_mod = 0;
 	int found = 0;
 	int ret;
-	int clear_filter;
+	int clear_filter = 0;
 
 	if (func) {
 		func_g.type = filter_parse_regex(func, len, &func_g.search,
diff -druNp --no-dereference linux-libre-4.12.3-gnu/kernel/trace/trace.c linux-libre-4.12.4-gnu/kernel/trace/trace.c
--- linux-libre-4.12.3-gnu/kernel/trace/trace.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/kernel/trace/trace.c	2017-07-27 18:10:39.000000000 -0400
@@ -7594,6 +7594,7 @@ static int instance_rmdir(const char *na
 	}
 	kfree(tr->topts);
 
+	free_cpumask_var(tr->tracing_cpumask);
 	kfree(tr->name);
 	kfree(tr);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/lib/flex_proportions.c linux-libre-4.12.4-gnu/lib/flex_proportions.c
--- linux-libre-4.12.3-gnu/lib/flex_proportions.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/lib/flex_proportions.c	2017-07-27 18:10:39.000000000 -0400
@@ -207,7 +207,7 @@ static void fprop_reflect_period_percpu(
 		if (val < (nr_cpu_ids * PROP_BATCH))
 			val = percpu_counter_sum(&pl->events);
 
-		__percpu_counter_add(&pl->events,
+		percpu_counter_add_batch(&pl->events,
 			-val + (val >> (period-pl->period)), PROP_BATCH);
 	} else
 		percpu_counter_set(&pl->events, 0);
@@ -219,7 +219,7 @@ static void fprop_reflect_period_percpu(
 void __fprop_inc_percpu(struct fprop_global *p, struct fprop_local_percpu *pl)
 {
 	fprop_reflect_period_percpu(p, pl);
-	__percpu_counter_add(&pl->events, 1, PROP_BATCH);
+	percpu_counter_add_batch(&pl->events, 1, PROP_BATCH);
 	percpu_counter_add(&p->events, 1);
 }
 
@@ -267,6 +267,6 @@ void __fprop_inc_percpu_max(struct fprop
 			return;
 	} else
 		fprop_reflect_period_percpu(p, pl);
-	__percpu_counter_add(&pl->events, 1, PROP_BATCH);
+	percpu_counter_add_batch(&pl->events, 1, PROP_BATCH);
 	percpu_counter_add(&p->events, 1);
 }
diff -druNp --no-dereference linux-libre-4.12.3-gnu/lib/percpu_counter.c linux-libre-4.12.4-gnu/lib/percpu_counter.c
--- linux-libre-4.12.3-gnu/lib/percpu_counter.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/lib/percpu_counter.c	2017-07-27 18:10:39.000000000 -0400
@@ -72,7 +72,14 @@ void percpu_counter_set(struct percpu_co
 }
 EXPORT_SYMBOL(percpu_counter_set);
 
-void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
+/**
+ * This function is both preempt and irq safe. The former is due to explicit
+ * preemption disable. The latter is guaranteed by the fact that the slow path
+ * is explicitly protected by an irq-safe spinlock whereas the fast patch uses
+ * this_cpu_add which is irq-safe by definition. Hence there is no need muck
+ * with irq state before calling this one
+ */
+void percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount, s32 batch)
 {
 	s64 count;
 
@@ -89,7 +96,7 @@ void __percpu_counter_add(struct percpu_
 	}
 	preempt_enable();
 }
-EXPORT_SYMBOL(__percpu_counter_add);
+EXPORT_SYMBOL(percpu_counter_add_batch);
 
 /*
  * Add up all the per-cpu counts, return the result.  This is a more accurate
diff -druNp --no-dereference linux-libre-4.12.3-gnu/Makefile linux-libre-4.12.4-gnu/Makefile
--- linux-libre-4.12.3-gnu/Makefile	2017-07-21 04:55:43.000000000 -0400
+++ linux-libre-4.12.4-gnu/Makefile	2017-07-27 21:25:02.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 12
-SUBLEVEL = 3
+SUBLEVEL = 4
 EXTRAVERSION = -gnu
 NAME = Fearless Coyote
 
@@ -631,6 +631,9 @@ include arch/$(SRCARCH)/Makefile
 
 KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
 KBUILD_CFLAGS	+= $(call cc-disable-warning,frame-address,)
+KBUILD_CFLAGS	+= $(call cc-disable-warning, format-truncation)
+KBUILD_CFLAGS	+= $(call cc-disable-warning, format-overflow)
+KBUILD_CFLAGS	+= $(call cc-disable-warning, int-in-bool-context)
 
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 KBUILD_CFLAGS	+= $(call cc-option,-Oz,-Os)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/mm/page-writeback.c linux-libre-4.12.4-gnu/mm/page-writeback.c
--- linux-libre-4.12.3-gnu/mm/page-writeback.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/mm/page-writeback.c	2017-07-27 18:10:39.000000000 -0400
@@ -601,7 +601,7 @@ static inline void __wb_writeout_inc(str
 {
 	struct wb_domain *cgdom;
 
-	__inc_wb_stat(wb, WB_WRITTEN);
+	inc_wb_stat(wb, WB_WRITTEN);
 	wb_domain_writeout_inc(&global_wb_domain, &wb->completions,
 			       wb->bdi->max_prop_frac);
 
@@ -2437,8 +2437,8 @@ void account_page_dirtied(struct page *p
 		__inc_node_page_state(page, NR_FILE_DIRTY);
 		__inc_zone_page_state(page, NR_ZONE_WRITE_PENDING);
 		__inc_node_page_state(page, NR_DIRTIED);
-		__inc_wb_stat(wb, WB_RECLAIMABLE);
-		__inc_wb_stat(wb, WB_DIRTIED);
+		inc_wb_stat(wb, WB_RECLAIMABLE);
+		inc_wb_stat(wb, WB_DIRTIED);
 		task_io_account_write(PAGE_SIZE);
 		current->nr_dirtied++;
 		this_cpu_inc(bdp_ratelimits);
@@ -2745,7 +2745,7 @@ int test_clear_page_writeback(struct pag
 			if (bdi_cap_account_writeback(bdi)) {
 				struct bdi_writeback *wb = inode_to_wb(inode);
 
-				__dec_wb_stat(wb, WB_WRITEBACK);
+				dec_wb_stat(wb, WB_WRITEBACK);
 				__wb_writeout_inc(wb);
 			}
 		}
@@ -2791,7 +2791,7 @@ int __test_set_page_writeback(struct pag
 						page_index(page),
 						PAGECACHE_TAG_WRITEBACK);
 			if (bdi_cap_account_writeback(bdi))
-				__inc_wb_stat(inode_to_wb(inode), WB_WRITEBACK);
+				inc_wb_stat(inode_to_wb(inode), WB_WRITEBACK);
 
 			/*
 			 * We can come through here when swapping anonymous
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/bluetooth/smp.c linux-libre-4.12.4-gnu/net/bluetooth/smp.c
--- linux-libre-4.12.3-gnu/net/bluetooth/smp.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/bluetooth/smp.c	2017-07-27 18:10:39.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/crypto.h>
+#include <crypto/algapi.h>
 #include <crypto/b128ops.h>
 #include <crypto/hash.h>
 
@@ -523,7 +524,7 @@ bool smp_irk_matches(struct hci_dev *hde
 	if (err)
 		return false;
 
-	return !memcmp(bdaddr->b, hash, 3);
+	return !crypto_memneq(bdaddr->b, hash, 3);
 }
 
 int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
@@ -579,7 +580,7 @@ int smp_generate_oob(struct hci_dev *hde
 			/* This is unlikely, but we need to check that
 			 * we didn't accidentially generate a debug key.
 			 */
-			if (memcmp(smp->local_sk, debug_sk, 32))
+			if (crypto_memneq(smp->local_sk, debug_sk, 32))
 				break;
 		}
 		smp->debug_key = false;
@@ -993,7 +994,7 @@ static u8 smp_random(struct smp_chan *sm
 	if (ret)
 		return SMP_UNSPECIFIED;
 
-	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
+	if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) {
 		BT_ERR("Pairing failed (confirmation values mismatch)");
 		return SMP_CONFIRM_FAILED;
 	}
@@ -1512,7 +1513,7 @@ static u8 sc_passkey_round(struct smp_ch
 			   smp->rrnd, r, cfm))
 			return SMP_UNSPECIFIED;
 
-		if (memcmp(smp->pcnf, cfm, 16))
+		if (crypto_memneq(smp->pcnf, cfm, 16))
 			return SMP_CONFIRM_FAILED;
 
 		smp->passkey_round++;
@@ -1908,7 +1909,7 @@ static u8 sc_send_public_key(struct smp_
 			/* This is unlikely, but we need to check that
 			 * we didn't accidentially generate a debug key.
 			 */
-			if (memcmp(smp->local_sk, debug_sk, 32))
+			if (crypto_memneq(smp->local_sk, debug_sk, 32))
 				break;
 		}
 	}
@@ -2176,7 +2177,7 @@ static u8 smp_cmd_pairing_random(struct
 		if (err)
 			return SMP_UNSPECIFIED;
 
-		if (memcmp(smp->pcnf, cfm, 16))
+		if (crypto_memneq(smp->pcnf, cfm, 16))
 			return SMP_CONFIRM_FAILED;
 	} else {
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
@@ -2660,7 +2661,7 @@ static int smp_cmd_public_key(struct l2c
 		if (err)
 			return SMP_UNSPECIFIED;
 
-		if (memcmp(cfm.confirm_val, smp->pcnf, 16))
+		if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16))
 			return SMP_CONFIRM_FAILED;
 	}
 
@@ -2693,7 +2694,7 @@ static int smp_cmd_public_key(struct l2c
 	else
 		hcon->pending_sec_level = BT_SECURITY_FIPS;
 
-	if (!memcmp(debug_pk, smp->remote_pk, 64))
+	if (!crypto_memneq(debug_pk, smp->remote_pk, 64))
 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
 
 	if (smp->method == DSP_PASSKEY) {
@@ -2792,7 +2793,7 @@ static int smp_cmd_dhkey_check(struct l2
 	if (err)
 		return SMP_UNSPECIFIED;
 
-	if (memcmp(check->e, e, 16))
+	if (crypto_memneq(check->e, e, 16))
 		return SMP_DHKEY_CHECK_FAILED;
 
 	if (!hcon->out) {
@@ -3506,10 +3507,10 @@ static int __init test_debug_key(void)
 	if (!generate_ecdh_keys(pk, sk))
 		return -EINVAL;
 
-	if (memcmp(sk, debug_sk, 32))
+	if (crypto_memneq(sk, debug_sk, 32))
 		return -EINVAL;
 
-	if (memcmp(pk, debug_pk, 64))
+	if (crypto_memneq(pk, debug_pk, 64))
 		return -EINVAL;
 
 	return 0;
@@ -3529,7 +3530,7 @@ static int __init test_ah(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(res, exp, 3))
+	if (crypto_memneq(res, exp, 3))
 		return -EINVAL;
 
 	return 0;
@@ -3559,7 +3560,7 @@ static int __init test_c1(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(res, exp, 16))
+	if (crypto_memneq(res, exp, 16))
 		return -EINVAL;
 
 	return 0;
@@ -3584,7 +3585,7 @@ static int __init test_s1(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(res, exp, 16))
+	if (crypto_memneq(res, exp, 16))
 		return -EINVAL;
 
 	return 0;
@@ -3616,7 +3617,7 @@ static int __init test_f4(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(res, exp, 16))
+	if (crypto_memneq(res, exp, 16))
 		return -EINVAL;
 
 	return 0;
@@ -3650,10 +3651,10 @@ static int __init test_f5(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(mackey, exp_mackey, 16))
+	if (crypto_memneq(mackey, exp_mackey, 16))
 		return -EINVAL;
 
-	if (memcmp(ltk, exp_ltk, 16))
+	if (crypto_memneq(ltk, exp_ltk, 16))
 		return -EINVAL;
 
 	return 0;
@@ -3686,7 +3687,7 @@ static int __init test_f6(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(res, exp, 16))
+	if (crypto_memneq(res, exp, 16))
 		return -EINVAL;
 
 	return 0;
@@ -3740,7 +3741,7 @@ static int __init test_h6(struct crypto_
 	if (err)
 		return err;
 
-	if (memcmp(res, exp, 16))
+	if (crypto_memneq(res, exp, 16))
 		return -EINVAL;
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/nfc/core.c linux-libre-4.12.4-gnu/net/nfc/core.c
--- linux-libre-4.12.3-gnu/net/nfc/core.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/nfc/core.c	2017-07-27 18:10:39.000000000 -0400
@@ -982,6 +982,8 @@ static void nfc_release(struct device *d
 			kfree(se);
 	}
 
+	ida_simple_remove(&nfc_index_ida, dev->idx);
+
 	kfree(dev);
 }
 
@@ -1056,6 +1058,7 @@ struct nfc_dev *nfc_allocate_device(stru
 				    int tx_headroom, int tx_tailroom)
 {
 	struct nfc_dev *dev;
+	int rc;
 
 	if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
 	    !ops->deactivate_target || !ops->im_transceive)
@@ -1068,6 +1071,15 @@ struct nfc_dev *nfc_allocate_device(stru
 	if (!dev)
 		return NULL;
 
+	rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
+	if (rc < 0)
+		goto err_free_dev;
+	dev->idx = rc;
+
+	dev->dev.class = &nfc_class;
+	dev_set_name(&dev->dev, "nfc%d", dev->idx);
+	device_initialize(&dev->dev);
+
 	dev->ops = ops;
 	dev->supported_protocols = supported_protocols;
 	dev->tx_headroom = tx_headroom;
@@ -1090,6 +1102,11 @@ struct nfc_dev *nfc_allocate_device(stru
 	}
 
 	return dev;
+
+err_free_dev:
+	kfree(dev);
+
+	return ERR_PTR(rc);
 }
 EXPORT_SYMBOL(nfc_allocate_device);
 
@@ -1104,14 +1121,6 @@ int nfc_register_device(struct nfc_dev *
 
 	pr_debug("dev_name=%s\n", dev_name(&dev->dev));
 
-	dev->idx = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
-	if (dev->idx < 0)
-		return dev->idx;
-
-	dev->dev.class = &nfc_class;
-	dev_set_name(&dev->dev, "nfc%d", dev->idx);
-	device_initialize(&dev->dev);
-
 	mutex_lock(&nfc_devlist_mutex);
 	nfc_devlist_generation++;
 	rc = device_add(&dev->dev);
@@ -1149,12 +1158,10 @@ EXPORT_SYMBOL(nfc_register_device);
  */
 void nfc_unregister_device(struct nfc_dev *dev)
 {
-	int rc, id;
+	int rc;
 
 	pr_debug("dev_name=%s\n", dev_name(&dev->dev));
 
-	id = dev->idx;
-
 	if (dev->rfkill) {
 		rfkill_unregister(dev->rfkill);
 		rfkill_destroy(dev->rfkill);
@@ -1179,8 +1186,6 @@ void nfc_unregister_device(struct nfc_de
 	nfc_devlist_generation++;
 	device_del(&dev->dev);
 	mutex_unlock(&nfc_devlist_mutex);
-
-	ida_simple_remove(&nfc_index_ida, id);
 }
 EXPORT_SYMBOL(nfc_unregister_device);
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/nfc/llcp_sock.c linux-libre-4.12.4-gnu/net/nfc/llcp_sock.c
--- linux-libre-4.12.3-gnu/net/nfc/llcp_sock.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/nfc/llcp_sock.c	2017-07-27 18:10:39.000000000 -0400
@@ -77,7 +77,8 @@ static int llcp_sock_bind(struct socket
 	struct sockaddr_nfc_llcp llcp_addr;
 	int len, ret = 0;
 
-	if (!addr || addr->sa_family != AF_NFC)
+	if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
+	    addr->sa_family != AF_NFC)
 		return -EINVAL;
 
 	pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);
@@ -151,7 +152,8 @@ static int llcp_raw_sock_bind(struct soc
 	struct sockaddr_nfc_llcp llcp_addr;
 	int len, ret = 0;
 
-	if (!addr || addr->sa_family != AF_NFC)
+	if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
+	    addr->sa_family != AF_NFC)
 		return -EINVAL;
 
 	pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);
@@ -662,8 +664,7 @@ static int llcp_sock_connect(struct sock
 
 	pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);
 
-	if (!addr || len < sizeof(struct sockaddr_nfc) ||
-	    addr->sa_family != AF_NFC)
+	if (!addr || len < sizeof(*addr) || addr->sa_family != AF_NFC)
 		return -EINVAL;
 
 	if (addr->service_name_len == 0 && addr->dsap == 0)
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/nfc/nci/core.c linux-libre-4.12.4-gnu/net/nfc/nci/core.c
--- linux-libre-4.12.3-gnu/net/nfc/nci/core.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/nfc/nci/core.c	2017-07-27 18:10:39.000000000 -0400
@@ -1173,8 +1173,7 @@ struct nci_dev *nci_allocate_device(stru
 	return ndev;
 
 free_nfc:
-	kfree(ndev->nfc_dev);
-
+	nfc_free_device(ndev->nfc_dev);
 free_nci:
 	kfree(ndev);
 	return NULL;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/nfc/netlink.c linux-libre-4.12.4-gnu/net/nfc/netlink.c
--- linux-libre-4.12.3-gnu/net/nfc/netlink.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/nfc/netlink.c	2017-07-27 18:10:39.000000000 -0400
@@ -907,7 +907,9 @@ static int nfc_genl_activate_target(stru
 	u32 device_idx, target_idx, protocol;
 	int rc;
 
-	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
+	if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
+	    !info->attrs[NFC_ATTR_TARGET_INDEX] ||
+	    !info->attrs[NFC_ATTR_PROTOCOLS])
 		return -EINVAL;
 
 	device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/sunrpc/auth_gss/gss_krb5_crypto.c linux-libre-4.12.4-gnu/net/sunrpc/auth_gss/gss_krb5_crypto.c
--- linux-libre-4.12.3-gnu/net/sunrpc/auth_gss/gss_krb5_crypto.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/sunrpc/auth_gss/gss_krb5_crypto.c	2017-07-27 18:10:39.000000000 -0400
@@ -34,6 +34,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#include <crypto/algapi.h>
 #include <crypto/hash.h>
 #include <crypto/skcipher.h>
 #include <linux/err.h>
@@ -927,7 +928,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kc
 	if (ret)
 		goto out_err;
 
-	if (memcmp(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) {
+	if (crypto_memneq(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) {
 		ret = GSS_S_BAD_SIG;
 		goto out_err;
 	}
diff -druNp --no-dereference linux-libre-4.12.3-gnu/net/sunrpc/xprtsock.c linux-libre-4.12.4-gnu/net/sunrpc/xprtsock.c
--- linux-libre-4.12.3-gnu/net/sunrpc/xprtsock.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/net/sunrpc/xprtsock.c	2017-07-27 18:10:39.000000000 -0400
@@ -1624,6 +1624,8 @@ static void xs_tcp_state_change(struct s
 		if (test_and_clear_bit(XPRT_SOCK_CONNECTING,
 					&transport->sock_state))
 			xprt_clear_connecting(xprt);
+		if (sk->sk_err)
+			xprt_wake_pending_tasks(xprt, -sk->sk_err);
 		xs_sock_mark_closed(xprt);
 	}
  out:
diff -druNp --no-dereference linux-libre-4.12.3-gnu/sound/soc/atmel/tse850-pcm5142.c linux-libre-4.12.4-gnu/sound/soc/atmel/tse850-pcm5142.c
--- linux-libre-4.12.3-gnu/sound/soc/atmel/tse850-pcm5142.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/sound/soc/atmel/tse850-pcm5142.c	2017-07-27 18:10:39.000000000 -0400
@@ -227,7 +227,7 @@ int tse850_put_ana(struct snd_kcontrol *
 static const char * const mux_text[] = { "Mixer", "Loop" };
 
 static const struct soc_enum mux_enum =
-	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, mux_text);
+	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(mux_text), mux_text);
 
 static const struct snd_kcontrol_new mux1 =
 	SOC_DAPM_ENUM_EXT("MUX1", mux_enum, tse850_get_mux1, tse850_put_mux1);
@@ -252,7 +252,7 @@ static const char * const ana_text[] = {
 };
 
 static const struct soc_enum ana_enum =
-	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 9, ana_text);
+	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(ana_text), ana_text);
 
 static const struct snd_kcontrol_new out =
 	SOC_DAPM_ENUM_EXT("ANA", ana_enum, tse850_get_ana, tse850_put_ana);
diff -druNp --no-dereference linux-libre-4.12.3-gnu/sound/soc/soc-compress.c linux-libre-4.12.4-gnu/sound/soc/soc-compress.c
--- linux-libre-4.12.3-gnu/sound/soc/soc-compress.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/sound/soc/soc-compress.c	2017-07-27 18:10:39.000000000 -0400
@@ -81,7 +81,8 @@ out:
 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 {
 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
-	struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+	struct snd_pcm_substream *fe_substream =
+		 fe->pcm->streams[cstream->direction].substream;
 	struct snd_soc_platform *platform = fe->platform;
 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
 	struct snd_soc_dpcm *dpcm;
@@ -467,7 +468,8 @@ static int soc_compr_set_params_fe(struc
 					struct snd_compr_params *params)
 {
 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
-	struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+	struct snd_pcm_substream *fe_substream =
+		 fe->pcm->streams[cstream->direction].substream;
 	struct snd_soc_platform *platform = fe->platform;
 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
 	int ret = 0, stream;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/sound/soc/zte/zx-i2s.c linux-libre-4.12.4-gnu/sound/soc/zte/zx-i2s.c
--- linux-libre-4.12.3-gnu/sound/soc/zte/zx-i2s.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/sound/soc/zte/zx-i2s.c	2017-07-27 18:10:39.000000000 -0400
@@ -203,13 +203,15 @@ static int zx_i2s_set_fmt(struct snd_soc
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		i2s->master = 1;
-		val |= ZX_I2S_TIMING_MAST;
-		break;
-	case SND_SOC_DAIFMT_CBS_CFS:
+		/* Codec is master, and I2S is slave. */
 		i2s->master = 0;
 		val |= ZX_I2S_TIMING_SLAVE;
 		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		/* Codec is slave, and I2S is master. */
+		i2s->master = 1;
+		val |= ZX_I2S_TIMING_MAST;
+		break;
 	default:
 		dev_err(cpu_dai->dev, "Unknown master/slave format\n");
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/tools/perf/ui/browser.c linux-libre-4.12.4-gnu/tools/perf/ui/browser.c
--- linux-libre-4.12.3-gnu/tools/perf/ui/browser.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/tools/perf/ui/browser.c	2017-07-27 18:10:39.000000000 -0400
@@ -704,7 +704,7 @@ static void __ui_browser__line_arrow_dow
 		ui_browser__gotorc(browser, row, column + 1);
 		SLsmg_draw_hline(2);
 
-		if (row++ == 0)
+		if (++row == 0)
 			goto out;
 	} else
 		row = 0;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c linux-libre-4.12.4-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
--- linux-libre-4.12.3-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c	2017-07-27 18:10:39.000000000 -0400
@@ -64,6 +64,25 @@ enum intel_pt_pkt_state {
 	INTEL_PT_STATE_FUP_NO_TIP,
 };
 
+static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state)
+{
+	switch (pkt_state) {
+	case INTEL_PT_STATE_NO_PSB:
+	case INTEL_PT_STATE_NO_IP:
+	case INTEL_PT_STATE_ERR_RESYNC:
+	case INTEL_PT_STATE_IN_SYNC:
+	case INTEL_PT_STATE_TNT:
+		return true;
+	case INTEL_PT_STATE_TIP:
+	case INTEL_PT_STATE_TIP_PGD:
+	case INTEL_PT_STATE_FUP:
+	case INTEL_PT_STATE_FUP_NO_TIP:
+		return false;
+	default:
+		return true;
+	};
+}
+
 #ifdef INTEL_PT_STRICT
 #define INTEL_PT_STATE_ERR1	INTEL_PT_STATE_NO_PSB
 #define INTEL_PT_STATE_ERR2	INTEL_PT_STATE_NO_PSB
@@ -92,6 +111,7 @@ struct intel_pt_decoder {
 	bool have_tma;
 	bool have_cyc;
 	bool fixup_last_mtc;
+	bool have_last_ip;
 	uint64_t pos;
 	uint64_t last_ip;
 	uint64_t ip;
@@ -99,6 +119,7 @@ struct intel_pt_decoder {
 	uint64_t timestamp;
 	uint64_t tsc_timestamp;
 	uint64_t ref_timestamp;
+	uint64_t sample_timestamp;
 	uint64_t ret_addr;
 	uint64_t ctc_timestamp;
 	uint64_t ctc_delta;
@@ -139,6 +160,7 @@ struct intel_pt_decoder {
 	unsigned int fup_tx_flags;
 	unsigned int tx_flags;
 	uint64_t timestamp_insn_cnt;
+	uint64_t sample_insn_cnt;
 	uint64_t stuck_ip;
 	int no_progress;
 	int stuck_ip_prd;
@@ -398,6 +420,7 @@ static uint64_t intel_pt_calc_ip(const s
 static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder)
 {
 	decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip);
+	decoder->have_last_ip = true;
 }
 
 static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder)
@@ -898,6 +921,7 @@ static int intel_pt_walk_insn(struct int
 
 	decoder->tot_insn_cnt += insn_cnt;
 	decoder->timestamp_insn_cnt += insn_cnt;
+	decoder->sample_insn_cnt += insn_cnt;
 	decoder->period_insn_cnt += insn_cnt;
 
 	if (err) {
@@ -1446,7 +1470,8 @@ static int intel_pt_walk_psbend(struct i
 
 		case INTEL_PT_FUP:
 			decoder->pge = true;
-			intel_pt_set_last_ip(decoder);
+			if (decoder->packet.count)
+				intel_pt_set_last_ip(decoder);
 			break;
 
 		case INTEL_PT_MODE_TSX:
@@ -1650,6 +1675,8 @@ next:
 			break;
 
 		case INTEL_PT_PSB:
+			decoder->last_ip = 0;
+			decoder->have_last_ip = true;
 			intel_pt_clear_stack(&decoder->stack);
 			err = intel_pt_walk_psbend(decoder);
 			if (err == -EAGAIN)
@@ -1730,8 +1757,9 @@ next:
 
 static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
 {
-	return decoder->last_ip || decoder->packet.count == 0 ||
-	       decoder->packet.count == 3 || decoder->packet.count == 6;
+	return decoder->packet.count &&
+	       (decoder->have_last_ip || decoder->packet.count == 3 ||
+		decoder->packet.count == 6);
 }
 
 /* Walk PSB+ packets to get in sync. */
@@ -1854,14 +1882,10 @@ static int intel_pt_walk_to_ip(struct in
 			break;
 
 		case INTEL_PT_FUP:
-			if (decoder->overflow) {
-				if (intel_pt_have_ip(decoder))
-					intel_pt_set_ip(decoder);
-				if (decoder->ip)
-					return 0;
-			}
-			if (decoder->packet.count)
-				intel_pt_set_last_ip(decoder);
+			if (intel_pt_have_ip(decoder))
+				intel_pt_set_ip(decoder);
+			if (decoder->ip)
+				return 0;
 			break;
 
 		case INTEL_PT_MTC:
@@ -1910,6 +1934,9 @@ static int intel_pt_walk_to_ip(struct in
 			break;
 
 		case INTEL_PT_PSB:
+			decoder->last_ip = 0;
+			decoder->have_last_ip = true;
+			intel_pt_clear_stack(&decoder->stack);
 			err = intel_pt_walk_psb(decoder);
 			if (err)
 				return err;
@@ -1935,6 +1962,8 @@ static int intel_pt_sync_ip(struct intel
 {
 	int err;
 
+	decoder->set_fup_tx_flags = false;
+
 	intel_pt_log("Scanning for full IP\n");
 	err = intel_pt_walk_to_ip(decoder);
 	if (err)
@@ -2043,6 +2072,7 @@ static int intel_pt_sync(struct intel_pt
 
 	decoder->pge = false;
 	decoder->continuous_period = false;
+	decoder->have_last_ip = false;
 	decoder->last_ip = 0;
 	decoder->ip = 0;
 	intel_pt_clear_stack(&decoder->stack);
@@ -2051,6 +2081,7 @@ static int intel_pt_sync(struct intel_pt
 	if (err)
 		return err;
 
+	decoder->have_last_ip = true;
 	decoder->pkt_state = INTEL_PT_STATE_NO_IP;
 
 	err = intel_pt_walk_psb(decoder);
@@ -2069,7 +2100,7 @@ static int intel_pt_sync(struct intel_pt
 
 static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder)
 {
-	uint64_t est = decoder->timestamp_insn_cnt << 1;
+	uint64_t est = decoder->sample_insn_cnt << 1;
 
 	if (!decoder->cbr || !decoder->max_non_turbo_ratio)
 		goto out;
@@ -2077,7 +2108,7 @@ static uint64_t intel_pt_est_timestamp(s
 	est *= decoder->max_non_turbo_ratio;
 	est /= decoder->cbr;
 out:
-	return decoder->timestamp + est;
+	return decoder->sample_timestamp + est;
 }
 
 const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
@@ -2093,7 +2124,9 @@ const struct intel_pt_state *intel_pt_de
 			err = intel_pt_sync(decoder);
 			break;
 		case INTEL_PT_STATE_NO_IP:
+			decoder->have_last_ip = false;
 			decoder->last_ip = 0;
+			decoder->ip = 0;
 			/* Fall through */
 		case INTEL_PT_STATE_ERR_RESYNC:
 			err = intel_pt_sync_ip(decoder);
@@ -2130,15 +2163,24 @@ const struct intel_pt_state *intel_pt_de
 		}
 	} while (err == -ENOLINK);
 
-	decoder->state.err = err ? intel_pt_ext_err(err) : 0;
-	decoder->state.timestamp = decoder->timestamp;
+	if (err) {
+		decoder->state.err = intel_pt_ext_err(err);
+		decoder->state.from_ip = decoder->ip;
+		decoder->sample_timestamp = decoder->timestamp;
+		decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
+	} else {
+		decoder->state.err = 0;
+		if (intel_pt_sample_time(decoder->pkt_state)) {
+			decoder->sample_timestamp = decoder->timestamp;
+			decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
+		}
+	}
+
+	decoder->state.timestamp = decoder->sample_timestamp;
 	decoder->state.est_timestamp = intel_pt_est_timestamp(decoder);
 	decoder->state.cr3 = decoder->cr3;
 	decoder->state.tot_insn_cnt = decoder->tot_insn_cnt;
 
-	if (err)
-		decoder->state.from_ip = decoder->ip;
-
 	return &decoder->state;
 }
 
diff -druNp --no-dereference linux-libre-4.12.3-gnu/tools/testing/nvdimm/test/nfit.c linux-libre-4.12.4-gnu/tools/testing/nvdimm/test/nfit.c
--- linux-libre-4.12.3-gnu/tools/testing/nvdimm/test/nfit.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/tools/testing/nvdimm/test/nfit.c	2017-07-27 18:10:39.000000000 -0400
@@ -1943,7 +1943,7 @@ static __init int nfit_test_init(void)
 			nfit_test->setup = nfit_test0_setup;
 			break;
 		case 1:
-			nfit_test->num_pm = 1;
+			nfit_test->num_pm = 2;
 			nfit_test->dcr_idx = NUM_DCR;
 			nfit_test->num_dcr = 2;
 			nfit_test->alloc = nfit_test1_alloc;
diff -druNp --no-dereference linux-libre-4.12.3-gnu/virt/kvm/vfio.c linux-libre-4.12.4-gnu/virt/kvm/vfio.c
--- linux-libre-4.12.3-gnu/virt/kvm/vfio.c	2017-07-21 00:59:24.000000000 -0400
+++ linux-libre-4.12.4-gnu/virt/kvm/vfio.c	2017-07-27 18:10:39.000000000 -0400
@@ -51,6 +51,22 @@ static struct vfio_group *kvm_vfio_group
 	return vfio_group;
 }
 
+static bool kvm_vfio_external_group_match_file(struct vfio_group *group,
+					       struct file *filep)
+{
+	bool ret, (*fn)(struct vfio_group *, struct file *);
+
+	fn = symbol_get(vfio_external_group_match_file);
+	if (!fn)
+		return false;
+
+	ret = fn(group, filep);
+
+	symbol_put(vfio_external_group_match_file);
+
+	return ret;
+}
+
 static void kvm_vfio_group_put_external_user(struct vfio_group *vfio_group)
 {
 	void (*fn)(struct vfio_group *);
@@ -231,18 +247,13 @@ static int kvm_vfio_set_group(struct kvm
 		if (!f.file)
 			return -EBADF;
 
-		vfio_group = kvm_vfio_group_get_external_user(f.file);
-		fdput(f);
-
-		if (IS_ERR(vfio_group))
-			return PTR_ERR(vfio_group);
-
 		ret = -ENOENT;
 
 		mutex_lock(&kv->lock);
 
 		list_for_each_entry(kvg, &kv->group_list, node) {
-			if (kvg->vfio_group != vfio_group)
+			if (!kvm_vfio_external_group_match_file(kvg->vfio_group,
+								f.file))
 				continue;
 
 			list_del(&kvg->node);
@@ -260,7 +271,7 @@ static int kvm_vfio_set_group(struct kvm
 
 		mutex_unlock(&kv->lock);
 
-		kvm_vfio_group_put_external_user(vfio_group);
+		fdput(f);
 
 		kvm_vfio_update_coherency(dev);
 
