diff -druNp --no-dereference linux-libre-4.12-gnu/arch/arm/boot/dts/armada-388-gp.dts linux-libre-4.12.6-gnu/arch/arm/boot/dts/armada-388-gp.dts
--- linux-libre-4.12-gnu/arch/arm/boot/dts/armada-388-gp.dts	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/arm/boot/dts/armada-388-gp.dts	2017-08-11 11:34:14.000000000 -0400
@@ -75,7 +75,7 @@
 					pinctrl-names = "default";
 					pinctrl-0 = <&pca0_pins>;
 					interrupt-parent = <&gpio0>;
-					interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+					interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
 					gpio-controller;
 					#gpio-cells = <2>;
 					interrupt-controller;
@@ -87,7 +87,7 @@
 					compatible = "nxp,pca9555";
 					pinctrl-names = "default";
 					interrupt-parent = <&gpio0>;
-					interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+					interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
 					gpio-controller;
 					#gpio-cells = <2>;
 					interrupt-controller;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/arm/boot/dts/tango4-vantage-1172.dts linux-libre-4.12.6-gnu/arch/arm/boot/dts/tango4-vantage-1172.dts
--- linux-libre-4.12-gnu/arch/arm/boot/dts/tango4-vantage-1172.dts	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/arm/boot/dts/tango4-vantage-1172.dts	2017-08-11 11:34:14.000000000 -0400
@@ -22,7 +22,7 @@
 };
 
 &eth0 {
-	phy-connection-type = "rgmii";
+	phy-connection-type = "rgmii-id";
 	phy-handle = <&eth0_phy>;
 	#address-cells = <1>;
 	#size-cells = <0>;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/arm/include/asm/elf.h linux-libre-4.12.6-gnu/arch/arm/include/asm/elf.h
--- linux-libre-4.12-gnu/arch/arm/include/asm/elf.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/arm/include/asm/elf.h	2017-08-11 11:34:14.000000000 -0400
@@ -112,12 +112,8 @@ int dump_task_regs(struct task_struct *t
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	4096
 
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE	(TASK_SIZE / 3 * 2)
+/* This is the base location for PIE (ET_DYN with INTERP) loads. */
+#define ELF_ET_DYN_BASE		0x400000UL
 
 /* When the program starts, a1 contains a pointer to a function to be 
    registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/arm/mach-mvebu/platsmp.c linux-libre-4.12.6-gnu/arch/arm/mach-mvebu/platsmp.c
--- linux-libre-4.12-gnu/arch/arm/mach-mvebu/platsmp.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/arm/mach-mvebu/platsmp.c	2017-08-11 11:34:14.000000000 -0400
@@ -211,7 +211,7 @@ static int mv98dx3236_resume_set_cpu_boo
 		return PTR_ERR(base);
 
 	writel(0, base + MV98DX3236_CPU_RESUME_CTRL_REG);
-	writel(virt_to_phys(boot_addr), base + MV98DX3236_CPU_RESUME_ADDR_REG);
+	writel(__pa_symbol(boot_addr), base + MV98DX3236_CPU_RESUME_ADDR_REG);
 
 	iounmap(base);
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/arm64/boot/dts/marvell/armada-37xx.dtsi linux-libre-4.12.6-gnu/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
--- linux-libre-4.12-gnu/arch/arm64/boot/dts/marvell/armada-37xx.dtsi	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/arm64/boot/dts/marvell/armada-37xx.dtsi	2017-08-11 11:34:14.000000000 -0400
@@ -75,14 +75,10 @@
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13
-			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
-			     <GIC_PPI 14
-			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
-			     <GIC_PPI 11
-			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
-			     <GIC_PPI 10
-			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
 	soc {
@@ -223,7 +219,7 @@
 				reg = <0x18800 0x100>, <0x18C00 0x20>;
 				gpiosb: gpio {
 					#gpio-cells = <2>;
-					gpio-ranges = <&pinctrl_sb 0 0 29>;
+					gpio-ranges = <&pinctrl_sb 0 0 30>;
 					gpio-controller;
 					interrupts =
 					<GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/arm64/include/asm/elf.h linux-libre-4.12.6-gnu/arch/arm64/include/asm/elf.h
--- linux-libre-4.12-gnu/arch/arm64/include/asm/elf.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/arm64/include/asm/elf.h	2017-08-11 11:34:14.000000000 -0400
@@ -113,12 +113,11 @@
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /*
- * This is the location that an ET_DYN program is loaded if exec'ed.  Typical
- * use of this is to invoke "./ld.so someprog" to test out a new version of
- * the loader.  We need to make sure that it is out of the way of the program
- * that it will "exec", and that there is sufficient room for the brk.
+ * This is the base location for PIE (ET_DYN with INTERP) loads. On
+ * 64-bit, this is raised to 4GB to leave the entire 32-bit address
+ * space open for things that want to use the area for 32-bit pointers.
  */
-#define ELF_ET_DYN_BASE	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE		0x100000000UL
 
 #ifndef __ASSEMBLY__
 
@@ -142,6 +141,7 @@ typedef struct user_fpsimd_state elf_fpr
 ({									\
 	clear_bit(TIF_32BIT, &current->mm->context.flags);		\
 	clear_thread_flag(TIF_32BIT);					\
+	current->personality &= ~READ_IMPLIES_EXEC;			\
 })
 
 /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
@@ -173,7 +173,8 @@ extern int arch_setup_additional_pages(s
 
 #ifdef CONFIG_COMPAT
 
-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
+#define COMPAT_ELF_ET_DYN_BASE		0x000400000UL
 
 /* AArch32 registers. */
 #define COMPAT_ELF_NGREG		18
@@ -187,6 +188,11 @@ typedef compat_elf_greg_t		compat_elf_gr
 					 ((x)->e_flags & EF_ARM_EABI_MASK))
 
 #define compat_start_thread		compat_start_thread
+/*
+ * Unlike the native SET_PERSONALITY macro, the compat version inherits
+ * READ_IMPLIES_EXEC across a fork() since this is the behaviour on
+ * arch/arm/.
+ */
 #define COMPAT_SET_PERSONALITY(ex)					\
 ({									\
 	set_bit(TIF_32BIT, &current->mm->context.flags);		\
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/mips/include/asm/branch.h linux-libre-4.12.6-gnu/arch/mips/include/asm/branch.h
--- linux-libre-4.12-gnu/arch/mips/include/asm/branch.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/include/asm/branch.h	2017-08-11 11:34:14.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-gnu/arch/mips/include/asm/mach-ralink/ralink_regs.h linux-libre-4.12.6-gnu/arch/mips/include/asm/mach-ralink/ralink_regs.h
--- linux-libre-4.12-gnu/arch/mips/include/asm/mach-ralink/ralink_regs.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/include/asm/mach-ralink/ralink_regs.h	2017-08-11 11:34:14.000000000 -0400
@@ -13,6 +13,8 @@
 #ifndef _RALINK_REGS_H_
 #define _RALINK_REGS_H_
 
+#include <linux/io.h>
+
 enum ralink_soc_type {
 	RALINK_UNKNOWN = 0,
 	RT2880_SOC,
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/mips/kernel/branch.c linux-libre-4.12.6-gnu/arch/mips/kernel/branch.c
--- linux-libre-4.12-gnu/arch/mips/kernel/branch.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/branch.c	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/proc.c linux-libre-4.12.6-gnu/arch/mips/kernel/proc.c
--- linux-libre-4.12-gnu/arch/mips/kernel/proc.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/proc.c	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/ptrace.c linux-libre-4.12.6-gnu/arch/mips/kernel/ptrace.c
--- linux-libre-4.12-gnu/arch/mips/kernel/ptrace.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/ptrace.c	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/scall32-o32.S linux-libre-4.12.6-gnu/arch/mips/kernel/scall32-o32.S
--- linux-libre-4.12-gnu/arch/mips/kernel/scall32-o32.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/scall32-o32.S	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/scall64-64.S linux-libre-4.12.6-gnu/arch/mips/kernel/scall64-64.S
--- linux-libre-4.12-gnu/arch/mips/kernel/scall64-64.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/scall64-64.S	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/scall64-n32.S linux-libre-4.12.6-gnu/arch/mips/kernel/scall64-n32.S
--- linux-libre-4.12-gnu/arch/mips/kernel/scall64-n32.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/scall64-n32.S	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/scall64-o32.S linux-libre-4.12.6-gnu/arch/mips/kernel/scall64-o32.S
--- linux-libre-4.12-gnu/arch/mips/kernel/scall64-o32.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/scall64-o32.S	2017-08-11 11:34:14.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-gnu/arch/mips/kernel/syscall.c linux-libre-4.12.6-gnu/arch/mips/kernel/syscall.c
--- linux-libre-4.12-gnu/arch/mips/kernel/syscall.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/kernel/syscall.c	2017-08-11 11:34:14.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-gnu/arch/mips/math-emu/cp1emu.c linux-libre-4.12.6-gnu/arch/mips/math-emu/cp1emu.c
--- linux-libre-4.12-gnu/arch/mips/math-emu/cp1emu.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/mips/math-emu/cp1emu.c	2017-08-11 11:34:14.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-gnu/arch/parisc/include/asm/dma-mapping.h linux-libre-4.12.6-gnu/arch/parisc/include/asm/dma-mapping.h
--- linux-libre-4.12-gnu/arch/parisc/include/asm/dma-mapping.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/include/asm/dma-mapping.h	2017-08-11 11:34:14.000000000 -0400
@@ -20,6 +20,8 @@
 ** flush/purge and allocate "regular" cacheable pages for everything.
 */
 
+#define DMA_ERROR_CODE	(~(dma_addr_t)0)
+
 #ifdef CONFIG_PA11
 extern const struct dma_map_ops pcxl_dma_ops;
 extern const struct dma_map_ops pcx_dma_ops;
@@ -54,12 +56,13 @@ parisc_walk_tree(struct device *dev)
 			break;
 		}
 	}
-	BUG_ON(!dev->platform_data);
 	return dev->platform_data;
 }
-		
-#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu)
-	
+
+#define GET_IOC(dev) ({					\
+	void *__pdata = parisc_walk_tree(dev);		\
+	__pdata ? HBA_DATA(__pdata)->iommu : NULL;	\
+})
 
 #ifdef CONFIG_IOMMU_CCIO
 struct parisc_device;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/include/asm/mmu_context.h linux-libre-4.12.6-gnu/arch/parisc/include/asm/mmu_context.h
--- linux-libre-4.12-gnu/arch/parisc/include/asm/mmu_context.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/include/asm/mmu_context.h	2017-08-11 11:34:14.000000000 -0400
@@ -49,15 +49,26 @@ static inline void load_context(mm_conte
 	mtctl(__space_to_prot(context), 8);
 }
 
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+static inline void switch_mm_irqs_off(struct mm_struct *prev,
+		struct mm_struct *next, struct task_struct *tsk)
 {
-
 	if (prev != next) {
 		mtctl(__pa(next->pgd), 25);
 		load_context(next->context);
 	}
 }
 
+static inline void switch_mm(struct mm_struct *prev,
+		struct mm_struct *next, struct task_struct *tsk)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	switch_mm_irqs_off(prev, next, tsk);
+	local_irq_restore(flags);
+}
+#define switch_mm_irqs_off switch_mm_irqs_off
+
 #define deactivate_mm(tsk,mm)	do { } while (0)
 
 static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/include/asm/thread_info.h linux-libre-4.12.6-gnu/arch/parisc/include/asm/thread_info.h
--- linux-libre-4.12-gnu/arch/parisc/include/asm/thread_info.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/include/asm/thread_info.h	2017-08-11 11:34:14.000000000 -0400
@@ -34,7 +34,7 @@ struct thread_info {
 
 /* thread information allocation */
 
-#define THREAD_SIZE_ORDER	2 /* PA-RISC requires at least 16k stack */
+#define THREAD_SIZE_ORDER	3 /* PA-RISC requires at least 32k stack */
 /* Be sure to hunt all references to this down when you change the size of
  * the kernel stack */
 #define THREAD_SIZE             (PAGE_SIZE << THREAD_SIZE_ORDER)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/kernel/cache.c linux-libre-4.12.6-gnu/arch/parisc/kernel/cache.c
--- linux-libre-4.12-gnu/arch/parisc/kernel/cache.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/kernel/cache.c	2017-08-11 11:34:14.000000000 -0400
@@ -453,8 +453,8 @@ void copy_user_page(void *vto, void *vfr
 	  before it can be accessed through the kernel mapping. */
 	preempt_disable();
 	flush_dcache_page_asm(__pa(vfrom), vaddr);
-	preempt_enable();
 	copy_page_asm(vto, vfrom);
+	preempt_enable();
 }
 EXPORT_SYMBOL(copy_user_page);
 
@@ -539,6 +539,10 @@ void flush_cache_mm(struct mm_struct *mm
 	struct vm_area_struct *vma;
 	pgd_t *pgd;
 
+	/* Flush the TLB to avoid speculation if coherency is required. */
+	if (parisc_requires_coherency())
+		flush_tlb_all();
+
 	/* Flushing the whole cache on each cpu takes forever on
 	   rp3440, etc.  So, avoid it if the mm isn't too big.  */
 	if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
@@ -577,33 +581,21 @@ void flush_cache_mm(struct mm_struct *mm
 void flush_cache_range(struct vm_area_struct *vma,
 		unsigned long start, unsigned long end)
 {
-	unsigned long addr;
-	pgd_t *pgd;
-
 	BUG_ON(!vma->vm_mm->context);
 
-	if ((end - start) >= parisc_cache_flush_threshold) {
-		flush_cache_all();
-		return;
-	}
+	/* Flush the TLB to avoid speculation if coherency is required. */
+	if (parisc_requires_coherency())
+		flush_tlb_range(vma, start, end);
 
-	if (vma->vm_mm->context == mfsp(3)) {
-		flush_user_dcache_range_asm(start, end);
-		if (vma->vm_flags & VM_EXEC)
-			flush_user_icache_range_asm(start, end);
+	if ((end - start) >= parisc_cache_flush_threshold
+	    || vma->vm_mm->context != mfsp(3)) {
+		flush_cache_all();
 		return;
 	}
 
-	pgd = vma->vm_mm->pgd;
-	for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) {
-		unsigned long pfn;
-		pte_t *ptep = get_ptep(pgd, addr);
-		if (!ptep)
-			continue;
-		pfn = pte_pfn(*ptep);
-		if (pfn_valid(pfn))
-			__flush_cache_page(vma, addr, PFN_PHYS(pfn));
-	}
+	flush_user_dcache_range_asm(start, end);
+	if (vma->vm_flags & VM_EXEC)
+		flush_user_icache_range_asm(start, end);
 }
 
 void
@@ -612,7 +604,8 @@ flush_cache_page(struct vm_area_struct *
 	BUG_ON(!vma->vm_mm->context);
 
 	if (pfn_valid(pfn)) {
-		flush_tlb_page(vma, vmaddr);
+		if (parisc_requires_coherency())
+			flush_tlb_page(vma, vmaddr);
 		__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
 	}
 }
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/kernel/irq.c linux-libre-4.12.6-gnu/arch/parisc/kernel/irq.c
--- linux-libre-4.12-gnu/arch/parisc/kernel/irq.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/kernel/irq.c	2017-08-11 11:34:14.000000000 -0400
@@ -380,7 +380,7 @@ static inline int eirr_to_irq(unsigned l
 /*
  * IRQ STACK - used for irq handler
  */
-#define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
+#define IRQ_STACK_SIZE      (4096 << 3) /* 32k irq stack size */
 
 union irq_stack_union {
 	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/kernel/process.c linux-libre-4.12.6-gnu/arch/parisc/kernel/process.c
--- linux-libre-4.12-gnu/arch/parisc/kernel/process.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/kernel/process.c	2017-08-11 11:34:14.000000000 -0400
@@ -53,6 +53,7 @@
 #include <linux/uaccess.h>
 #include <linux/rcupdate.h>
 #include <linux/random.h>
+#include <linux/nmi.h>
 
 #include <asm/io.h>
 #include <asm/asm-offsets.h>
@@ -145,6 +146,7 @@ void machine_power_off(void)
 
 	/* prevent soft lockup/stalled CPU messages for endless loop. */
 	rcu_sysrq_start();
+	lockup_detector_suspend();
 	for (;;);
 }
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/kernel/syscall_table.S linux-libre-4.12.6-gnu/arch/parisc/kernel/syscall_table.S
--- linux-libre-4.12-gnu/arch/parisc/kernel/syscall_table.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/kernel/syscall_table.S	2017-08-11 11:34:14.000000000 -0400
@@ -361,7 +361,7 @@
 	ENTRY_SAME(ni_syscall)	/* 263: reserved for vserver */
 	ENTRY_SAME(add_key)
 	ENTRY_SAME(request_key)		/* 265 */
-	ENTRY_SAME(keyctl)
+	ENTRY_COMP(keyctl)
 	ENTRY_SAME(ioprio_set)
 	ENTRY_SAME(ioprio_get)
 	ENTRY_SAME(inotify_init)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/parisc/mm/fault.c linux-libre-4.12.6-gnu/arch/parisc/mm/fault.c
--- linux-libre-4.12-gnu/arch/parisc/mm/fault.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/parisc/mm/fault.c	2017-08-11 11:34:14.000000000 -0400
@@ -367,7 +367,7 @@ bad_area:
 		case 15:	/* Data TLB miss fault/Data page fault */
 			/* send SIGSEGV when outside of vma */
 			if (!vma ||
-			    address < vma->vm_start || address > vma->vm_end) {
+			    address < vma->vm_start || address >= vma->vm_end) {
 				si.si_signo = SIGSEGV;
 				si.si_code = SEGV_MAPERR;
 				break;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/include/asm/atomic.h linux-libre-4.12.6-gnu/arch/powerpc/include/asm/atomic.h
--- linux-libre-4.12-gnu/arch/powerpc/include/asm/atomic.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/include/asm/atomic.h	2017-08-11 11:34:14.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-gnu/arch/powerpc/include/asm/elf.h linux-libre-4.12.6-gnu/arch/powerpc/include/asm/elf.h
--- linux-libre-4.12-gnu/arch/powerpc/include/asm/elf.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/include/asm/elf.h	2017-08-11 11:34:14.000000000 -0400
@@ -23,12 +23,13 @@
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE	0x20000000
+/*
+ * This is the base location for PIE (ET_DYN with INTERP) loads. On
+ * 64-bit, this is raised to 4GB to leave the entire 32-bit address
+ * space open for things that want to use the area for 32-bit pointers.
+ */
+#define ELF_ET_DYN_BASE		(is_32bit_task() ? 0x000400000UL : \
+						   0x100000000UL)
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/include/asm/reg.h linux-libre-4.12.6-gnu/arch/powerpc/include/asm/reg.h
--- linux-libre-4.12-gnu/arch/powerpc/include/asm/reg.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/include/asm/reg.h	2017-08-11 11:34:14.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-gnu/arch/powerpc/kernel/irq.c linux-libre-4.12.6-gnu/arch/powerpc/kernel/irq.c
--- linux-libre-4.12-gnu/arch/powerpc/kernel/irq.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/kernel/irq.c	2017-08-11 11:34:14.000000000 -0400
@@ -145,6 +145,19 @@ notrace unsigned int __check_irq_replay(
 
 	/* Clear bit 0 which we wouldn't clear otherwise */
 	local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
+	if (happened & PACA_IRQ_HARD_DIS) {
+		/*
+		 * We may have missed a decrementer interrupt if hard disabled.
+		 * Check the decrementer register in case we had a rollover
+		 * while hard disabled.
+		 */
+		if (!(happened & PACA_IRQ_DEC)) {
+			if (decrementer_check_overflow()) {
+				local_paca->irq_happened |= PACA_IRQ_DEC;
+				happened |= PACA_IRQ_DEC;
+			}
+		}
+	}
 
 	/*
 	 * Force the delivery of pending soft-disabled interrupts on PS3.
@@ -170,7 +183,7 @@ notrace unsigned int __check_irq_replay(
 	 * in case we also had a rollover while hard disabled
 	 */
 	local_paca->irq_happened &= ~PACA_IRQ_DEC;
-	if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
+	if (happened & PACA_IRQ_DEC)
 		return 0x900;
 
 	/* Finally check if an external interrupt happened */
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/kernel/misc_64.S linux-libre-4.12.6-gnu/arch/powerpc/kernel/misc_64.S
--- linux-libre-4.12-gnu/arch/powerpc/kernel/misc_64.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/kernel/misc_64.S	2017-08-11 11:34:14.000000000 -0400
@@ -614,6 +614,18 @@ _GLOBAL(kexec_sequence)
 	li	r0,0
 	std	r0,16(r1)
 
+BEGIN_FTR_SECTION
+	/*
+	 * This is the best time to turn AMR/IAMR off.
+	 * key 0 is used in radix for supervisor<->user
+	 * protection, but on hash key 0 is reserved
+	 * ideally we want to enter with a clean state.
+	 * NOTE, we rely on r0 being 0 from above.
+	 */
+	mtspr	SPRN_IAMR,r0
+	mtspr	SPRN_AMOR,r0
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+
 	/* save regs for local vars on new stack.
 	 * yes, we won't go back, but ...
 	 */
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/kernel/ptrace.c linux-libre-4.12.6-gnu/arch/powerpc/kernel/ptrace.c
--- linux-libre-4.12-gnu/arch/powerpc/kernel/ptrace.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/kernel/ptrace.c	2017-08-11 11:34:14.000000000 -0400
@@ -127,12 +127,19 @@ static void flush_tmregs_to_thread(struc
 	 * If task is not current, it will have been flushed already to
 	 * it's thread_struct during __switch_to().
 	 *
-	 * A reclaim flushes ALL the state.
+	 * A reclaim flushes ALL the state or if not in TM save TM SPRs
+	 * in the appropriate thread structures from live.
 	 */
 
-	if (tsk == current && MSR_TM_SUSPENDED(mfmsr()))
-		tm_reclaim_current(TM_CAUSE_SIGNAL);
+	if (tsk != current)
+		return;
 
+	if (MSR_TM_SUSPENDED(mfmsr())) {
+		tm_reclaim_current(TM_CAUSE_SIGNAL);
+	} else {
+		tm_enable();
+		tm_save_sprs(&(tsk->thread));
+	}
 }
 #else
 static inline void flush_tmregs_to_thread(struct task_struct *tsk) { }
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c linux-libre-4.12.6-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c
--- linux-libre-4.12-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c	2017-08-11 11:34:14.000000000 -0400
@@ -164,8 +164,10 @@ long kvmppc_alloc_reset_hpt(struct kvm *
 		goto out;
 	}
 
-	if (kvm->arch.hpt.virt)
+	if (kvm->arch.hpt.virt) {
 		kvmppc_free_hpt(&kvm->arch.hpt);
+		kvmppc_rmap_reset(kvm);
+	}
 
 	err = kvmppc_allocate_hpt(&info, order);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/kvm/book3s_hv.c linux-libre-4.12.6-gnu/arch/powerpc/kvm/book3s_hv.c
--- linux-libre-4.12-gnu/arch/powerpc/kvm/book3s_hv.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/kvm/book3s_hv.c	2017-08-11 11:34:14.000000000 -0400
@@ -2938,6 +2938,8 @@ static int kvmppc_vcpu_run_hv(struct kvm
 			run->fail_entry.hardware_entry_failure_reason = 0;
 			return -EINVAL;
 		}
+		/* Enable TM so we can read the TM SPRs */
+		mtmsr(mfmsr() | MSR_TM);
 		current->thread.tm_tfhar = mfspr(SPRN_TFHAR);
 		current->thread.tm_tfiar = mfspr(SPRN_TFIAR);
 		current->thread.tm_texasr = mfspr(SPRN_TEXASR);
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/kvm/book3s_xive.c linux-libre-4.12.6-gnu/arch/powerpc/kvm/book3s_xive.c
--- linux-libre-4.12-gnu/arch/powerpc/kvm/book3s_xive.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/kvm/book3s_xive.c	2017-08-11 11:34:14.000000000 -0400
@@ -1257,8 +1257,8 @@ static void xive_pre_save_scan(struct kv
 		if (!xc)
 			continue;
 		for (j = 0; j < KVMPPC_XIVE_Q_COUNT; j++) {
-			if (xc->queues[i].qpage)
-				xive_pre_save_queue(xive, &xc->queues[i]);
+			if (xc->queues[j].qpage)
+				xive_pre_save_queue(xive, &xc->queues[j]);
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/lib/sstep.c linux-libre-4.12.6-gnu/arch/powerpc/lib/sstep.c
--- linux-libre-4.12-gnu/arch/powerpc/lib/sstep.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/lib/sstep.c	2017-08-11 11:34:14.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-gnu/arch/powerpc/mm/mmu_context_book3s64.c linux-libre-4.12.6-gnu/arch/powerpc/mm/mmu_context_book3s64.c
--- linux-libre-4.12-gnu/arch/powerpc/mm/mmu_context_book3s64.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/mm/mmu_context_book3s64.c	2017-08-11 11:34:14.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-gnu/arch/powerpc/mm/pgtable-radix.c linux-libre-4.12.6-gnu/arch/powerpc/mm/pgtable-radix.c
--- linux-libre-4.12-gnu/arch/powerpc/mm/pgtable-radix.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/mm/pgtable-radix.c	2017-08-11 11:34:14.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-gnu/arch/powerpc/perf/isa207-common.c linux-libre-4.12.6-gnu/arch/powerpc/perf/isa207-common.c
--- linux-libre-4.12-gnu/arch/powerpc/perf/isa207-common.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/perf/isa207-common.c	2017-08-11 11:34:14.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-gnu/arch/powerpc/platforms/powernv/idle.c linux-libre-4.12.6-gnu/arch/powerpc/platforms/powernv/idle.c
--- linux-libre-4.12-gnu/arch/powerpc/platforms/powernv/idle.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/platforms/powernv/idle.c	2017-08-11 11:34:14.000000000 -0400
@@ -261,6 +261,7 @@ static u64 pnv_deepest_stop_psscr_val;
 static u64 pnv_deepest_stop_psscr_mask;
 static bool deepest_stop_found;
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * pnv_cpu_offline: A function that puts the CPU into the deepest
  * available platform idle state on a CPU-Offline.
@@ -293,6 +294,7 @@ unsigned long pnv_cpu_offline(unsigned i
 
 	return srr1;
 }
+#endif
 
 /*
  * Power ISA 3.0 idle initialization.
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/powerpc/platforms/pseries/lpar.c linux-libre-4.12.6-gnu/arch/powerpc/platforms/pseries/lpar.c
--- linux-libre-4.12-gnu/arch/powerpc/platforms/pseries/lpar.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/platforms/pseries/lpar.c	2017-08-11 11:34:14.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-gnu/arch/powerpc/platforms/pseries/reconfig.c linux-libre-4.12.6-gnu/arch/powerpc/platforms/pseries/reconfig.c
--- linux-libre-4.12-gnu/arch/powerpc/platforms/pseries/reconfig.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/powerpc/platforms/pseries/reconfig.c	2017-08-11 11:34:14.000000000 -0400
@@ -82,7 +82,6 @@ static int pSeries_reconfig_remove_node(
 
 	of_detach_node(np);
 	of_node_put(parent);
-	of_node_put(np); /* Must decrement the refcount */
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/s390/include/asm/elf.h linux-libre-4.12.6-gnu/arch/s390/include/asm/elf.h
--- linux-libre-4.12-gnu/arch/s390/include/asm/elf.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/s390/include/asm/elf.h	2017-08-11 11:34:14.000000000 -0400
@@ -161,14 +161,13 @@ extern unsigned int vdso_enabled;
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	4096
 
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk. 64-bit
-   tasks are aligned to 4GB. */
-#define ELF_ET_DYN_BASE (is_compat_task() ? \
-				(STACK_TOP / 3 * 2) : \
-				(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
+/*
+ * This is the base location for PIE (ET_DYN with INTERP) loads. On
+ * 64-bit, this is raised to 4GB to leave the entire 32-bit address
+ * space open for things that want to use the area for 32-bit pointers.
+ */
+#define ELF_ET_DYN_BASE		(is_compat_task() ? 0x000400000UL : \
+						    0x100000000UL)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports. */
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/s390/include/asm/syscall.h linux-libre-4.12.6-gnu/arch/s390/include/asm/syscall.h
--- linux-libre-4.12-gnu/arch/s390/include/asm/syscall.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/s390/include/asm/syscall.h	2017-08-11 11:34:14.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-gnu/arch/sparc/include/asm/asm-prototypes.h linux-libre-4.12.6-gnu/arch/sparc/include/asm/asm-prototypes.h
--- linux-libre-4.12-gnu/arch/sparc/include/asm/asm-prototypes.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.12.6-gnu/arch/sparc/include/asm/asm-prototypes.h	2017-08-11 11:34:14.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <asm/xor.h>
+#include <asm/checksum.h>
+#include <asm/trap_block.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <asm/ftrace.h>
+#include <asm/cacheflush.h>
+#include <asm/oplib.h>
+#include <linux/atomic.h>
+
+void *__memscan_zero(void *, size_t);
+void *__memscan_generic(void *, int, size_t);
+void *__bzero(void *, size_t);
+void VISenter(void); /* Dummy prototype to supress warning */
+#undef memcpy
+#undef memset
+void *memcpy(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+typedef int TItype __attribute__((mode(TI)));
+TItype __multi3(TItype a, TItype b);
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/include/asm/mmu_context_64.h linux-libre-4.12.6-gnu/arch/sparc/include/asm/mmu_context_64.h
--- linux-libre-4.12-gnu/arch/sparc/include/asm/mmu_context_64.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/include/asm/mmu_context_64.h	2017-08-11 11:34:14.000000000 -0400
@@ -27,9 +27,11 @@ void destroy_context(struct mm_struct *m
 void __tsb_context_switch(unsigned long pgd_pa,
 			  struct tsb_config *tsb_base,
 			  struct tsb_config *tsb_huge,
-			  unsigned long tsb_descr_pa);
+			  unsigned long tsb_descr_pa,
+			  unsigned long secondary_ctx);
 
-static inline void tsb_context_switch(struct mm_struct *mm)
+static inline void tsb_context_switch_ctx(struct mm_struct *mm,
+					  unsigned long ctx)
 {
 	__tsb_context_switch(__pa(mm->pgd),
 			     &mm->context.tsb_block[MM_TSB_BASE],
@@ -40,9 +42,12 @@ static inline void tsb_context_switch(st
 #else
 			     NULL
 #endif
-			     , __pa(&mm->context.tsb_descr[MM_TSB_BASE]));
+			     , __pa(&mm->context.tsb_descr[MM_TSB_BASE]),
+			     ctx);
 }
 
+#define tsb_context_switch(X) tsb_context_switch_ctx(X, 0)
+
 void tsb_grow(struct mm_struct *mm,
 	      unsigned long tsb_index,
 	      unsigned long mm_rss);
@@ -112,8 +117,7 @@ static inline void switch_mm(struct mm_s
 	 * cpu0 to update it's TSB because at that point the cpu_vm_mask
 	 * only had cpu1 set in it.
 	 */
-	load_secondary_context(mm);
-	tsb_context_switch(mm);
+	tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
 
 	/* Any time a processor runs a context on an address space
 	 * for the first time, we must flush that context out of the
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/include/asm/trap_block.h linux-libre-4.12.6-gnu/arch/sparc/include/asm/trap_block.h
--- linux-libre-4.12-gnu/arch/sparc/include/asm/trap_block.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/include/asm/trap_block.h	2017-08-11 11:34:14.000000000 -0400
@@ -54,6 +54,7 @@ extern struct trap_per_cpu trap_block[NR
 void init_cur_cpu_trap(struct thread_info *);
 void setup_tba(void);
 extern int ncpus_probed;
+extern u64 cpu_mondo_counter[NR_CPUS];
 
 unsigned long real_hard_smp_processor_id(void);
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/kernel/smp_64.c linux-libre-4.12.6-gnu/arch/sparc/kernel/smp_64.c
--- linux-libre-4.12-gnu/arch/sparc/kernel/smp_64.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/kernel/smp_64.c	2017-08-11 11:34:14.000000000 -0400
@@ -622,22 +622,48 @@ retry:
 	}
 }
 
-/* Multi-cpu list version.  */
+#define	CPU_MONDO_COUNTER(cpuid)	(cpu_mondo_counter[cpuid])
+#define	MONDO_USEC_WAIT_MIN		2
+#define	MONDO_USEC_WAIT_MAX		100
+#define	MONDO_RETRY_LIMIT		500000
+
+/* Multi-cpu list version.
+ *
+ * Deliver xcalls to 'cnt' number of cpus in 'cpu_list'.
+ * Sometimes not all cpus receive the mondo, requiring us to re-send
+ * the mondo until all cpus have received, or cpus are truly stuck
+ * unable to receive mondo, and we timeout.
+ * Occasionally a target cpu strand is borrowed briefly by hypervisor to
+ * perform guest service, such as PCIe error handling. Consider the
+ * service time, 1 second overall wait is reasonable for 1 cpu.
+ * Here two in-between mondo check wait time are defined: 2 usec for
+ * single cpu quick turn around and up to 100usec for large cpu count.
+ * Deliver mondo to large number of cpus could take longer, we adjusts
+ * the retry count as long as target cpus are making forward progress.
+ */
 static void hypervisor_xcall_deliver(struct trap_per_cpu *tb, int cnt)
 {
-	int retries, this_cpu, prev_sent, i, saw_cpu_error;
+	int this_cpu, tot_cpus, prev_sent, i, rem;
+	int usec_wait, retries, tot_retries;
+	u16 first_cpu = 0xffff;
+	unsigned long xc_rcvd = 0;
 	unsigned long status;
+	int ecpuerror_id = 0;
+	int enocpu_id = 0;
 	u16 *cpu_list;
+	u16 cpu;
 
 	this_cpu = smp_processor_id();
-
 	cpu_list = __va(tb->cpu_list_pa);
-
-	saw_cpu_error = 0;
-	retries = 0;
+	usec_wait = cnt * MONDO_USEC_WAIT_MIN;
+	if (usec_wait > MONDO_USEC_WAIT_MAX)
+		usec_wait = MONDO_USEC_WAIT_MAX;
+	retries = tot_retries = 0;
+	tot_cpus = cnt;
 	prev_sent = 0;
+
 	do {
-		int forward_progress, n_sent;
+		int n_sent, mondo_delivered, target_cpu_busy;
 
 		status = sun4v_cpu_mondo_send(cnt,
 					      tb->cpu_list_pa,
@@ -645,94 +671,113 @@ static void hypervisor_xcall_deliver(str
 
 		/* HV_EOK means all cpus received the xcall, we're done.  */
 		if (likely(status == HV_EOK))
-			break;
+			goto xcall_done;
+
+		/* If not these non-fatal errors, panic */
+		if (unlikely((status != HV_EWOULDBLOCK) &&
+			(status != HV_ECPUERROR) &&
+			(status != HV_ENOCPU)))
+			goto fatal_errors;
 
 		/* First, see if we made any forward progress.
 		 *
+		 * Go through the cpu_list, count the target cpus that have
+		 * received our mondo (n_sent), and those that did not (rem).
+		 * Re-pack cpu_list with the cpus remain to be retried in the
+		 * front - this simplifies tracking the truly stalled cpus.
+		 *
 		 * The hypervisor indicates successful sends by setting
 		 * cpu list entries to the value 0xffff.
+		 *
+		 * EWOULDBLOCK means some target cpus did not receive the
+		 * mondo and retry usually helps.
+		 *
+		 * ECPUERROR means at least one target cpu is in error state,
+		 * it's usually safe to skip the faulty cpu and retry.
+		 *
+		 * ENOCPU means one of the target cpu doesn't belong to the
+		 * domain, perhaps offlined which is unexpected, but not
+		 * fatal and it's okay to skip the offlined cpu.
 		 */
+		rem = 0;
 		n_sent = 0;
 		for (i = 0; i < cnt; i++) {
-			if (likely(cpu_list[i] == 0xffff))
+			cpu = cpu_list[i];
+			if (likely(cpu == 0xffff)) {
 				n_sent++;
+			} else if ((status == HV_ECPUERROR) &&
+				(sun4v_cpu_state(cpu) == HV_CPU_STATE_ERROR)) {
+				ecpuerror_id = cpu + 1;
+			} else if (status == HV_ENOCPU && !cpu_online(cpu)) {
+				enocpu_id = cpu + 1;
+			} else {
+				cpu_list[rem++] = cpu;
+			}
 		}
 
-		forward_progress = 0;
-		if (n_sent > prev_sent)
-			forward_progress = 1;
+		/* No cpu remained, we're done. */
+		if (rem == 0)
+			break;
 
-		prev_sent = n_sent;
+		/* Otherwise, update the cpu count for retry. */
+		cnt = rem;
 
-		/* If we get a HV_ECPUERROR, then one or more of the cpus
-		 * in the list are in error state.  Use the cpu_state()
-		 * hypervisor call to find out which cpus are in error state.
+		/* Record the overall number of mondos received by the
+		 * first of the remaining cpus.
 		 */
-		if (unlikely(status == HV_ECPUERROR)) {
-			for (i = 0; i < cnt; i++) {
-				long err;
-				u16 cpu;
+		if (first_cpu != cpu_list[0]) {
+			first_cpu = cpu_list[0];
+			xc_rcvd = CPU_MONDO_COUNTER(first_cpu);
+		}
 
-				cpu = cpu_list[i];
-				if (cpu == 0xffff)
-					continue;
+		/* Was any mondo delivered successfully? */
+		mondo_delivered = (n_sent > prev_sent);
+		prev_sent = n_sent;
 
-				err = sun4v_cpu_state(cpu);
-				if (err == HV_CPU_STATE_ERROR) {
-					saw_cpu_error = (cpu + 1);
-					cpu_list[i] = 0xffff;
-				}
-			}
-		} else if (unlikely(status != HV_EWOULDBLOCK))
-			goto fatal_mondo_error;
+		/* or, was any target cpu busy processing other mondos? */
+		target_cpu_busy = (xc_rcvd < CPU_MONDO_COUNTER(first_cpu));
+		xc_rcvd = CPU_MONDO_COUNTER(first_cpu);
 
-		/* Don't bother rewriting the CPU list, just leave the
-		 * 0xffff and non-0xffff entries in there and the
-		 * hypervisor will do the right thing.
-		 *
-		 * Only advance timeout state if we didn't make any
-		 * forward progress.
+		/* Retry count is for no progress. If we're making progress,
+		 * reset the retry count.
 		 */
-		if (unlikely(!forward_progress)) {
-			if (unlikely(++retries > 10000))
-				goto fatal_mondo_timeout;
-
-			/* Delay a little bit to let other cpus catch up
-			 * on their cpu mondo queue work.
-			 */
-			udelay(2 * cnt);
+		if (likely(mondo_delivered || target_cpu_busy)) {
+			tot_retries += retries;
+			retries = 0;
+		} else if (unlikely(retries > MONDO_RETRY_LIMIT)) {
+			goto fatal_mondo_timeout;
 		}
-	} while (1);
 
-	if (unlikely(saw_cpu_error))
-		goto fatal_mondo_cpu_error;
+		/* Delay a little bit to let other cpus catch up on
+		 * their cpu mondo queue work.
+		 */
+		if (!mondo_delivered)
+			udelay(usec_wait);
 
-	return;
+		retries++;
+	} while (1);
 
-fatal_mondo_cpu_error:
-	printk(KERN_CRIT "CPU[%d]: SUN4V mondo cpu error, some target cpus "
-	       "(including %d) were in error state\n",
-	       this_cpu, saw_cpu_error - 1);
+xcall_done:
+	if (unlikely(ecpuerror_id > 0)) {
+		pr_crit("CPU[%d]: SUN4V mondo cpu error, target cpu(%d) was in error state\n",
+		       this_cpu, ecpuerror_id - 1);
+	} else if (unlikely(enocpu_id > 0)) {
+		pr_crit("CPU[%d]: SUN4V mondo cpu error, target cpu(%d) does not belong to the domain\n",
+		       this_cpu, enocpu_id - 1);
+	}
 	return;
 
-fatal_mondo_timeout:
-	printk(KERN_CRIT "CPU[%d]: SUN4V mondo timeout, no forward "
-	       " progress after %d retries.\n",
-	       this_cpu, retries);
-	goto dump_cpu_list_and_out;
-
-fatal_mondo_error:
-	printk(KERN_CRIT "CPU[%d]: Unexpected SUN4V mondo error %lu\n",
-	       this_cpu, status);
-	printk(KERN_CRIT "CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) "
-	       "mondo_block_pa(%lx)\n",
-	       this_cpu, cnt, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
+fatal_errors:
+	/* fatal errors include bad alignment, etc */
+	pr_crit("CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) mondo_block_pa(%lx)\n",
+	       this_cpu, tot_cpus, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
+	panic("Unexpected SUN4V mondo error %lu\n", status);
 
-dump_cpu_list_and_out:
-	printk(KERN_CRIT "CPU[%d]: CPU list [ ", this_cpu);
-	for (i = 0; i < cnt; i++)
-		printk("%u ", cpu_list[i]);
-	printk("]\n");
+fatal_mondo_timeout:
+	/* some cpus being non-responsive to the cpu mondo */
+	pr_crit("CPU[%d]: SUN4V mondo timeout, cpu(%d) made no forward progress after %d retries. Total target cpus(%d).\n",
+	       this_cpu, first_cpu, (tot_retries + retries), tot_cpus);
+	panic("SUN4V mondo timeout panic\n");
 }
 
 static void (*xcall_deliver_impl)(struct trap_per_cpu *, int);
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/kernel/sun4v_ivec.S linux-libre-4.12.6-gnu/arch/sparc/kernel/sun4v_ivec.S
--- linux-libre-4.12-gnu/arch/sparc/kernel/sun4v_ivec.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/kernel/sun4v_ivec.S	2017-08-11 11:34:14.000000000 -0400
@@ -26,6 +26,21 @@ sun4v_cpu_mondo:
 	ldxa	[%g0] ASI_SCRATCHPAD, %g4
 	sub	%g4, TRAP_PER_CPU_FAULT_INFO, %g4
 
+	/* Get smp_processor_id() into %g3 */
+	sethi	%hi(trap_block), %g5
+	or	%g5, %lo(trap_block), %g5
+	sub	%g4, %g5, %g3
+	srlx	%g3, TRAP_BLOCK_SZ_SHIFT, %g3
+
+	/* Increment cpu_mondo_counter[smp_processor_id()] */
+	sethi	%hi(cpu_mondo_counter), %g5
+	or	%g5, %lo(cpu_mondo_counter), %g5
+	sllx	%g3, 3, %g3
+	add	%g5, %g3, %g5
+	ldx	[%g5], %g3
+	add	%g3, 1, %g3
+	stx	%g3, [%g5]
+
 	/* Get CPU mondo queue base phys address into %g7.  */
 	ldx	[%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/kernel/traps_64.c linux-libre-4.12.6-gnu/arch/sparc/kernel/traps_64.c
--- linux-libre-4.12-gnu/arch/sparc/kernel/traps_64.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/kernel/traps_64.c	2017-08-11 11:34:14.000000000 -0400
@@ -2733,6 +2733,7 @@ void do_getpsr(struct pt_regs *regs)
 	}
 }
 
+u64 cpu_mondo_counter[NR_CPUS] = {0};
 struct trap_per_cpu trap_block[NR_CPUS];
 EXPORT_SYMBOL(trap_block);
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/kernel/tsb.S linux-libre-4.12.6-gnu/arch/sparc/kernel/tsb.S
--- linux-libre-4.12-gnu/arch/sparc/kernel/tsb.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/kernel/tsb.S	2017-08-11 11:34:14.000000000 -0400
@@ -360,6 +360,7 @@ tsb_flush:
 	 * %o1:	TSB base config pointer
 	 * %o2:	TSB huge config pointer, or NULL if none
 	 * %o3:	Hypervisor TSB descriptor physical address
+	 * %o4: Secondary context to load, if non-zero
 	 *
 	 * We have to run this whole thing with interrupts
 	 * disabled so that the current cpu doesn't change
@@ -372,6 +373,17 @@ __tsb_context_switch:
 	rdpr	%pstate, %g1
 	wrpr	%g1, PSTATE_IE, %pstate
 
+	brz,pn	%o4, 1f
+	 mov	SECONDARY_CONTEXT, %o5
+
+661:	stxa	%o4, [%o5] ASI_DMMU
+	.section .sun4v_1insn_patch, "ax"
+	.word	661b
+	stxa	%o4, [%o5] ASI_MMU
+	.previous
+	flush	%g6
+
+1:
 	TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
 
 	stx	%o0, [%g2 + TRAP_PER_CPU_PGD_PADDR]
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/lib/atomic_64.S linux-libre-4.12.6-gnu/arch/sparc/lib/atomic_64.S
--- linux-libre-4.12-gnu/arch/sparc/lib/atomic_64.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/lib/atomic_64.S	2017-08-11 11:34:14.000000000 -0400
@@ -62,19 +62,23 @@ ENTRY(atomic_fetch_##op) /* %o0 = increm
 ENDPROC(atomic_fetch_##op);						\
 EXPORT_SYMBOL(atomic_fetch_##op);
 
-#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
+ATOMIC_OP(add)
+ATOMIC_OP_RETURN(add)
+ATOMIC_FETCH_OP(add)
 
-ATOMIC_OPS(add)
-ATOMIC_OPS(sub)
+ATOMIC_OP(sub)
+ATOMIC_OP_RETURN(sub)
+ATOMIC_FETCH_OP(sub)
 
-#undef ATOMIC_OPS
-#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
+ATOMIC_OP(and)
+ATOMIC_FETCH_OP(and)
 
-ATOMIC_OPS(and)
-ATOMIC_OPS(or)
-ATOMIC_OPS(xor)
+ATOMIC_OP(or)
+ATOMIC_FETCH_OP(or)
+
+ATOMIC_OP(xor)
+ATOMIC_FETCH_OP(xor)
 
-#undef ATOMIC_OPS
 #undef ATOMIC_FETCH_OP
 #undef ATOMIC_OP_RETURN
 #undef ATOMIC_OP
@@ -124,19 +128,23 @@ ENTRY(atomic64_fetch_##op) /* %o0 = incr
 ENDPROC(atomic64_fetch_##op);						\
 EXPORT_SYMBOL(atomic64_fetch_##op);
 
-#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op) ATOMIC64_FETCH_OP(op)
+ATOMIC64_OP(add)
+ATOMIC64_OP_RETURN(add)
+ATOMIC64_FETCH_OP(add)
 
-ATOMIC64_OPS(add)
-ATOMIC64_OPS(sub)
+ATOMIC64_OP(sub)
+ATOMIC64_OP_RETURN(sub)
+ATOMIC64_FETCH_OP(sub)
 
-#undef ATOMIC64_OPS
-#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_FETCH_OP(op)
+ATOMIC64_OP(and)
+ATOMIC64_FETCH_OP(and)
 
-ATOMIC64_OPS(and)
-ATOMIC64_OPS(or)
-ATOMIC64_OPS(xor)
+ATOMIC64_OP(or)
+ATOMIC64_FETCH_OP(or)
+
+ATOMIC64_OP(xor)
+ATOMIC64_FETCH_OP(xor)
 
-#undef ATOMIC64_OPS
 #undef ATOMIC64_FETCH_OP
 #undef ATOMIC64_OP_RETURN
 #undef ATOMIC64_OP
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/lib/checksum_64.S linux-libre-4.12.6-gnu/arch/sparc/lib/checksum_64.S
--- linux-libre-4.12-gnu/arch/sparc/lib/checksum_64.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/lib/checksum_64.S	2017-08-11 11:34:14.000000000 -0400
@@ -38,6 +38,7 @@ csum_partial_fix_alignment:
 
 	.align		32
 	.globl		csum_partial
+	.type		csum_partial,#function
 	EXPORT_SYMBOL(csum_partial)
 csum_partial:		/* %o0=buff, %o1=len, %o2=sum */
 	prefetch	[%o0 + 0x000], #n_reads
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/lib/csum_copy.S linux-libre-4.12.6-gnu/arch/sparc/lib/csum_copy.S
--- linux-libre-4.12-gnu/arch/sparc/lib/csum_copy.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/lib/csum_copy.S	2017-08-11 11:34:14.000000000 -0400
@@ -65,6 +65,7 @@
 	 add		%o5, %o4, %o4
 
 	.globl		FUNC_NAME
+	.type		FUNC_NAME,#function
 	EXPORT_SYMBOL(FUNC_NAME)
 FUNC_NAME:		/* %o0=src, %o1=dst, %o2=len, %o3=sum */
 	LOAD(prefetch, %o0 + 0x000, #n_reads)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/lib/memscan_64.S linux-libre-4.12.6-gnu/arch/sparc/lib/memscan_64.S
--- linux-libre-4.12-gnu/arch/sparc/lib/memscan_64.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/lib/memscan_64.S	2017-08-11 11:34:14.000000000 -0400
@@ -14,6 +14,8 @@
 	.text
 	.align	32
 	.globl		__memscan_zero, __memscan_generic
+	.type		__memscan_zero,#function
+	.type		__memscan_generic,#function
 	.globl		memscan
 	EXPORT_SYMBOL(__memscan_zero)
 	EXPORT_SYMBOL(__memscan_generic)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/lib/memset.S linux-libre-4.12.6-gnu/arch/sparc/lib/memset.S
--- linux-libre-4.12-gnu/arch/sparc/lib/memset.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/lib/memset.S	2017-08-11 11:34:14.000000000 -0400
@@ -63,6 +63,7 @@
 __bzero_begin:
 
 	.globl	__bzero
+	.type	__bzero,#function
 	.globl	memset
 	EXPORT_SYMBOL(__bzero)
 	EXPORT_SYMBOL(memset)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/lib/U3memcpy.S linux-libre-4.12.6-gnu/arch/sparc/lib/U3memcpy.S
--- linux-libre-4.12-gnu/arch/sparc/lib/U3memcpy.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/lib/U3memcpy.S	2017-08-11 11:34:14.000000000 -0400
@@ -145,13 +145,13 @@ ENDPROC(U3_retl_o2_plus_GS_plus_0x08)
 ENTRY(U3_retl_o2_and_7_plus_GS)
 	and	%o2, 7, %o2
 	retl
-	 add	%o2, GLOBAL_SPARE, %o2
+	 add	%o2, GLOBAL_SPARE, %o0
 ENDPROC(U3_retl_o2_and_7_plus_GS)
 ENTRY(U3_retl_o2_and_7_plus_GS_plus_8)
 	add	GLOBAL_SPARE, 8, GLOBAL_SPARE
 	and	%o2, 7, %o2
 	retl
-	 add	%o2, GLOBAL_SPARE, %o2
+	 add	%o2, GLOBAL_SPARE, %o0
 ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8)
 #endif
 
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/mm/gup.c linux-libre-4.12.6-gnu/arch/sparc/mm/gup.c
--- linux-libre-4.12-gnu/arch/sparc/mm/gup.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/mm/gup.c	2017-08-11 11:34:14.000000000 -0400
@@ -78,8 +78,8 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd
 		return 0;
 
 	refs = 0;
-	head = pmd_page(pmd);
-	page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+	page = pmd_page(pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+	head = compound_head(page);
 	do {
 		VM_BUG_ON(compound_head(page) != head);
 		pages[*nr] = page;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/mm/init_64.c linux-libre-4.12.6-gnu/arch/sparc/mm/init_64.c
--- linux-libre-4.12-gnu/arch/sparc/mm/init_64.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/mm/init_64.c	2017-08-11 11:34:14.000000000 -0400
@@ -325,6 +325,29 @@ static void __update_mmu_tsb_insert(stru
 }
 
 #ifdef CONFIG_HUGETLB_PAGE
+static void __init add_huge_page_size(unsigned long size)
+{
+	unsigned int order;
+
+	if (size_to_hstate(size))
+		return;
+
+	order = ilog2(size) - PAGE_SHIFT;
+	hugetlb_add_hstate(order);
+}
+
+static int __init hugetlbpage_init(void)
+{
+	add_huge_page_size(1UL << HPAGE_64K_SHIFT);
+	add_huge_page_size(1UL << HPAGE_SHIFT);
+	add_huge_page_size(1UL << HPAGE_256MB_SHIFT);
+	add_huge_page_size(1UL << HPAGE_2GB_SHIFT);
+
+	return 0;
+}
+
+arch_initcall(hugetlbpage_init);
+
 static int __init setup_hugepagesz(char *string)
 {
 	unsigned long long hugepage_size;
@@ -364,7 +387,7 @@ static int __init setup_hugepagesz(char
 		goto out;
 	}
 
-	hugetlb_add_hstate(hugepage_shift - PAGE_SHIFT);
+	add_huge_page_size(hugepage_size);
 	rc = 1;
 
 out:
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/sparc/power/hibernate.c linux-libre-4.12.6-gnu/arch/sparc/power/hibernate.c
--- linux-libre-4.12-gnu/arch/sparc/power/hibernate.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/sparc/power/hibernate.c	2017-08-11 11:34:14.000000000 -0400
@@ -35,6 +35,5 @@ void restore_processor_state(void)
 {
 	struct mm_struct *mm = current->active_mm;
 
-	load_secondary_context(mm);
-	tsb_context_switch(mm);
+	tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
 }
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/crypto/sha1_ssse3_glue.c linux-libre-4.12.6-gnu/arch/x86/crypto/sha1_ssse3_glue.c
--- linux-libre-4.12-gnu/arch/x86/crypto/sha1_ssse3_glue.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/crypto/sha1_ssse3_glue.c	2017-08-11 11:34:14.000000000 -0400
@@ -201,7 +201,7 @@ asmlinkage void sha1_transform_avx2(u32
 
 static bool avx2_usable(void)
 {
-	if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
+	if (false && avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
 		&& boot_cpu_has(X86_FEATURE_BMI1)
 		&& boot_cpu_has(X86_FEATURE_BMI2))
 		return true;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/include/asm/elf.h linux-libre-4.12.6-gnu/arch/x86/include/asm/elf.h
--- linux-libre-4.12-gnu/arch/x86/include/asm/elf.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/include/asm/elf.h	2017-08-11 11:34:14.000000000 -0400
@@ -245,12 +245,13 @@ extern int force_personality32;
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	4096
 
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+/*
+ * This is the base location for PIE (ET_DYN with INTERP) loads. On
+ * 64-bit, this is raised to 4GB to leave the entire 32-bit address
+ * space open for things that want to use the area for 32-bit pointers.
+ */
+#define ELF_ET_DYN_BASE		(mmap_is_ia32() ? 0x000400000UL : \
+						  0x100000000UL)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports.  This could be done in user space,
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/include/asm/msr-index.h linux-libre-4.12.6-gnu/arch/x86/include/asm/msr-index.h
--- linux-libre-4.12-gnu/arch/x86/include/asm/msr-index.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/include/asm/msr-index.h	2017-08-11 11:34:14.000000000 -0400
@@ -420,6 +420,8 @@
 #define MSR_IA32_TSC_ADJUST             0x0000003b
 #define MSR_IA32_BNDCFGS		0x00000d90
 
+#define MSR_IA32_BNDCFGS_RSVD		0x00000ffc
+
 #define MSR_IA32_XSS			0x00000da0
 
 #define FEATURE_CONTROL_LOCKED				(1<<0)
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/include/asm/pat.h linux-libre-4.12.6-gnu/arch/x86/include/asm/pat.h
--- linux-libre-4.12-gnu/arch/x86/include/asm/pat.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/include/asm/pat.h	2017-08-11 11:34:14.000000000 -0400
@@ -7,6 +7,7 @@
 bool pat_enabled(void);
 void pat_disable(const char *reason);
 extern void pat_init(void);
+extern void init_cache_modes(void);
 
 extern int reserve_memtype(u64 start, u64 end,
 		enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/include/asm/xen/hypercall.h linux-libre-4.12.6-gnu/arch/x86/include/asm/xen/hypercall.h
--- linux-libre-4.12-gnu/arch/x86/include/asm/xen/hypercall.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/include/asm/xen/hypercall.h	2017-08-11 11:34:14.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-gnu/arch/x86/kernel/acpi/boot.c linux-libre-4.12.6-gnu/arch/x86/kernel/acpi/boot.c
--- linux-libre-4.12-gnu/arch/x86/kernel/acpi/boot.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/kernel/acpi/boot.c	2017-08-11 11:34:14.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-gnu/arch/x86/kernel/apic/io_apic.c linux-libre-4.12.6-gnu/arch/x86/kernel/apic/io_apic.c
--- linux-libre-4.12-gnu/arch/x86/kernel/apic/io_apic.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/kernel/apic/io_apic.c	2017-08-11 11:34:14.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-gnu/arch/x86/kernel/kvm.c linux-libre-4.12.6-gnu/arch/x86/kernel/kvm.c
--- linux-libre-4.12-gnu/arch/x86/kernel/kvm.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/kernel/kvm.c	2017-08-11 11:34:14.000000000 -0400
@@ -151,6 +151,8 @@ void kvm_async_pf_task_wait(u32 token)
 		if (hlist_unhashed(&n.link))
 			break;
 
+		rcu_irq_exit();
+
 		if (!n.halted) {
 			local_irq_enable();
 			schedule();
@@ -159,11 +161,11 @@ void kvm_async_pf_task_wait(u32 token)
 			/*
 			 * We cannot reschedule. So halt.
 			 */
-			rcu_irq_exit();
 			native_safe_halt();
 			local_irq_disable();
-			rcu_irq_enter();
 		}
+
+		rcu_irq_enter();
 	}
 	if (!n.halted)
 		finish_swait(&n.wq, &wait);
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/kernel/setup.c linux-libre-4.12.6-gnu/arch/x86/kernel/setup.c
--- linux-libre-4.12-gnu/arch/x86/kernel/setup.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/kernel/setup.c	2017-08-11 11:34:14.000000000 -0400
@@ -1076,6 +1076,13 @@ void __init setup_arch(char **cmdline_p)
 	max_possible_pfn = max_pfn;
 
 	/*
+	 * This call is required when the CPU does not support PAT. If
+	 * mtrr_bp_init() invoked it already via pat_init() the call has no
+	 * effect.
+	 */
+	init_cache_modes();
+
+	/*
 	 * Define random base addresses for memory sections after max_pfn is
 	 * defined and before each memory section base is used.
 	 */
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/kvm/cpuid.h linux-libre-4.12.6-gnu/arch/x86/kvm/cpuid.h
--- linux-libre-4.12-gnu/arch/x86/kvm/cpuid.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/kvm/cpuid.h	2017-08-11 11:34:14.000000000 -0400
@@ -144,6 +144,14 @@ static inline bool guest_cpuid_has_rtm(s
 	return best && (best->ebx & bit(X86_FEATURE_RTM));
 }
 
+static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *best;
+
+	best = kvm_find_cpuid_entry(vcpu, 7, 0);
+	return best && (best->ebx & bit(X86_FEATURE_MPX));
+}
+
 static inline bool guest_cpuid_has_rdtscp(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpuid_entry2 *best;
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/kvm/vmx.c linux-libre-4.12.6-gnu/arch/x86/kvm/vmx.c
--- linux-libre-4.12-gnu/arch/x86/kvm/vmx.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/kvm/vmx.c	2017-08-11 11:34:14.000000000 -0400
@@ -3195,7 +3195,8 @@ static int vmx_get_msr(struct kvm_vcpu *
 		msr_info->data = vmcs_readl(GUEST_SYSENTER_ESP);
 		break;
 	case MSR_IA32_BNDCFGS:
-		if (!kvm_mpx_supported())
+		if (!kvm_mpx_supported() ||
+		    (!msr_info->host_initiated && !guest_cpuid_has_mpx(vcpu)))
 			return 1;
 		msr_info->data = vmcs_read64(GUEST_BNDCFGS);
 		break;
@@ -3277,7 +3278,11 @@ static int vmx_set_msr(struct kvm_vcpu *
 		vmcs_writel(GUEST_SYSENTER_ESP, data);
 		break;
 	case MSR_IA32_BNDCFGS:
-		if (!kvm_mpx_supported())
+		if (!kvm_mpx_supported() ||
+		    (!msr_info->host_initiated && !guest_cpuid_has_mpx(vcpu)))
+			return 1;
+		if (is_noncanonical_address(data & PAGE_MASK) ||
+		    (data & MSR_IA32_BNDCFGS_RSVD))
 			return 1;
 		vmcs_write64(GUEST_BNDCFGS, data);
 		break;
@@ -6547,7 +6552,6 @@ static __init int hardware_setup(void)
 	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
 	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
 	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
-	vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
 
 	memcpy(vmx_msr_bitmap_legacy_x2apic_apicv,
 			vmx_msr_bitmap_legacy, PAGE_SIZE);
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/lib/copy_user_64.S linux-libre-4.12.6-gnu/arch/x86/lib/copy_user_64.S
--- linux-libre-4.12-gnu/arch/x86/lib/copy_user_64.S	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/lib/copy_user_64.S	2017-08-11 11:34:14.000000000 -0400
@@ -37,7 +37,7 @@ ENTRY(copy_user_generic_unrolled)
 	movl %edx,%ecx
 	andl $63,%edx
 	shrl $6,%ecx
-	jz 17f
+	jz .L_copy_short_string
 1:	movq (%rsi),%r8
 2:	movq 1*8(%rsi),%r9
 3:	movq 2*8(%rsi),%r10
@@ -58,7 +58,8 @@ ENTRY(copy_user_generic_unrolled)
 	leaq 64(%rdi),%rdi
 	decl %ecx
 	jnz 1b
-17:	movl %edx,%ecx
+.L_copy_short_string:
+	movl %edx,%ecx
 	andl $7,%edx
 	shrl $3,%ecx
 	jz 20f
@@ -174,6 +175,8 @@ EXPORT_SYMBOL(copy_user_generic_string)
  */
 ENTRY(copy_user_enhanced_fast_string)
 	ASM_STAC
+	cmpl $64,%edx
+	jb .L_copy_short_string	/* less then 64 bytes, avoid the costly 'rep' */
 	movl %edx,%ecx
 1:	rep
 	movsb
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/mm/pat.c linux-libre-4.12.6-gnu/arch/x86/mm/pat.c
--- linux-libre-4.12-gnu/arch/x86/mm/pat.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/mm/pat.c	2017-08-11 11:34:14.000000000 -0400
@@ -37,14 +37,14 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "" fmt
 
-static bool boot_cpu_done;
-
-static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
-static void init_cache_modes(void);
+static bool __read_mostly boot_cpu_done;
+static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT);
+static bool __read_mostly pat_initialized;
+static bool __read_mostly init_cm_done;
 
 void pat_disable(const char *reason)
 {
-	if (!__pat_enabled)
+	if (pat_disabled)
 		return;
 
 	if (boot_cpu_done) {
@@ -52,10 +52,8 @@ void pat_disable(const char *reason)
 		return;
 	}
 
-	__pat_enabled = 0;
+	pat_disabled = true;
 	pr_info("x86/PAT: %s\n", reason);
-
-	init_cache_modes();
 }
 
 static int __init nopat(char *str)
@@ -67,7 +65,7 @@ early_param("nopat", nopat);
 
 bool pat_enabled(void)
 {
-	return !!__pat_enabled;
+	return pat_initialized;
 }
 EXPORT_SYMBOL_GPL(pat_enabled);
 
@@ -205,6 +203,8 @@ static void __init_cache_modes(u64 pat)
 		update_cache_mode_entry(i, cache);
 	}
 	pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg);
+
+	init_cm_done = true;
 }
 
 #define PAT(x, y)	((u64)PAT_ ## y << ((x)*8))
@@ -225,6 +225,7 @@ static void pat_bsp_init(u64 pat)
 	}
 
 	wrmsrl(MSR_IA32_CR_PAT, pat);
+	pat_initialized = true;
 
 	__init_cache_modes(pat);
 }
@@ -242,10 +243,9 @@ static void pat_ap_init(u64 pat)
 	wrmsrl(MSR_IA32_CR_PAT, pat);
 }
 
-static void init_cache_modes(void)
+void init_cache_modes(void)
 {
 	u64 pat = 0;
-	static int init_cm_done;
 
 	if (init_cm_done)
 		return;
@@ -287,8 +287,6 @@ static void init_cache_modes(void)
 	}
 
 	__init_cache_modes(pat);
-
-	init_cm_done = 1;
 }
 
 /**
@@ -306,10 +304,8 @@ void pat_init(void)
 	u64 pat;
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 
-	if (!pat_enabled()) {
-		init_cache_modes();
+	if (pat_disabled)
 		return;
-	}
 
 	if ((c->x86_vendor == X86_VENDOR_INTEL) &&
 	    (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
diff -druNp --no-dereference linux-libre-4.12-gnu/arch/x86/pci/fixup.c linux-libre-4.12.6-gnu/arch/x86/pci/fixup.c
--- linux-libre-4.12-gnu/arch/x86/pci/fixup.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/pci/fixup.c	2017-08-11 11:34:14.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-gnu/arch/x86/xen/smp_pv.c linux-libre-4.12.6-gnu/arch/x86/xen/smp_pv.c
--- linux-libre-4.12-gnu/arch/x86/xen/smp_pv.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/arch/x86/xen/smp_pv.c	2017-08-11 11:34:14.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-gnu/block/blk-core.c linux-libre-4.12.6-gnu/block/blk-core.c
--- linux-libre-4.12-gnu/block/blk-core.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/block/blk-core.c	2017-08-11 11:34:14.000000000 -0400
@@ -3307,6 +3307,10 @@ EXPORT_SYMBOL(blk_finish_plug);
  */
 void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
 {
+	/* not support for RQF_PM and ->rpm_status in blk-mq yet */
+	if (q->mq_ops)
+		return;
+
 	q->dev = dev;
 	q->rpm_status = RPM_ACTIVE;
 	pm_runtime_set_autosuspend_delay(q->dev, -1);
diff -druNp --no-dereference linux-libre-4.12-gnu/block/blk-mq.c linux-libre-4.12.6-gnu/block/blk-mq.c
--- linux-libre-4.12-gnu/block/blk-mq.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/block/blk-mq.c	2017-08-11 11:34:14.000000000 -0400
@@ -37,9 +37,6 @@
 #include "blk-wbt.h"
 #include "blk-mq-sched.h"
 
-static DEFINE_MUTEX(all_q_mutex);
-static LIST_HEAD(all_q_list);
-
 static void blk_mq_poll_stats_start(struct request_queue *q);
 static void blk_mq_poll_stats_fn(struct blk_stat_callback *cb);
 static void __blk_mq_stop_hw_queues(struct request_queue *q, bool sync);
@@ -1975,8 +1972,8 @@ static void blk_mq_init_cpu_queues(struc
 		INIT_LIST_HEAD(&__ctx->rq_list);
 		__ctx->queue = q;
 
-		/* If the cpu isn't online, the cpu is mapped to first hctx */
-		if (!cpu_online(i))
+		/* If the cpu isn't present, the cpu is mapped to first hctx */
+		if (!cpu_present(i))
 			continue;
 
 		hctx = blk_mq_map_queue(q, i);
@@ -2019,8 +2016,7 @@ static void blk_mq_free_map_and_requests
 	}
 }
 
-static void blk_mq_map_swqueue(struct request_queue *q,
-			       const struct cpumask *online_mask)
+static void blk_mq_map_swqueue(struct request_queue *q)
 {
 	unsigned int i, hctx_idx;
 	struct blk_mq_hw_ctx *hctx;
@@ -2038,13 +2034,11 @@ static void blk_mq_map_swqueue(struct re
 	}
 
 	/*
-	 * Map software to hardware queues
+	 * Map software to hardware queues.
+	 *
+	 * If the cpu isn't present, the cpu is mapped to first hctx.
 	 */
-	for_each_possible_cpu(i) {
-		/* If the cpu isn't online, the cpu is mapped to first hctx */
-		if (!cpumask_test_cpu(i, online_mask))
-			continue;
-
+	for_each_present_cpu(i) {
 		hctx_idx = q->mq_map[i];
 		/* unmapped hw queue can be remapped after CPU topo changed */
 		if (!set->tags[hctx_idx] &&
@@ -2340,16 +2334,8 @@ struct request_queue *blk_mq_init_alloca
 		blk_queue_softirq_done(q, set->ops->complete);
 
 	blk_mq_init_cpu_queues(q, set->nr_hw_queues);
-
-	get_online_cpus();
-	mutex_lock(&all_q_mutex);
-
-	list_add_tail(&q->all_q_node, &all_q_list);
 	blk_mq_add_queue_tag_set(set, q);
-	blk_mq_map_swqueue(q, cpu_online_mask);
-
-	mutex_unlock(&all_q_mutex);
-	put_online_cpus();
+	blk_mq_map_swqueue(q);
 
 	if (!(set->flags & BLK_MQ_F_NO_SCHED)) {
 		int ret;
@@ -2375,18 +2361,12 @@ void blk_mq_free_queue(struct request_qu
 {
 	struct blk_mq_tag_set	*set = q->tag_set;
 
-	mutex_lock(&all_q_mutex);
-	list_del_init(&q->all_q_node);
-	mutex_unlock(&all_q_mutex);
-
 	blk_mq_del_queue_tag_set(q);
-
 	blk_mq_exit_hw_queues(q, set, set->nr_hw_queues);
 }
 
 /* Basically redo blk_mq_init_queue with queue frozen */
-static void blk_mq_queue_reinit(struct request_queue *q,
-				const struct cpumask *online_mask)
+static void blk_mq_queue_reinit(struct request_queue *q)
 {
 	WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth));
 
@@ -2399,76 +2379,12 @@ static void blk_mq_queue_reinit(struct r
 	 * involves free and re-allocate memory, worthy doing?)
 	 */
 
-	blk_mq_map_swqueue(q, online_mask);
+	blk_mq_map_swqueue(q);
 
 	blk_mq_sysfs_register(q);
 	blk_mq_debugfs_register_hctxs(q);
 }
 
-/*
- * New online cpumask which is going to be set in this hotplug event.
- * Declare this cpumasks as global as cpu-hotplug operation is invoked
- * one-by-one and dynamically allocating this could result in a failure.
- */
-static struct cpumask cpuhp_online_new;
-
-static void blk_mq_queue_reinit_work(void)
-{
-	struct request_queue *q;
-
-	mutex_lock(&all_q_mutex);
-	/*
-	 * We need to freeze and reinit all existing queues.  Freezing
-	 * involves synchronous wait for an RCU grace period and doing it
-	 * one by one may take a long time.  Start freezing all queues in
-	 * one swoop and then wait for the completions so that freezing can
-	 * take place in parallel.
-	 */
-	list_for_each_entry(q, &all_q_list, all_q_node)
-		blk_freeze_queue_start(q);
-	list_for_each_entry(q, &all_q_list, all_q_node)
-		blk_mq_freeze_queue_wait(q);
-
-	list_for_each_entry(q, &all_q_list, all_q_node)
-		blk_mq_queue_reinit(q, &cpuhp_online_new);
-
-	list_for_each_entry(q, &all_q_list, all_q_node)
-		blk_mq_unfreeze_queue(q);
-
-	mutex_unlock(&all_q_mutex);
-}
-
-static int blk_mq_queue_reinit_dead(unsigned int cpu)
-{
-	cpumask_copy(&cpuhp_online_new, cpu_online_mask);
-	blk_mq_queue_reinit_work();
-	return 0;
-}
-
-/*
- * Before hotadded cpu starts handling requests, new mappings must be
- * established.  Otherwise, these requests in hw queue might never be
- * dispatched.
- *
- * For example, there is a single hw queue (hctx) and two CPU queues (ctx0
- * for CPU0, and ctx1 for CPU1).
- *
- * Now CPU1 is just onlined and a request is inserted into ctx1->rq_list
- * and set bit0 in pending bitmap as ctx1->index_hw is still zero.
- *
- * And then while running hw queue, blk_mq_flush_busy_ctxs() finds bit0 is set
- * in pending bitmap and tries to retrieve requests in hctx->ctxs[0]->rq_list.
- * But htx->ctxs[0] is a pointer to ctx0, so the request in ctx1->rq_list is
- * ignored.
- */
-static int blk_mq_queue_reinit_prepare(unsigned int cpu)
-{
-	cpumask_copy(&cpuhp_online_new, cpu_online_mask);
-	cpumask_set_cpu(cpu, &cpuhp_online_new);
-	blk_mq_queue_reinit_work();
-	return 0;
-}
-
 static int __blk_mq_alloc_rq_maps(struct blk_mq_tag_set *set)
 {
 	int i;
@@ -2679,7 +2595,7 @@ static void __blk_mq_update_nr_hw_queues
 	blk_mq_update_queue_map(set);
 	list_for_each_entry(q, &set->tag_list, tag_set_list) {
 		blk_mq_realloc_hw_ctxs(set, q);
-		blk_mq_queue_reinit(q, cpu_online_mask);
+		blk_mq_queue_reinit(q);
 	}
 
 	list_for_each_entry(q, &set->tag_list, tag_set_list)
@@ -2895,24 +2811,10 @@ bool blk_mq_poll(struct request_queue *q
 }
 EXPORT_SYMBOL_GPL(blk_mq_poll);
 
-void blk_mq_disable_hotplug(void)
-{
-	mutex_lock(&all_q_mutex);
-}
-
-void blk_mq_enable_hotplug(void)
-{
-	mutex_unlock(&all_q_mutex);
-}
-
 static int __init blk_mq_init(void)
 {
 	cpuhp_setup_state_multi(CPUHP_BLK_MQ_DEAD, "block/mq:dead", NULL,
 				blk_mq_hctx_notify_dead);
-
-	cpuhp_setup_state_nocalls(CPUHP_BLK_MQ_PREPARE, "block/mq:prepare",
-				  blk_mq_queue_reinit_prepare,
-				  blk_mq_queue_reinit_dead);
 	return 0;
 }
 subsys_initcall(blk_mq_init);
diff -druNp --no-dereference linux-libre-4.12-gnu/block/blk-mq-cpumap.c linux-libre-4.12.6-gnu/block/blk-mq-cpumap.c
--- linux-libre-4.12-gnu/block/blk-mq-cpumap.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/block/blk-mq-cpumap.c	2017-08-11 11:34:14.000000000 -0400
@@ -35,7 +35,6 @@ int blk_mq_map_queues(struct blk_mq_tag_
 {
 	unsigned int *map = set->mq_map;
 	unsigned int nr_queues = set->nr_hw_queues;
-	const struct cpumask *online_mask = cpu_online_mask;
 	unsigned int i, nr_cpus, nr_uniq_cpus, queue, first_sibling;
 	cpumask_var_t cpus;
 
@@ -44,7 +43,7 @@ int blk_mq_map_queues(struct blk_mq_tag_
 
 	cpumask_clear(cpus);
 	nr_cpus = nr_uniq_cpus = 0;
-	for_each_cpu(i, online_mask) {
+	for_each_present_cpu(i) {
 		nr_cpus++;
 		first_sibling = get_first_sibling(i);
 		if (!cpumask_test_cpu(first_sibling, cpus))
@@ -54,7 +53,7 @@ int blk_mq_map_queues(struct blk_mq_tag_
 
 	queue = 0;
 	for_each_possible_cpu(i) {
-		if (!cpumask_test_cpu(i, online_mask)) {
+		if (!cpumask_test_cpu(i, cpu_present_mask)) {
 			map[i] = 0;
 			continue;
 		}
diff -druNp --no-dereference linux-libre-4.12-gnu/block/blk-mq.h linux-libre-4.12.6-gnu/block/blk-mq.h
--- linux-libre-4.12-gnu/block/blk-mq.h	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/block/blk-mq.h	2017-08-11 11:34:14.000000000 -0400
@@ -56,11 +56,6 @@ void __blk_mq_insert_request(struct blk_
 				bool at_head);
 void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
 				struct list_head *list);
-/*
- * CPU hotplug helpers
- */
-void blk_mq_enable_hotplug(void);
-void blk_mq_disable_hotplug(void);
 
 /*
  * CPU -> queue mappings
diff -druNp --no-dereference linux-libre-4.12-gnu/crypto/authencesn.c linux-libre-4.12.6-gnu/crypto/authencesn.c
--- linux-libre-4.12-gnu/crypto/authencesn.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/crypto/authencesn.c	2017-08-11 11:34:14.000000000 -0400
@@ -248,6 +248,9 @@ static int crypto_authenc_esn_decrypt_ta
 	u8 *ihash = ohash + crypto_ahash_digestsize(auth);
 	u32 tmp[2];
 
+	if (!authsize)
+		goto decrypt;
+
 	/* Move high-order bits of sequence number back. */
 	scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
 	scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
@@ -256,6 +259,8 @@ static int crypto_authenc_esn_decrypt_ta
 	if (crypto_memneq(ihash, ohash, authsize))
 		return -EBADMSG;
 
+decrypt:
+
 	sg_init_table(areq_ctx->dst, 2);
 	dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
 
diff -druNp --no-dereference linux-libre-4.12-gnu/crypto/drbg.c linux-libre-4.12.6-gnu/crypto/drbg.c
--- linux-libre-4.12-gnu/crypto/drbg.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/crypto/drbg.c	2017-08-11 11:34:14.000000000 -0400
@@ -1691,6 +1691,7 @@ static int drbg_init_sym_kernel(struct d
 		return PTR_ERR(sk_tfm);
 	}
 	drbg->ctr_handle = sk_tfm;
+	init_completion(&drbg->ctr_completion);
 
 	req = skcipher_request_alloc(sk_tfm, GFP_KERNEL);
 	if (!req) {
diff -druNp --no-dereference linux-libre-4.12-gnu/crypto/rsa-pkcs1pad.c linux-libre-4.12.6-gnu/crypto/rsa-pkcs1pad.c
--- linux-libre-4.12-gnu/crypto/rsa-pkcs1pad.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/crypto/rsa-pkcs1pad.c	2017-08-11 11:34:14.000000000 -0400
@@ -496,7 +496,7 @@ static int pkcs1pad_verify_complete(stru
 		goto done;
 	pos++;
 
-	if (memcmp(out_buf + pos, digest_info->data, digest_info->size))
+	if (crypto_memneq(out_buf + pos, digest_info->data, digest_info->size))
 		goto done;
 
 	pos += digest_info->size;
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/acpi/acpi_lpss.c linux-libre-4.12.6-gnu/drivers/acpi/acpi_lpss.c
--- linux-libre-4.12-gnu/drivers/acpi/acpi_lpss.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/acpi/acpi_lpss.c	2017-08-11 11:34:14.000000000 -0400
@@ -85,6 +85,7 @@ static const struct lpss_device_desc lps
 };
 
 struct lpss_private_data {
+	struct acpi_device *adev;
 	void __iomem *mmio_base;
 	resource_size_t mmio_size;
 	unsigned int fixed_clk_rate;
@@ -155,6 +156,12 @@ static struct pwm_lookup byt_pwm_lookup[
 
 static void byt_pwm_setup(struct lpss_private_data *pdata)
 {
+	struct acpi_device *adev = pdata->adev;
+
+	/* Only call pwm_add_table for the first PWM controller */
+	if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
+		return;
+
 	if (!acpi_dev_present("INT33FD", NULL, -1))
 		pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup));
 }
@@ -180,6 +187,12 @@ static struct pwm_lookup bsw_pwm_lookup[
 
 static void bsw_pwm_setup(struct lpss_private_data *pdata)
 {
+	struct acpi_device *adev = pdata->adev;
+
+	/* Only call pwm_add_table for the first PWM controller */
+	if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
+		return;
+
 	pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup));
 }
 
@@ -456,6 +469,7 @@ static int acpi_lpss_create_device(struc
 		goto err_out;
 	}
 
+	pdata->adev = adev;
 	pdata->dev_desc = dev_desc;
 
 	if (dev_desc->setup)
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/acpi/ec.c linux-libre-4.12.6-gnu/drivers/acpi/ec.c
--- linux-libre-4.12-gnu/drivers/acpi/ec.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/acpi/ec.c	2017-08-11 11:34:14.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-gnu/drivers/acpi/nfit/core.c linux-libre-4.12.6-gnu/drivers/acpi/nfit/core.c
--- linux-libre-4.12-gnu/drivers/acpi/nfit/core.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/acpi/nfit/core.c	2017-08-11 11:34:14.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-gnu/drivers/ata/libata-scsi.c linux-libre-4.12.6-gnu/drivers/ata/libata-scsi.c
--- linux-libre-4.12-gnu/drivers/ata/libata-scsi.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/ata/libata-scsi.c	2017-08-11 11:34:14.000000000 -0400
@@ -3028,10 +3028,12 @@ static unsigned int atapi_xlat(struct at
 static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
 {
 	if (!sata_pmp_attached(ap)) {
-		if (likely(devno < ata_link_max_devices(&ap->link)))
+		if (likely(devno >= 0 &&
+			   devno < ata_link_max_devices(&ap->link)))
 			return &ap->link.device[devno];
 	} else {
-		if (likely(devno < ap->nr_pmp_links))
+		if (likely(devno >= 0 &&
+			   devno < ap->nr_pmp_links))
 			return &ap->pmp_link[devno].device[0];
 	}
 
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/base/core.c linux-libre-4.12.6-gnu/drivers/base/core.c
--- linux-libre-4.12-gnu/drivers/base/core.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/base/core.c	2017-08-11 11:34:14.000000000 -0400
@@ -2667,7 +2667,11 @@ void device_shutdown(void)
 		pm_runtime_get_noresume(dev);
 		pm_runtime_barrier(dev);
 
-		if (dev->bus && dev->bus->shutdown) {
+		if (dev->class && dev->class->shutdown) {
+			if (initcall_debug)
+				dev_info(dev, "shutdown\n");
+			dev->class->shutdown(dev);
+		} else if (dev->bus && dev->bus->shutdown) {
 			if (initcall_debug)
 				dev_info(dev, "shutdown\n");
 			dev->bus->shutdown(dev);
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/base/platform.c linux-libre-4.12.6-gnu/drivers/base/platform.c
--- linux-libre-4.12-gnu/drivers/base/platform.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/base/platform.c	2017-08-11 11:34:14.000000000 -0400
@@ -866,7 +866,7 @@ static ssize_t driver_override_store(str
 				     const char *buf, size_t count)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	char *driver_override, *old = pdev->driver_override, *cp;
+	char *driver_override, *old, *cp;
 
 	if (count > PATH_MAX)
 		return -EINVAL;
@@ -879,12 +879,15 @@ static ssize_t driver_override_store(str
 	if (cp)
 		*cp = '\0';
 
+	device_lock(dev);
+	old = pdev->driver_override;
 	if (strlen(driver_override)) {
 		pdev->driver_override = driver_override;
 	} else {
 		kfree(driver_override);
 		pdev->driver_override = NULL;
 	}
+	device_unlock(dev);
 
 	kfree(old);
 
@@ -895,8 +898,12 @@ static ssize_t driver_override_show(stru
 				    struct device_attribute *attr, char *buf)
 {
 	struct platform_device *pdev = to_platform_device(dev);
+	ssize_t len;
 
-	return sprintf(buf, "%s\n", pdev->driver_override);
+	device_lock(dev);
+	len = sprintf(buf, "%s\n", pdev->driver_override);
+	device_unlock(dev);
+	return len;
 }
 static DEVICE_ATTR_RW(driver_override);
 
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/base/power/domain.c linux-libre-4.12.6-gnu/drivers/base/power/domain.c
--- linux-libre-4.12-gnu/drivers/base/power/domain.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/base/power/domain.c	2017-08-11 11:34:14.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-gnu/drivers/base/power/sysfs.c linux-libre-4.12.6-gnu/drivers/base/power/sysfs.c
--- linux-libre-4.12-gnu/drivers/base/power/sysfs.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/base/power/sysfs.c	2017-08-11 11:34:14.000000000 -0400
@@ -272,6 +272,8 @@ static ssize_t pm_qos_latency_tolerance_
 			value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT;
 		else if (!strcmp(buf, "any") || !strcmp(buf, "any\n"))
 			value = PM_QOS_LATENCY_ANY;
+		else
+			return -EINVAL;
 	}
 	ret = dev_pm_qos_update_user_latency_tolerance(dev, value);
 	return ret < 0 ? ret : n;
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/base/power/wakeup.c linux-libre-4.12.6-gnu/drivers/base/power/wakeup.c
--- linux-libre-4.12-gnu/drivers/base/power/wakeup.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/base/power/wakeup.c	2017-08-11 11:34:14.000000000 -0400
@@ -60,6 +60,8 @@ static LIST_HEAD(wakeup_sources);
 
 static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue);
 
+DEFINE_STATIC_SRCU(wakeup_srcu);
+
 static struct wakeup_source deleted_ws = {
 	.name = "deleted",
 	.lock =  __SPIN_LOCK_UNLOCKED(deleted_ws.lock),
@@ -198,7 +200,7 @@ void wakeup_source_remove(struct wakeup_
 	spin_lock_irqsave(&events_lock, flags);
 	list_del_rcu(&ws->entry);
 	spin_unlock_irqrestore(&events_lock, flags);
-	synchronize_rcu();
+	synchronize_srcu(&wakeup_srcu);
 }
 EXPORT_SYMBOL_GPL(wakeup_source_remove);
 
@@ -332,12 +334,12 @@ void device_wakeup_detach_irq(struct dev
 void device_wakeup_arm_wake_irqs(void)
 {
 	struct wakeup_source *ws;
+	int srcuidx;
 
-	rcu_read_lock();
+	srcuidx = srcu_read_lock(&wakeup_srcu);
 	list_for_each_entry_rcu(ws, &wakeup_sources, entry)
 		dev_pm_arm_wake_irq(ws->wakeirq);
-
-	rcu_read_unlock();
+	srcu_read_unlock(&wakeup_srcu, srcuidx);
 }
 
 /**
@@ -348,12 +350,12 @@ void device_wakeup_arm_wake_irqs(void)
 void device_wakeup_disarm_wake_irqs(void)
 {
 	struct wakeup_source *ws;
+	int srcuidx;
 
-	rcu_read_lock();
+	srcuidx = srcu_read_lock(&wakeup_srcu);
 	list_for_each_entry_rcu(ws, &wakeup_sources, entry)
 		dev_pm_disarm_wake_irq(ws->wakeirq);
-
-	rcu_read_unlock();
+	srcu_read_unlock(&wakeup_srcu, srcuidx);
 }
 
 /**
@@ -804,10 +806,10 @@ EXPORT_SYMBOL_GPL(pm_wakeup_dev_event);
 void pm_print_active_wakeup_sources(void)
 {
 	struct wakeup_source *ws;
-	int active = 0;
+	int srcuidx, active = 0;
 	struct wakeup_source *last_activity_ws = NULL;
 
-	rcu_read_lock();
+	srcuidx = srcu_read_lock(&wakeup_srcu);
 	list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
 		if (ws->active) {
 			pr_debug("active wakeup source: %s\n", ws->name);
@@ -823,7 +825,7 @@ void pm_print_active_wakeup_sources(void
 	if (!active && last_activity_ws)
 		pr_debug("last active wakeup source: %s\n",
 			last_activity_ws->name);
-	rcu_read_unlock();
+	srcu_read_unlock(&wakeup_srcu, srcuidx);
 }
 EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
 
@@ -950,8 +952,9 @@ void pm_wakep_autosleep_enabled(bool set
 {
 	struct wakeup_source *ws;
 	ktime_t now = ktime_get();
+	int srcuidx;
 
-	rcu_read_lock();
+	srcuidx = srcu_read_lock(&wakeup_srcu);
 	list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
 		spin_lock_irq(&ws->lock);
 		if (ws->autosleep_enabled != set) {
@@ -965,7 +968,7 @@ void pm_wakep_autosleep_enabled(bool set
 		}
 		spin_unlock_irq(&ws->lock);
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&wakeup_srcu, srcuidx);
 }
 #endif /* CONFIG_PM_AUTOSLEEP */
 
@@ -1026,15 +1029,16 @@ static int print_wakeup_source_stats(str
 static int wakeup_sources_stats_show(struct seq_file *m, void *unused)
 {
 	struct wakeup_source *ws;
+	int srcuidx;
 
 	seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
 		"expire_count\tactive_since\ttotal_time\tmax_time\t"
 		"last_change\tprevent_suspend_time\n");
 
-	rcu_read_lock();
+	srcuidx = srcu_read_lock(&wakeup_srcu);
 	list_for_each_entry_rcu(ws, &wakeup_sources, entry)
 		print_wakeup_source_stats(m, ws);
-	rcu_read_unlock();
+	srcu_read_unlock(&wakeup_srcu, srcuidx);
 
 	print_wakeup_source_stats(m, &deleted_ws);
 
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/char/ipmi/ipmi_msghandler.c linux-libre-4.12.6-gnu/drivers/char/ipmi/ipmi_msghandler.c
--- linux-libre-4.12-gnu/drivers/char/ipmi/ipmi_msghandler.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/char/ipmi/ipmi_msghandler.c	2017-08-11 11:34:14.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-gnu/drivers/char/ipmi/ipmi_ssif.c linux-libre-4.12.6-gnu/drivers/char/ipmi/ipmi_ssif.c
--- linux-libre-4.12-gnu/drivers/char/ipmi/ipmi_ssif.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/char/ipmi/ipmi_ssif.c	2017-08-11 11:34:14.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-gnu/drivers/char/ipmi/ipmi_watchdog.c linux-libre-4.12.6-gnu/drivers/char/ipmi/ipmi_watchdog.c
--- linux-libre-4.12-gnu/drivers/char/ipmi/ipmi_watchdog.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/char/ipmi/ipmi_watchdog.c	2017-08-11 11:34:14.000000000 -0400
@@ -1163,10 +1163,11 @@ static int wdog_reboot_handler(struct no
 			ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
 			ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 		} else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
-			/* Set a long timer to let the reboot happens, but
-			   reboot if it hangs, but only if the watchdog
+			/* Set a long timer to let the reboot happen or
+			   reset if it hangs, but only if the watchdog
 			   timer was already running. */
-			timeout = 120;
+			if (timeout < 120)
+				timeout = 120;
 			pretimeout = 0;
 			ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
 			ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/char/tpm/tpm-chip.c linux-libre-4.12.6-gnu/drivers/char/tpm/tpm-chip.c
--- linux-libre-4.12-gnu/drivers/char/tpm/tpm-chip.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/char/tpm/tpm-chip.c	2017-08-11 11:34:14.000000000 -0400
@@ -143,6 +143,39 @@ static void tpm_devs_release(struct devi
 }
 
 /**
+ * tpm_class_shutdown() - prepare the TPM device for loss of power.
+ * @dev: device to which the chip is associated.
+ *
+ * Issues a TPM2_Shutdown command prior to loss of power, as required by the
+ * TPM 2.0 spec.
+ * Then, calls bus- and device- specific shutdown code.
+ *
+ * XXX: This codepath relies on the fact that sysfs is not enabled for
+ * TPM2: sysfs uses an implicit lock on chip->ops, so this could race if TPM2
+ * has sysfs support enabled before TPM sysfs's implicit locking is fixed.
+ */
+static int tpm_class_shutdown(struct device *dev)
+{
+	struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
+
+	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+		down_write(&chip->ops_sem);
+		tpm2_shutdown(chip, TPM2_SU_CLEAR);
+		chip->ops = NULL;
+		up_write(&chip->ops_sem);
+	}
+	/* Allow bus- and device-specific code to run. Note: since chip->ops
+	 * is NULL, more-specific shutdown code will not be able to issue TPM
+	 * commands.
+	 */
+	if (dev->bus && dev->bus->shutdown)
+		dev->bus->shutdown(dev);
+	else if (dev->driver && dev->driver->shutdown)
+		dev->driver->shutdown(dev);
+	return 0;
+}
+
+/**
  * tpm_chip_alloc() - allocate a new struct tpm_chip instance
  * @pdev: device to which the chip is associated
  *        At this point pdev mst be initialized, but does not have to
@@ -181,6 +214,7 @@ struct tpm_chip *tpm_chip_alloc(struct d
 	device_initialize(&chip->devs);
 
 	chip->dev.class = tpm_class;
+	chip->dev.class->shutdown = tpm_class_shutdown;
 	chip->dev.release = tpm_dev_release;
 	chip->dev.parent = pdev;
 	chip->dev.groups = chip->groups;
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/char/tpm/tpm-sysfs.c linux-libre-4.12.6-gnu/drivers/char/tpm/tpm-sysfs.c
--- linux-libre-4.12-gnu/drivers/char/tpm/tpm-sysfs.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/char/tpm/tpm-sysfs.c	2017-08-11 11:34:14.000000000 -0400
@@ -36,9 +36,10 @@ static ssize_t pubek_show(struct device
 	ssize_t err;
 	int i, rc;
 	char *str = buf;
-
 	struct tpm_chip *chip = to_tpm_chip(dev);
 
+	memset(&tpm_cmd, 0, sizeof(tpm_cmd));
+
 	tpm_cmd.header.in = tpm_readpubek_header;
 	err = tpm_transmit_cmd(chip, NULL, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
 			       READ_PUBEK_RESULT_MIN_BODY_SIZE, 0,
@@ -294,6 +295,9 @@ static const struct attribute_group tpm_
 
 void tpm_sysfs_add_device(struct tpm_chip *chip)
 {
+	/* XXX: If you wish to remove this restriction, you must first update
+	 * tpm_sysfs to explicitly lock chip->ops.
+	 */
 	if (chip->flags & TPM_CHIP_FLAG_TPM2)
 		return;
 
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/clk/sunxi-ng/ccu-sun5i.c linux-libre-4.12.6-gnu/drivers/clk/sunxi-ng/ccu-sun5i.c
--- linux-libre-4.12-gnu/drivers/clk/sunxi-ng/ccu-sun5i.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/clk/sunxi-ng/ccu-sun5i.c	2017-08-11 11:34:14.000000000 -0400
@@ -184,7 +184,7 @@ static struct ccu_mux cpu_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("cpu",
 						      cpu_parents,
 						      &ccu_mux_ops,
-						      CLK_IS_CRITICAL),
+						      CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
 	}
 };
 
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/cpufreq/intel_pstate.c linux-libre-4.12.6-gnu/drivers/cpufreq/intel_pstate.c
--- linux-libre-4.12-gnu/drivers/cpufreq/intel_pstate.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/cpufreq/intel_pstate.c	2017-08-11 11:34:14.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-gnu/drivers/crypto/atmel-sha.c linux-libre-4.12.6-gnu/drivers/crypto/atmel-sha.c
--- linux-libre-4.12-gnu/drivers/crypto/atmel-sha.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/atmel-sha.c	2017-08-11 11:34:14.000000000 -0400
@@ -1204,7 +1204,9 @@ static int atmel_sha_finup(struct ahash_
 	ctx->flags |= SHA_FLAGS_FINUP;
 
 	err1 = atmel_sha_update(req);
-	if (err1 == -EINPROGRESS || err1 == -EBUSY)
+	if (err1 == -EINPROGRESS ||
+	    (err1 == -EBUSY && (ahash_request_flags(req) &
+				CRYPTO_TFM_REQ_MAY_BACKLOG)))
 		return err1;
 
 	/*
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/crypto/bcm/spu2.c linux-libre-4.12.6-gnu/drivers/crypto/bcm/spu2.c
--- linux-libre-4.12-gnu/drivers/crypto/bcm/spu2.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/bcm/spu2.c	2017-08-11 11:34:14.000000000 -0400
@@ -302,6 +302,7 @@ spu2_hash_xlate(enum hash_alg hash_alg,
 		break;
 	case HASH_ALG_SHA3_512:
 		*spu2_type = SPU2_HASH_TYPE_SHA3_512;
+		break;
 	case HASH_ALG_LAST:
 	default:
 		err = -EINVAL;
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/crypto/caam/caamalg.c linux-libre-4.12.6-gnu/drivers/crypto/caam/caamalg.c
--- linux-libre-4.12-gnu/drivers/crypto/caam/caamalg.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/caam/caamalg.c	2017-08-11 11:34:14.000000000 -0400
@@ -882,10 +882,10 @@ static void ablkcipher_encrypt_done(stru
 {
 	struct ablkcipher_request *req = context;
 	struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -904,6 +904,14 @@ static void ablkcipher_encrypt_done(stru
 #endif
 
 	ablkcipher_unmap(jrdev, edesc, req);
+
+	/*
+	 * The crypto API expects us to set the IV (req->info) to the last
+	 * ciphertext block. This is used e.g. by the CTS mode.
+	 */
+	scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
+				 ivsize, 0);
+
 	kfree(edesc);
 
 	ablkcipher_request_complete(req, err);
@@ -914,10 +922,10 @@ static void ablkcipher_decrypt_done(stru
 {
 	struct ablkcipher_request *req = context;
 	struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -935,6 +943,14 @@ static void ablkcipher_decrypt_done(stru
 #endif
 
 	ablkcipher_unmap(jrdev, edesc, req);
+
+	/*
+	 * The crypto API expects us to set the IV (req->info) to the last
+	 * ciphertext block.
+	 */
+	scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
+				 ivsize, 0);
+
 	kfree(edesc);
 
 	ablkcipher_request_complete(req, err);
@@ -1475,8 +1491,7 @@ static struct ablkcipher_edesc *ablkciph
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
 		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct ablkcipher_edesc *edesc;
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/crypto/caam/caamhash.c linux-libre-4.12.6-gnu/drivers/crypto/caam/caamhash.c
--- linux-libre-4.12-gnu/drivers/crypto/caam/caamhash.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/caam/caamhash.c	2017-08-11 11:34:14.000000000 -0400
@@ -396,7 +396,7 @@ static int hash_digest_key(struct caam_h
 	ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result);
 	if (!ret) {
 		/* in progress */
-		wait_for_completion_interruptible(&result.completion);
+		wait_for_completion(&result.completion);
 		ret = result.err;
 #ifdef DEBUG
 		print_hex_dump(KERN_ERR,
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/crypto/caam/key_gen.c linux-libre-4.12.6-gnu/drivers/crypto/caam/key_gen.c
--- linux-libre-4.12-gnu/drivers/crypto/caam/key_gen.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/caam/key_gen.c	2017-08-11 11:34:14.000000000 -0400
@@ -149,7 +149,7 @@ int gen_split_key(struct device *jrdev,
 	ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result);
 	if (!ret) {
 		/* in progress */
-		wait_for_completion_interruptible(&result.completion);
+		wait_for_completion(&result.completion);
 		ret = result.err;
 #ifdef DEBUG
 		print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/crypto/Kconfig linux-libre-4.12.6-gnu/drivers/crypto/Kconfig
--- linux-libre-4.12-gnu/drivers/crypto/Kconfig	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/Kconfig	2017-08-11 11:34:14.000000000 -0400
@@ -629,7 +629,7 @@ source "drivers/crypto/virtio/Kconfig"
 config CRYPTO_DEV_BCM_SPU
 	tristate "Broadcom symmetric crypto/hash acceleration support"
 	depends on ARCH_BCM_IPROC
-	depends on BCM_PDC_MBOX
+	depends on MAILBOX
 	default m
 	select CRYPTO_DES
 	select CRYPTO_MD5
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/crypto/talitos.c linux-libre-4.12.6-gnu/drivers/crypto/talitos.c
--- linux-libre-4.12-gnu/drivers/crypto/talitos.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/crypto/talitos.c	2017-08-11 11:34:14.000000000 -0400
@@ -816,7 +816,7 @@ static void talitos_unregister_rng(struc
  * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
  */
 #define TALITOS_CRA_PRIORITY_AEAD_HSNA	(TALITOS_CRA_PRIORITY - 1)
-#define TALITOS_MAX_KEY_SIZE		96
+#define TALITOS_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
 #define TALITOS_MAX_IV_LENGTH		16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
 
 struct talitos_ctx {
@@ -1495,6 +1495,11 @@ static int ablkcipher_setkey(struct cryp
 {
 	struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
 
+	if (keylen > TALITOS_MAX_KEY_SIZE) {
+		crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+		return -EINVAL;
+	}
+
 	memcpy(&ctx->key, key, keylen);
 	ctx->keylen = keylen;
 
diff -druNp --no-dereference linux-libre-4.12-gnu/drivers/dax/device.c linux-libre-4.12.6-gnu/drivers/dax/device.c
--- linux-libre-4.12-gnu/drivers/dax/device.c	2017-07-02 19:07:02.000000000 -0400
+++ linux-libre-4.12.6-gnu/drivers/dax/device.c	2017-08-11 11:34:14.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,