diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/alpha/kernel/ptrace.c linux-libre-3.16.52-gnu/arch/alpha/kernel/ptrace.c
--- linux-libre-3.16.51-gnu/arch/alpha/kernel/ptrace.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/alpha/kernel/ptrace.c	2018-01-01 15:52:14.000000000 -0500
@@ -281,7 +281,7 @@ long arch_ptrace(struct task_struct *chi
 	/* When I and D space are separate, these will need to be fixed.  */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA:
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp), 0);
 		ret = -EIO;
 		if (copied != sizeof(tmp))
 			break;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm/boot/dts/da850-evm.dts linux-libre-3.16.52-gnu/arch/arm/boot/dts/da850-evm.dts
--- linux-libre-3.16.51-gnu/arch/arm/boot/dts/da850-evm.dts	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm/boot/dts/da850-evm.dts	2018-01-01 15:52:14.000000000 -0500
@@ -14,6 +14,13 @@
 	compatible = "ti,da850-evm", "ti,da850";
 	model = "DA850/AM1808/OMAP-L138 EVM";
 
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		serial2 = &serial2;
+		ethernet0 = &eth0;
+	};
+
 	soc {
 		pmx_core: pinmux@1c14120 {
 			status = "okay";
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm/include/asm/Kbuild linux-libre-3.16.52-gnu/arch/arm/include/asm/Kbuild
--- linux-libre-3.16.51-gnu/arch/arm/include/asm/Kbuild	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm/include/asm/Kbuild	2018-01-01 15:52:14.000000000 -0500
@@ -36,4 +36,3 @@ generic-y += termbits.h
 generic-y += termios.h
 generic-y += timex.h
 generic-y += trace_clock.h
-generic-y += unaligned.h
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm/include/asm/unaligned.h linux-libre-3.16.52-gnu/arch/arm/include/asm/unaligned.h
--- linux-libre-3.16.51-gnu/arch/arm/include/asm/unaligned.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm/include/asm/unaligned.h	2018-01-01 15:52:14.000000000 -0500
@@ -0,0 +1,27 @@
+#ifndef __ASM_ARM_UNALIGNED_H
+#define __ASM_ARM_UNALIGNED_H
+
+/*
+ * We generally want to set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS on ARMv6+,
+ * but we don't want to use linux/unaligned/access_ok.h since that can lead
+ * to traps on unaligned stm/ldm or strd/ldrd.
+ */
+#include <asm/byteorder.h>
+
+#if defined(__LITTLE_ENDIAN)
+# include <linux/unaligned/le_struct.h>
+# include <linux/unaligned/be_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned	__get_unaligned_le
+# define put_unaligned	__put_unaligned_le
+#elif defined(__BIG_ENDIAN)
+# include <linux/unaligned/be_struct.h>
+# include <linux/unaligned/le_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned	__get_unaligned_be
+# define put_unaligned	__put_unaligned_be
+#else
+# error need to define endianess
+#endif
+
+#endif /* __ASM_ARM_UNALIGNED_H */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm/kernel/traps.c linux-libre-3.16.52-gnu/arch/arm/kernel/traps.c
--- linux-libre-3.16.51-gnu/arch/arm/kernel/traps.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm/kernel/traps.c	2018-01-01 15:52:14.000000000 -0500
@@ -129,30 +129,26 @@ static void dump_mem(const char *lvl, co
 	set_fs(fs);
 }
 
-static void dump_instr(const char *lvl, struct pt_regs *regs)
+static void __dump_instr(const char *lvl, struct pt_regs *regs)
 {
 	unsigned long addr = instruction_pointer(regs);
 	const int thumb = thumb_mode(regs);
 	const int width = thumb ? 4 : 8;
-	mm_segment_t fs;
 	char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
 	int i;
 
 	/*
-	 * We need to switch to kernel mode so that we can use __get_user
-	 * to safely read from kernel space.  Note that we now dump the
-	 * code first, just in case the backtrace kills us.
+	 * Note that we now dump the code first, just in case the backtrace
+	 * kills us.
 	 */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
 
 	for (i = -4; i < 1 + !!thumb; i++) {
 		unsigned int val, bad;
 
 		if (thumb)
-			bad = __get_user(val, &((u16 *)addr)[i]);
+			bad = get_user(val, &((u16 *)addr)[i]);
 		else
-			bad = __get_user(val, &((u32 *)addr)[i]);
+			bad = get_user(val, &((u32 *)addr)[i]);
 
 		if (!bad)
 			p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
@@ -163,8 +159,20 @@ static void dump_instr(const char *lvl,
 		}
 	}
 	printk("%sCode: %s\n", lvl, str);
+}
 
-	set_fs(fs);
+static void dump_instr(const char *lvl, struct pt_regs *regs)
+{
+	mm_segment_t fs;
+
+	if (!user_mode(regs)) {
+		fs = get_fs();
+		set_fs(KERNEL_DS);
+		__dump_instr(lvl, regs);
+		set_fs(fs);
+	} else {
+		__dump_instr(lvl, regs);
+	}
 }
 
 #ifdef CONFIG_ARM_UNWIND
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm/kvm/emulate.c linux-libre-3.16.52-gnu/arch/arm/kvm/emulate.c
--- linux-libre-3.16.51-gnu/arch/arm/kvm/emulate.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm/kvm/emulate.c	2018-01-01 15:52:14.000000000 -0500
@@ -295,7 +295,7 @@ void kvm_inject_undefined(struct kvm_vcp
 	u32 return_offset = (is_thumb) ? 2 : 4;
 
 	new_spsr_value = cpsr;
-	new_lr_value = *vcpu_pc(vcpu) - return_offset;
+	new_lr_value = *vcpu_pc(vcpu) + return_offset;
 
 	*vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | UND_MODE;
 	*vcpu_cpsr(vcpu) |= PSR_I_BIT;
@@ -324,9 +324,8 @@ static void inject_abt(struct kvm_vcpu *
 	unsigned long new_spsr_value;
 	unsigned long cpsr = *vcpu_cpsr(vcpu);
 	u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
-	bool is_thumb = (cpsr & PSR_T_BIT);
 	u32 vect_offset;
-	u32 return_offset = (is_thumb) ? 4 : 0;
+	u32 return_offset = (is_pabt) ? 4 : 8;
 	bool is_lpae;
 
 	new_spsr_value = cpsr;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm/kvm/mmio.c linux-libre-3.16.52-gnu/arch/arm/kvm/mmio.c
--- linux-libre-3.16.51-gnu/arch/arm/kvm/mmio.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm/kvm/mmio.c	2018-01-01 15:52:14.000000000 -0500
@@ -113,7 +113,7 @@ int kvm_handle_mmio_return(struct kvm_vc
 		}
 
 		trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
-			       data);
+			       &data);
 		data = vcpu_data_host_to_guest(vcpu, data, len);
 		*vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt) = data;
 	}
@@ -192,7 +192,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu,
 	trace_kvm_mmio((mmio.is_write) ? KVM_TRACE_MMIO_WRITE :
 					 KVM_TRACE_MMIO_READ_UNSATISFIED,
 			mmio.len, fault_ipa,
-			(mmio.is_write) ? data : 0);
+			(mmio.is_write) ? &data : NULL);
 
 	if (mmio.is_write)
 		mmio_write_buf(mmio.data, mmio.len, data);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm64/kernel/head.S linux-libre-3.16.52-gnu/arch/arm64/kernel/head.S
--- linux-libre-3.16.51-gnu/arch/arm64/kernel/head.S	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm64/kernel/head.S	2018-01-01 15:52:14.000000000 -0500
@@ -269,6 +269,7 @@ ENDPROC(stext)
  * booted in EL1 or EL2 respectively.
  */
 ENTRY(el2_setup)
+	msr	SPsel, #1			// We want to use SP_EL{1,2}
 	mrs	x0, CurrentEL
 	cmp	x0, #CurrentEL_EL2
 	b.ne	1f
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm64/kernel/traps.c linux-libre-3.16.52-gnu/arch/arm64/kernel/traps.c
--- linux-libre-3.16.51-gnu/arch/arm64/kernel/traps.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm64/kernel/traps.c	2018-01-01 15:52:14.000000000 -0500
@@ -59,8 +59,7 @@ static void dump_mem(const char *lvl, co
 
 	/*
 	 * We need to switch to kernel mode so that we can use __get_user
-	 * to safely read from kernel space.  Note that we now dump the
-	 * code first, just in case the backtrace kills us.
+	 * to safely read from kernel space.
 	 */
 	fs = get_fs();
 	set_fs(KERNEL_DS);
@@ -97,25 +96,16 @@ static void dump_backtrace_entry(unsigne
 			 stack + sizeof(struct pt_regs));
 }
 
-static void dump_instr(const char *lvl, struct pt_regs *regs)
+static void __dump_instr(const char *lvl, struct pt_regs *regs)
 {
 	unsigned long addr = instruction_pointer(regs);
-	mm_segment_t fs;
 	char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
 	int i;
 
-	/*
-	 * We need to switch to kernel mode so that we can use __get_user
-	 * to safely read from kernel space.  Note that we now dump the
-	 * code first, just in case the backtrace kills us.
-	 */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-
 	for (i = -4; i < 1; i++) {
 		unsigned int val, bad;
 
-		bad = __get_user(val, &((u32 *)addr)[i]);
+		bad = get_user(val, &((u32 *)addr)[i]);
 
 		if (!bad)
 			p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val);
@@ -125,8 +115,18 @@ static void dump_instr(const char *lvl,
 		}
 	}
 	printk("%sCode: %s\n", lvl, str);
+}
 
-	set_fs(fs);
+static void dump_instr(const char *lvl, struct pt_regs *regs)
+{
+	if (!user_mode(regs)) {
+		mm_segment_t fs = get_fs();
+		set_fs(KERNEL_DS);
+		__dump_instr(lvl, regs);
+		set_fs(fs);
+	} else {
+		__dump_instr(lvl, regs);
+	}
 }
 
 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm64/kvm/inject_fault.c linux-libre-3.16.52-gnu/arch/arm64/kvm/inject_fault.c
--- linux-libre-3.16.51-gnu/arch/arm64/kvm/inject_fault.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm64/kvm/inject_fault.c	2018-01-01 15:52:14.000000000 -0500
@@ -29,12 +29,26 @@
 				 PSR_I_BIT | PSR_D_BIT)
 #define EL1_EXCEPT_SYNC_OFFSET	0x200
 
+/*
+ * Table taken from ARMv8 ARM DDI0487B-B, table G1-10.
+ */
+static const u8 return_offsets[8][2] = {
+	[0] = { 0, 0 },		/* Reset, unused */
+	[1] = { 4, 2 },		/* Undefined */
+	[2] = { 0, 0 },		/* SVC, unused */
+	[3] = { 4, 4 },		/* Prefetch abort */
+	[4] = { 8, 8 },		/* Data abort */
+	[5] = { 0, 0 },		/* HVC, unused */
+	[6] = { 4, 4 },		/* IRQ, unused */
+	[7] = { 4, 4 },		/* FIQ, unused */
+};
+
 static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 {
 	unsigned long cpsr;
 	unsigned long new_spsr_value = *vcpu_cpsr(vcpu);
 	bool is_thumb = (new_spsr_value & COMPAT_PSR_T_BIT);
-	u32 return_offset = (is_thumb) ? 4 : 0;
+	u32 return_offset = return_offsets[vect_offset >> 2][is_thumb];
 	u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
 
 	cpsr = mode | COMPAT_PSR_I_BIT;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/arm64/mm/fault.c linux-libre-3.16.52-gnu/arch/arm64/mm/fault.c
--- linux-libre-3.16.51-gnu/arch/arm64/mm/fault.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/arm64/mm/fault.c	2018-01-01 15:52:14.000000000 -0500
@@ -386,7 +386,7 @@ static struct fault_info {
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"input address range fault"	},
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 1 translation fault"	},
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 2 translation fault"	},
-	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"level 3 translation fault"	},
+	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 3 translation fault"	},
 	{ do_bad,		SIGBUS,  0,		"reserved access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 1 access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/blackfin/kernel/ptrace.c linux-libre-3.16.52-gnu/arch/blackfin/kernel/ptrace.c
--- linux-libre-3.16.51-gnu/arch/blackfin/kernel/ptrace.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/blackfin/kernel/ptrace.c	2018-01-01 15:52:14.000000000 -0500
@@ -270,7 +270,7 @@ long arch_ptrace(struct task_struct *chi
 			switch (bfin_mem_access_type(addr, to_copy)) {
 			case BFIN_MEM_ACCESS_CORE:
 			case BFIN_MEM_ACCESS_CORE_ONLY:
-				copied = access_process_vm(child, addr, &tmp,
+				copied = ptrace_access_vm(child, addr, &tmp,
 				                           to_copy, 0);
 				if (copied)
 					break;
@@ -323,7 +323,7 @@ long arch_ptrace(struct task_struct *chi
 			switch (bfin_mem_access_type(addr, to_copy)) {
 			case BFIN_MEM_ACCESS_CORE:
 			case BFIN_MEM_ACCESS_CORE_ONLY:
-				copied = access_process_vm(child, addr, &data,
+				copied = ptrace_access_vm(child, addr, &data,
 				                           to_copy, 1);
 				break;
 			case BFIN_MEM_ACCESS_DMA:
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/cris/arch-v32/kernel/ptrace.c linux-libre-3.16.52-gnu/arch/cris/arch-v32/kernel/ptrace.c
--- linux-libre-3.16.51-gnu/arch/cris/arch-v32/kernel/ptrace.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/cris/arch-v32/kernel/ptrace.c	2018-01-01 15:52:14.000000000 -0500
@@ -147,7 +147,7 @@ long arch_ptrace(struct task_struct *chi
 				/* The trampoline page is globally mapped, no page table to traverse.*/
 				tmp = *(unsigned long*)addr;
 			} else {
-				copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+				copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp), 0);
 
 				if (copied != sizeof(tmp))
 					break;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/ia64/kernel/ptrace.c linux-libre-3.16.52-gnu/arch/ia64/kernel/ptrace.c
--- linux-libre-3.16.51-gnu/arch/ia64/kernel/ptrace.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/ia64/kernel/ptrace.c	2018-01-01 15:52:14.000000000 -0500
@@ -1156,7 +1156,7 @@ arch_ptrace (struct task_struct *child,
 	case PTRACE_PEEKTEXT:
 	case PTRACE_PEEKDATA:
 		/* read word at location addr */
-		if (access_process_vm(child, addr, &data, sizeof(data), 0)
+		if (ptrace_access_vm(child, addr, &data, sizeof(data), 0)
 		    != sizeof(data))
 			return -EIO;
 		/* ensure return value is not mistaken for error code */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/mips/ar7/platform.c linux-libre-3.16.52-gnu/arch/mips/ar7/platform.c
--- linux-libre-3.16.51-gnu/arch/mips/ar7/platform.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/mips/ar7/platform.c	2018-01-01 15:52:14.000000000 -0500
@@ -581,6 +581,7 @@ static int __init ar7_register_uarts(voi
 	uart_port.type		= PORT_AR7;
 	uart_port.uartclk	= clk_get_rate(bus_clk) / 2;
 	uart_port.iotype	= UPIO_MEM32;
+	uart_port.flags		= UPF_FIXED_TYPE;
 	uart_port.regshift	= 2;
 
 	uart_port.line		= 0;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/mips/include/asm/mips-cm.h linux-libre-3.16.52-gnu/arch/mips/include/asm/mips-cm.h
--- linux-libre-3.16.51-gnu/arch/mips/include/asm/mips-cm.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/mips/include/asm/mips-cm.h	2018-01-01 15:52:14.000000000 -0500
@@ -173,8 +173,8 @@ BUILD_CM_Cx_R_(tcid_8_priority,	0x80)
 #define CM_GCR_BASE_GCRBASE_MSK			(_ULCAST_(0x1ffff) << 15)
 #define CM_GCR_BASE_CMDEFTGT_SHF		0
 #define CM_GCR_BASE_CMDEFTGT_MSK		(_ULCAST_(0x3) << 0)
-#define  CM_GCR_BASE_CMDEFTGT_DISABLED		0
-#define  CM_GCR_BASE_CMDEFTGT_MEM		1
+#define  CM_GCR_BASE_CMDEFTGT_MEM		0
+#define  CM_GCR_BASE_CMDEFTGT_RESERVED		1
 #define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
 #define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/mips/kernel/ptrace32.c linux-libre-3.16.52-gnu/arch/mips/kernel/ptrace32.c
--- linux-libre-3.16.51-gnu/arch/mips/kernel/ptrace32.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/mips/kernel/ptrace32.c	2018-01-01 15:52:14.000000000 -0500
@@ -69,7 +69,7 @@ long compat_arch_ptrace(struct task_stru
 		if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
 			break;
 
-		copied = access_process_vm(child, (u64)addrOthers, &tmp,
+		copied = ptrace_access_vm(child, (u64)addrOthers, &tmp,
 				sizeof(tmp), 0);
 		if (copied != sizeof(tmp))
 			break;
@@ -178,7 +178,7 @@ long compat_arch_ptrace(struct task_stru
 		if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
 			break;
 		ret = 0;
-		if (access_process_vm(child, (u64)addrOthers, &data,
+		if (ptrace_access_vm(child, (u64)addrOthers, &data,
 					sizeof(data), 1) == sizeof(data))
 			break;
 		ret = -EIO;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/mips/mm/uasm-micromips.c linux-libre-3.16.52-gnu/arch/mips/mm/uasm-micromips.c
--- linux-libre-3.16.51-gnu/arch/mips/mm/uasm-micromips.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/mips/mm/uasm-micromips.c	2018-01-01 15:52:14.000000000 -0500
@@ -83,7 +83,7 @@ static struct insn insn_table_MM[] = {
 	{ insn_jr, M(mm_pool32a_op, 0, 0, 0, mm_jalr_op, mm_pool32axf_op), RS },
 	{ insn_lb, M(mm_lb32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
 	{ insn_ld, 0, 0 },
-	{ insn_lh, M(mm_lh32_op, 0, 0, 0, 0, 0), RS | RS | SIMM },
+	{ insn_lh, M(mm_lh32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
 	{ insn_ll, M(mm_pool32c_op, 0, 0, (mm_ll_func << 1), 0, 0), RS | RT | SIMM },
 	{ insn_lld, 0, 0 },
 	{ insn_lui, M(mm_pool32i_op, mm_lui_op, 0, 0, 0, 0), RS | SIMM },
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/parisc/kernel/syscall.S linux-libre-3.16.52-gnu/arch/parisc/kernel/syscall.S
--- linux-libre-3.16.51-gnu/arch/parisc/kernel/syscall.S	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/parisc/kernel/syscall.S	2018-01-01 15:52:14.000000000 -0500
@@ -742,7 +742,7 @@ lws_compare_and_swap_2:
 10:	ldd	0(%sr3,%r25), %r25
 11:	ldd	0(%sr3,%r24), %r24
 #else
-	/* Load new value into r22/r23 - high/low */
+	/* Load old value into r22/r23 - high/low */
 10:	ldw	0(%sr3,%r25), %r22
 11:	ldw	4(%sr3,%r25), %r23
 	/* Load new value into fr4 for atomic store later */
@@ -834,11 +834,11 @@ cas2_action:
 	copy	%r0, %r28
 #else
 	/* Compare first word */
-19:	ldw,ma	0(%sr3,%r26), %r29
+19:	ldw	0(%sr3,%r26), %r29
 	sub,=	%r29, %r22, %r0
 	b,n	cas2_end
 	/* Compare second word */
-20:	ldw,ma	4(%sr3,%r26), %r29
+20:	ldw	4(%sr3,%r26), %r29
 	sub,=	%r29, %r23, %r0
 	b,n	cas2_end
 	/* Perform the store */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/powerpc/kernel/ptrace32.c linux-libre-3.16.52-gnu/arch/powerpc/kernel/ptrace32.c
--- linux-libre-3.16.51-gnu/arch/powerpc/kernel/ptrace32.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/powerpc/kernel/ptrace32.c	2018-01-01 15:52:14.000000000 -0500
@@ -73,7 +73,7 @@ long compat_arch_ptrace(struct task_stru
 		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
 			break;
 
-		copied = access_process_vm(child, (u64)addrOthers, &tmp,
+		copied = ptrace_access_vm(child, (u64)addrOthers, &tmp,
 				sizeof(tmp), 0);
 		if (copied != sizeof(tmp))
 			break;
@@ -178,7 +178,7 @@ long compat_arch_ptrace(struct task_stru
 		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
 			break;
 		ret = 0;
-		if (access_process_vm(child, (u64)addrOthers, &tmp,
+		if (ptrace_access_vm(child, (u64)addrOthers, &tmp,
 					sizeof(tmp), 1) == sizeof(tmp))
 			break;
 		ret = -EIO;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/powerpc/perf/core-book3s.c linux-libre-3.16.52-gnu/arch/powerpc/perf/core-book3s.c
--- linux-libre-3.16.51-gnu/arch/powerpc/perf/core-book3s.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/powerpc/perf/core-book3s.c	2018-01-01 15:52:14.000000000 -0500
@@ -755,6 +755,11 @@ void perf_event_print_debug(void)
 	u32 pmcs[MAX_HWEVENTS];
 	int i;
 
+	if (!ppmu) {
+		pr_info("Performance monitor hardware not registered.\n");
+		return;
+	}
+
 	if (!ppmu->n_counter)
 		return;
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/powerpc/platforms/pseries/mobility.c linux-libre-3.16.52-gnu/arch/powerpc/platforms/pseries/mobility.c
--- linux-libre-3.16.51-gnu/arch/powerpc/platforms/pseries/mobility.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/powerpc/platforms/pseries/mobility.c	2018-01-01 15:52:14.000000000 -0500
@@ -224,8 +224,10 @@ static int add_dt_node(__be32 parent_pha
 		return -ENOENT;
 
 	dn = dlpar_configure_connector(drc_index, parent_dn);
-	if (!dn)
+	if (!dn) {
+		of_node_put(parent_dn);
 		return -ENOENT;
+	}
 
 	rc = dlpar_attach_node(dn);
 	if (rc)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/s390/mm/gup.c linux-libre-3.16.52-gnu/arch/s390/mm/gup.c
--- linux-libre-3.16.51-gnu/arch/s390/mm/gup.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/s390/mm/gup.c	2018-01-01 15:52:14.000000000 -0500
@@ -51,13 +51,12 @@ static inline int gup_pte_range(pmd_t *p
 static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
 		unsigned long end, int write, struct page **pages, int *nr)
 {
-	unsigned long mask, result;
 	struct page *head, *page, *tail;
+	unsigned long mask;
 	int refs;
 
-	result = write ? 0 : _SEGMENT_ENTRY_PROTECT;
-	mask = result | _SEGMENT_ENTRY_INVALID;
-	if ((pmd_val(pmd) & mask) != result)
+	mask = (write ? _SEGMENT_ENTRY_PROTECT : 0) | _SEGMENT_ENTRY_INVALID;
+	if ((pmd_val(pmd) & mask) != 0)
 		return 0;
 	VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT));
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh2a/cpu/sh7264.h linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh2a/cpu/sh7264.h
--- linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh2a/cpu/sh7264.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh2a/cpu/sh7264.h	2018-01-01 15:52:14.000000000 -0500
@@ -43,9 +43,7 @@ enum {
 	GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
 	GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
 
-	/* Port H */
-	GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
-	GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+	/* Port H - Port H does not have a Data Register */
 
 	/* Port I - not on device */
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h
--- linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h	2018-01-01 15:52:14.000000000 -0500
@@ -45,9 +45,7 @@ enum {
 	GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
 	GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
 
-	/* Port H */
-	GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
-	GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+	/* Port H - Port H does not have a Data Register */
 
 	/* Port I - not on device */
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh4/cpu/sh7722.h linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh4/cpu/sh7722.h
--- linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh4/cpu/sh7722.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh4/cpu/sh7722.h	2018-01-01 15:52:14.000000000 -0500
@@ -67,7 +67,7 @@ enum {
 	GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
 
 	/* PTQ */
-	GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
+	GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
 	GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
 
 	/* PTR */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh4/cpu/sh7757.h linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh4/cpu/sh7757.h
--- linux-libre-3.16.51-gnu/arch/sh/include/cpu-sh4/cpu/sh7757.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/sh/include/cpu-sh4/cpu/sh7757.h	2018-01-01 15:52:14.000000000 -0500
@@ -40,7 +40,7 @@ enum {
 
 	/* PTJ */
 	GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3,
-	GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV,
+	GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6,
 
 	/* PTK */
 	GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3,
@@ -48,7 +48,7 @@ enum {
 
 	/* PTL */
 	GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3,
-	GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV,
+	GPIO_PTL4, GPIO_PTL5, GPIO_PTL6,
 
 	/* PTM */
 	GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3,
@@ -56,7 +56,7 @@ enum {
 
 	/* PTN */
 	GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3,
-	GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV,
+	GPIO_PTN4, GPIO_PTN5, GPIO_PTN6,
 
 	/* PTO */
 	GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3,
@@ -68,7 +68,7 @@ enum {
 
 	/* PTQ */
 	GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3,
-	GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV,
+	GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6,
 
 	/* PTR */
 	GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/tile/kernel/setup.c linux-libre-3.16.52-gnu/arch/tile/kernel/setup.c
--- linux-libre-3.16.51-gnu/arch/tile/kernel/setup.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/tile/kernel/setup.c	2018-01-01 15:52:14.000000000 -0500
@@ -139,7 +139,7 @@ static int __init setup_maxnodemem(char
 {
 	char *endp;
 	unsigned long long maxnodemem;
-	long node;
+	unsigned long node;
 
 	node = str ? simple_strtoul(str, &endp, 0) : INT_MAX;
 	if (node >= MAX_NUMNODES || *endp != ':')
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/crypto/salsa20_glue.c linux-libre-3.16.52-gnu/arch/x86/crypto/salsa20_glue.c
--- linux-libre-3.16.51-gnu/arch/x86/crypto/salsa20_glue.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/crypto/salsa20_glue.c	2018-01-01 15:52:14.000000000 -0500
@@ -59,13 +59,6 @@ static int encrypt(struct blkcipher_desc
 
 	salsa20_ivsetup(ctx, walk.iv);
 
-	if (likely(walk.nbytes == nbytes))
-	{
-		salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
-				      walk.dst.virt.addr, nbytes);
-		return blkcipher_walk_done(desc, &walk, 0);
-	}
-
 	while (walk.nbytes >= 64) {
 		salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
 				      walk.dst.virt.addr,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/include/asm/uaccess.h linux-libre-3.16.52-gnu/arch/x86/include/asm/uaccess.h
--- linux-libre-3.16.51-gnu/arch/x86/include/asm/uaccess.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/include/asm/uaccess.h	2018-01-01 15:52:14.000000000 -0500
@@ -7,6 +7,7 @@
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
 #include <linux/string.h>
+#include <linux/preempt_mask.h>
 #include <asm/asm.h>
 #include <asm/page.h>
 #include <asm/smap.h>
@@ -66,6 +67,12 @@ static inline bool __chk_range_not_ok(un
 	__chk_range_not_ok((unsigned long __force)(addr), size, limit); \
 })
 
+#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
+# define WARN_ON_IN_IRQ()	WARN_ON_ONCE(!in_task())
+#else
+# define WARN_ON_IN_IRQ()
+#endif
+
 /**
  * access_ok: - Checks if a user space pointer is valid
  * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
@@ -85,8 +92,11 @@ static inline bool __chk_range_not_ok(un
  * checks that the pointer is in the user space range - after calling
  * this function, memory access functions may still return -EFAULT.
  */
-#define access_ok(type, addr, size) \
-	likely(!__range_not_ok(addr, size, user_addr_max()))
+#define access_ok(type, addr, size)					\
+({									\
+	WARN_ON_IN_IRQ();						\
+	likely(!__range_not_ok(addr, size, user_addr_max()));		\
+})
 
 /*
  * The exception table consists of pairs of addresses relative to the
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/kernel/amd_nb.c linux-libre-3.16.52-gnu/arch/x86/kernel/amd_nb.c
--- linux-libre-3.16.51-gnu/arch/x86/kernel/amd_nb.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/kernel/amd_nb.c	2018-01-01 15:52:14.000000000 -0500
@@ -13,16 +13,24 @@
 #include <linux/spinlock.h>
 #include <asm/amd_nb.h>
 
+#define PCI_DEVICE_ID_AMD_17H_DF_F3	0x1463
+#define PCI_DEVICE_ID_AMD_17H_DF_F4	0x1464
+
 static u32 *flush_words;
 
+#define PCI_DEVICE_ID_AMD_CNB17H_F4     0x1704
+
 const struct pci_device_id amd_nb_misc_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
 	{}
 };
 EXPORT_SYMBOL(amd_nb_misc_ids);
@@ -30,8 +38,11 @@ EXPORT_SYMBOL(amd_nb_misc_ids);
 static const struct pci_device_id amd_nb_link_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
 	{}
 };
 
@@ -278,6 +289,41 @@ void amd_flush_garts(void)
 }
 EXPORT_SYMBOL_GPL(amd_flush_garts);
 
+static void __fix_erratum_688(void *info)
+{
+#define MSR_AMD64_IC_CFG 0xC0011021
+
+	msr_set_bit(MSR_AMD64_IC_CFG, 3);
+	msr_set_bit(MSR_AMD64_IC_CFG, 14);
+}
+
+/* Apply erratum 688 fix so machines without a BIOS fix work. */
+static __init void fix_erratum_688(void)
+{
+	struct pci_dev *F4;
+	u32 val;
+
+	if (boot_cpu_data.x86 != 0x14)
+		return;
+
+	if (!amd_northbridges.num)
+		return;
+
+	F4 = node_to_amd_nb(0)->link;
+	if (!F4)
+		return;
+
+	if (pci_read_config_dword(F4, 0x164, &val))
+		return;
+
+	if (val & BIT(2))
+		return;
+
+	on_each_cpu(__fix_erratum_688, NULL, 0);
+
+	pr_info("x86/cpu/AMD: CPU erratum 688 worked around\n");
+}
+
 static __init int init_amd_nbs(void)
 {
 	int err = 0;
@@ -290,6 +336,8 @@ static __init int init_amd_nbs(void)
 	if (amd_cache_gart() < 0)
 		pr_notice("Cannot initialize GART flush words, GART support disabled\n");
 
+	fix_erratum_688();
+
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/kernel/cpu/microcode/intel.c linux-libre-3.16.52-gnu/arch/x86/kernel/cpu/microcode/intel.c
--- linux-libre-3.16.51-gnu/arch/x86/kernel/cpu/microcode/intel.c	2017-11-26 13:21:20.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/kernel/cpu/microcode/intel.c	2018-01-02 11:12:17.000000000 -0500
@@ -267,6 +267,18 @@ static int get_ucode_fw(void *to, const
 	return 0;
 }
 
+static bool is_blacklisted(unsigned int cpu)
+{
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+	if (c->x86 == 6 && c->x86_model == 0x4F) {
+		pr_err_once("late loading on model 79 is disabled.\n");
+		return true;
+	}
+
+	return false;
+}
+
 static enum ucode_state request_microcode_fw(int cpu, struct device *device,
 					     bool refresh_fw)
 {
@@ -275,6 +287,9 @@ static enum ucode_state request_microcod
 	const struct firmware *firmware;
 	enum ucode_state ret;
 
+	if (is_blacklisted(cpu))
+		return UCODE_NFOUND;
+
 	sprintf(name, "/*(DEBLOBBED)*/",
 		c->x86, c->x86_model, c->x86_mask);
 
@@ -299,6 +314,9 @@ static int get_ucode_user(void *to, cons
 static enum ucode_state
 request_microcode_user(int cpu, const void __user *buf, size_t size)
 {
+	if (is_blacklisted(cpu))
+		return UCODE_NFOUND;
+
 	return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/kvm/vmx.c linux-libre-3.16.52-gnu/arch/x86/kvm/vmx.c
--- linux-libre-3.16.51-gnu/arch/x86/kvm/vmx.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/kvm/vmx.c	2018-01-01 15:52:14.000000000 -0500
@@ -8670,7 +8670,7 @@ static void load_vmcs12_host_state(struc
 	 * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask();
 	 */
 	vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK);
-	kvm_set_cr4(vcpu, vmcs12->host_cr4);
+	vmx_set_cr4(vcpu, vmcs12->host_cr4);
 
 	nested_ept_uninit_mmu_context(vcpu);
 
@@ -9029,12 +9029,7 @@ static int __init vmx_init(void)
 	memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
 	memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
 
-	/*
-	 * Allow direct access to the PC debug port (it is often used for I/O
-	 * delays, but the vmexits simply slow things down).
-	 */
 	memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
-	clear_bit(0x80, vmx_io_bitmap_a);
 
 	memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/kvm/x86.c linux-libre-3.16.52-gnu/arch/x86/kvm/x86.c
--- linux-libre-3.16.51-gnu/arch/x86/kvm/x86.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/kvm/x86.c	2018-01-01 15:52:14.000000000 -0500
@@ -4052,7 +4052,7 @@ static int vcpu_mmio_read(struct kvm_vcp
 		      !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, n, v))
 		    && kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, n, v))
 			break;
-		trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v);
+		trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, v);
 		handled += n;
 		addr += n;
 		len -= n;
@@ -4276,7 +4276,7 @@ static int read_prepare(struct kvm_vcpu
 {
 	if (vcpu->mmio_read_completed) {
 		trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
-			       vcpu->mmio_fragments[0].gpa, *(u64 *)val);
+			       vcpu->mmio_fragments[0].gpa, val);
 		vcpu->mmio_read_completed = 0;
 		return 1;
 	}
@@ -4298,14 +4298,14 @@ static int write_emulate(struct kvm_vcpu
 
 static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val)
 {
-	trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
+	trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, val);
 	return vcpu_mmio_write(vcpu, gpa, bytes, val);
 }
 
 static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
 			  void *val, int bytes)
 {
-	trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
+	trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, NULL);
 	return X86EMUL_IO_NEEDED;
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/arch/x86/oprofile/op_model_ppro.c linux-libre-3.16.52-gnu/arch/x86/oprofile/op_model_ppro.c
--- linux-libre-3.16.51-gnu/arch/x86/oprofile/op_model_ppro.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/arch/x86/oprofile/op_model_ppro.c	2018-01-01 15:52:14.000000000 -0500
@@ -212,8 +212,8 @@ static void arch_perfmon_setup_counters(
 	eax.full = cpuid_eax(0xa);
 
 	/* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */
-	if (eax.split.version_id == 0 && __this_cpu_read(cpu_info.x86) == 6 &&
-		__this_cpu_read(cpu_info.x86_model) == 15) {
+	if (eax.split.version_id == 0 && boot_cpu_data.x86 == 6 &&
+	    boot_cpu_data.x86_model == 15) {
 		eax.split.version_id = 2;
 		eax.split.num_counters = 2;
 		eax.split.bit_width = 40;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/block/bio.c linux-libre-3.16.52-gnu/block/bio.c
--- linux-libre-3.16.51-gnu/block/bio.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/block/bio.c	2018-01-01 15:52:14.000000000 -0500
@@ -1286,6 +1286,7 @@ static struct bio *__bio_map_user_iov(st
 	struct bio *bio;
 	int cur_page = 0;
 	int ret, offset;
+	struct bio_vec *bvec;
 
 	for (i = 0; i < iov_count; i++) {
 		unsigned long uaddr = (unsigned long)iov[i].iov_base;
@@ -1329,7 +1330,12 @@ static struct bio *__bio_map_user_iov(st
 
 		ret = get_user_pages_fast(uaddr, local_nr_pages,
 				write_to_vm, &pages[cur_page]);
-		if (ret < local_nr_pages) {
+		if (unlikely(ret < local_nr_pages)) {
+			for (j = cur_page; j < page_limit; j++) {
+				if (!pages[j])
+					break;
+				put_page(pages[j]);
+			}
 			ret = -EFAULT;
 			goto out_unmap;
 		}
@@ -1384,10 +1390,8 @@ static struct bio *__bio_map_user_iov(st
 	return bio;
 
  out_unmap:
-	for (i = 0; i < nr_pages; i++) {
-		if(!pages[i])
-			break;
-		page_cache_release(pages[i]);
+	bio_for_each_segment_all(bvec, bio, j) {
+		put_page(bvec->bv_page);
 	}
  out:
 	kfree(pages);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/crypto/hmac.c linux-libre-3.16.52-gnu/crypto/hmac.c
--- linux-libre-3.16.51-gnu/crypto/hmac.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/crypto/hmac.c	2018-01-01 15:52:14.000000000 -0500
@@ -197,11 +197,15 @@ static int hmac_create(struct crypto_tem
 	salg = shash_attr_alg(tb[1], 0, 0);
 	if (IS_ERR(salg))
 		return PTR_ERR(salg);
+	alg = &salg->base;
 
+	/* The underlying hash algorithm must be unkeyed */
 	err = -EINVAL;
+	if (crypto_shash_alg_has_setkey(salg))
+		goto out_put_alg;
+
 	ds = salg->digestsize;
 	ss = salg->statesize;
-	alg = &salg->base;
 	if (ds > alg->cra_blocksize ||
 	    ss < alg->cra_blocksize)
 		goto out_put_alg;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/crypto/salsa20_generic.c linux-libre-3.16.52-gnu/crypto/salsa20_generic.c
--- linux-libre-3.16.51-gnu/crypto/salsa20_generic.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/crypto/salsa20_generic.c	2018-01-01 15:52:14.000000000 -0500
@@ -188,13 +188,6 @@ static int encrypt(struct blkcipher_desc
 
 	salsa20_ivsetup(ctx, walk.iv);
 
-	if (likely(walk.nbytes == nbytes))
-	{
-		salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
-				      walk.src.virt.addr, nbytes);
-		return blkcipher_walk_done(desc, &walk, 0);
-	}
-
 	while (walk.nbytes >= 64) {
 		salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
 				      walk.src.virt.addr,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/crypto/shash.c linux-libre-3.16.52-gnu/crypto/shash.c
--- linux-libre-3.16.51-gnu/crypto/shash.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/crypto/shash.c	2018-01-01 15:52:14.000000000 -0500
@@ -24,11 +24,12 @@
 
 static const struct crypto_type crypto_shash_type;
 
-static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
-			   unsigned int keylen)
+int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
+		    unsigned int keylen)
 {
 	return -ENOSYS;
 }
+EXPORT_SYMBOL_GPL(shash_no_setkey);
 
 static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
 				  unsigned int keylen)
@@ -274,12 +275,14 @@ static int shash_async_finup(struct ahas
 
 int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
 {
-	struct scatterlist *sg = req->src;
-	unsigned int offset = sg->offset;
 	unsigned int nbytes = req->nbytes;
+	struct scatterlist *sg;
+	unsigned int offset;
 	int err;
 
-	if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
+	if (nbytes &&
+	    (sg = req->src, offset = sg->offset,
+	     nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) {
 		void *data;
 
 		data = kmap_atomic(sg_page(sg));
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/block/rbd.c linux-libre-3.16.52-gnu/drivers/block/rbd.c
--- linux-libre-3.16.51-gnu/drivers/block/rbd.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/block/rbd.c	2018-01-01 15:52:14.000000000 -0500
@@ -2584,7 +2584,7 @@ static int rbd_img_obj_parent_read_full(
 	 * from the parent.
 	 */
 	page_count = (u32)calc_pages_for(0, length);
-	pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
+	pages = ceph_alloc_page_vector(page_count, GFP_NOIO);
 	if (IS_ERR(pages)) {
 		result = PTR_ERR(pages);
 		pages = NULL;
@@ -2711,7 +2711,7 @@ static int rbd_img_obj_exists_submit(str
 	 */
 	size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32);
 	page_count = (u32)calc_pages_for(0, size);
-	pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
+	pages = ceph_alloc_page_vector(page_count, GFP_NOIO);
 	if (IS_ERR(pages))
 		return PTR_ERR(pages);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/bus/mvebu-mbus.c linux-libre-3.16.52-gnu/drivers/bus/mvebu-mbus.c
--- linux-libre-3.16.51-gnu/drivers/bus/mvebu-mbus.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/bus/mvebu-mbus.c	2018-01-01 15:52:14.000000000 -0500
@@ -523,7 +523,7 @@ mvebu_mbus_default_setup_cpu_target(stru
 			if (mbus->hw_io_coherency)
 				w->mbus_attr |= ATTR_HW_COHERENCY;
 			w->base = base & DDR_BASE_CS_LOW_MASK;
-			w->size = (size | ~DDR_SIZE_MASK) + 1;
+			w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
 		}
 	}
 	mvebu_mbus_dram_info.num_cs = cs;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/crypto/talitos.c linux-libre-3.16.52-gnu/drivers/crypto/talitos.c
--- linux-libre-3.16.51-gnu/drivers/crypto/talitos.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/crypto/talitos.c	2018-01-01 15:52:14.000000000 -0500
@@ -1581,9 +1581,9 @@ static int common_nonsnoop_hash(struct t
 		req_ctx->swinit = 0;
 	} else {
 		desc->ptr[1] = zero_entry;
-		/* Indicate next op is not the first. */
-		req_ctx->first = 0;
 	}
+	/* Indicate next op is not the first. */
+	req_ctx->first = 0;
 
 	/* HMAC key */
 	if (ctx->keylen)
@@ -2550,7 +2550,8 @@ static struct talitos_crypto_alg *talito
 		t_alg->algt.alg.hash.final = ahash_final;
 		t_alg->algt.alg.hash.finup = ahash_finup;
 		t_alg->algt.alg.hash.digest = ahash_digest;
-		t_alg->algt.alg.hash.setkey = ahash_setkey;
+		if (!strncmp(alg->cra_name, "hmac", 4))
+			t_alg->algt.alg.hash.setkey = ahash_setkey;
 
 		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
 		    !strncmp(alg->cra_name, "hmac", 4)) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/gpio/gpiolib-acpi.c linux-libre-3.16.52-gnu/drivers/gpio/gpiolib-acpi.c
--- linux-libre-3.16.51-gnu/drivers/gpio/gpiolib-acpi.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/gpio/gpiolib-acpi.c	2018-01-01 15:52:14.000000000 -0500
@@ -130,7 +130,7 @@ static acpi_status acpi_gpiochip_request
 
 	if (pin <= 255) {
 		char ev_name[5];
-		sprintf(ev_name, "_%c%02X",
+		sprintf(ev_name, "_%c%02hhX",
 			agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L',
 			pin);
 		if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle)))
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/gpu/drm/i915/intel_bios.c linux-libre-3.16.52-gnu/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-3.16.51-gnu/drivers/gpu/drm/i915/intel_bios.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/gpu/drm/i915/intel_bios.c	2018-01-01 15:52:14.000000000 -0500
@@ -939,6 +939,13 @@ static void parse_ddi_port(struct drm_i9
 	is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0;
 	is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR);
 
+	if (port == PORT_A && is_dvi) {
+		DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n",
+			      is_hdmi ? "/HDMI" : "");
+		is_dvi = false;
+		is_hdmi = false;
+	}
+
 	info->supports_dvi = is_dvi;
 	info->supports_hdmi = is_hdmi;
 	info->supports_dp = is_dp;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/hid/i2c-hid/i2c-hid.c linux-libre-3.16.52-gnu/drivers/hid/i2c-hid/i2c-hid.c
--- linux-libre-3.16.51-gnu/drivers/hid/i2c-hid/i2c-hid.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/hid/i2c-hid/i2c-hid.c	2018-01-01 15:52:14.000000000 -0500
@@ -526,7 +526,8 @@ static int i2c_hid_alloc_buffers(struct
 {
 	/* the worst case is computed from the set_report command with a
 	 * reportID > 15 and the maximum report length */
-	int args_len = sizeof(__u8) + /* optional ReportID byte */
+	int args_len = sizeof(__u8) + /* ReportID */
+		       sizeof(__u8) + /* optional ReportID byte */
 		       sizeof(__u16) + /* data register */
 		       sizeof(__u16) + /* size of the report */
 		       report_size; /* report */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/iio/adc/ad7793.c linux-libre-3.16.52-gnu/drivers/iio/adc/ad7793.c
--- linux-libre-3.16.51-gnu/drivers/iio/adc/ad7793.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/iio/adc/ad7793.c	2018-01-01 15:52:14.000000000 -0500
@@ -257,7 +257,7 @@ static int ad7793_setup(struct iio_dev *
 	unsigned int vref_mv)
 {
 	struct ad7793_state *st = iio_priv(indio_dev);
-	int i, ret = -1;
+	int i, ret;
 	unsigned long long scale_uv;
 	u32 id;
 
@@ -266,7 +266,7 @@ static int ad7793_setup(struct iio_dev *
 		return ret;
 
 	/* reset the serial interface */
-	ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret));
+	ret = ad_sd_reset(&st->sd, 32);
 	if (ret < 0)
 		goto out;
 	usleep_range(500, 2000); /* Wait for at least 500us */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/iio/adc/ad_sigma_delta.c linux-libre-3.16.52-gnu/drivers/iio/adc/ad_sigma_delta.c
--- linux-libre-3.16.51-gnu/drivers/iio/adc/ad_sigma_delta.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/iio/adc/ad_sigma_delta.c	2018-01-01 15:52:14.000000000 -0500
@@ -177,6 +177,34 @@ out:
 }
 EXPORT_SYMBOL_GPL(ad_sd_read_reg);
 
+/**
+ * ad_sd_reset() - Reset the serial interface
+ *
+ * @sigma_delta: The sigma delta device
+ * @reset_length: Number of SCLKs with DIN = 1
+ *
+ * Returns 0 on success, an error code otherwise.
+ **/
+int ad_sd_reset(struct ad_sigma_delta *sigma_delta,
+	unsigned int reset_length)
+{
+	uint8_t *buf;
+	unsigned int size;
+	int ret;
+
+	size = DIV_ROUND_UP(reset_length, 8);
+	buf = kcalloc(size, sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	memset(buf, 0xff, size);
+	ret = spi_write(sigma_delta->spi, buf, size);
+	kfree(buf);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ad_sd_reset);
+
 static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
 	unsigned int mode, unsigned int channel)
 {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/iio/adc/mcp320x.c linux-libre-3.16.52-gnu/drivers/iio/adc/mcp320x.c
--- linux-libre-3.16.51-gnu/drivers/iio/adc/mcp320x.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/iio/adc/mcp320x.c	2018-01-01 15:52:14.000000000 -0500
@@ -180,6 +180,7 @@ static int mcp320x_probe(struct spi_devi
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &mcp320x_info;
+	spi_set_drvdata(spi, indio_dev);
 
 	chip_info = &mcp3208_chip_infos[spi_get_device_id(spi)->driver_data];
 	indio_dev->channels = chip_info->channels;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/iio/industrialio-core.c linux-libre-3.16.52-gnu/drivers/iio/industrialio-core.c
--- linux-libre-3.16.51-gnu/drivers/iio/industrialio-core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/iio/industrialio-core.c	2018-01-01 15:52:14.000000000 -0500
@@ -184,8 +184,10 @@ static ssize_t iio_debugfs_read_reg(stru
 	ret = indio_dev->info->debugfs_reg_access(indio_dev,
 						  indio_dev->cached_reg_addr,
 						  0, &val);
-	if (ret)
+	if (ret) {
 		dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__);
+		return ret;
+	}
 
 	len = snprintf(buf, sizeof(buf), "0x%X\n", val);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/infiniband/hw/mlx5/mem.c linux-libre-3.16.52-gnu/drivers/infiniband/hw/mlx5/mem.c
--- linux-libre-3.16.51-gnu/drivers/infiniband/hw/mlx5/mem.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/infiniband/hw/mlx5/mem.c	2018-01-01 15:52:14.000000000 -0500
@@ -46,46 +46,33 @@ void mlx5_ib_cont_pages(struct ib_umem *
 {
 	unsigned long tmp;
 	unsigned long m;
-	int i, k;
-	u64 base = 0;
-	int p = 0;
-	int skip;
-	int mask;
-	u64 len;
-	u64 pfn;
+	u64 base = ~0, p = 0;
+	u64 len, pfn;
+	int i = 0;
 	struct scatterlist *sg;
 	int entry;
 
 	addr = addr >> PAGE_SHIFT;
 	tmp = (unsigned long)addr;
-	m = find_first_bit(&tmp, sizeof(tmp));
-	skip = 1 << m;
-	mask = skip - 1;
-	i = 0;
+	m = find_first_bit(&tmp, BITS_PER_LONG);
+
 	for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) {
 		len = sg_dma_len(sg) >> PAGE_SHIFT;
 		pfn = sg_dma_address(sg) >> PAGE_SHIFT;
-		for (k = 0; k < len; k++) {
-			if (!(i & mask)) {
-				tmp = (unsigned long)pfn;
-				m = min_t(unsigned long, m, find_first_bit(&tmp, sizeof(tmp)));
-				skip = 1 << m;
-				mask = skip - 1;
-				base = pfn;
-				p = 0;
-			} else {
-				if (base + p != pfn) {
-					tmp = (unsigned long)p;
-					m = find_first_bit(&tmp, sizeof(tmp));
-					skip = 1 << m;
-					mask = skip - 1;
-					base = pfn;
-					p = 0;
-				}
-			}
-			p++;
-			i++;
+		if (base + p != pfn) {
+			/* If either the offset or the new
+			 * base are unaligned update m
+			 */
+			tmp = (unsigned long)(pfn | p);
+			if (!IS_ALIGNED(tmp, 1 << m))
+				m = find_first_bit(&tmp, BITS_PER_LONG);
+
+			base = pfn;
+			p = 0;
 		}
+
+		p += len;
+		i += len;
 	}
 
 	if (i) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c linux-libre-3.16.52-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
--- linux-libre-3.16.51-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c	2018-01-01 15:52:14.000000000 -0500
@@ -235,7 +235,10 @@ static int ocrdma_get_mbx_errno(u32 stat
 		case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES:
 			err_num = -EAGAIN;
 			break;
+		default:
+			err_num = -EFAULT;
 		}
+		break;
 	default:
 		err_num = -EFAULT;
 	}
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-3.16.52-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-3.16.51-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2018-01-01 15:52:14.000000000 -0500
@@ -961,19 +961,6 @@ static inline int update_parent_pkey(str
 		 */
 		priv->dev->broadcast[8] = priv->pkey >> 8;
 		priv->dev->broadcast[9] = priv->pkey & 0xff;
-
-		/*
-		 * Update the broadcast address in the priv->broadcast object,
-		 * in case it already exists, otherwise no one will do that.
-		 */
-		if (priv->broadcast) {
-			spin_lock_irq(&priv->lock);
-			memcpy(priv->broadcast->mcmember.mgid.raw,
-			       priv->dev->broadcast + 4,
-			sizeof(union ib_gid));
-			spin_unlock_irq(&priv->lock);
-		}
-
 		return 0;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/input/ff-core.c linux-libre-3.16.52-gnu/drivers/input/ff-core.c
--- linux-libre-3.16.51-gnu/drivers/input/ff-core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/input/ff-core.c	2018-01-01 15:52:14.000000000 -0500
@@ -239,9 +239,15 @@ int input_ff_erase(struct input_dev *dev
 EXPORT_SYMBOL_GPL(input_ff_erase);
 
 /*
- * flush_effects - erase all effects owned by a file handle
+ * input_ff_flush - erase all effects owned by a file handle
+ * @dev: input device to erase effect from
+ * @file: purported owner of the effects
+ *
+ * This function erases all force-feedback effects associated with
+ * the given owner from specified device. Note that @file may be %NULL,
+ * in which case all effects will be erased.
  */
-static int flush_effects(struct input_dev *dev, struct file *file)
+int input_ff_flush(struct input_dev *dev, struct file *file)
 {
 	struct ff_device *ff = dev->ff;
 	int i;
@@ -257,6 +263,7 @@ static int flush_effects(struct input_de
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(input_ff_flush);
 
 /**
  * input_ff_event() - generic handler for force-feedback events
@@ -340,7 +347,7 @@ int input_ff_create(struct input_dev *de
 	mutex_init(&ff->mutex);
 
 	dev->ff = ff;
-	dev->flush = flush_effects;
+	dev->flush = input_ff_flush;
 	dev->event = input_ff_event;
 	__set_bit(EV_FF, dev->evbit);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/input/misc/ims-pcu.c linux-libre-3.16.52-gnu/drivers/input/misc/ims-pcu.c
--- linux-libre-3.16.51-gnu/drivers/input/misc/ims-pcu.c	2017-11-26 13:37:22.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/input/misc/ims-pcu.c	2018-01-02 11:26:50.000000000 -0500
@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_in
 		return NULL;
 	}
 
-	while (buflen > 0) {
+	while (buflen >= sizeof(*union_desc)) {
 		union_desc = (struct usb_cdc_union_desc *)buf;
 
+		if (union_desc->bLength > buflen) {
+			dev_err(&intf->dev, "Too large descriptor\n");
+			return NULL;
+		}
+
 		if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
 		    union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
 			dev_dbg(&intf->dev, "Found union header\n");
-			return union_desc;
+
+			if (union_desc->bLength >= sizeof(*union_desc))
+				return union_desc;
+
+			dev_err(&intf->dev,
+				"Union descriptor to short (%d vs %zd\n)",
+				union_desc->bLength, sizeof(*union_desc));
+			return NULL;
 		}
 
 		buflen -= union_desc->bLength;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/input/misc/uinput.c linux-libre-3.16.52-gnu/drivers/input/misc/uinput.c
--- linux-libre-3.16.51-gnu/drivers/input/misc/uinput.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/input/misc/uinput.c	2018-01-01 15:52:14.000000000 -0500
@@ -98,14 +98,15 @@ static int uinput_request_reserve_slot(s
 					uinput_request_alloc_id(udev, request));
 }
 
-static void uinput_request_done(struct uinput_device *udev,
-				struct uinput_request *request)
+static void uinput_request_release_slot(struct uinput_device *udev,
+					unsigned int id)
 {
 	/* Mark slot as available */
-	udev->requests[request->id] = NULL;
-	wake_up(&udev->requests_waitq);
+	spin_lock(&udev->requests_lock);
+	udev->requests[id] = NULL;
+	spin_unlock(&udev->requests_lock);
 
-	complete(&request->done);
+	wake_up(&udev->requests_waitq);
 }
 
 static int uinput_request_send(struct uinput_device *udev,
@@ -138,20 +139,22 @@ static int uinput_request_send(struct ui
 static int uinput_request_submit(struct uinput_device *udev,
 				 struct uinput_request *request)
 {
-	int error;
+	int retval;
 
-	error = uinput_request_reserve_slot(udev, request);
-	if (error)
-		return error;
+	retval = uinput_request_reserve_slot(udev, request);
+	if (retval)
+		return retval;
 
-	error = uinput_request_send(udev, request);
-	if (error) {
-		uinput_request_done(udev, request);
-		return error;
-	}
+	retval = uinput_request_send(udev, request);
+	if (retval)
+		goto out;
 
 	wait_for_completion(&request->done);
-	return request->retval;
+	retval = request->retval;
+
+ out:
+	uinput_request_release_slot(udev, request->id);
+	return retval;
 }
 
 /*
@@ -169,7 +172,7 @@ static void uinput_flush_requests(struct
 		request = udev->requests[i];
 		if (request) {
 			request->retval = -ENODEV;
-			uinput_request_done(udev, request);
+			complete(&request->done);
 		}
 	}
 
@@ -230,6 +233,18 @@ static int uinput_dev_erase_effect(struc
 	return uinput_request_submit(udev, &request);
 }
 
+static int uinput_dev_flush(struct input_dev *dev, struct file *file)
+{
+	/*
+	 * If we are called with file == NULL that means we are tearing
+	 * down the device, and therefore we can not handle FF erase
+	 * requests: either we are handling UI_DEV_DESTROY (and holding
+	 * the udev->mutex), or the file descriptor is closed and there is
+	 * nobody on the other side anymore.
+	 */
+	return file ? input_ff_flush(dev, file) : 0;
+}
+
 static void uinput_destroy_device(struct uinput_device *udev)
 {
 	const char *name, *phys;
@@ -273,6 +288,12 @@ static int uinput_create_device(struct u
 		dev->ff->playback = uinput_dev_playback;
 		dev->ff->set_gain = uinput_dev_set_gain;
 		dev->ff->set_autocenter = uinput_dev_set_autocenter;
+		/*
+		 * The standard input_ff_flush() implementation does
+		 * not quite work for uinput as we can't reasonably
+		 * handle FF requests during device teardown.
+		 */
+		dev->flush = uinput_dev_flush;
 	}
 
 	error = input_register_device(udev->dev);
@@ -840,7 +861,7 @@ static long uinput_ioctl_handler(struct
 			}
 
 			req->retval = ff_up.retval;
-			uinput_request_done(udev, req);
+			complete(&req->done);
 			goto out;
 
 		case UI_END_FF_ERASE:
@@ -856,7 +877,7 @@ static long uinput_ioctl_handler(struct
 			}
 
 			req->retval = ff_erase.retval;
-			uinput_request_done(udev, req);
+			complete(&req->done);
 			goto out;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/input/touchscreen/ti_am335x_tsc.c linux-libre-3.16.52-gnu/drivers/input/touchscreen/ti_am335x_tsc.c
--- linux-libre-3.16.51-gnu/drivers/input/touchscreen/ti_am335x_tsc.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/input/touchscreen/ti_am335x_tsc.c	2018-01-01 15:52:14.000000000 -0500
@@ -157,7 +157,7 @@ static void titsc_step_config(struct tit
 		break;
 	case 5:
 		config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
-				ts_dev->bit_xn | ts_dev->bit_yp;
+				STEPCONFIG_XNP | STEPCONFIG_YPN;
 		break;
 	case 8:
 		config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/iommu/amd_iommu.c linux-libre-3.16.52-gnu/drivers/iommu/amd_iommu.c
--- linux-libre-3.16.51-gnu/drivers/iommu/amd_iommu.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/iommu/amd_iommu.c	2018-01-01 15:52:14.000000000 -0500
@@ -3440,6 +3440,7 @@ static size_t amd_iommu_unmap(struct iom
 	mutex_unlock(&domain->api_lock);
 
 	domain_flush_tlb_pde(domain);
+	domain_flush_complete(domain);
 
 	return unmap_size;
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/iommu/exynos-iommu.c linux-libre-3.16.52-gnu/drivers/iommu/exynos-iommu.c
--- linux-libre-3.16.51-gnu/drivers/iommu/exynos-iommu.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/iommu/exynos-iommu.c	2018-01-01 15:52:14.000000000 -0500
@@ -676,7 +676,7 @@ static int __init exynos_sysmmu_probe(st
 	return 0;
 }
 
-static const struct of_device_id sysmmu_of_match[] __initconst = {
+static const struct of_device_id sysmmu_of_match[] = {
 	{ .compatible	= "samsung,exynos-sysmmu", },
 	{ },
 };
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/can/c_can/c_can_pci.c linux-libre-3.16.52-gnu/drivers/net/can/c_can/c_can_pci.c
--- linux-libre-3.16.51-gnu/drivers/net/can/c_can/c_can_pci.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/can/c_can/c_can_pci.c	2018-01-01 15:52:14.000000000 -0500
@@ -178,7 +178,6 @@ static int c_can_pci_probe(struct pci_de
 		break;
 	case BOSCH_D_CAN:
 		priv->regs = reg_map_d_can;
-		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
 		break;
 	default:
 		ret = -EINVAL;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/can/c_can/c_can_platform.c linux-libre-3.16.52-gnu/drivers/net/can/c_can/c_can_platform.c
--- linux-libre-3.16.51-gnu/drivers/net/can/c_can/c_can_platform.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/can/c_can/c_can_platform.c	2018-01-01 15:52:14.000000000 -0500
@@ -266,7 +266,6 @@ static int c_can_plat_probe(struct platf
 		break;
 	case BOSCH_D_CAN:
 		priv->regs = reg_map_d_can;
-		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
 		priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
 		priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
 		priv->read_reg32 = d_can_plat_read_reg32;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/can/usb/esd_usb2.c linux-libre-3.16.52-gnu/drivers/net/can/usb/esd_usb2.c
--- linux-libre-3.16.51-gnu/drivers/net/can/usb/esd_usb2.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/can/usb/esd_usb2.c	2018-01-01 15:52:14.000000000 -0500
@@ -334,7 +334,7 @@ static void esd_usb2_rx_can_msg(struct e
 		}
 
 		cf->can_id = id & ESD_IDMASK;
-		cf->can_dlc = get_can_dlc(msg->msg.rx.dlc);
+		cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR);
 
 		if (id & ESD_EXTID)
 			cf->can_id |= CAN_EFF_FLAG;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/can/usb/gs_usb.c linux-libre-3.16.52-gnu/drivers/net/can/usb/gs_usb.c
--- linux-libre-3.16.51-gnu/drivers/net/can/usb/gs_usb.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/can/usb/gs_usb.c	2018-01-01 15:52:14.000000000 -0500
@@ -356,6 +356,8 @@ static void gs_usb_recieve_bulk_callback
 
 		gs_free_tx_context(txc);
 
+		atomic_dec(&dev->active_tx_urbs);
+
 		netif_wake_queue(netdev);
 	}
 
@@ -444,14 +446,6 @@ static void gs_usb_xmit_callback(struct
 			  urb->transfer_buffer_length,
 			  urb->transfer_buffer,
 			  urb->transfer_dma);
-
-	atomic_dec(&dev->active_tx_urbs);
-
-	if (!netif_device_present(netdev))
-		return;
-
-	if (netif_queue_stopped(netdev))
-		netif_wake_queue(netdev);
 }
 
 static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, struct net_device *netdev)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/can/usb/kvaser_usb.c linux-libre-3.16.52-gnu/drivers/net/can/usb/kvaser_usb.c
--- linux-libre-3.16.51-gnu/drivers/net/can/usb/kvaser_usb.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/can/usb/kvaser_usb.c	2018-01-01 15:52:14.000000000 -0500
@@ -1263,7 +1263,8 @@ static int kvaser_usb_close(struct net_d
 	if (err)
 		netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
 
-	if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel))
+	err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel);
+	if (err)
 		netdev_warn(netdev, "Cannot reset card, error %d\n", err);
 
 	err = kvaser_usb_stop_chip(priv);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/macvtap.c linux-libre-3.16.52-gnu/drivers/net/macvtap.c
--- linux-libre-3.16.51-gnu/drivers/net/macvtap.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/macvtap.c	2018-01-01 15:52:14.000000000 -0500
@@ -1051,10 +1051,12 @@ static long macvtap_ioctl(struct file *f
 		return 0;
 
 	case TUNSETSNDBUF:
-		if (get_user(u, up))
+		if (get_user(s, sp))
 			return -EFAULT;
+		if (s <= 0)
+			return -EINVAL;
 
-		q->sk.sk_sndbuf = u;
+		q->sk.sk_sndbuf = s;
 		return 0;
 
 	case TUNGETVNETHDRSZ:
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/tun.c linux-libre-3.16.52-gnu/drivers/net/tun.c
--- linux-libre-3.16.51-gnu/drivers/net/tun.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/tun.c	2018-01-01 15:52:14.000000000 -0500
@@ -1647,6 +1647,9 @@ static int tun_set_iff(struct net *net,
 
 		if (!dev)
 			return -ENOMEM;
+		err = dev_get_valid_name(net, dev, name);
+		if (err)
+			goto err_free_dev;
 
 		dev_net_set(dev, net);
 		dev->rtnl_link_ops = &tun_link_ops;
@@ -2051,6 +2054,10 @@ static long __tun_chr_ioctl(struct file
 			ret = -EFAULT;
 			break;
 		}
+		if (sndbuf <= 0) {
+			ret = -EINVAL;
+			break;
+		}
 
 		tun->sndbuf = sndbuf;
 		tun_set_sndbuf(tun);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.c linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--- linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.c	2018-01-01 15:52:14.000000000 -0500
@@ -26,50 +26,6 @@
 #include "fwil.h"
 
 /**
- * struct brcm_ethhdr - broadcom specific ether header.
- *
- * @subtype: subtype for this packet.
- * @length: TODO: length of appended data.
- * @version: version indication.
- * @oui: OUI of this packet.
- * @usr_subtype: subtype for this OUI.
- */
-struct brcm_ethhdr {
-	__be16 subtype;
-	__be16 length;
-	u8 version;
-	u8 oui[3];
-	__be16 usr_subtype;
-} __packed;
-
-struct brcmf_event_msg_be {
-	__be16 version;
-	__be16 flags;
-	__be32 event_type;
-	__be32 status;
-	__be32 reason;
-	__be32 auth_type;
-	__be32 datalen;
-	u8 addr[ETH_ALEN];
-	char ifname[IFNAMSIZ];
-	u8 ifidx;
-	u8 bsscfgidx;
-} __packed;
-
-/**
- * struct brcmf_event - contents of broadcom event packet.
- *
- * @eth: standard ether header.
- * @hdr: broadcom specific ether header.
- * @msg: common part of the actual event message.
- */
-struct brcmf_event {
-	struct ethhdr eth;
-	struct brcm_ethhdr hdr;
-	struct brcmf_event_msg_be msg;
-} __packed;
-
-/**
  * struct brcmf_fweh_queue_item - event item on event queue.
  *
  * @q: list element for queuing.
@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item {
 	u8 ifidx;
 	u8 ifaddr[ETH_ALEN];
 	struct brcmf_event_msg_be emsg;
+	u32 datalen;
 	u8 data[0];
 };
 
@@ -292,6 +249,11 @@ static void brcmf_fweh_event_worker(stru
 		brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
 				   min_t(u32, emsg.datalen, 64),
 				   "event payload, len=%d\n", emsg.datalen);
+		if (emsg.datalen > event->datalen) {
+			brcmf_err("event invalid length header=%d, msg=%d\n",
+				  event->datalen, emsg.datalen);
+			goto event_free;
+		}
 
 		/* special handling of interface event */
 		if (event->code == BRCMF_E_IF) {
@@ -423,7 +385,8 @@ int brcmf_fweh_activate_events(struct br
  * dispatch the event to a registered handler (using worker).
  */
 void brcmf_fweh_process_event(struct brcmf_pub *drvr,
-			      struct brcmf_event *event_packet)
+			      struct brcmf_event *event_packet,
+			      u32 packet_len)
 {
 	enum brcmf_fweh_event_code code;
 	struct brcmf_fweh_info *fweh = &drvr->fweh;
@@ -443,6 +406,10 @@ void brcmf_fweh_process_event(struct brc
 	if (code != BRCMF_E_IF && !fweh->evt_handler[code])
 		return;
 
+	if (datalen > BRCMF_DCMD_MAXLEN ||
+	    datalen + sizeof(*event_packet) > packet_len)
+		return;
+
 	if (in_interrupt())
 		alloc_flag = GFP_ATOMIC;
 
@@ -456,6 +423,7 @@ void brcmf_fweh_process_event(struct brc
 	/* use memcpy to get aligned event message */
 	memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
 	memcpy(event->data, data, datalen);
+	event->datalen = datalen;
 	memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
 
 	brcmf_fweh_queue_event(fweh, event);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
--- linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h	2018-01-01 15:52:14.000000000 -0500
@@ -27,7 +27,6 @@
 struct brcmf_pub;
 struct brcmf_if;
 struct brcmf_cfg80211_info;
-struct brcmf_event;
 
 /* list of firmware events */
 #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \
@@ -173,11 +172,53 @@ enum brcmf_fweh_event_code {
 /**
  * definitions for event packet validation.
  */
-#define BRCMF_EVENT_OUI_OFFSET		19
-#define BRCM_OUI			"\x00\x10\x18"
-#define DOT11_OUI_LEN			3
-#define BCMILCP_BCM_SUBTYPE_EVENT	1
+#define BRCM_OUI				"\x00\x10\x18"
+#define BCMILCP_BCM_SUBTYPE_EVENT		1
+
+
+/**
+ * struct brcm_ethhdr - broadcom specific ether header.
+ *
+ * @subtype: subtype for this packet.
+ * @length: TODO: length of appended data.
+ * @version: version indication.
+ * @oui: OUI of this packet.
+ * @usr_subtype: subtype for this OUI.
+ */
+struct brcm_ethhdr {
+	__be16 subtype;
+	__be16 length;
+	u8 version;
+	u8 oui[3];
+	__be16 usr_subtype;
+} __packed;
+
+struct brcmf_event_msg_be {
+	__be16 version;
+	__be16 flags;
+	__be32 event_type;
+	__be32 status;
+	__be32 reason;
+	__be32 auth_type;
+	__be32 datalen;
+	u8 addr[ETH_ALEN];
+	char ifname[IFNAMSIZ];
+	u8 ifidx;
+	u8 bsscfgidx;
+} __packed;
 
+/**
+ * struct brcmf_event - contents of broadcom event packet.
+ *
+ * @eth: standard ether header.
+ * @hdr: broadcom specific ether header.
+ * @msg: common part of the actual event message.
+ */
+struct brcmf_event {
+	struct ethhdr eth;
+	struct brcm_ethhdr hdr;
+	struct brcmf_event_msg_be msg;
+} __packed;
 
 /**
  * struct brcmf_event_msg - firmware event message.
@@ -247,33 +288,34 @@ void brcmf_fweh_unregister(struct brcmf_
 			   enum brcmf_fweh_event_code code);
 int brcmf_fweh_activate_events(struct brcmf_if *ifp);
 void brcmf_fweh_process_event(struct brcmf_pub *drvr,
-			      struct brcmf_event *event_packet);
+			      struct brcmf_event *event_packet,
+			      u32 packet_len);
 
 static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
 					  struct sk_buff *skb)
 {
 	struct brcmf_event *event_packet;
-	u8 *data;
 	u16 usr_stype;
 
 	/* only process events when protocol matches */
 	if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
 		return;
 
+	if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
+		return;
+
 	/* check for BRCM oui match */
 	event_packet = (struct brcmf_event *)skb_mac_header(skb);
-	data = (u8 *)event_packet;
-	data += BRCMF_EVENT_OUI_OFFSET;
-	if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN))
+	if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
+		   sizeof(event_packet->hdr.oui)))
 		return;
 
 	/* final match on usr_subtype */
-	data += DOT11_OUI_LEN;
-	usr_stype = get_unaligned_be16(data);
+	usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype);
 	if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
 		return;
 
-	brcmf_fweh_process_event(drvr, event_packet);
+	brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN);
 }
 
 #endif /* FWEH_H_ */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--- linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c	2018-01-01 15:52:14.000000000 -0500
@@ -1363,6 +1363,11 @@ int brcmf_p2p_notify_action_frame_rx(str
 	u16 mgmt_type;
 	u8 action;
 
+	if (e->datalen < sizeof(*rxframe)) {
+		brcmf_dbg(SCAN, "Event data to small. Ignore\n");
+		return 0;
+	}
+
 	ch.chspec = be16_to_cpu(rxframe->chanspec);
 	cfg->d11inf.decchspec(&ch);
 	/* Check if wpa_supplicant has registered for this frame */
@@ -1861,6 +1866,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
 	brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code,
 		  e->reason);
 
+	if (e->datalen < sizeof(*rxframe)) {
+		brcmf_dbg(SCAN, "Event data to small. Ignore\n");
+		return 0;
+	}
+
 	ch.chspec = be16_to_cpu(rxframe->chanspec);
 	cfg->d11inf.decchspec(&ch);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
--- linux-libre-3.16.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c	2018-01-01 15:52:14.000000000 -0500
@@ -3036,6 +3036,11 @@ brcmf_notify_sched_scan_results(struct b
 
 	brcmf_dbg(SCAN, "Enter\n");
 
+	if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
+		brcmf_dbg(SCAN, "Event data to small. Ignore\n");
+		return 0;
+	}
+
 	if (e->event_code == BRCMF_E_PFN_NET_LOST) {
 		brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
 		return 0;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c linux-libre-3.16.52-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c
--- linux-libre-3.16.51-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c	2018-01-01 15:52:14.000000000 -0500
@@ -1004,6 +1004,11 @@ static void iwl_mvm_mc_iface_iterator(vo
 	struct iwl_mvm_mc_iter_data *data = _data;
 	struct iwl_mvm *mvm = data->mvm;
 	struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
+	struct iwl_host_cmd hcmd = {
+		.id = MCAST_FILTER_CMD,
+		.flags = CMD_ASYNC,
+		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
+	};
 	int ret, len;
 
 	/* if we don't have free ports, mcast frames will be dropped */
@@ -1018,7 +1023,10 @@ static void iwl_mvm_mc_iface_iterator(vo
 	memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
 	len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
 
-	ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd);
+	hcmd.len[0] = len;
+	hcmd.data[0] = cmd;
+
+	ret = iwl_mvm_send_cmd(mvm, &hcmd);
 	if (ret)
 		IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/pci/pci-sysfs.c linux-libre-3.16.52-gnu/drivers/pci/pci-sysfs.c
--- linux-libre-3.16.51-gnu/drivers/pci/pci-sysfs.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/pci/pci-sysfs.c	2018-01-01 15:52:14.000000000 -0500
@@ -514,7 +514,7 @@ static ssize_t driver_override_store(str
 				     const char *buf, size_t count)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	char *driver_override, *old = pdev->driver_override, *cp;
+	char *driver_override, *old, *cp;
 
 	/* We need to keep extra room for a newline */
 	if (count >= (PAGE_SIZE - 1))
@@ -528,12 +528,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);
 
@@ -544,8 +547,12 @@ static ssize_t driver_override_show(stru
 				    struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
+	ssize_t len;
 
-	return snprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override);
+	device_lock(dev);
+	len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override);
+	device_unlock(dev);
+	return len;
 }
 static DEVICE_ATTR_RW(driver_override);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/s390/scsi/zfcp_aux.c linux-libre-3.16.52-gnu/drivers/s390/scsi/zfcp_aux.c
--- linux-libre-3.16.51-gnu/drivers/s390/scsi/zfcp_aux.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/s390/scsi/zfcp_aux.c	2018-01-01 15:52:14.000000000 -0500
@@ -356,6 +356,8 @@ struct zfcp_adapter *zfcp_adapter_enqueu
 	INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
 	INIT_WORK(&adapter->ns_up_work, zfcp_fc_sym_name_update);
 
+	adapter->erp_action.adapter = adapter;
+
 	if (zfcp_qdio_setup(adapter))
 		goto failed;
 
@@ -512,6 +514,9 @@ struct zfcp_port *zfcp_port_enqueue(stru
 	port->dev.groups = zfcp_port_attr_groups;
 	port->dev.release = zfcp_port_release;
 
+	port->erp_action.adapter = adapter;
+	port->erp_action.port = port;
+
 	if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
 		kfree(port);
 		goto err_out;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/s390/scsi/zfcp_erp.c linux-libre-3.16.52-gnu/drivers/s390/scsi/zfcp_erp.c
--- linux-libre-3.16.51-gnu/drivers/s390/scsi/zfcp_erp.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/s390/scsi/zfcp_erp.c	2018-01-01 15:52:14.000000000 -0500
@@ -193,9 +193,8 @@ static struct zfcp_erp_action *zfcp_erp_
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
 				&zfcp_sdev->status);
 		erp_action = &zfcp_sdev->erp_action;
-		memset(erp_action, 0, sizeof(struct zfcp_erp_action));
-		erp_action->port = port;
-		erp_action->sdev = sdev;
+		WARN_ON_ONCE(erp_action->port != port);
+		WARN_ON_ONCE(erp_action->sdev != sdev);
 		if (!(atomic_read(&zfcp_sdev->status) &
 		      ZFCP_STATUS_COMMON_RUNNING))
 			act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -208,8 +207,8 @@ static struct zfcp_erp_action *zfcp_erp_
 		zfcp_erp_action_dismiss_port(port);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
 		erp_action = &port->erp_action;
-		memset(erp_action, 0, sizeof(struct zfcp_erp_action));
-		erp_action->port = port;
+		WARN_ON_ONCE(erp_action->port != port);
+		WARN_ON_ONCE(erp_action->sdev != NULL);
 		if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
 			act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
 		break;
@@ -219,7 +218,8 @@ static struct zfcp_erp_action *zfcp_erp_
 		zfcp_erp_action_dismiss_adapter(adapter);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
 		erp_action = &adapter->erp_action;
-		memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+		WARN_ON_ONCE(erp_action->port != NULL);
+		WARN_ON_ONCE(erp_action->sdev != NULL);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING))
 			act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -229,7 +229,11 @@ static struct zfcp_erp_action *zfcp_erp_
 		return NULL;
 	}
 
-	erp_action->adapter = adapter;
+	WARN_ON_ONCE(erp_action->adapter != adapter);
+	memset(&erp_action->list, 0, sizeof(erp_action->list));
+	memset(&erp_action->timer, 0, sizeof(erp_action->timer));
+	erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED;
+	erp_action->fsf_req_id = 0;
 	erp_action->action = need;
 	erp_action->status = act_status;
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/s390/scsi/zfcp_scsi.c linux-libre-3.16.52-gnu/drivers/s390/scsi/zfcp_scsi.c
--- linux-libre-3.16.51-gnu/drivers/s390/scsi/zfcp_scsi.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/s390/scsi/zfcp_scsi.c	2018-01-01 15:52:14.000000000 -0500
@@ -136,10 +136,15 @@ static int zfcp_scsi_slave_alloc(struct
 	struct zfcp_unit *unit;
 	int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE;
 
+	zfcp_sdev->erp_action.adapter = adapter;
+	zfcp_sdev->erp_action.sdev = sdev;
+
 	port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
 	if (!port)
 		return -ENXIO;
 
+	zfcp_sdev->erp_action.port = port;
+
 	unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
 	if (unit)
 		put_device(&unit->dev);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/scsi/libiscsi.c linux-libre-3.16.52-gnu/drivers/scsi/libiscsi.c
--- linux-libre-3.16.51-gnu/drivers/scsi/libiscsi.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/scsi/libiscsi.c	2018-01-01 15:52:14.000000000 -0500
@@ -1727,7 +1727,7 @@ int iscsi_queuecommand(struct Scsi_Host
 
 	if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
 		reason = FAILURE_SESSION_IN_RECOVERY;
-		sc->result = DID_REQUEUE;
+		sc->result = DID_REQUEUE << 16;
 		goto fault;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/scsi/lpfc/lpfc_init.c linux-libre-3.16.52-gnu/drivers/scsi/lpfc/lpfc_init.c
--- linux-libre-3.16.51-gnu/drivers/scsi/lpfc/lpfc_init.c	2017-11-26 13:38:33.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/scsi/lpfc/lpfc_init.c	2018-01-02 11:28:32.000000000 -0500
@@ -5242,6 +5242,7 @@ lpfc_sli4_driver_resource_setup(struct l
 			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2999 Unsupported SLI4 Parameters "
 				"Extents and RPI headers enabled.\n");
+			rc = -EIO;
 			goto out_free_bsmbx;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/scsi/scsi_scan.c linux-libre-3.16.52-gnu/drivers/scsi/scsi_scan.c
--- linux-libre-3.16.51-gnu/drivers/scsi/scsi_scan.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/scsi/scsi_scan.c	2018-01-01 15:52:14.000000000 -0500
@@ -962,6 +962,9 @@ static int scsi_add_lun(struct scsi_devi
 	if (*bflags & BLIST_NO_DIF)
 		sdev->no_dif = 1;
 
+	if (*bflags & BLIST_UNMAP_LIMIT_WS)
+		sdev->unmap_limit_for_ws = 1;
+
 	sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
 
 	if (*bflags & BLIST_TRY_VPD_PAGES)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/scsi/sd.c linux-libre-3.16.52-gnu/drivers/scsi/sd.c
--- linux-libre-3.16.51-gnu/drivers/scsi/sd.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/scsi/sd.c	2018-01-01 15:52:14.000000000 -0500
@@ -651,13 +651,21 @@ static void sd_config_discard(struct scs
 		break;
 
 	case SD_LBP_WS16:
-		max_blocks = min_not_zero(sdkp->max_ws_blocks,
-					  (u32)SD_MAX_WS16_BLOCKS);
+		if (sdkp->device->unmap_limit_for_ws)
+			max_blocks = sdkp->max_unmap_blocks;
+		else
+			max_blocks = sdkp->max_ws_blocks;
+
+		max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);
 		break;
 
 	case SD_LBP_WS10:
-		max_blocks = min_not_zero(sdkp->max_ws_blocks,
-					  (u32)SD_MAX_WS10_BLOCKS);
+		if (sdkp->device->unmap_limit_for_ws)
+			max_blocks = sdkp->max_unmap_blocks;
+		else
+			max_blocks = sdkp->max_ws_blocks;
+
+		max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);
 		break;
 
 	case SD_LBP_ZERO:
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/staging/iio/adc/ad7192.c linux-libre-3.16.52-gnu/drivers/staging/iio/adc/ad7192.c
--- linux-libre-3.16.51-gnu/drivers/staging/iio/adc/ad7192.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/staging/iio/adc/ad7192.c	2018-01-01 15:52:14.000000000 -0500
@@ -206,11 +206,9 @@ static int ad7192_setup(struct ad7192_st
 	struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi);
 	unsigned long long scale_uv;
 	int i, ret, id;
-	u8 ones[6];
 
 	/* reset the serial interface */
-	memset(&ones, 0xFF, 6);
-	ret = spi_write(st->sd.spi, &ones, 6);
+	ret = ad_sd_reset(&st->sd, 48);
 	if (ret < 0)
 		goto out;
 	msleep(1); /* Wait for at least 500us */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/staging/iio/meter/ade7759.c linux-libre-3.16.52-gnu/drivers/staging/iio/meter/ade7759.c
--- linux-libre-3.16.51-gnu/drivers/staging/iio/meter/ade7759.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/staging/iio/meter/ade7759.c	2018-01-01 15:52:14.000000000 -0500
@@ -124,7 +124,7 @@ static int ade7759_spi_read_reg_40(struc
 				reg_address);
 		goto error_ret;
 	}
-	*val = ((u64)st->rx[1] << 32) | (st->rx[2] << 24) |
+	*val = ((u64)st->rx[1] << 32) | ((u64)st->rx[2] << 24) |
 		(st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5];
 
 error_ret:
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/class/cdc-acm.c linux-libre-3.16.52-gnu/drivers/usb/class/cdc-acm.c
--- linux-libre-3.16.51-gnu/drivers/usb/class/cdc-acm.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/class/cdc-acm.c	2018-01-01 15:52:14.000000000 -0500
@@ -1775,6 +1775,9 @@ static const struct usb_device_id acm_id
 	{ USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},
+	{ USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */
+	.driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */
+	},
 
 	{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
 	.driver_info = CLEAR_HALT_CONDITIONS,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/core/config.c linux-libre-3.16.52-gnu/drivers/usb/core/config.c
--- linux-libre-3.16.51-gnu/drivers/usb/core/config.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/core/config.c	2018-01-01 15:52:14.000000000 -0500
@@ -519,6 +519,9 @@ static int usb_parse_configuration(struc
 	unsigned iad_num = 0;
 
 	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+	nintf = nintf_orig = config->desc.bNumInterfaces;
+	config->desc.bNumInterfaces = 0;	// Adjusted later
+
 	if (config->desc.bDescriptorType != USB_DT_CONFIG ||
 	    config->desc.bLength < USB_DT_CONFIG_SIZE ||
 	    config->desc.bLength > size) {
@@ -532,7 +535,6 @@ static int usb_parse_configuration(struc
 	buffer += config->desc.bLength;
 	size -= config->desc.bLength;
 
-	nintf = nintf_orig = config->desc.bNumInterfaces;
 	if (nintf > USB_MAXINTERFACES) {
 		dev_warn(ddev, "config %d has too many interfaces: %d, "
 		    "using maximum allowed: %d\n",
@@ -824,7 +826,7 @@ int usb_get_configuration(struct usb_dev
 		}
 
 		if (dev->quirks & USB_QUIRK_DELAY_INIT)
-			msleep(100);
+			msleep(200);
 
 		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
 		    bigbuffer, length);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/core/hub.c linux-libre-3.16.52-gnu/drivers/usb/core/hub.c
--- linux-libre-3.16.51-gnu/drivers/usb/core/hub.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/core/hub.c	2018-01-01 15:52:14.000000000 -0500
@@ -2625,13 +2625,16 @@ static int hub_port_wait_reset(struct us
 	if (!(portstatus & USB_PORT_STAT_CONNECTION))
 		return -ENOTCONN;
 
-	/* bomb out completely if the connection bounced.  A USB 3.0
-	 * connection may bounce if multiple warm resets were issued,
+	/* Retry if connect change is set but status is still connected.
+	 * A USB 3.0 connection may bounce if multiple warm resets were issued,
 	 * but the device may have successfully re-connected. Ignore it.
 	 */
 	if (!hub_is_superspeed(hub->hdev) &&
-			(portchange & USB_PORT_STAT_C_CONNECTION))
-		return -ENOTCONN;
+	    (portchange & USB_PORT_STAT_C_CONNECTION)) {
+		usb_clear_port_feature(hub->hdev, port1,
+				       USB_PORT_FEAT_C_CONNECTION);
+		return -EAGAIN;
+	}
 
 	if (!(portstatus & USB_PORT_STAT_ENABLE))
 		return -EBUSY;
@@ -4699,7 +4702,7 @@ static void hub_port_connect(struct usb_
 			goto loop;
 
 		if (udev->quirks & USB_QUIRK_DELAY_INIT)
-			msleep(1000);
+			msleep(2000);
 
 		/* consecutive bus-powered hubs aren't reliable; they can
 		 * violate the voltage drop budget.  if the new child has
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/core/quirks.c linux-libre-3.16.52-gnu/drivers/usb/core/quirks.c
--- linux-libre-3.16.51-gnu/drivers/usb/core/quirks.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/core/quirks.c	2018-01-01 15:52:14.000000000 -0500
@@ -218,6 +218,10 @@ static const struct usb_device_id usb_qu
 	/* Corsair Strafe RGB */
 	{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
 
+	/* MIDI keyboard WORLDE MINI */
+	{ USB_DEVICE(0x1c75, 0x0204), .driver_info =
+			USB_QUIRK_CONFIG_INTF_STRINGS },
+
 	/* Acer C120 LED Projector */
 	{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/composite.c linux-libre-3.16.52-gnu/drivers/usb/gadget/composite.c
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/composite.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/composite.c	2018-01-01 15:52:14.000000000 -0500
@@ -1815,6 +1815,8 @@ static DEVICE_ATTR_RO(suspended);
 static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
 {
 	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
+	struct usb_gadget_strings	*gstr = cdev->driver->strings[0];
+	struct usb_string		*dev_str = gstr->strings;
 
 	/* composite_disconnect() must already have been called
 	 * by the underlying peripheral controller driver!
@@ -1834,6 +1836,9 @@ static void __composite_unbind(struct us
 
 	composite_dev_cleanup(cdev);
 
+	if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
+		dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";
+
 	kfree(cdev->def_manufacturer);
 	kfree(cdev);
 	set_gadget_data(gadget, NULL);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/dummy_hcd.c linux-libre-3.16.52-gnu/drivers/usb/gadget/dummy_hcd.c
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/dummy_hcd.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/dummy_hcd.c	2018-01-01 15:52:14.000000000 -0500
@@ -173,6 +173,8 @@ struct dummy_hcd {
 
 	struct usb_device		*udev;
 	struct list_head		urbp_list;
+	struct urbp			*next_frame_urbp;
+
 	u32				stream_en_ep;
 	u8				num_stream[30 / 2];
 
@@ -189,11 +191,13 @@ struct dummy {
 	 */
 	struct dummy_ep			ep[DUMMY_ENDPOINTS];
 	int				address;
+	int				callback_usage;
 	struct usb_gadget		gadget;
 	struct usb_gadget_driver	*driver;
 	struct dummy_request		fifo_req;
 	u8				fifo_buf[FIFO_SIZE];
 	u16				devstatus;
+	unsigned			ints_enabled:1;
 	unsigned			udc_suspended:1;
 	unsigned			pullup:1;
 
@@ -311,11 +315,10 @@ static void set_link_state_by_speed(stru
 			     USB_PORT_STAT_CONNECTION) == 0)
 				dum_hcd->port_status |=
 					(USB_PORT_STAT_C_CONNECTION << 16);
-			if ((dum_hcd->port_status &
-			     USB_PORT_STAT_ENABLE) == 1 &&
-				(dum_hcd->port_status &
-				 USB_SS_PORT_LS_U0) == 1 &&
-				dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
+			if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) &&
+			    (dum_hcd->port_status &
+			     USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 &&
+			    dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
 				dum_hcd->active = 1;
 		}
 	} else {
@@ -352,6 +355,7 @@ static void set_link_state_by_speed(stru
 static void set_link_state(struct dummy_hcd *dum_hcd)
 {
 	struct dummy *dum = dum_hcd->dum;
+	unsigned int power_bit;
 
 	dum_hcd->active = 0;
 	if (dum->pullup)
@@ -362,36 +366,40 @@ static void set_link_state(struct dummy_
 			return;
 
 	set_link_state_by_speed(dum_hcd);
+	power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
+			USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
 
 	if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
 	     dum_hcd->active)
 		dum_hcd->resuming = 0;
 
 	/* if !connected or reset */
-	if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
+	if ((dum_hcd->port_status & power_bit) == 0 ||
 			(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
 		/*
 		 * We're connected and not reset (reset occurred now),
 		 * and driver attached - disconnect!
 		 */
-		if ((dum_hcd->old_status & USB_PORT_STAT_CONNECTION) != 0 &&
+		if ((dum_hcd->old_status & power_bit) != 0 &&
 		    (dum_hcd->old_status & USB_PORT_STAT_RESET) == 0 &&
-		    dum->driver) {
+		    dum->ints_enabled) {
 			stop_activity(dum);
+			++dum->callback_usage;
 			spin_unlock(&dum->lock);
 			dum->driver->disconnect(&dum->gadget);
 			spin_lock(&dum->lock);
+			--dum->callback_usage;
 		}
-	} else if (dum_hcd->active != dum_hcd->old_active) {
-		if (dum_hcd->old_active && dum->driver->suspend) {
-			spin_unlock(&dum->lock);
+	} else if (dum_hcd->active != dum_hcd->old_active &&
+			dum->ints_enabled) {
+		++dum->callback_usage;
+		spin_unlock(&dum->lock);
+		if (dum_hcd->old_active && dum->driver->suspend)
 			dum->driver->suspend(&dum->gadget);
-			spin_lock(&dum->lock);
-		} else if (!dum_hcd->old_active &&  dum->driver->resume) {
-			spin_unlock(&dum->lock);
+		else if (!dum_hcd->old_active &&  dum->driver->resume)
 			dum->driver->resume(&dum->gadget);
-			spin_lock(&dum->lock);
-		}
+		spin_lock(&dum->lock);
+		--dum->callback_usage;
 	}
 
 	dum_hcd->old_status = dum_hcd->port_status;
@@ -907,9 +915,12 @@ static int dummy_udc_start(struct usb_ga
 	 * can't enumerate without help from the driver we're binding.
 	 */
 
+	spin_lock_irq(&dum->lock);
 	dum->devstatus = 0;
 
 	dum->driver = driver;
+	dum->ints_enabled = 1;
+	spin_unlock_irq(&dum->lock);
 	dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n",
 			driver->driver.name);
 	return 0;
@@ -925,7 +936,19 @@ static int dummy_udc_stop(struct usb_gad
 		dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n",
 				driver->driver.name);
 
+	spin_lock_irq(&dum->lock);
+	dum->ints_enabled = 0;
+	stop_activity(dum);
+
+	/* emulate synchronize_irq(): wait for callbacks to finish */
+	while (dum->callback_usage > 0) {
+		spin_unlock_irq(&dum->lock);
+		usleep_range(1000, 2000);
+		spin_lock_irq(&dum->lock);
+	}
+
 	dum->driver = NULL;
+	spin_unlock_irq(&dum->lock);
 
 	return 0;
 }
@@ -974,7 +997,12 @@ static int dummy_udc_probe(struct platfo
 	dum = *((void **)dev_get_platdata(&pdev->dev));
 	dum->gadget.name = gadget_name;
 	dum->gadget.ops = &dummy_ops;
-	dum->gadget.max_speed = USB_SPEED_SUPER;
+	if (mod_data.is_super_speed)
+		dum->gadget.max_speed = USB_SPEED_SUPER;
+	else if (mod_data.is_high_speed)
+		dum->gadget.max_speed = USB_SPEED_HIGH;
+	else
+		dum->gadget.max_speed = USB_SPEED_FULL;
 
 	dum->gadget.dev.parent = &pdev->dev;
 	init_dummy_udc_hw(dum);
@@ -1184,6 +1212,8 @@ static int dummy_urb_enqueue(
 
 	list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list);
 	urb->hcpriv = urbp;
+	if (!dum_hcd->next_frame_urbp)
+		dum_hcd->next_frame_urbp = urbp;
 	if (usb_pipetype(urb->pipe) == PIPE_CONTROL)
 		urb->error_count = 1;		/* mark as a new urb */
 
@@ -1446,6 +1476,8 @@ static struct dummy_ep *find_endpoint(st
 	if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ?
 			dum->ss_hcd : dum->hs_hcd)))
 		return NULL;
+	if (!dum->ints_enabled)
+		return NULL;
 	if ((address & ~USB_DIR_IN) == 0)
 		return &dum->ep[0];
 	for (i = 1; i < DUMMY_ENDPOINTS; i++) {
@@ -1687,6 +1719,7 @@ static void dummy_timer(unsigned long _d
 		spin_unlock_irqrestore(&dum->lock, flags);
 		return;
 	}
+	dum_hcd->next_frame_urbp = NULL;
 
 	for (i = 0; i < DUMMY_ENDPOINTS; i++) {
 		if (!ep_name[i])
@@ -1703,6 +1736,10 @@ restart:
 		int			type;
 		int			status = -EINPROGRESS;
 
+		/* stop when we reach URBs queued after the timer interrupt */
+		if (urbp == dum_hcd->next_frame_urbp)
+			break;
+
 		urb = urbp->urb;
 		if (urb->unlinked)
 			goto return_urb;
@@ -1782,10 +1819,12 @@ restart:
 			 * until setup() returns; no reentrancy issues etc.
 			 */
 			if (value > 0) {
+				++dum->callback_usage;
 				spin_unlock(&dum->lock);
 				value = dum->driver->setup(&dum->gadget,
 						&setup);
 				spin_lock(&dum->lock);
+				--dum->callback_usage;
 
 				if (value >= 0) {
 					/* no delays (max 64KB data stage) */
@@ -2490,8 +2529,6 @@ static struct hc_driver dummy_hcd = {
 	.product_desc =		"Dummy host controller",
 	.hcd_priv_size =	sizeof(struct dummy_hcd),
 
-	.flags =		HCD_USB3 | HCD_SHARED,
-
 	.reset =		dummy_setup,
 	.start =		dummy_start,
 	.stop =			dummy_stop,
@@ -2520,8 +2557,12 @@ static int dummy_hcd_probe(struct platfo
 	dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
 	dum = *((void **)dev_get_platdata(&pdev->dev));
 
-	if (!mod_data.is_super_speed)
+	if (mod_data.is_super_speed)
+		dummy_hcd.flags = HCD_USB3 | HCD_SHARED;
+	else if (mod_data.is_high_speed)
 		dummy_hcd.flags = HCD_USB2;
+	else
+		dummy_hcd.flags = HCD_USB11;
 	hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev));
 	if (!hs_hcd)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/f_mass_storage.c linux-libre-3.16.52-gnu/drivers/usb/gadget/f_mass_storage.c
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/f_mass_storage.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/f_mass_storage.c	2018-01-01 15:52:14.000000000 -0500
@@ -307,8 +307,6 @@ struct fsg_common {
 	struct completion	thread_notifier;
 	struct task_struct	*thread_task;
 
-	/* Callback functions. */
-	const struct fsg_operations	*ops;
 	/* Gadget's private data. */
 	void			*private_data;
 
@@ -2498,6 +2496,8 @@ static void handle_exception(struct fsg_
 static int fsg_main_thread(void *common_)
 {
 	struct fsg_common	*common = common_;
+	struct fsg_lun		**curlun_it;
+	unsigned		i;
 
 	/*
 	 * Allow the thread to be killed by a signal, but set the signal mask
@@ -2559,22 +2559,18 @@ static int fsg_main_thread(void *common_
 	common->thread_task = NULL;
 	spin_unlock_irq(&common->lock);
 
-	if (!common->ops || !common->ops->thread_exits
-	 || common->ops->thread_exits(common) < 0) {
-		struct fsg_lun **curlun_it = common->luns;
-		unsigned i = common->nluns;
+	/* Eject media from all LUNs */
+	curlun_it = common->luns;
+	i = common->nluns;
 
-		down_write(&common->filesem);
-		for (; i--; ++curlun_it) {
-			struct fsg_lun *curlun = *curlun_it;
-			if (!curlun || !fsg_lun_is_open(curlun))
-				continue;
+	down_write(&common->filesem);
+	for (; i--; ++curlun_it) {
+		struct fsg_lun *curlun = *curlun_it;
 
+		if (curlun && fsg_lun_is_open(curlun))
 			fsg_lun_close(curlun);
-			curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
-		}
-		up_write(&common->filesem);
 	}
+	up_write(&common->filesem);
 
 	/* Let fsg_unbind() know the thread has exited */
 	complete_and_exit(&common->thread_notifier, 0);
@@ -2842,13 +2838,6 @@ int fsg_common_set_nluns(struct fsg_comm
 }
 EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
 
-void fsg_common_set_ops(struct fsg_common *common,
-			const struct fsg_operations *ops)
-{
-	common->ops = ops;
-}
-EXPORT_SYMBOL_GPL(fsg_common_set_ops);
-
 void fsg_common_free_buffers(struct fsg_common *common)
 {
 	_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/f_mass_storage.h linux-libre-3.16.52-gnu/drivers/usb/gadget/f_mass_storage.h
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/f_mass_storage.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/f_mass_storage.h	2018-01-01 15:52:14.000000000 -0500
@@ -60,17 +60,6 @@ struct fsg_module_parameters {
 struct fsg_common;
 
 /* FSF callback functions */
-struct fsg_operations {
-	/*
-	 * Callback function to call when thread exits.  If no
-	 * callback is set or it returns value lower then zero MSF
-	 * will force eject all LUNs it operates on (including those
-	 * marked as non-removable or with prevent_medium_removal flag
-	 * set).
-	 */
-	int (*thread_exits)(struct fsg_common *common);
-};
-
 struct fsg_lun_opts {
 	struct config_group group;
 	struct fsg_lun *lun;
@@ -145,9 +134,6 @@ void fsg_common_free_luns(struct fsg_com
 
 int fsg_common_set_nluns(struct fsg_common *common, int nluns);
 
-void fsg_common_set_ops(struct fsg_common *common,
-			const struct fsg_operations *ops);
-
 int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
 			  unsigned int id, const char *name,
 			  const char **name_pfx);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/inode.c linux-libre-3.16.52-gnu/drivers/usb/gadget/inode.c
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/inode.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/inode.c	2018-01-01 15:52:14.000000000 -0500
@@ -26,7 +26,7 @@
 #include <linux/poll.h>
 #include <linux/mmu_context.h>
 #include <linux/aio.h>
-
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
 
@@ -113,6 +113,7 @@ enum ep0_state {
 struct dev_data {
 	spinlock_t			lock;
 	atomic_t			count;
+	int				udc_usage;
 	enum ep0_state			state;		/* P: lock */
 	struct usb_gadgetfs_event	event [N_EVENT];
 	unsigned			ev_next;
@@ -620,9 +621,9 @@ static void ep_aio_complete(struct usb_e
 		priv->actual = req->actual;
 		schedule_work(&priv->work);
 	}
-	spin_unlock(&epdata->dev->lock);
 
 	usb_ep_free_request(ep, req);
+	spin_unlock(&epdata->dev->lock);
 	put_ep(epdata);
 }
 
@@ -1011,9 +1012,11 @@ ep0_read (struct file *fd, char __user *
 			struct usb_request	*req = dev->req;
 
 			if ((retval = setup_req (ep, req, 0)) == 0) {
+				++dev->udc_usage;
 				spin_unlock_irq (&dev->lock);
 				retval = usb_ep_queue (ep, req, GFP_KERNEL);
 				spin_lock_irq (&dev->lock);
+				--dev->udc_usage;
 			}
 			dev->state = STATE_DEV_CONNECTED;
 
@@ -1055,11 +1058,14 @@ ep0_read (struct file *fd, char __user *
 				retval = -EIO;
 			else {
 				len = min (len, (size_t)dev->req->actual);
-// FIXME don't call this with the spinlock held ...
+				++dev->udc_usage;
+				spin_unlock_irq(&dev->lock);
 				if (copy_to_user (buf, dev->req->buf, len))
 					retval = -EFAULT;
 				else
 					retval = len;
+				spin_lock_irq(&dev->lock);
+				--dev->udc_usage;
 				clean_req (dev->gadget->ep0, dev->req);
 				/* NOTE userspace can't yet choose to stall */
 			}
@@ -1205,6 +1211,7 @@ ep0_write (struct file *fd, const char _
 			retval = setup_req (dev->gadget->ep0, dev->req, len);
 			if (retval == 0) {
 				dev->state = STATE_DEV_CONNECTED;
+				++dev->udc_usage;
 				spin_unlock_irq (&dev->lock);
 				if (copy_from_user (dev->req->buf, buf, len))
 					retval = -EFAULT;
@@ -1215,12 +1222,13 @@ ep0_write (struct file *fd, const char _
 						dev->gadget->ep0, dev->req,
 						GFP_KERNEL);
 				}
+				spin_lock_irq(&dev->lock);
+				--dev->udc_usage;
 				if (retval < 0) {
-					spin_lock_irq (&dev->lock);
 					clean_req (dev->gadget->ep0, dev->req);
-					spin_unlock_irq (&dev->lock);
 				} else
 					retval = len;
+				spin_unlock_irq(&dev->lock);
 
 				return retval;
 			}
@@ -1313,9 +1321,21 @@ static long dev_ioctl (struct file *fd,
 	struct usb_gadget	*gadget = dev->gadget;
 	long ret = -ENOTTY;
 
-	if (gadget->ops->ioctl)
+	spin_lock_irq(&dev->lock);
+	if (dev->state == STATE_DEV_OPENED ||
+			dev->state == STATE_DEV_UNBOUND) {
+		/* Not bound to a UDC */
+	} else if (gadget->ops->ioctl) {
+		++dev->udc_usage;
+		spin_unlock_irq(&dev->lock);
+
 		ret = gadget->ops->ioctl (gadget, code, value);
 
+		spin_lock_irq(&dev->lock);
+		--dev->udc_usage;
+	}
+	spin_unlock_irq(&dev->lock);
+
 	return ret;
 }
 
@@ -1546,10 +1566,12 @@ delegate:
 				if (value < 0)
 					break;
 
+				++dev->udc_usage;
 				spin_unlock (&dev->lock);
 				value = usb_ep_queue (gadget->ep0, dev->req,
 							GFP_KERNEL);
 				spin_lock (&dev->lock);
+				--dev->udc_usage;
 				if (value < 0) {
 					clean_req (gadget->ep0, dev->req);
 					break;
@@ -1573,8 +1595,12 @@ delegate:
 		req->length = value;
 		req->zero = value < w_length;
 
+		++dev->udc_usage;
 		spin_unlock (&dev->lock);
 		value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL);
+		spin_lock(&dev->lock);
+		--dev->udc_usage;
+		spin_unlock(&dev->lock);
 		if (value < 0) {
 			DBG (dev, "ep_queue --> %d\n", value);
 			req->status = 0;
@@ -1601,21 +1627,24 @@ static void destroy_ep_files (struct dev
 		/* break link to FS */
 		ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles);
 		list_del_init (&ep->epfiles);
+		spin_unlock_irq (&dev->lock);
+
 		dentry = ep->dentry;
 		ep->dentry = NULL;
 		parent = dentry->d_parent->d_inode;
 
 		/* break link to controller */
+		mutex_lock(&ep->lock);
 		if (ep->state == STATE_EP_ENABLED)
 			(void) usb_ep_disable (ep->ep);
 		ep->state = STATE_EP_UNBOUND;
 		usb_ep_free_request (ep->ep, ep->req);
 		ep->ep = NULL;
+		mutex_unlock(&ep->lock);
+
 		wake_up (&ep->wait);
 		put_ep (ep);
 
-		spin_unlock_irq (&dev->lock);
-
 		/* break link to dcache */
 		mutex_lock (&parent->i_mutex);
 		d_delete (dentry);
@@ -1688,6 +1717,11 @@ gadgetfs_unbind (struct usb_gadget *gadg
 
 	spin_lock_irq (&dev->lock);
 	dev->state = STATE_DEV_UNBOUND;
+	while (dev->udc_usage > 0) {
+		spin_unlock_irq(&dev->lock);
+		usleep_range(1000, 2000);
+		spin_lock_irq(&dev->lock);
+	}
 	spin_unlock_irq (&dev->lock);
 
 	destroy_ep_files (dev);
@@ -1764,9 +1798,10 @@ static void
 gadgetfs_suspend (struct usb_gadget *gadget)
 {
 	struct dev_data		*dev = get_gadget_data (gadget);
+	unsigned long		flags;
 
 	INFO (dev, "suspended from state %d\n", dev->state);
-	spin_lock (&dev->lock);
+	spin_lock_irqsave(&dev->lock, flags);
 	switch (dev->state) {
 	case STATE_DEV_SETUP:		// VERY odd... host died??
 	case STATE_DEV_CONNECTED:
@@ -1777,7 +1812,7 @@ gadgetfs_suspend (struct usb_gadget *gad
 	default:
 		break;
 	}
-	spin_unlock (&dev->lock);
+	spin_unlock_irqrestore(&dev->lock, flags);
 }
 
 static struct usb_gadget_driver gadgetfs_driver = {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/mass_storage.c linux-libre-3.16.52-gnu/drivers/usb/gadget/mass_storage.c
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/mass_storage.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/mass_storage.c	2018-01-01 15:52:14.000000000 -0500
@@ -121,15 +121,6 @@ static unsigned int fsg_num_buffers = CO
 
 FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
 
-static unsigned long msg_registered;
-static void msg_cleanup(void);
-
-static int msg_thread_exits(struct fsg_common *common)
-{
-	msg_cleanup();
-	return 0;
-}
-
 static int __init msg_do_config(struct usb_configuration *c)
 {
 	struct fsg_opts *opts;
@@ -172,9 +163,6 @@ static struct usb_configuration msg_conf
 
 static int __init msg_bind(struct usb_composite_dev *cdev)
 {
-	static const struct fsg_operations ops = {
-		.thread_exits = msg_thread_exits,
-	};
 	struct fsg_opts *opts;
 	struct fsg_config config;
 	int status;
@@ -195,8 +183,6 @@ static int __init msg_bind(struct usb_co
 	if (status)
 		goto fail_set_nluns;
 
-	fsg_common_set_ops(opts->common, &ops);
-
 	status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
 	if (status)
 		goto fail_set_cdev;
@@ -221,7 +207,6 @@ static int __init msg_bind(struct usb_co
 	usb_composite_overwrite_options(cdev, &coverwrite);
 	dev_info(&cdev->gadget->dev,
 		 DRIVER_DESC ", version: " DRIVER_VERSION "\n");
-	set_bit(0, &msg_registered);
 	return 0;
 
 fail_string_ids:
@@ -268,9 +253,8 @@ static int __init msg_init(void)
 }
 module_init(msg_init);
 
-static void msg_cleanup(void)
+static void __exit msg_cleanup(void)
 {
-	if (test_and_clear_bit(0, &msg_registered))
-		usb_composite_unregister(&msg_driver);
+	usb_composite_unregister(&msg_driver);
 }
 module_exit(msg_cleanup);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/gadget/net2280.c linux-libre-3.16.52-gnu/drivers/usb/gadget/net2280.c
--- linux-libre-3.16.51-gnu/drivers/usb/gadget/net2280.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/gadget/net2280.c	2018-01-01 15:52:14.000000000 -0500
@@ -1941,11 +1941,8 @@ stop_activity (struct net2280 *dev, stru
 		nuke (&dev->ep [i]);
 
 	/* report disconnect; the driver is already quiesced */
-	if (driver) {
-		spin_unlock(&dev->lock);
+	if (driver)
 		driver->disconnect(&dev->gadget);
-		spin_lock(&dev->lock);
-	}
 
 	usb_reinit (dev);
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/host/pci-quirks.c linux-libre-3.16.52-gnu/drivers/usb/host/pci-quirks.c
--- linux-libre-3.16.51-gnu/drivers/usb/host/pci-quirks.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/host/pci-quirks.c	2018-01-01 15:52:14.000000000 -0500
@@ -1024,7 +1024,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports
  *
  * Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS.
  * It signals to the BIOS that the OS wants control of the host controller,
- * and then waits 5 seconds for the BIOS to hand over control.
+ * and then waits 1 second for the BIOS to hand over control.
  * If we timeout, assume the BIOS is broken and take control anyway.
  */
 static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
@@ -1070,9 +1070,9 @@ static void quirk_usb_handoff_xhci(struc
 	if (val & XHCI_HC_BIOS_OWNED) {
 		writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
 
-		/* Wait for 5 seconds with 10 microsecond polling interval */
+		/* Wait for 1 second with 10 microsecond polling interval */
 		timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED,
-				0, 5000, 10);
+				0, 1000000, 10);
 
 		/* Assume a buggy BIOS and take HC ownership anyway */
 		if (timeout) {
@@ -1100,7 +1100,7 @@ hc_init:
 	 * operational or runtime registers.  Wait 5 seconds and no more.
 	 */
 	timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_CNR, 0,
-			5000, 10);
+			5000000, 10);
 	/* Assume a buggy HC and start HC initialization anyway */
 	if (timeout) {
 		val = readl(op_reg_base + XHCI_STS_OFFSET);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/host/xhci.h linux-libre-3.16.52-gnu/drivers/usb/host/xhci.h
--- linux-libre-3.16.51-gnu/drivers/usb/host/xhci.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/host/xhci.h	2018-01-01 15:52:14.000000000 -0500
@@ -1437,7 +1437,7 @@ struct xhci_bus_state {
 
 static inline unsigned int hcd_index(struct usb_hcd *hcd)
 {
-	if (hcd->speed == HCD_USB3)
+	if (hcd->speed >= HCD_USB3)
 		return 0;
 	else
 		return 1;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/host/xhci-hub.c linux-libre-3.16.52-gnu/drivers/usb/host/xhci-hub.c
--- linux-libre-3.16.51-gnu/drivers/usb/host/xhci-hub.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/host/xhci-hub.c	2018-01-01 15:52:14.000000000 -0500
@@ -293,15 +293,25 @@ static int xhci_stop_device(struct xhci_
 						     GFP_NOWAIT);
 			if (!command) {
 				spin_unlock_irqrestore(&xhci->lock, flags);
-				xhci_free_command(xhci, cmd);
-				return -ENOMEM;
+				ret = -ENOMEM;
+				goto cmd_cleanup;
+			}
 
+			ret = xhci_queue_stop_endpoint(xhci, command, slot_id,
+						       i, suspend);
+			if (ret) {
+				spin_unlock_irqrestore(&xhci->lock, flags);
+				xhci_free_command(xhci, command);
+				goto cmd_cleanup;
 			}
-			xhci_queue_stop_endpoint(xhci, command, slot_id, i,
-						 suspend);
 		}
 	}
-	xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+	ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+	if (ret) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		goto cmd_cleanup;
+	}
+
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -312,6 +322,8 @@ static int xhci_stop_device(struct xhci_
 		xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
 		ret = -ETIME;
 	}
+
+cmd_cleanup:
 	xhci_free_command(xhci, cmd);
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/renesas_usbhs/fifo.c linux-libre-3.16.52-gnu/drivers/usb/renesas_usbhs/fifo.c
--- linux-libre-3.16.51-gnu/drivers/usb/renesas_usbhs/fifo.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/renesas_usbhs/fifo.c	2018-01-01 15:52:14.000000000 -0500
@@ -261,11 +261,26 @@ static void usbhsf_fifo_clear(struct usb
 			      struct usbhs_fifo *fifo)
 {
 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+	int ret = 0;
 
-	if (!usbhs_pipe_is_dcp(pipe))
-		usbhsf_fifo_barrier(priv, fifo);
+	if (!usbhs_pipe_is_dcp(pipe)) {
+		/*
+		 * This driver checks the pipe condition first to avoid -EBUSY
+		 * from usbhsf_fifo_barrier() with about 10 msec delay in
+		 * the interrupt handler if the pipe is RX direction and empty.
+		 */
+		if (usbhs_pipe_is_dir_in(pipe))
+			ret = usbhs_pipe_is_accessible(pipe);
+		if (!ret)
+			ret = usbhsf_fifo_barrier(priv, fifo);
+	}
 
-	usbhs_write(priv, fifo->ctr, BCLR);
+	/*
+	 * if non-DCP pipe, this driver should set BCLR when
+	 * usbhsf_fifo_barrier() returns 0.
+	 */
+	if (!ret)
+		usbhs_write(priv, fifo->ctr, BCLR);
 }
 
 static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv,
@@ -813,9 +828,9 @@ static void xfer_work(struct work_struct
 	dev_dbg(dev, "  %s %d (%d/ %d)\n",
 		fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
 
-	usbhsf_dma_start(pipe, fifo);
 	usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
 	dma_async_issue_pending(chan);
+	usbhsf_dma_start(pipe, fifo);
 	usbhs_pipe_enable(pipe);
 
 xfer_work_end:
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/serial/cp210x.c linux-libre-3.16.52-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-3.16.51-gnu/drivers/usb/serial/cp210x.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/serial/cp210x.c	2018-01-01 15:52:14.000000000 -0500
@@ -170,6 +170,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
 	{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+	{ USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */
 	{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
 	{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
 	{ USB_DEVICE(0x1901, 0x0194) },	/* GE Healthcare Remote Alarm Box */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/serial/ftdi_sio.c linux-libre-3.16.52-gnu/drivers/usb/serial/ftdi_sio.c
--- linux-libre-3.16.51-gnu/drivers/usb/serial/ftdi_sio.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/serial/ftdi_sio.c	2018-01-01 15:52:14.000000000 -0500
@@ -1028,6 +1028,8 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
 	{ USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) },
+	{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) },
 	{ }					/* Terminating entry */
 };
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/serial/ftdi_sio_ids.h linux-libre-3.16.52-gnu/drivers/usb/serial/ftdi_sio_ids.h
--- linux-libre-3.16.51-gnu/drivers/usb/serial/ftdi_sio_ids.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/serial/ftdi_sio_ids.h	2018-01-01 15:52:14.000000000 -0500
@@ -610,6 +610,13 @@
 #define ADI_GNICEPLUS_PID	0xF001
 
 /*
+ * Cypress WICED USB UART
+ */
+#define CYPRESS_VID			0x04B4
+#define CYPRESS_WICED_BT_USB_PID	0x009B
+#define CYPRESS_WICED_WL_USB_PID	0xF900
+
+/*
  * Microchip Technology, Inc.
  *
  * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/serial/metro-usb.c linux-libre-3.16.52-gnu/drivers/usb/serial/metro-usb.c
--- linux-libre-3.16.51-gnu/drivers/usb/serial/metro-usb.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/serial/metro-usb.c	2018-01-01 15:52:14.000000000 -0500
@@ -45,6 +45,7 @@ struct metrousb_private {
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) },	/* MS7820 */
 	{ }, /* Terminating entry. */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/serial/option.c linux-libre-3.16.52-gnu/drivers/usb/serial/option.c
--- linux-libre-3.16.51-gnu/drivers/usb/serial/option.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/serial/option.c	2018-01-01 15:52:14.000000000 -0500
@@ -524,6 +524,7 @@ static void option_instat_callback(struc
 
 /* TP-LINK Incorporated products */
 #define TPLINK_VENDOR_ID			0x2357
+#define TPLINK_PRODUCT_LTE			0x000D
 #define TPLINK_PRODUCT_MA180			0x0201
 
 /* Changhong products */
@@ -2022,6 +2023,7 @@ static const struct usb_device_id option
 	{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
 	{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) },
 	{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) },	/* TP-Link LTE Module */
 	{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
 	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE(TPLINK_VENDOR_ID, 0x9000),					/* TP-Link MA260 */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/serial/qcserial.c linux-libre-3.16.52-gnu/drivers/usb/serial/qcserial.c
--- linux-libre-3.16.51-gnu/drivers/usb/serial/qcserial.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/serial/qcserial.c	2018-01-01 15:52:14.000000000 -0500
@@ -172,6 +172,10 @@ static const struct usb_device_id id_tab
 	{DEVICE_SWI(0x413c, 0x81b3)},	/* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
 	{DEVICE_SWI(0x413c, 0x81b5)},	/* Dell Wireless 5811e QDL */
 	{DEVICE_SWI(0x413c, 0x81b6)},	/* Dell Wireless 5811e QDL */
+	{DEVICE_SWI(0x413c, 0x81cf)},   /* Dell Wireless 5819 */
+	{DEVICE_SWI(0x413c, 0x81d0)},   /* Dell Wireless 5819 */
+	{DEVICE_SWI(0x413c, 0x81d1)},   /* Dell Wireless 5818 */
+	{DEVICE_SWI(0x413c, 0x81d2)},   /* Dell Wireless 5818 */
 
 	/* Huawei devices */
 	{DEVICE_HWI(0x03f0, 0x581d)},	/* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/storage/transport.c linux-libre-3.16.52-gnu/drivers/usb/storage/transport.c
--- linux-libre-3.16.51-gnu/drivers/usb/storage/transport.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/storage/transport.c	2018-01-01 15:52:14.000000000 -0500
@@ -808,12 +808,24 @@ Retry_Sense:
 			if (result == USB_STOR_TRANSPORT_GOOD) {
 				srb->result = SAM_STAT_GOOD;
 				srb->sense_buffer[0] = 0x0;
+			}
+
+			/*
+			 * ATA-passthru commands use sense data to report
+			 * the command completion status, and often devices
+			 * return Check Condition status when nothing is
+			 * wrong.
+			 */
+			else if (srb->cmnd[0] == ATA_16 ||
+					srb->cmnd[0] == ATA_12) {
+				/* leave the data alone */
+			}
 
 			/* If there was a problem, report an unspecified
 			 * hardware error to prevent the higher layers from
 			 * entering an infinite retry loop.
 			 */
-			} else {
+			else {
 				srb->result = DID_ERROR << 16;
 				if ((sshdr.response_code & 0x72) == 0x72)
 					srb->sense_buffer[1] = HARDWARE_ERROR;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/usb/storage/unusual_devs.h linux-libre-3.16.52-gnu/drivers/usb/storage/unusual_devs.h
--- linux-libre-3.16.51-gnu/drivers/usb/storage/unusual_devs.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/usb/storage/unusual_devs.h	2018-01-01 15:52:14.000000000 -0500
@@ -1360,6 +1360,13 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_SANE_SENSE ),
 
+/* Reported by Kris Lindgren <kris.lindgren@gmail.com> */
+UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999,
+		"Seagate",
+		"External",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_NO_WP_DETECT ),
+
 UNUSUAL_DEV(  0x0d49, 0x7310, 0x0000, 0x9999,
 		"Maxtor",
 		"USB to SATA",
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/uwb/hwa-rc.c linux-libre-3.16.52-gnu/drivers/uwb/hwa-rc.c
--- linux-libre-3.16.51-gnu/drivers/uwb/hwa-rc.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/uwb/hwa-rc.c	2018-01-01 15:52:14.000000000 -0500
@@ -827,6 +827,8 @@ static int hwarc_probe(struct usb_interf
 
 	if (iface->cur_altsetting->desc.bNumEndpoints < 1)
 		return -ENODEV;
+	if (!usb_endpoint_xfer_int(&iface->cur_altsetting->endpoint[0].desc))
+		return -ENODEV;
 
 	result = -ENOMEM;
 	uwb_rc = uwb_rc_alloc();
diff -druNp --no-dereference linux-libre-3.16.51-gnu/drivers/uwb/uwbd.c linux-libre-3.16.52-gnu/drivers/uwb/uwbd.c
--- linux-libre-3.16.51-gnu/drivers/uwb/uwbd.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/drivers/uwb/uwbd.c	2018-01-01 15:52:14.000000000 -0500
@@ -303,18 +303,22 @@ static int uwbd(void *param)
 /** Start the UWB daemon */
 void uwbd_start(struct uwb_rc *rc)
 {
-	rc->uwbd.task = kthread_run(uwbd, rc, "uwbd");
-	if (rc->uwbd.task == NULL)
+	struct task_struct *task = kthread_run(uwbd, rc, "uwbd");
+	if (IS_ERR(task)) {
+		rc->uwbd.task = NULL;
 		printk(KERN_ERR "UWB: Cannot start management daemon; "
 		       "UWB won't work\n");
-	else
+	} else {
+		rc->uwbd.task = task;
 		rc->uwbd.pid = rc->uwbd.task->pid;
+	}
 }
 
 /* Stop the UWB daemon and free any unprocessed events */
 void uwbd_stop(struct uwb_rc *rc)
 {
-	kthread_stop(rc->uwbd.task);
+	if (rc->uwbd.task)
+		kthread_stop(rc->uwbd.task);
 	uwbd_flush(rc);
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/block_dev.c linux-libre-3.16.52-gnu/fs/block_dev.c
--- linux-libre-3.16.51-gnu/fs/block_dev.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/block_dev.c	2018-01-01 15:52:14.000000000 -0500
@@ -419,10 +419,12 @@ int bdev_write_page(struct block_device
 		return -EOPNOTSUPP;
 	set_page_writeback(page);
 	result = ops->rw_page(bdev, sector + get_start_sect(bdev), page, rw);
-	if (result)
+	if (result) {
 		end_page_writeback(page);
-	else
+	} else {
+		clean_page_buffers(page);
 		unlock_page(page);
+	}
 	return result;
 }
 EXPORT_SYMBOL_GPL(bdev_write_page);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/btrfs/ioctl.c linux-libre-3.16.52-gnu/fs/btrfs/ioctl.c
--- linux-libre-3.16.51-gnu/fs/btrfs/ioctl.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/btrfs/ioctl.c	2018-01-01 15:52:14.000000000 -0500
@@ -2745,9 +2745,9 @@ static long btrfs_ioctl_fs_info(struct b
 	}
 	mutex_unlock(&fs_devices->device_list_mutex);
 
-	fi_args->nodesize = root->fs_info->super_copy->nodesize;
-	fi_args->sectorsize = root->fs_info->super_copy->sectorsize;
-	fi_args->clone_alignment = root->fs_info->super_copy->sectorsize;
+	fi_args->nodesize = root->nodesize;
+	fi_args->sectorsize = root->sectorsize;
+	fi_args->clone_alignment = root->sectorsize;
 
 	if (copy_to_user(arg, fi_args, sizeof(*fi_args)))
 		ret = -EFAULT;
@@ -3980,6 +3980,10 @@ static long btrfs_ioctl_default_subvol(s
 		ret = PTR_ERR(new_root);
 		goto out;
 	}
+	if (!is_fstree(new_root->objectid)) {
+		ret = -ENOENT;
+		goto out;
+	}
 
 	path = btrfs_alloc_path();
 	if (!path) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/cifs/cifsfs.c linux-libre-3.16.52-gnu/fs/cifs/cifsfs.c
--- linux-libre-3.16.51-gnu/fs/cifs/cifsfs.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/cifs/cifsfs.c	2018-01-01 15:52:14.000000000 -0500
@@ -1294,7 +1294,7 @@ exit_cifs(void)
 	exit_cifs_idmap();
 #endif
 #ifdef CONFIG_CIFS_UPCALL
-	unregister_key_type(&cifs_spnego_key_type);
+	exit_cifs_spnego();
 #endif
 	cifs_destroy_request_bufs();
 	cifs_destroy_mids();
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/cifs/connect.c linux-libre-3.16.52-gnu/fs/cifs/connect.c
--- linux-libre-3.16.51-gnu/fs/cifs/connect.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/cifs/connect.c	2018-01-01 15:52:14.000000000 -0500
@@ -3956,6 +3956,14 @@ cifs_setup_session(const unsigned int xi
 	cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
 		 server->sec_mode, server->capabilities, server->timeAdj);
 
+	if (ses->auth_key.response) {
+		cifs_dbg(VFS, "Free previous auth_key.response = %p\n",
+			 ses->auth_key.response);
+		kfree(ses->auth_key.response);
+		ses->auth_key.response = NULL;
+		ses->auth_key.len = 0;
+	}
+
 	if (server->ops->sess_setup)
 		rc = server->ops->sess_setup(xid, ses, nls_info);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/cifs/file.c linux-libre-3.16.52-gnu/fs/cifs/file.c
--- linux-libre-3.16.51-gnu/fs/cifs/file.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/cifs/file.c	2018-01-01 15:52:14.000000000 -0500
@@ -225,6 +225,13 @@ cifs_nt_open(char *full_path, struct ino
 	if (backup_cred(cifs_sb))
 		create_options |= CREATE_OPEN_BACKUP_INTENT;
 
+	/* O_SYNC also has bit for O_DSYNC so following check picks up either */
+	if (f_flags & O_SYNC)
+		create_options |= CREATE_WRITE_THROUGH;
+
+	if (f_flags & O_DIRECT)
+		create_options |= CREATE_NO_BUFFER;
+
 	oparms.tcon = tcon;
 	oparms.cifs_sb = cifs_sb;
 	oparms.desired_access = desired_access;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/cifs/smb2pdu.c linux-libre-3.16.52-gnu/fs/cifs/smb2pdu.c
--- linux-libre-3.16.51-gnu/fs/cifs/smb2pdu.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/cifs/smb2pdu.c	2018-01-01 15:52:14.000000000 -0500
@@ -479,21 +479,28 @@ int smb3_validate_negotiate(const unsign
 {
 	int rc = 0;
 	struct validate_negotiate_info_req vneg_inbuf;
-	struct validate_negotiate_info_rsp *pneg_rsp;
+	struct validate_negotiate_info_rsp *pneg_rsp = NULL;
 	u32 rsplen;
 
 	cifs_dbg(FYI, "validate negotiate\n");
 
 	/*
 	 * validation ioctl must be signed, so no point sending this if we
-	 * can not sign it.  We could eventually change this to selectively
+	 * can not sign it (ie are not known user).  Even if signing is not
+	 * required (enabled but not negotiated), in those cases we selectively
 	 * sign just this, the first and only signed request on a connection.
-	 * This is good enough for now since a user who wants better security
-	 * would also enable signing on the mount. Having validation of
-	 * negotiate info for signed connections helps reduce attack vectors
+	 * Having validation of negotiate info  helps reduce attack vectors.
 	 */
-	if (tcon->ses->server->sign == false)
+	if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
+		return 0; /* validation requires signing */
+
+	if (tcon->ses->user_name == NULL) {
+		cifs_dbg(FYI, "Can't validate negotiate: null user mount\n");
 		return 0; /* validation requires signing */
+	}
+
+	if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
+		cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n");
 
 	vneg_inbuf.Capabilities =
 			cpu_to_le32(tcon->ses->server->vals->req_capabilities);
@@ -528,8 +535,9 @@ int smb3_validate_negotiate(const unsign
 			 rsplen);
 
 		/* relax check since Mac returns max bufsize allowed on ioctl */
-		if (rsplen > CIFSMaxBufSize)
-			return -EIO;
+		if ((rsplen > CIFSMaxBufSize)
+		     || (rsplen < sizeof(struct validate_negotiate_info_rsp)))
+			goto err_rsp_free;
 	}
 
 	/* check validate negotiate info response matches what we got earlier */
@@ -548,10 +556,13 @@ int smb3_validate_negotiate(const unsign
 
 	/* validate negotiate successful */
 	cifs_dbg(FYI, "validate negotiate info successful\n");
+	kfree(pneg_rsp);
 	return 0;
 
 vneg_out:
 	cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
+err_rsp_free:
+	kfree(pneg_rsp);
 	return -EIO;
 }
 
@@ -1114,7 +1125,7 @@ SMB2_open(const unsigned int xid, struct
 	struct TCP_Server_Info *server;
 	struct cifs_tcon *tcon = oparms->tcon;
 	struct cifs_ses *ses = tcon->ses;
-	struct kvec iov[4];
+	struct kvec iov[4] = {{NULL, 0}};
 	int resp_buftype;
 	int uni_path_len;
 	__le16 *copy_path = NULL;
@@ -1215,7 +1226,7 @@ SMB2_open(const unsigned int xid, struct
 
 	if (rc != 0) {
 		cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
-		if (err_buf)
+		if (err_buf && rsp)
 			*err_buf = kmemdup(rsp, get_rfc1002_length(rsp) + 4,
 					   GFP_KERNEL);
 		goto creat_exit;
@@ -1331,6 +1342,9 @@ SMB2_ioctl(const unsigned int xid, struc
 	} else
 		iov[0].iov_len = get_rfc1002_length(req) + 4;
 
+	/* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+	if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+		req->hdr.Flags |= SMB2_FLAGS_SIGNED;
 
 	rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
 	rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/direct-io.c linux-libre-3.16.52-gnu/fs/direct-io.c
--- linux-libre-3.16.51-gnu/fs/direct-io.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/direct-io.c	2018-01-01 15:52:14.000000000 -0500
@@ -812,7 +812,8 @@ out:
 	 */
 	if (sdio->boundary) {
 		ret = dio_send_cur_page(dio, sdio, map_bh);
-		dio_bio_submit(dio, sdio);
+		if (sdio->bio)
+			dio_bio_submit(dio, sdio);
 		page_cache_release(sdio->cur_page);
 		sdio->cur_page = NULL;
 	}
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/ecryptfs/ecryptfs_kernel.h linux-libre-3.16.52-gnu/fs/ecryptfs/ecryptfs_kernel.h
--- linux-libre-3.16.51-gnu/fs/ecryptfs/ecryptfs_kernel.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/ecryptfs/ecryptfs_kernel.h	2018-01-01 15:52:14.000000000 -0500
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
 static inline struct ecryptfs_auth_tok *
 ecryptfs_get_encrypted_key_payload_data(struct key *key)
 {
-	if (key->type == &key_type_encrypted)
-		return (struct ecryptfs_auth_tok *)
-			(&((struct encrypted_key_payload *)key->payload.data)->payload_data);
-	else
+	struct encrypted_key_payload *payload;
+
+	if (key->type != &key_type_encrypted)
 		return NULL;
+
+	payload = key->payload.data;
+	if (!payload)
+		return ERR_PTR(-EKEYREVOKED);
+
+	return (struct ecryptfs_auth_tok *)payload->payload_data;
 }
 
 static inline struct key *ecryptfs_get_encrypted_key(char *sig)
@@ -114,13 +119,17 @@ static inline struct ecryptfs_auth_tok *
 ecryptfs_get_key_payload_data(struct key *key)
 {
 	struct ecryptfs_auth_tok *auth_tok;
+	struct user_key_payload *ukp;
 
 	auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
-	if (!auth_tok)
-		return (struct ecryptfs_auth_tok *)
-			(((struct user_key_payload *)key->payload.data)->data);
-	else
+	if (auth_tok)
 		return auth_tok;
+
+	ukp = key->payload.data;
+	if (!ukp)
+		return ERR_PTR(-EKEYREVOKED);
+
+	return (struct ecryptfs_auth_tok *)ukp->data;
 }
 
 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/ecryptfs/keystore.c linux-libre-3.16.52-gnu/fs/ecryptfs/keystore.c
--- linux-libre-3.16.51-gnu/fs/ecryptfs/keystore.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/ecryptfs/keystore.c	2018-01-01 15:52:14.000000000 -0500
@@ -459,7 +459,8 @@ out:
  * @auth_tok_key: key containing the authentication token
  * @auth_tok: authentication token
  *
- * Returns zero on valid auth tok; -EINVAL otherwise
+ * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
+ * -EKEYREVOKED if the key was revoked before we acquired its semaphore.
  */
 static int
 ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct
 	int rc = 0;
 
 	(*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
+	if (IS_ERR(*auth_tok)) {
+		rc = PTR_ERR(*auth_tok);
+		*auth_tok = NULL;
+		goto out;
+	}
+
 	if (ecryptfs_verify_version((*auth_tok)->version)) {
 		printk(KERN_ERR "Data structure version mismatch. Userspace "
 		       "tools must match eCryptfs kernel module with major "
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/exec.c linux-libre-3.16.52-gnu/fs/exec.c
--- linux-libre-3.16.51-gnu/fs/exec.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/exec.c	2018-01-01 15:52:14.000000000 -0500
@@ -56,6 +56,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/oom.h>
 #include <linux/compat.h>
+#include <linux/user_namespace.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1129,8 +1130,22 @@ EXPORT_SYMBOL(flush_old_exec);
 
 void would_dump(struct linux_binprm *bprm, struct file *file)
 {
-	if (inode_permission(file_inode(file), MAY_READ) < 0)
+	struct inode *inode = file_inode(file);
+	if (inode_permission(inode, MAY_READ) < 0) {
+		struct user_namespace *old, *user_ns;
 		bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+
+		/* Ensure mm->user_ns contains the executable */
+		user_ns = old = bprm->mm->user_ns;
+		while ((user_ns != &init_user_ns) &&
+		       !privileged_wrt_inode_uidgid(user_ns, inode))
+			user_ns = user_ns->parent;
+
+		if (old != user_ns) {
+			bprm->mm->user_ns = get_user_ns(user_ns);
+			put_user_ns(old);
+		}
+	}
 }
 EXPORT_SYMBOL(would_dump);
 
@@ -1160,7 +1175,6 @@ void setup_new_exec(struct linux_binprm
 	    !gid_eq(bprm->cred->gid, current_egid())) {
 		current->pdeath_signal = 0;
 	} else {
-		would_dump(bprm, bprm->file);
 		if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
 			set_dumpable(current->mm, suid_dumpable);
 	}
@@ -1259,7 +1273,7 @@ static void check_unsafe_exec(struct lin
 	unsigned n_fs;
 
 	if (p->ptrace) {
-		if (p->ptrace & PT_PTRACE_CAP)
+		if (ptracer_capable(p, current_user_ns()))
 			bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP;
 		else
 			bprm->unsafe |= LSM_UNSAFE_PTRACE;
@@ -1564,6 +1578,8 @@ static int do_execve_common(struct filen
 	if (retval < 0)
 		goto out;
 
+	would_dump(bprm, bprm->file);
+
 	retval = exec_binprm(bprm);
 	if (retval < 0)
 		goto out;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/fscache/object-list.c linux-libre-3.16.52-gnu/fs/fscache/object-list.c
--- linux-libre-3.16.51-gnu/fs/fscache/object-list.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/fscache/object-list.c	2018-01-01 15:52:14.000000000 -0500
@@ -330,6 +330,13 @@ static void fscache_objlist_config(struc
 	rcu_read_lock();
 
 	confkey = key->payload.data;
+	if (!confkey) {
+		/* key was revoked */
+		rcu_read_unlock();
+		key_put(key);
+		goto no_config;
+	}
+
 	buf = confkey->data;
 
 	for (len = confkey->datalen - 1; len >= 0; len--) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/fuse/dir.c linux-libre-3.16.52-gnu/fs/fuse/dir.c
--- linux-libre-3.16.51-gnu/fs/fuse/dir.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/fuse/dir.c	2018-01-01 15:52:14.000000000 -0500
@@ -1382,7 +1382,8 @@ static int parse_dirplusfile(char *buf,
 			*/
 			over = !dir_emit(ctx, dirent->name, dirent->namelen,
 				       dirent->ino, dirent->type);
-			ctx->pos = dirent->off;
+			if (!over)
+				ctx->pos = dirent->off;
 		}
 
 		buf += reclen;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/mpage.c linux-libre-3.16.52-gnu/fs/mpage.c
--- linux-libre-3.16.51-gnu/fs/mpage.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/mpage.c	2018-01-01 15:52:14.000000000 -0500
@@ -457,6 +457,16 @@ static void clean_buffers(struct page *p
 		try_to_free_buffers(page);
 }
 
+/*
+ * For situations where we want to clean all buffers attached to a page.
+ * We don't need to calculate how many buffers are attached to the page,
+ * we just need to specify a number larger than the maximum number of buffers.
+ */
+void clean_page_buffers(struct page *page)
+{
+	clean_buffers(page, ~0U);
+}
+
 static int __mpage_writepage(struct page *page, struct writeback_control *wbc,
 		      void *data)
 {
@@ -594,10 +604,8 @@ alloc_new:
 	if (bio == NULL) {
 		if (first_unmapped == blocks_per_page) {
 			if (!bdev_write_page(bdev, blocks[0] << (blkbits - 9),
-								page, wbc)) {
-				clean_buffers(page, first_unmapped);
+								page, wbc))
 				goto out;
-			}
 		}
 		bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
 				bio_get_nr_vecs(bdev), GFP_NOFS|__GFP_HIGH);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/ocfs2/alloc.c linux-libre-3.16.52-gnu/fs/ocfs2/alloc.c
--- linux-libre-3.16.51-gnu/fs/ocfs2/alloc.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/ocfs2/alloc.c	2018-01-01 15:52:14.000000000 -0500
@@ -7226,13 +7226,24 @@ out:
 
 static int ocfs2_trim_extent(struct super_block *sb,
 			     struct ocfs2_group_desc *gd,
-			     u32 start, u32 count)
+			     u64 group, u32 start, u32 count)
 {
 	u64 discard, bcount;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
 
 	bcount = ocfs2_clusters_to_blocks(sb, count);
-	discard = le64_to_cpu(gd->bg_blkno) +
-			ocfs2_clusters_to_blocks(sb, start);
+	discard = ocfs2_clusters_to_blocks(sb, start);
+
+	/*
+	 * For the first cluster group, the gd->bg_blkno is not at the start
+	 * of the group, but at an offset from the start. If we add it while
+	 * calculating discard for first group, we will wrongly start fstrim a
+	 * few blocks after the desried start block and the range can cross
+	 * over into the next cluster group. So, add it only if this is not
+	 * the first cluster group.
+	 */
+	if (group != osb->first_cluster_group_blkno)
+		discard += le64_to_cpu(gd->bg_blkno);
 
 	trace_ocfs2_trim_extent(sb, (unsigned long long)discard, bcount);
 
@@ -7240,7 +7251,7 @@ static int ocfs2_trim_extent(struct supe
 }
 
 static int ocfs2_trim_group(struct super_block *sb,
-			    struct ocfs2_group_desc *gd,
+			    struct ocfs2_group_desc *gd, u64 group,
 			    u32 start, u32 max, u32 minbits)
 {
 	int ret = 0, count = 0, next;
@@ -7259,7 +7270,7 @@ static int ocfs2_trim_group(struct super
 		next = ocfs2_find_next_bit(bitmap, max, start);
 
 		if ((next - start) >= minbits) {
-			ret = ocfs2_trim_extent(sb, gd,
+			ret = ocfs2_trim_extent(sb, gd, group,
 						start, next - start);
 			if (ret < 0) {
 				mlog_errno(ret);
@@ -7357,7 +7368,8 @@ int ocfs2_trim_fs(struct super_block *sb
 		}
 
 		gd = (struct ocfs2_group_desc *)gd_bh->b_data;
-		cnt = ocfs2_trim_group(sb, gd, first_bit, last_bit, minlen);
+		cnt = ocfs2_trim_group(sb, gd, group,
+				       first_bit, last_bit, minlen);
 		brelse(gd_bh);
 		gd_bh = NULL;
 		if (cnt < 0) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/read_write.c linux-libre-3.16.52-gnu/fs/read_write.c
--- linux-libre-3.16.51-gnu/fs/read_write.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/read_write.c	2018-01-01 15:52:14.000000000 -0500
@@ -116,7 +116,7 @@ generic_file_llseek_size(struct file *fi
 		 * In the generic case the entire file is data, so as long as
 		 * offset isn't at the end of the file then the offset is data.
 		 */
-		if (offset >= eof)
+		if ((unsigned long long)offset >= eof)
 			return -ENXIO;
 		break;
 	case SEEK_HOLE:
@@ -124,7 +124,7 @@ generic_file_llseek_size(struct file *fi
 		 * There is a virtual hole at the end of the file, so as long as
 		 * offset isn't i_size or larger, return i_size.
 		 */
-		if (offset >= eof)
+		if ((unsigned long long)offset >= eof)
 			return -ENXIO;
 		offset = eof;
 		break;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/fs/xattr.c linux-libre-3.16.52-gnu/fs/xattr.c
--- linux-libre-3.16.51-gnu/fs/xattr.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/fs/xattr.c	2018-01-01 15:52:14.000000000 -0500
@@ -163,7 +163,7 @@ xattr_getsecurity(struct inode *inode, c
 	}
 	memcpy(value, buffer, len);
 out:
-	security_release_secctx(buffer, len);
+	kfree(buffer);
 out_noalloc:
 	return len;
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/crypto/internal/hash.h linux-libre-3.16.52-gnu/include/crypto/internal/hash.h
--- linux-libre-3.16.51-gnu/include/crypto/internal/hash.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/crypto/internal/hash.h	2018-01-01 15:52:14.000000000 -0500
@@ -83,6 +83,14 @@ int ahash_register_instance(struct crypt
 			    struct ahash_instance *inst);
 void ahash_free_instance(struct crypto_instance *inst);
 
+int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
+		    unsigned int keylen);
+
+static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
+{
+	return alg->setkey != shash_no_setkey;
+}
+
 int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn,
 			    struct hash_alg_common *alg,
 			    struct crypto_instance *inst);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/buffer_head.h linux-libre-3.16.52-gnu/include/linux/buffer_head.h
--- linux-libre-3.16.51-gnu/include/linux/buffer_head.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/buffer_head.h	2018-01-01 15:52:14.000000000 -0500
@@ -222,6 +222,7 @@ int generic_write_end(struct file *, str
 				loff_t, unsigned, unsigned,
 				struct page *, void *);
 void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
+void clean_page_buffers(struct page *page);
 int cont_write_begin(struct file *, struct address_space *, loff_t,
 			unsigned, unsigned, struct page **, void **,
 			get_block_t *, loff_t *);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/capability.h linux-libre-3.16.52-gnu/include/linux/capability.h
--- linux-libre-3.16.51-gnu/include/linux/capability.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/capability.h	2018-01-01 15:52:14.000000000 -0500
@@ -213,8 +213,10 @@ extern bool has_ns_capability_noaudit(st
 				      struct user_namespace *ns, int cap);
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
+extern bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode);
 extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
+extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
 
 /* audit system wants to get cap info from files as well */
 extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/iio/adc/ad_sigma_delta.h linux-libre-3.16.52-gnu/include/linux/iio/adc/ad_sigma_delta.h
--- linux-libre-3.16.51-gnu/include/linux/iio/adc/ad_sigma_delta.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/iio/adc/ad_sigma_delta.h	2018-01-01 15:52:14.000000000 -0500
@@ -111,6 +111,9 @@ int ad_sd_write_reg(struct ad_sigma_delt
 int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
 	unsigned int size, unsigned int *val);
 
+int ad_sd_reset(struct ad_sigma_delta *sigma_delta,
+	unsigned int reset_length);
+
 int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
 	const struct iio_chan_spec *chan, int *val);
 int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/input.h linux-libre-3.16.52-gnu/include/linux/input.h
--- linux-libre-3.16.51-gnu/include/linux/input.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/input.h	2018-01-01 15:52:14.000000000 -0500
@@ -527,6 +527,7 @@ int input_ff_event(struct input_dev *dev
 
 int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file);
 int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
+int input_ff_flush(struct input_dev *dev, struct file *file);
 
 int input_ff_create_memless(struct input_dev *dev, void *data,
 		int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/key.h linux-libre-3.16.52-gnu/include/linux/key.h
--- linux-libre-3.16.51-gnu/include/linux/key.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/key.h	2018-01-01 15:52:14.000000000 -0500
@@ -170,6 +170,7 @@ struct key {
 #define KEY_FLAG_INVALIDATED	7	/* set if key has been invalidated */
 #define KEY_FLAG_TRUSTED	8	/* set if key is trusted */
 #define KEY_FLAG_TRUSTED_ONLY	9	/* set if keyring only accepts links to trusted keys */
+#define KEY_FLAG_UID_KEYRING	11	/* set if key is a user or user session keyring */
 
 	/* the key type and key description string
 	 * - the desc is used to match a key against search criteria
@@ -221,6 +222,7 @@ extern struct key *key_alloc(struct key_
 #define KEY_ALLOC_QUOTA_OVERRUN	0x0001	/* add to quota, permit even if overrun */
 #define KEY_ALLOC_NOT_IN_QUOTA	0x0002	/* not in quota */
 #define KEY_ALLOC_TRUSTED	0x0004	/* Key should be flagged as trusted */
+#define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
 
 extern void key_revoke(struct key *key);
 extern void key_invalidate(struct key *key);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/mbus.h linux-libre-3.16.52-gnu/include/linux/mbus.h
--- linux-libre-3.16.51-gnu/include/linux/mbus.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/mbus.h	2018-01-01 15:52:14.000000000 -0500
@@ -29,8 +29,8 @@ struct mbus_dram_target_info
 	struct mbus_dram_window {
 		u8	cs_index;
 		u8	mbus_attr;
-		u32	base;
-		u32	size;
+		u64	base;
+		u64	size;
 	} cs[4];
 };
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/mm.h linux-libre-3.16.52-gnu/include/linux/mm.h
--- linux-libre-3.16.51-gnu/include/linux/mm.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/mm.h	2018-01-01 15:52:14.000000000 -0500
@@ -1209,6 +1209,8 @@ static inline int fixup_user_fault(struc
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
 		void *buf, int len, int write);
+extern int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+		unsigned long addr, void *buf, int len, int write);
 
 long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 		      unsigned long start, unsigned long nr_pages,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/mm_types.h linux-libre-3.16.52-gnu/include/linux/mm_types.h
--- linux-libre-3.16.51-gnu/include/linux/mm_types.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/mm_types.h	2018-01-01 15:52:14.000000000 -0500
@@ -419,6 +419,7 @@ struct mm_struct {
 	 */
 	struct task_struct __rcu *owner;
 #endif
+	struct user_namespace *user_ns;
 
 	/* store ref to file /proc/<pid>/exe symlink points to */
 	struct file *exe_file;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/mmzone.h linux-libre-3.16.52-gnu/include/linux/mmzone.h
--- linux-libre-3.16.51-gnu/include/linux/mmzone.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/mmzone.h	2018-01-01 15:52:14.000000000 -0500
@@ -1094,8 +1094,14 @@ static inline unsigned long early_pfn_to
 #error Allocator MAX_ORDER exceeds SECTION_SIZE
 #endif
 
-#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)
-#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT)
+static inline unsigned long pfn_to_section_nr(unsigned long pfn)
+{
+	return pfn >> PFN_SECTION_SHIFT;
+}
+static inline unsigned long section_nr_to_pfn(unsigned long sec)
+{
+	return sec << PFN_SECTION_SHIFT;
+}
 
 #define SECTION_ALIGN_UP(pfn)	(((pfn) + PAGES_PER_SECTION - 1) & PAGE_SECTION_MASK)
 #define SECTION_ALIGN_DOWN(pfn)	((pfn) & PAGE_SECTION_MASK)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/netdevice.h linux-libre-3.16.52-gnu/include/linux/netdevice.h
--- linux-libre-3.16.51-gnu/include/linux/netdevice.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/netdevice.h	2018-01-01 15:52:14.000000000 -0500
@@ -3000,6 +3000,9 @@ void ether_setup(struct net_device *dev)
 struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 				    void (*setup)(struct net_device *),
 				    unsigned int txqs, unsigned int rxqs);
+int dev_get_valid_name(struct net *net, struct net_device *dev,
+		       const char *name);
+
 #define alloc_netdev(sizeof_priv, name, setup) \
 	alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1)
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/of.h linux-libre-3.16.52-gnu/include/linux/of.h
--- linux-libre-3.16.51-gnu/include/linux/of.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/of.h	2018-01-01 15:52:14.000000000 -0500
@@ -503,6 +503,16 @@ static inline struct device_node *of_get
 	return NULL;
 }
 
+static inline int of_n_addr_cells(struct device_node *np)
+{
+	return 0;
+
+}
+static inline int of_n_size_cells(struct device_node *np)
+{
+	return 0;
+}
+
 static inline int of_property_read_u64(const struct device_node *np,
 				       const char *propname, u64 *out_value)
 {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/pci_ids.h linux-libre-3.16.52-gnu/include/linux/pci_ids.h
--- linux-libre-3.16.51-gnu/include/linux/pci_ids.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/pci_ids.h	2018-01-01 15:52:14.000000000 -0500
@@ -520,6 +520,8 @@
 #define PCI_DEVICE_ID_AMD_15H_M10H_F3	0x1403
 #define PCI_DEVICE_ID_AMD_15H_M30H_NB_F3 0x141d
 #define PCI_DEVICE_ID_AMD_15H_M30H_NB_F4 0x141e
+#define PCI_DEVICE_ID_AMD_15H_M60H_NB_F3 0x1573
+#define PCI_DEVICE_ID_AMD_15H_M60H_NB_F4 0x1574
 #define PCI_DEVICE_ID_AMD_15H_NB_F0	0x1600
 #define PCI_DEVICE_ID_AMD_15H_NB_F1	0x1601
 #define PCI_DEVICE_ID_AMD_15H_NB_F2	0x1602
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/preempt_mask.h linux-libre-3.16.52-gnu/include/linux/preempt_mask.h
--- linux-libre-3.16.51-gnu/include/linux/preempt_mask.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/preempt_mask.h	2018-01-01 15:52:14.000000000 -0500
@@ -57,19 +57,24 @@
 
 /*
  * Are we doing bottom half or hardware interrupt processing?
- * Are we in a softirq context? Interrupt context?
- * in_softirq - Are we currently processing softirq or have bh disabled?
- * in_serving_softirq - Are we currently processing softirq?
+ *
+ * in_irq()       - We're in (hard) IRQ context
+ * in_softirq()   - We have BH disabled, or are processing softirqs
+ * in_interrupt() - We're in NMI,IRQ,SoftIRQ context or have BH disabled
+ * in_serving_softirq() - We're in softirq context
+ * in_nmi()       - We're in NMI context
+ * in_task()	  - We're in task context
+ *
+ * Note: due to the BH disabled confusion: in_softirq(),in_interrupt() really
+ *       should not be used in new code.
  */
 #define in_irq()		(hardirq_count())
 #define in_softirq()		(softirq_count())
 #define in_interrupt()		(irq_count())
 #define in_serving_softirq()	(softirq_count() & SOFTIRQ_OFFSET)
-
-/*
- * Are we in NMI context?
- */
-#define in_nmi()	(preempt_count() & NMI_MASK)
+#define in_nmi()		(preempt_count() & NMI_MASK)
+#define in_task()		(!(preempt_count() & \
+				   (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)))
 
 /*
  * The preempt_count offset after preempt_disable();
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/ptrace.h linux-libre-3.16.52-gnu/include/linux/ptrace.h
--- linux-libre-3.16.51-gnu/include/linux/ptrace.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/ptrace.h	2018-01-01 15:52:14.000000000 -0500
@@ -8,6 +8,9 @@
 #include <linux/pid_namespace.h>	/* For task_active_pid_ns.  */
 #include <uapi/linux/ptrace.h>
 
+extern int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
+			    void *buf, int len, int write);
+
 /*
  * Ptrace flags
  *
@@ -19,7 +22,6 @@
 #define PT_SEIZED	0x00010000	/* SEIZE used, enable new behavior */
 #define PT_PTRACED	0x00000001
 #define PT_DTRACE	0x00000002	/* delayed trace (used on m68k, i386) */
-#define PT_PTRACE_CAP	0x00000004	/* ptracer can follow suid-exec */
 
 #define PT_OPT_FLAG_SHIFT	3
 /* PT_TRACE_* event enable flags */
@@ -50,7 +52,8 @@ extern int ptrace_request(struct task_st
 			  unsigned long addr, unsigned long data);
 extern void ptrace_notify(int exit_code);
 extern void __ptrace_link(struct task_struct *child,
-			  struct task_struct *new_parent);
+			  struct task_struct *new_parent,
+			  const struct cred *ptracer_cred);
 extern void __ptrace_unlink(struct task_struct *child);
 extern void exit_ptrace(struct task_struct *tracer);
 #define PTRACE_MODE_READ	0x01
@@ -202,7 +205,7 @@ static inline void ptrace_init_task(stru
 
 	if (unlikely(ptrace) && current->ptrace) {
 		child->ptrace = current->ptrace;
-		__ptrace_link(child, current->parent);
+		__ptrace_link(child, current->parent, current->ptracer_cred);
 
 		if (child->ptrace & PT_SEIZED)
 			task_set_jobctl_pending(child, JOBCTL_TRAP_STOP);
@@ -211,6 +214,8 @@ static inline void ptrace_init_task(stru
 
 		set_tsk_thread_flag(child, TIF_SIGPENDING);
 	}
+	else
+		child->ptracer_cred = NULL;
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/sched.h linux-libre-3.16.52-gnu/include/linux/sched.h
--- linux-libre-3.16.51-gnu/include/linux/sched.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/sched.h	2018-01-01 15:52:14.000000000 -0500
@@ -1385,6 +1385,7 @@ struct task_struct {
 	struct list_head cpu_timers[3];
 
 /* process credentials */
+	const struct cred __rcu *ptracer_cred; /* Tracer's credentials at attach */
 	const struct cred __rcu *real_cred; /* objective and real subjective task
 					 * credentials (COW) */
 	const struct cred __rcu *cred;	/* effective (overridable) subjective task
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/linux/skbuff.h linux-libre-3.16.52-gnu/include/linux/skbuff.h
--- linux-libre-3.16.51-gnu/include/linux/skbuff.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/linux/skbuff.h	2018-01-01 15:52:14.000000000 -0500
@@ -2965,6 +2965,13 @@ static inline void nf_reset_trace(struct
 #endif
 }
 
+static inline void ipvs_reset(struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_IP_VS)
+	skb->ipvs_property = 0;
+#endif
+}
+
 /* Note: This doesn't put any conntrack and bridge info in dst. */
 static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
 {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/net/protocol.h linux-libre-3.16.52-gnu/include/net/protocol.h
--- linux-libre-3.16.51-gnu/include/net/protocol.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/net/protocol.h	2018-01-01 15:52:14.000000000 -0500
@@ -39,7 +39,7 @@
 
 /* This is used to register protocols. */
 struct net_protocol {
-	void			(*early_demux)(struct sk_buff *skb);
+	int			(*early_demux)(struct sk_buff *skb);
 	int			(*handler)(struct sk_buff *skb);
 	void			(*err_handler)(struct sk_buff *skb, u32 info);
 	unsigned int		no_policy:1,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/net/route.h linux-libre-3.16.52-gnu/include/net/route.h
--- linux-libre-3.16.51-gnu/include/net/route.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/net/route.h	2018-01-01 15:52:14.000000000 -0500
@@ -159,7 +159,9 @@ static inline struct rtable *ip_route_ou
 	fl4->fl4_gre_key = gre_key;
 	return ip_route_output_key(net, fl4);
 }
-
+int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+			  u8 tos, struct net_device *dev,
+			  struct in_device *in_dev, u32 *itag);
 int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
 			 u8 tos, struct net_device *devin);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/net/tcp.h linux-libre-3.16.52-gnu/include/net/tcp.h
--- linux-libre-3.16.51-gnu/include/net/tcp.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/net/tcp.h	2018-01-01 15:52:14.000000000 -0500
@@ -350,7 +350,7 @@ void tcp_v4_err(struct sk_buff *skb, u32
 
 void tcp_shutdown(struct sock *sk, int how);
 
-void tcp_v4_early_demux(struct sk_buff *skb);
+int tcp_v4_early_demux(struct sk_buff *skb);
 int tcp_v4_rcv(struct sk_buff *skb);
 
 int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
@@ -1515,12 +1515,12 @@ static inline void tcp_highest_sack_rese
 	tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
 }
 
-/* Called when old skb is about to be deleted (to be combined with new skb) */
-static inline void tcp_highest_sack_combine(struct sock *sk,
+/* Called when old skb is about to be deleted and replaced by new skb */
+static inline void tcp_highest_sack_replace(struct sock *sk,
 					    struct sk_buff *old,
 					    struct sk_buff *new)
 {
-	if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
+	if (old == tcp_highest_sack(sk))
 		tcp_sk(sk)->highest_sack = new;
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/net/udp.h linux-libre-3.16.52-gnu/include/net/udp.h
--- linux-libre-3.16.51-gnu/include/net/udp.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/net/udp.h	2018-01-01 15:52:14.000000000 -0500
@@ -177,7 +177,7 @@ int udp_lib_get_port(struct sock *sk, un
 		     unsigned int hash2_nulladdr);
 
 /* net/ipv4/udp.c */
-void udp_v4_early_demux(struct sk_buff *skb);
+int udp_v4_early_demux(struct sk_buff *skb);
 int udp_get_port(struct sock *sk, unsigned short snum,
 		 int (*saddr_cmp)(const struct sock *,
 				  const struct sock *));
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/scsi/scsi_device.h linux-libre-3.16.52-gnu/include/scsi/scsi_device.h
--- linux-libre-3.16.51-gnu/include/scsi/scsi_device.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/scsi/scsi_device.h	2018-01-01 15:52:14.000000000 -0500
@@ -175,6 +175,7 @@ struct scsi_device {
 	unsigned wce_default_on:1;	/* Cache is ON by default */
 	unsigned no_dif:1;	/* T10 PI (DIF) should be disabled */
 	unsigned broken_fua:1;		/* Don't set FUA bit */
+	unsigned unmap_limit_for_ws:1;	/* Use the UNMAP limit for WRITE SAME */
 
 	atomic_t disk_events_disable_depth; /* disable depth for disk events */
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/scsi/scsi_devinfo.h linux-libre-3.16.52-gnu/include/scsi/scsi_devinfo.h
--- linux-libre-3.16.51-gnu/include/scsi/scsi_devinfo.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/scsi/scsi_devinfo.h	2018-01-01 15:52:14.000000000 -0500
@@ -37,5 +37,6 @@
 #define BLIST_TRY_VPD_PAGES	0x10000000 /* Attempt to read VPD pages */
 #define BLIST_NO_RSOC		0x20000000 /* don't try to issue RSOC */
 #define BLIST_MAX_1024		0x40000000 /* maximum 1024 sector cdb length */
+#define BLIST_UNMAP_LIMIT_WS	0x80000000 /* Use UNMAP limit for WRITE SAME */
 
 #endif
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/sound/seq_kernel.h linux-libre-3.16.52-gnu/include/sound/seq_kernel.h
--- linux-libre-3.16.51-gnu/include/sound/seq_kernel.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/sound/seq_kernel.h	2018-01-01 15:52:14.000000000 -0500
@@ -55,7 +55,8 @@ typedef union snd_seq_timestamp snd_seq_
 #define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS	200
 
 /* max delivery path length */
-#define SNDRV_SEQ_MAX_HOPS		10
+/* NOTE: this shouldn't be greater than MAX_LOCKDEP_SUBCLASSES */
+#define SNDRV_SEQ_MAX_HOPS		8
 
 /* max size of event size */
 #define SNDRV_SEQ_MAX_EVENT_LEN		0x3fffffff
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/sound/seq_virmidi.h linux-libre-3.16.52-gnu/include/sound/seq_virmidi.h
--- linux-libre-3.16.51-gnu/include/sound/seq_virmidi.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/sound/seq_virmidi.h	2018-01-01 15:52:14.000000000 -0500
@@ -60,6 +60,7 @@ struct snd_virmidi_dev {
 	int port;			/* created/attached port */
 	unsigned int flags;		/* SNDRV_VIRMIDI_* */
 	rwlock_t filelist_lock;
+	struct rw_semaphore filelist_sem;
 	struct list_head filelist;
 };
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/sound/timer.h linux-libre-3.16.52-gnu/include/sound/timer.h
--- linux-libre-3.16.51-gnu/include/sound/timer.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/sound/timer.h	2018-01-01 15:52:14.000000000 -0500
@@ -90,6 +90,8 @@ struct snd_timer {
 	struct list_head ack_list_head;
 	struct list_head sack_list_head; /* slow ack list head */
 	struct tasklet_struct task_queue;
+	int max_instances;	/* upper limit of timer instances */
+	int num_instances;	/* current number of timer instances */
 };
 
 struct snd_timer_instance {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/trace/events/kvm.h linux-libre-3.16.52-gnu/include/trace/events/kvm.h
--- linux-libre-3.16.51-gnu/include/trace/events/kvm.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/trace/events/kvm.h	2018-01-01 15:52:14.000000000 -0500
@@ -163,7 +163,7 @@ TRACE_EVENT(kvm_ack_irq,
 	{ KVM_TRACE_MMIO_WRITE, "write" }
 
 TRACE_EVENT(kvm_mmio,
-	TP_PROTO(int type, int len, u64 gpa, u64 val),
+	TP_PROTO(int type, int len, u64 gpa, void *val),
 	TP_ARGS(type, len, gpa, val),
 
 	TP_STRUCT__entry(
@@ -177,7 +177,10 @@ TRACE_EVENT(kvm_mmio,
 		__entry->type		= type;
 		__entry->len		= len;
 		__entry->gpa		= gpa;
-		__entry->val		= val;
+		__entry->val		= 0;
+		if (val)
+			memcpy(&__entry->val, val,
+			       min_t(u32, sizeof(__entry->val), len));
 	),
 
 	TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx",
diff -druNp --no-dereference linux-libre-3.16.51-gnu/include/uapi/linux/spi/spidev.h linux-libre-3.16.52-gnu/include/uapi/linux/spi/spidev.h
--- linux-libre-3.16.51-gnu/include/uapi/linux/spi/spidev.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/include/uapi/linux/spi/spidev.h	2018-01-01 15:52:14.000000000 -0500
@@ -23,6 +23,7 @@
 #define SPIDEV_H
 
 #include <linux/types.h>
+#include <linux/ioctl.h>
 
 /* User space versions of kernel symbols for SPI clocking modes,
  * matching <linux/spi/spi.h>
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/capability.c linux-libre-3.16.52-gnu/kernel/capability.c
--- linux-libre-3.16.51-gnu/kernel/capability.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/capability.c	2018-01-01 15:52:14.000000000 -0500
@@ -428,6 +428,19 @@ bool capable(int cap)
 EXPORT_SYMBOL(capable);
 
 /**
+ * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode?
+ * @ns: The user namespace in question
+ * @inode: The inode in question
+ *
+ * Return true if the inode uid and gid are within the namespace.
+ */
+bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode)
+{
+	return kuid_has_mapping(ns, inode->i_uid) &&
+		kgid_has_mapping(ns, inode->i_gid);
+}
+
+/**
  * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
  * @inode: The inode in question
  * @cap: The capability in question
@@ -440,7 +453,26 @@ bool capable_wrt_inode_uidgid(const stru
 {
 	struct user_namespace *ns = current_user_ns();
 
-	return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
-		kgid_has_mapping(ns, inode->i_gid);
+	return ns_capable(ns, cap) && privileged_wrt_inode_uidgid(ns, inode);
 }
 EXPORT_SYMBOL(capable_wrt_inode_uidgid);
+
+/**
+ * ptracer_capable - Determine if the ptracer holds CAP_SYS_PTRACE in the namespace
+ * @tsk: The task that may be ptraced
+ * @ns: The user namespace to search for CAP_SYS_PTRACE in
+ *
+ * Return true if the task that is ptracing the current task had CAP_SYS_PTRACE
+ * in the specified user namespace.
+ */
+bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns)
+{
+	int ret = 0;  /* An absent tracer adds no restrictions */
+	const struct cred *cred;
+	rcu_read_lock();
+	cred = rcu_dereference(tsk->ptracer_cred);
+	if (cred)
+		ret = security_capable_noaudit(cred, ns, CAP_SYS_PTRACE);
+	rcu_read_unlock();
+	return (ret == 0);
+}
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/fork.c linux-libre-3.16.52-gnu/kernel/fork.c
--- linux-libre-3.16.51-gnu/kernel/fork.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/fork.c	2018-01-01 15:52:14.000000000 -0500
@@ -527,7 +527,8 @@ static void mm_init_aio(struct mm_struct
 #endif
 }
 
-static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
+static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
+	struct user_namespace *user_ns)
 {
 	atomic_set(&mm->mm_users, 1);
 	atomic_set(&mm->mm_count, 1);
@@ -551,6 +552,7 @@ static struct mm_struct *mm_init(struct
 
 	if (likely(!mm_alloc_pgd(mm))) {
 		mmu_notifier_mm_init(mm);
+		mm->user_ns = get_user_ns(user_ns);
 		return mm;
 	}
 
@@ -588,7 +590,7 @@ struct mm_struct *mm_alloc(void)
 
 	memset(mm, 0, sizeof(*mm));
 	mm_init_cpumask(mm);
-	return mm_init(mm, current);
+	return mm_init(mm, current, current_user_ns());
 }
 
 /*
@@ -603,6 +605,7 @@ void __mmdrop(struct mm_struct *mm)
 	destroy_context(mm);
 	mmu_notifier_mm_destroy(mm);
 	check_mm(mm);
+	put_user_ns(mm->user_ns);
 	free_mm(mm);
 }
 EXPORT_SYMBOL_GPL(__mmdrop);
@@ -822,7 +825,7 @@ static struct mm_struct *dup_mm(struct t
 #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
 	mm->pmd_huge_pte = NULL;
 #endif
-	if (!mm_init(mm, tsk))
+	if (!mm_init(mm, tsk, mm->user_ns))
 		goto fail_nomem;
 
 	if (init_new_context(tsk, mm))
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/params.c linux-libre-3.16.52-gnu/kernel/params.c
--- linux-libre-3.16.51-gnu/kernel/params.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/params.c	2018-01-01 15:52:14.000000000 -0500
@@ -581,7 +581,7 @@ EXPORT_SYMBOL(__kernel_param_unlock);
 /*
  * add_sysfs_param - add a parameter to sysfs
  * @mk: struct module_kobject
- * @kparam: the actual parameter definition to add to sysfs
+ * @kp: the actual parameter definition to add to sysfs
  * @name: name of parameter
  *
  * Create a kobject if for a (per-module) parameter if mp NULL, and
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/ptrace.c linux-libre-3.16.52-gnu/kernel/ptrace.c
--- linux-libre-3.16.51-gnu/kernel/ptrace.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/ptrace.c	2018-01-01 15:52:14.000000000 -0500
@@ -27,6 +27,35 @@
 #include <linux/cn_proc.h>
 #include <linux/compat.h>
 
+/*
+ * Access another process' address space via ptrace.
+ * Source/target buffer must be kernel space,
+ * Do not walk the page table directly, use get_user_pages
+ */
+int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
+		     void *buf, int len, int write)
+{
+	struct mm_struct *mm;
+	int ret;
+
+	mm = get_task_mm(tsk);
+	if (!mm)
+		return 0;
+
+	if (!tsk->ptrace ||
+	    (current != tsk->parent) ||
+	    ((get_dumpable(mm) != SUID_DUMP_USER) &&
+	     !ptracer_capable(tsk, mm->user_ns))) {
+		mmput(mm);
+		return 0;
+	}
+
+	ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
+	mmput(mm);
+
+	return ret;
+}
+
 
 static int ptrace_trapping_sleep_fn(void *flags)
 {
@@ -34,17 +63,26 @@ static int ptrace_trapping_sleep_fn(void
 	return 0;
 }
 
+void __ptrace_link(struct task_struct *child, struct task_struct *new_parent,
+		   const struct cred *ptracer_cred)
+{
+	BUG_ON(!list_empty(&child->ptrace_entry));
+	list_add(&child->ptrace_entry, &new_parent->ptraced);
+	child->parent = new_parent;
+	child->ptracer_cred = get_cred(ptracer_cred);
+}
+
 /*
  * ptrace a task: make the debugger its new parent and
  * move it to the ptrace list.
  *
  * Must be called with the tasklist lock write-held.
  */
-void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
+static void ptrace_link(struct task_struct *child, struct task_struct *new_parent)
 {
-	BUG_ON(!list_empty(&child->ptrace_entry));
-	list_add(&child->ptrace_entry, &new_parent->ptraced);
-	child->parent = new_parent;
+	rcu_read_lock();
+	__ptrace_link(child, new_parent, __task_cred(new_parent));
+	rcu_read_unlock();
 }
 
 /**
@@ -77,14 +115,17 @@ void __ptrace_link(struct task_struct *c
  */
 void __ptrace_unlink(struct task_struct *child)
 {
+	const struct cred *old_cred;
 	BUG_ON(!child->ptrace);
 
-	child->ptrace = 0;
 	child->parent = child->real_parent;
 	list_del_init(&child->ptrace_entry);
+	old_cred = child->ptracer_cred;
+	child->ptracer_cred = NULL;
+	put_cred(old_cred);
 
 	spin_lock(&child->sighand->siglock);
-
+	child->ptrace = 0;
 	/*
 	 * Clear all pending traps and TRAPPING.  TRAPPING should be
 	 * cleared regardless of JOBCTL_STOP_PENDING.  Do it explicitly.
@@ -231,7 +272,7 @@ static int ptrace_has_cap(struct user_na
 static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
 	const struct cred *cred = current_cred(), *tcred;
-	int dumpable = 0;
+	struct mm_struct *mm;
 	kuid_t caller_uid;
 	kgid_t caller_gid;
 
@@ -282,16 +323,11 @@ static int __ptrace_may_access(struct ta
 	return -EPERM;
 ok:
 	rcu_read_unlock();
-	smp_rmb();
-	if (task->mm)
-		dumpable = get_dumpable(task->mm);
-	rcu_read_lock();
-	if (dumpable != SUID_DUMP_USER &&
-	    !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
-		rcu_read_unlock();
-		return -EPERM;
-	}
-	rcu_read_unlock();
+	mm = task->mm;
+	if (mm &&
+	    ((get_dumpable(mm) != SUID_DUMP_USER) &&
+	     !ptrace_has_cap(mm->user_ns, mode)))
+	    return -EPERM;
 
 	return security_ptrace_access_check(task, mode);
 }
@@ -355,13 +391,9 @@ static int ptrace_attach(struct task_str
 
 	if (seize)
 		flags |= PT_SEIZED;
-	rcu_read_lock();
-	if (ns_capable(__task_cred(task)->user_ns, CAP_SYS_PTRACE))
-		flags |= PT_PTRACE_CAP;
-	rcu_read_unlock();
 	task->ptrace = flags;
 
-	__ptrace_link(task, current);
+	ptrace_link(task, current);
 
 	/* SEIZE doesn't trap tracee on attach */
 	if (!seize)
@@ -428,7 +460,7 @@ static int ptrace_traceme(void)
 		 */
 		if (!ret && !(current->real_parent->flags & PF_EXITING)) {
 			current->ptrace = PT_PTRACED;
-			__ptrace_link(current, current->real_parent);
+			ptrace_link(current, current->real_parent);
 		}
 	}
 	write_unlock_irq(&tasklist_lock);
@@ -561,7 +593,8 @@ int ptrace_readdata(struct task_struct *
 		int this_len, retval;
 
 		this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
-		retval = access_process_vm(tsk, src, buf, this_len, 0);
+		retval = ptrace_access_vm(tsk, src, buf, this_len, 0);
+
 		if (!retval) {
 			if (copied)
 				break;
@@ -588,7 +621,7 @@ int ptrace_writedata(struct task_struct
 		this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
 		if (copy_from_user(buf, src, this_len))
 			return -EFAULT;
-		retval = access_process_vm(tsk, dst, buf, this_len, 1);
+		retval = ptrace_access_vm(tsk, dst, buf, this_len, 1);
 		if (!retval) {
 			if (copied)
 				break;
@@ -1133,7 +1166,7 @@ int generic_ptrace_peekdata(struct task_
 	unsigned long tmp;
 	int copied;
 
-	copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
+	copied = ptrace_access_vm(tsk, addr, &tmp, sizeof(tmp), 0);
 	if (copied != sizeof(tmp))
 		return -EIO;
 	return put_user(tmp, (unsigned long __user *)data);
@@ -1144,7 +1177,7 @@ int generic_ptrace_pokedata(struct task_
 {
 	int copied;
 
-	copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
+	copied = ptrace_access_vm(tsk, addr, &data, sizeof(data), 1);
 	return (copied == sizeof(data)) ? 0 : -EIO;
 }
 
@@ -1162,7 +1195,7 @@ int compat_ptrace_request(struct task_st
 	switch (request) {
 	case PTRACE_PEEKTEXT:
 	case PTRACE_PEEKDATA:
-		ret = access_process_vm(child, addr, &word, sizeof(word), 0);
+		ret = ptrace_access_vm(child, addr, &word, sizeof(word), 0);
 		if (ret != sizeof(word))
 			ret = -EIO;
 		else
@@ -1171,7 +1204,7 @@ int compat_ptrace_request(struct task_st
 
 	case PTRACE_POKETEXT:
 	case PTRACE_POKEDATA:
-		ret = access_process_vm(child, addr, &data, sizeof(data), 1);
+		ret = ptrace_access_vm(child, addr, &data, sizeof(data), 1);
 		ret = (ret != sizeof(data) ? -EIO : 0);
 		break;
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/sched/core.c linux-libre-3.16.52-gnu/kernel/sched/core.c
--- linux-libre-3.16.51-gnu/kernel/sched/core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/sched/core.c	2018-01-01 15:52:14.000000000 -0500
@@ -5782,14 +5782,14 @@ enum s_alloc {
 static void
 build_group_mask(struct sched_domain *sd, struct sched_group *sg, struct cpumask *mask)
 {
-	const struct cpumask *span = sched_domain_span(sd);
+	const struct cpumask *sg_span = sched_group_cpus(sg);
 	struct sd_data *sdd = sd->private;
 	struct sched_domain *sibling;
 	int i;
 
 	cpumask_clear(mask);
 
-	for_each_cpu(i, span) {
+	for_each_cpu(i, sg_span) {
 		sibling = *per_cpu_ptr(sdd->sd, i);
 
 		/*
@@ -5801,7 +5801,7 @@ build_group_mask(struct sched_domain *sd
 			continue;
 
 		/* If we would not end up here, we can't continue from here */
-		if (!cpumask_equal(span, sched_domain_span(sibling->child)))
+		if (!cpumask_equal(sg_span, sched_domain_span(sibling->child)))
 			continue;
 
 		cpumask_set_cpu(i, mask);
@@ -5869,7 +5869,7 @@ static void init_overlap_sched_group(str
 static int
 build_overlap_sched_groups(struct sched_domain *sd, int cpu)
 {
-	struct sched_group *first = NULL, *last = NULL, *groups = NULL, *sg;
+	struct sched_group *first = NULL, *last = NULL, *sg;
 	const struct cpumask *span = sched_domain_span(sd);
 	struct cpumask *covered = sched_domains_tmpmask;
 	struct sd_data *sdd = sd->private;
@@ -5899,15 +5899,6 @@ build_overlap_sched_groups(struct sched_
 
 		init_overlap_sched_group(sd, sg);
 
-		/*
-		 * Make sure the first group of this domain contains the
-		 * canonical balance cpu. Otherwise the sched_domain iteration
-		 * breaks. See update_sg_lb_stats().
-		 */
-		if ((!groups && cpumask_test_cpu(cpu, sg_span)) ||
-		    group_balance_cpu(sg) == cpu)
-			groups = sg;
-
 		if (!first)
 			first = sg;
 		if (last)
@@ -5915,7 +5906,7 @@ build_overlap_sched_groups(struct sched_
 		last = sg;
 		last->next = first;
 	}
-	sd->groups = groups;
+	sd->groups = first;
 
 	return 0;
 
@@ -6631,7 +6622,7 @@ static int build_sched_domains(const str
 			sd = build_sched_domain(tl, cpu_map, attr, sd, i);
 			if (tl == sched_domain_topology)
 				*per_cpu_ptr(d.sd, i) = sd;
-			if (tl->flags & SDTL_OVERLAP || sched_feat(FORCE_SD_OVERLAP))
+			if (tl->flags & SDTL_OVERLAP)
 				sd->flags |= SD_OVERLAP;
 			if (cpumask_equal(cpu_map, sched_domain_span(sd)))
 				break;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/sched/features.h linux-libre-3.16.52-gnu/kernel/sched/features.h
--- linux-libre-3.16.51-gnu/kernel/sched/features.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/sched/features.h	2018-01-01 15:52:14.000000000 -0500
@@ -56,7 +56,6 @@ SCHED_FEAT(NONTASK_CAPACITY, true)
  */
 SCHED_FEAT(TTWU_QUEUE, true)
 
-SCHED_FEAT(FORCE_SD_OVERLAP, false)
 SCHED_FEAT(RT_RUNTIME_SHARE, true)
 SCHED_FEAT(LB_MIN, false)
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/sysctl.c linux-libre-3.16.52-gnu/kernel/sysctl.c
--- linux-libre-3.16.51-gnu/kernel/sysctl.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/sysctl.c	2018-01-01 15:52:14.000000000 -0500
@@ -342,7 +342,8 @@ static struct ctl_table kern_table[] = {
 		.data		= &sysctl_sched_time_avg,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one,
 	},
 	{
 		.procname	= "sched_shares_window_ns",
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/trace/trace.c linux-libre-3.16.52-gnu/kernel/trace/trace.c
--- linux-libre-3.16.51-gnu/kernel/trace/trace.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/trace/trace.c	2018-01-01 15:52:14.000000000 -0500
@@ -3191,11 +3191,17 @@ static int tracing_open(struct inode *in
 	/* If this file was open for write, then erase contents */
 	if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
 		int cpu = tracing_get_cpu(inode);
+		struct trace_buffer *trace_buf = &tr->trace_buffer;
+
+#ifdef CONFIG_TRACER_MAX_TRACE
+		if (tr->current_trace->print_max)
+			trace_buf = &tr->max_buffer;
+#endif
 
 		if (cpu == RING_BUFFER_ALL_CPUS)
-			tracing_reset_online_cpus(&tr->trace_buffer);
+			tracing_reset_online_cpus(trace_buf);
 		else
-			tracing_reset(&tr->trace_buffer, cpu);
+			tracing_reset(trace_buf, cpu);
 	}
 
 	if (file->f_mode & FMODE_READ) {
@@ -4408,7 +4414,7 @@ static int tracing_wait_pipe(struct file
 		 *
 		 * iter->pos will be 0 if we haven't read anything.
 		 */
-		if (!tracing_is_on() && iter->pos)
+		if (!tracer_tracing_is_on(iter->tr) && iter->pos)
 			break;
 
 		mutex_unlock(&iter->mutex);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/workqueue.c linux-libre-3.16.52-gnu/kernel/workqueue.c
--- linux-libre-3.16.51-gnu/kernel/workqueue.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/workqueue.c	2018-01-01 15:52:14.000000000 -0500
@@ -68,6 +68,7 @@ enum {
 	 * attach_mutex to avoid changing binding state while
 	 * worker_attach_to_pool() is in progress.
 	 */
+	POOL_MANAGER_ACTIVE	= 1 << 0,	/* being managed */
 	POOL_DISASSOCIATED	= 1 << 2,	/* cpu can't serve workers */
 
 	/* worker flags */
@@ -158,7 +159,6 @@ struct worker_pool {
 						/* L: hash of busy workers */
 
 	/* see manage_workers() for details on the two manager mutexes */
-	struct mutex		manager_arb;	/* manager arbitration */
 	struct mutex		attach_mutex;	/* attach/detach exclusion */
 	struct list_head	workers;	/* A: attached workers */
 	struct completion	*detach_completion; /* all workers detached */
@@ -288,6 +288,7 @@ static struct workqueue_attrs *wq_update
 
 static DEFINE_MUTEX(wq_pool_mutex);	/* protects pools and workqueues list */
 static DEFINE_SPINLOCK(wq_mayday_lock);	/* protects wq->maydays list */
+static DECLARE_WAIT_QUEUE_HEAD(wq_manager_wait); /* wait for manager to go away */
 
 static LIST_HEAD(workqueues);		/* PL: list of all workqueues */
 static bool workqueue_freezing;		/* PL: have wqs started freezing? */
@@ -793,7 +794,7 @@ static bool need_to_create_worker(struct
 /* Do we have too many workers and should some go away? */
 static bool too_many_workers(struct worker_pool *pool)
 {
-	bool managing = mutex_is_locked(&pool->manager_arb);
+	bool managing = pool->flags & POOL_MANAGER_ACTIVE;
 	int nr_idle = pool->nr_idle + managing; /* manager is considered idle */
 	int nr_busy = pool->nr_workers - nr_idle;
 
@@ -1996,22 +1997,15 @@ static bool manage_workers(struct worker
 {
 	struct worker_pool *pool = worker->pool;
 
-	/*
-	 * Anyone who successfully grabs manager_arb wins the arbitration
-	 * and becomes the manager.  mutex_trylock() on pool->manager_arb
-	 * failure while holding pool->lock reliably indicates that someone
-	 * else is managing the pool and the worker which failed trylock
-	 * can proceed to executing work items.  This means that anyone
-	 * grabbing manager_arb is responsible for actually performing
-	 * manager duties.  If manager_arb is grabbed and released without
-	 * actual management, the pool may stall indefinitely.
-	 */
-	if (!mutex_trylock(&pool->manager_arb))
+	if (pool->flags & POOL_MANAGER_ACTIVE)
 		return false;
 
+	pool->flags |= POOL_MANAGER_ACTIVE;
+
 	maybe_create_worker(pool);
 
-	mutex_unlock(&pool->manager_arb);
+	pool->flags &= ~POOL_MANAGER_ACTIVE;
+	wake_up(&wq_manager_wait);
 	return true;
 }
 
@@ -3490,7 +3484,6 @@ static int init_worker_pool(struct worke
 	setup_timer(&pool->mayday_timer, pool_mayday_timeout,
 		    (unsigned long)pool);
 
-	mutex_init(&pool->manager_arb);
 	mutex_init(&pool->attach_mutex);
 	INIT_LIST_HEAD(&pool->workers);
 
@@ -3546,13 +3539,15 @@ static void put_unbound_pool(struct work
 	hash_del(&pool->hash_node);
 
 	/*
-	 * Become the manager and destroy all workers.  Grabbing
-	 * manager_arb prevents @pool's workers from blocking on
-	 * attach_mutex.
+	 * Become the manager and destroy all workers.  This prevents
+	 * @pool's workers from blocking on attach_mutex.  We're the last
+	 * manager and @pool gets freed with the flag set.
 	 */
-	mutex_lock(&pool->manager_arb);
-
 	spin_lock_irq(&pool->lock);
+	wait_event_lock_irq(wq_manager_wait,
+			    !(pool->flags & POOL_MANAGER_ACTIVE), pool->lock);
+	pool->flags |= POOL_MANAGER_ACTIVE;
+
 	while ((worker = first_idle_worker(pool)))
 		destroy_worker(worker);
 	WARN_ON(pool->nr_workers || pool->nr_idle);
@@ -3566,8 +3561,6 @@ static void put_unbound_pool(struct work
 	if (pool->detach_completion)
 		wait_for_completion(pool->detach_completion);
 
-	mutex_unlock(&pool->manager_arb);
-
 	/* shut down the timers */
 	del_timer_sync(&pool->idle_timer);
 	del_timer_sync(&pool->mayday_timer);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/kernel/workqueue_internal.h linux-libre-3.16.52-gnu/kernel/workqueue_internal.h
--- linux-libre-3.16.51-gnu/kernel/workqueue_internal.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/kernel/workqueue_internal.h	2018-01-01 15:52:14.000000000 -0500
@@ -9,6 +9,7 @@
 
 #include <linux/workqueue.h>
 #include <linux/kthread.h>
+#include <linux/preempt.h>
 
 struct worker_pool;
 
@@ -59,7 +60,7 @@ struct worker {
  */
 static inline struct worker *current_wq_worker(void)
 {
-	if (current->flags & PF_WQ_WORKER)
+	if (in_task() && (current->flags & PF_WQ_WORKER))
 		return kthread_data(current);
 	return NULL;
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/lib/asn1_decoder.c linux-libre-3.16.52-gnu/lib/asn1_decoder.c
--- linux-libre-3.16.51-gnu/lib/asn1_decoder.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/lib/asn1_decoder.c	2018-01-01 15:52:14.000000000 -0500
@@ -220,7 +220,7 @@ next_op:
 		hdr = 2;
 
 		/* Extract a tag from the data */
-		if (unlikely(dp >= datalen - 1))
+		if (unlikely(datalen - dp < 2))
 			goto data_overrun_error;
 		tag = data[dp++];
 		if (unlikely((tag & 0x1f) == ASN1_LONG_TAG))
@@ -266,7 +266,7 @@ next_op:
 				int n = len - 0x80;
 				if (unlikely(n > 2))
 					goto length_too_long;
-				if (unlikely(dp >= datalen - n))
+				if (unlikely(n > datalen - dp))
 					goto data_overrun_error;
 				hdr += n;
 				for (len = 0; n > 0; n--) {
@@ -276,6 +276,9 @@ next_op:
 				if (unlikely(len > datalen - dp))
 					goto data_overrun_error;
 			}
+		} else {
+			if (unlikely(len > datalen - dp))
+				goto data_overrun_error;
 		}
 
 		if (flags & FLAG_CONS) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/lib/digsig.c linux-libre-3.16.52-gnu/lib/digsig.c
--- linux-libre-3.16.51-gnu/lib/digsig.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/lib/digsig.c	2018-01-01 15:52:14.000000000 -0500
@@ -86,6 +86,12 @@ static int digsig_verify_rsa(struct key
 	down_read(&key->sem);
 	ukp = key->payload.data;
 
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		err = -EKEYREVOKED;
+		goto err1;
+	}
+
 	if (ukp->datalen < sizeof(*pkh))
 		goto err1;
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/Makefile linux-libre-3.16.52-gnu/Makefile
--- linux-libre-3.16.51-gnu/Makefile	2017-11-26 13:21:10.000000000 -0500
+++ linux-libre-3.16.52-gnu/Makefile	2018-01-02 11:12:10.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 16
-SUBLEVEL = 51
+SUBLEVEL = 52
 EXTRAVERSION =-gnu
 NAME = Museum of Fishiegoodies
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/mm/huge_memory.c linux-libre-3.16.52-gnu/mm/huge_memory.c
--- linux-libre-3.16.51-gnu/mm/huge_memory.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/mm/huge_memory.c	2018-01-01 15:52:14.000000000 -0500
@@ -1230,17 +1230,11 @@ struct page *follow_trans_huge_pmd(struc
 
 	if (flags & FOLL_TOUCH) {
 		pmd_t _pmd;
-		/*
-		 * We should set the dirty bit only for FOLL_WRITE but
-		 * for now the dirty bit in the pmd is meaningless.
-		 * And if the dirty bit will become meaningful and
-		 * we'll only set it with FOLL_WRITE, an atomic
-		 * set_bit will be required on the pmd to set the
-		 * young bit, instead of the current set_pmd_at.
-		 */
-		_pmd = pmd_mkyoung(pmd_mkdirty(*pmd));
+		_pmd = pmd_mkyoung(*pmd);
+		if (flags & FOLL_WRITE)
+			_pmd = pmd_mkdirty(_pmd);
 		if (pmdp_set_access_flags(vma, addr & HPAGE_PMD_MASK,
-					  pmd, _pmd,  1))
+					  pmd, _pmd, flags & FOLL_WRITE))
 			update_mmu_cache_pmd(vma, addr, pmd);
 	}
 	if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/mm/init-mm.c linux-libre-3.16.52-gnu/mm/init-mm.c
--- linux-libre-3.16.51-gnu/mm/init-mm.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/mm/init-mm.c	2018-01-01 15:52:14.000000000 -0500
@@ -6,6 +6,7 @@
 #include <linux/cpumask.h>
 
 #include <linux/atomic.h>
+#include <linux/user_namespace.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 
@@ -21,5 +22,6 @@ struct mm_struct init_mm = {
 	.mmap_sem	= __RWSEM_INITIALIZER(init_mm.mmap_sem),
 	.page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
 	.mmlist		= LIST_HEAD_INIT(init_mm.mmlist),
+	.user_ns	= &init_user_ns,
 	INIT_MM_CONTEXT(init_mm)
 };
diff -druNp --no-dereference linux-libre-3.16.51-gnu/mm/memory.c linux-libre-3.16.52-gnu/mm/memory.c
--- linux-libre-3.16.51-gnu/mm/memory.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/mm/memory.c	2018-01-01 15:52:14.000000000 -0500
@@ -3560,7 +3560,7 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
  * Access another process' address space as given in mm.  If non-NULL, use the
  * given task for page fault accounting.
  */
-static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
 		unsigned long addr, void *buf, int len, int write)
 {
 	struct vm_area_struct *vma;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/mm/memory_hotplug.c linux-libre-3.16.52-gnu/mm/memory_hotplug.c
--- linux-libre-3.16.51-gnu/mm/memory_hotplug.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/mm/memory_hotplug.c	2018-01-01 15:52:14.000000000 -0500
@@ -520,7 +520,7 @@ EXPORT_SYMBOL_GPL(__add_pages);
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
 /* find the smallest valid pfn in the range [start_pfn, end_pfn) */
-static int find_smallest_section_pfn(int nid, struct zone *zone,
+static unsigned long find_smallest_section_pfn(int nid, struct zone *zone,
 				     unsigned long start_pfn,
 				     unsigned long end_pfn)
 {
@@ -545,7 +545,7 @@ static int find_smallest_section_pfn(int
 }
 
 /* find the biggest valid pfn in the range [start_pfn, end_pfn). */
-static int find_biggest_section_pfn(int nid, struct zone *zone,
+static unsigned long find_biggest_section_pfn(int nid, struct zone *zone,
 				    unsigned long start_pfn,
 				    unsigned long end_pfn)
 {
@@ -735,7 +735,7 @@ static int __remove_section(struct zone
 		return ret;
 
 	scn_nr = __section_nr(ms);
-	start_pfn = section_nr_to_pfn(scn_nr);
+	start_pfn = section_nr_to_pfn((unsigned long)scn_nr);
 	__remove_zone(zone, start_pfn);
 
 	sparse_remove_one_section(zone, ms);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/mm/nommu.c linux-libre-3.16.52-gnu/mm/nommu.c
--- linux-libre-3.16.51-gnu/mm/nommu.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/mm/nommu.c	2018-01-01 15:52:14.000000000 -0500
@@ -2007,7 +2007,7 @@ int generic_file_remap_pages(struct vm_a
 }
 EXPORT_SYMBOL(generic_file_remap_pages);
 
-static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
 		unsigned long addr, void *buf, int len, int write)
 {
 	struct vm_area_struct *vma;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/8021q/vlan.c linux-libre-3.16.52-gnu/net/8021q/vlan.c
--- linux-libre-3.16.51-gnu/net/8021q/vlan.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/8021q/vlan.c	2018-01-01 15:52:14.000000000 -0500
@@ -364,6 +364,9 @@ static int vlan_device_event(struct noti
 			dev->name);
 		vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
 	}
+	if (event == NETDEV_DOWN &&
+	    (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
+		vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
 
 	vlan_info = rtnl_dereference(dev->vlan_info);
 	if (!vlan_info)
@@ -408,9 +411,6 @@ static int vlan_device_event(struct noti
 		break;
 
 	case NETDEV_DOWN:
-		if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
-			vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
-
 		/* Put all VLANs for this dev in the down state too.  */
 		vlan_group_for_each_dev(grp, i, vlandev) {
 			flgs = vlandev->flags;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/bluetooth/bnep/core.c linux-libre-3.16.52-gnu/net/bluetooth/bnep/core.c
--- linux-libre-3.16.51-gnu/net/bluetooth/bnep/core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/bluetooth/bnep/core.c	2018-01-01 15:52:14.000000000 -0500
@@ -533,6 +533,9 @@ int bnep_add_connection(struct bnep_conn
 
 	BT_DBG("");
 
+	if (!l2cap_is_socket(sock))
+		return -EBADFD;
+
 	baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
 	baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/bluetooth/cmtp/core.c linux-libre-3.16.52-gnu/net/bluetooth/cmtp/core.c
--- linux-libre-3.16.51-gnu/net/bluetooth/cmtp/core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/bluetooth/cmtp/core.c	2018-01-01 15:52:14.000000000 -0500
@@ -334,6 +334,9 @@ int cmtp_add_connection(struct cmtp_conn
 
 	BT_DBG("");
 
+	if (!l2cap_is_socket(sock))
+		return -EBADFD;
+
 	session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
 	if (!session)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/core/dev.c linux-libre-3.16.52-gnu/net/core/dev.c
--- linux-libre-3.16.51-gnu/net/core/dev.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/core/dev.c	2018-01-01 15:52:14.000000000 -0500
@@ -1056,9 +1056,8 @@ static int dev_alloc_name_ns(struct net
 	return ret;
 }
 
-static int dev_get_valid_name(struct net *net,
-			      struct net_device *dev,
-			      const char *name)
+int dev_get_valid_name(struct net *net, struct net_device *dev,
+		       const char *name)
 {
 	BUG_ON(!net);
 
@@ -1074,6 +1073,7 @@ static int dev_get_valid_name(struct net
 
 	return 0;
 }
+EXPORT_SYMBOL(dev_get_valid_name);
 
 /**
  *	dev_change_name - change name of a device
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/core/rtnetlink.c linux-libre-3.16.52-gnu/net/core/rtnetlink.c
--- linux-libre-3.16.51-gnu/net/core/rtnetlink.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/core/rtnetlink.c	2018-01-01 15:52:14.000000000 -0500
@@ -1187,7 +1187,10 @@ static const struct nla_policy ifla_poli
 	[IFLA_LINKINFO]		= { .type = NLA_NESTED },
 	[IFLA_NET_NS_PID]	= { .type = NLA_U32 },
 	[IFLA_NET_NS_FD]	= { .type = NLA_U32 },
-	[IFLA_IFALIAS]	        = { .type = NLA_STRING, .len = IFALIASZ-1 },
+	/* IFLA_IFALIAS is a string, but policy is set to NLA_BINARY to
+	 * allow 0-length string (needed to remove an alias).
+	 */
+	[IFLA_IFALIAS]	        = { .type = NLA_BINARY, .len = IFALIASZ - 1 },
 	[IFLA_VFINFO_LIST]	= {. type = NLA_NESTED },
 	[IFLA_VF_PORTS]		= { .type = NLA_NESTED },
 	[IFLA_PORT_SELF]	= { .type = NLA_NESTED },
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/core/skbuff.c linux-libre-3.16.52-gnu/net/core/skbuff.c
--- linux-libre-3.16.51-gnu/net/core/skbuff.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/core/skbuff.c	2018-01-01 15:52:14.000000000 -0500
@@ -3961,6 +3961,7 @@ void skb_scrub_packet(struct sk_buff *sk
 	if (!xnet)
 		return;
 
+	ipvs_reset(skb);
 	skb_orphan(skb);
 	skb->mark = 0;
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/dccp/proto.c linux-libre-3.16.52-gnu/net/dccp/proto.c
--- linux-libre-3.16.51-gnu/net/dccp/proto.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/dccp/proto.c	2018-01-01 15:52:14.000000000 -0500
@@ -252,6 +252,7 @@ int dccp_disconnect(struct sock *sk, int
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct inet_sock *inet = inet_sk(sk);
+	struct dccp_sock *dp = dccp_sk(sk);
 	int err = 0;
 	const int old_state = sk->sk_state;
 
@@ -271,6 +272,10 @@ int dccp_disconnect(struct sock *sk, int
 		sk->sk_err = ECONNRESET;
 
 	dccp_clear_xmit_timers(sk);
+	ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
+	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
+	dp->dccps_hc_rx_ccid = NULL;
+	dp->dccps_hc_tx_ccid = NULL;
 
 	__skb_queue_purge(&sk->sk_receive_queue);
 	__skb_queue_purge(&sk->sk_write_queue);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv4/ip_input.c linux-libre-3.16.52-gnu/net/ipv4/ip_input.c
--- linux-libre-3.16.51-gnu/net/ipv4/ip_input.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv4/ip_input.c	2018-01-01 15:52:14.000000000 -0500
@@ -313,6 +313,7 @@ static int ip_rcv_finish(struct sk_buff
 {
 	const struct iphdr *iph = ip_hdr(skb);
 	struct rtable *rt;
+	int err;
 
 	if (sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
 		const struct net_protocol *ipprot;
@@ -320,7 +321,9 @@ static int ip_rcv_finish(struct sk_buff
 
 		ipprot = rcu_dereference(inet_protos[protocol]);
 		if (ipprot && ipprot->early_demux) {
-			ipprot->early_demux(skb);
+			err = ipprot->early_demux(skb);
+			if (unlikely(err))
+				goto drop_error;
 			/* must reload iph, skb->head might have changed */
 			iph = ip_hdr(skb);
 		}
@@ -331,14 +334,10 @@ static int ip_rcv_finish(struct sk_buff
 	 *	how the packet travels inside Linux networking.
 	 */
 	if (!skb_dst(skb)) {
-		int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
-					       iph->tos, skb->dev);
-		if (unlikely(err)) {
-			if (err == -EXDEV)
-				NET_INC_STATS_BH(dev_net(skb->dev),
-						 LINUX_MIB_IPRPFILTER);
-			goto drop;
-		}
+		err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
+					   iph->tos, skb->dev);
+		if (unlikely(err))
+			goto drop_error;
 	}
 
 #ifdef CONFIG_IP_ROUTE_CLASSID
@@ -368,6 +367,11 @@ static int ip_rcv_finish(struct sk_buff
 drop:
 	kfree_skb(skb);
 	return NET_RX_DROP;
+
+drop_error:
+	if (err == -EXDEV)
+		NET_INC_STATS_BH(dev_net(skb->dev), LINUX_MIB_IPRPFILTER);
+	goto drop;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv4/ip_vti.c linux-libre-3.16.52-gnu/net/ipv4/ip_vti.c
--- linux-libre-3.16.51-gnu/net/ipv4/ip_vti.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv4/ip_vti.c	2018-01-01 15:52:14.000000000 -0500
@@ -151,6 +151,7 @@ static netdev_tx_t vti_xmit(struct sk_bu
 	struct ip_tunnel_parm *parms = &tunnel->parms;
 	struct dst_entry *dst = skb_dst(skb);
 	struct net_device *tdev;	/* Device to other host */
+	int pkt_len = skb->len;
 	int err;
 
 	if (!dst) {
@@ -194,7 +195,7 @@ static netdev_tx_t vti_xmit(struct sk_bu
 
 	err = dst_output(skb);
 	if (net_xmit_eval(err) == 0)
-		err = skb->len;
+		err = pkt_len;
 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 	return NETDEV_TX_OK;
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv4/route.c linux-libre-3.16.52-gnu/net/ipv4/route.c
--- linux-libre-3.16.51-gnu/net/ipv4/route.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv4/route.c	2018-01-01 15:52:14.000000000 -0500
@@ -1440,40 +1440,53 @@ static struct rtable *rt_dst_alloc(struc
 }
 
 /* called in rcu_read_lock() section */
-static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-				u8 tos, struct net_device *dev, int our)
+int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+			  u8 tos, struct net_device *dev,
+			  struct in_device *in_dev, u32 *itag)
 {
-	struct rtable *rth;
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
-	u32 itag = 0;
 	int err;
 
 	/* Primary sanity checks. */
-
 	if (in_dev == NULL)
 		return -EINVAL;
 
 	if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
 	    skb->protocol != htons(ETH_P_IP))
-		goto e_inval;
+		return -EINVAL;
 
 	if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev)))
 		if (ipv4_is_loopback(saddr))
-			goto e_inval;
+			return -EINVAL;
 
 	if (ipv4_is_zeronet(saddr)) {
 		if (!ipv4_is_local_multicast(daddr))
-			goto e_inval;
+			return -EINVAL;
 	} else {
 		err = fib_validate_source(skb, saddr, 0, tos, 0, dev,
-					  in_dev, &itag);
+					  in_dev, itag);
 		if (err < 0)
-			goto e_err;
+			return err;
 	}
+	return 0;
+}
+
+/* called in rcu_read_lock() section */
+static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+			     u8 tos, struct net_device *dev, int our)
+{
+	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct rtable *rth;
+	u32 itag = 0;
+	int err;
+
+	err = ip_mc_validate_source(skb, daddr, saddr, tos, dev, in_dev, &itag);
+	if (err)
+		return err;
+
 	rth = rt_dst_alloc(dev_net(dev)->loopback_dev,
 			   IN_DEV_CONF_GET(in_dev, NOPOLICY), false, false);
 	if (!rth)
-		goto e_nobufs;
+		return -ENOBUFS;
 
 #ifdef CONFIG_IP_ROUTE_CLASSID
 	rth->dst.tclassid = itag;
@@ -1502,13 +1515,6 @@ static int ip_route_input_mc(struct sk_b
 
 	skb_dst_set(skb, &rth->dst);
 	return 0;
-
-e_nobufs:
-	return -ENOBUFS;
-e_inval:
-	return -EINVAL;
-e_err:
-	return err;
 }
 
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv4/tcp_ipv4.c linux-libre-3.16.52-gnu/net/ipv4/tcp_ipv4.c
--- linux-libre-3.16.51-gnu/net/ipv4/tcp_ipv4.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv4/tcp_ipv4.c	2018-01-01 15:52:14.000000000 -0500
@@ -1616,23 +1616,23 @@ csum_err:
 }
 EXPORT_SYMBOL(tcp_v4_do_rcv);
 
-void tcp_v4_early_demux(struct sk_buff *skb)
+int tcp_v4_early_demux(struct sk_buff *skb)
 {
 	const struct iphdr *iph;
 	const struct tcphdr *th;
 	struct sock *sk;
 
 	if (skb->pkt_type != PACKET_HOST)
-		return;
+		return 0;
 
 	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr)))
-		return;
+		return 0;
 
 	iph = ip_hdr(skb);
 	th = tcp_hdr(skb);
 
 	if (th->doff < sizeof(struct tcphdr) / 4)
-		return;
+		return 0;
 
 	sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
 				       iph->saddr, th->source,
@@ -1651,6 +1651,7 @@ void tcp_v4_early_demux(struct sk_buff *
 				skb_dst_set_noref(skb, dst);
 		}
 	}
+	return 0;
 }
 
 /* Packet is added to VJ-style prequeue for processing in process
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv4/tcp_output.c linux-libre-3.16.52-gnu/net/ipv4/tcp_output.c
--- linux-libre-3.16.51-gnu/net/ipv4/tcp_output.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv4/tcp_output.c	2018-01-01 15:52:14.000000000 -0500
@@ -1817,6 +1817,7 @@ static int tcp_mtu_probe(struct sock *sk
 	nskb->ip_summed = skb->ip_summed;
 
 	tcp_insert_write_queue_before(nskb, skb, sk);
+	tcp_highest_sack_replace(sk, skb, nskb);
 
 	len = 0;
 	tcp_for_write_queue_from_safe(skb, next, sk) {
@@ -2327,7 +2328,7 @@ static void tcp_collapse_retrans(struct
 
 	BUG_ON(tcp_skb_pcount(skb) != 1 || tcp_skb_pcount(next_skb) != 1);
 
-	tcp_highest_sack_combine(sk, next_skb, skb);
+	tcp_highest_sack_replace(sk, next_skb, skb);
 
 	tcp_unlink_write_queue(next_skb, sk);
 
@@ -3058,6 +3059,10 @@ static int tcp_send_syn_data(struct sock
 		goto done;
 	}
 
+	/* data was not sent, this is our new send_head */
+	sk->sk_send_head = syn_data;
+	tp->packets_out -= tcp_skb_pcount(syn_data);
+
 fallback:
 	/* Send a regular SYN with Fast Open cookie request option */
 	if (fo->cookie.len > 0)
@@ -3104,6 +3109,11 @@ int tcp_connect(struct sock *sk)
 	 */
 	tp->snd_nxt = tp->write_seq;
 	tp->pushed_seq = tp->write_seq;
+	buff = tcp_send_head(sk);
+	if (unlikely(buff)) {
+		tp->snd_nxt	= TCP_SKB_CB(buff)->seq;
+		tp->pushed_seq	= TCP_SKB_CB(buff)->seq;
+	}
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS);
 
 	/* Timer for repeating the SYN until an answer. */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv4/udp.c linux-libre-3.16.52-gnu/net/ipv4/udp.c
--- linux-libre-3.16.51-gnu/net/ipv4/udp.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv4/udp.c	2018-01-01 15:52:14.000000000 -0500
@@ -1950,9 +1950,10 @@ static struct sock *__udp4_lib_demux_loo
 	return result;
 }
 
-void udp_v4_early_demux(struct sk_buff *skb)
+int udp_v4_early_demux(struct sk_buff *skb)
 {
 	struct net *net = dev_net(skb->dev);
+	struct in_device *in_dev = NULL;
 	const struct iphdr *iph;
 	const struct udphdr *uh;
 	struct sock *sk;
@@ -1962,33 +1963,33 @@ void udp_v4_early_demux(struct sk_buff *
 
 	/* validate the packet */
 	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr)))
-		return;
+		return 0;
 
 	iph = ip_hdr(skb);
 	uh = udp_hdr(skb);
 
-	if (skb->pkt_type == PACKET_BROADCAST ||
-	    skb->pkt_type == PACKET_MULTICAST) {
-		struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
+	if (skb->pkt_type == PACKET_MULTICAST) {
+		in_dev = __in_dev_get_rcu(skb->dev);
 
 		if (!in_dev)
-			return;
+			return 0;
 
 		ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
 				       iph->protocol);
 		if (!ours)
-			return;
+			return 0;
+
 		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
 						   uh->source, iph->saddr, dif);
 	} else if (skb->pkt_type == PACKET_HOST) {
 		sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
 					     uh->source, iph->saddr, dif);
 	} else {
-		return;
+		return 0;
 	}
 
 	if (!sk)
-		return;
+		return 0;
 
 	skb->sk = sk;
 	skb->destructor = sock_edemux;
@@ -1997,6 +1998,8 @@ void udp_v4_early_demux(struct sk_buff *
 	if (dst)
 		dst = dst_check(dst, 0);
 	if (dst) {
+		u32 itag = 0;
+
 		/* DST_NOCACHE can not be used without taking a reference */
 		if (dst->flags & DST_NOCACHE) {
 			if (likely(atomic_inc_not_zero(&dst->__refcnt)))
@@ -2004,7 +2007,16 @@ void udp_v4_early_demux(struct sk_buff *
 		} else {
 			skb_dst_set_noref(skb, dst);
 		}
+
+		/* for unconnected multicast sockets we need to validate
+		 * the source on each packet
+		 */
+		if (!inet_sk(sk)->inet_daddr && in_dev)
+			return ip_mc_validate_source(skb, iph->daddr,
+						     iph->saddr, iph->tos,
+						     skb->dev, in_dev, &itag);
 	}
+	return 0;
 }
 
 int udp_rcv(struct sk_buff *skb)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv6/ip6_gre.c linux-libre-3.16.52-gnu/net/ipv6/ip6_gre.c
--- linux-libre-3.16.51-gnu/net/ipv6/ip6_gre.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv6/ip6_gre.c	2018-01-01 15:52:14.000000000 -0500
@@ -404,15 +404,18 @@ static void ip6gre_err(struct sk_buff *s
 		struct ipv6_tlv_tnl_enc_lim *tel;
 		__u32 mtu;
 	case ICMPV6_DEST_UNREACH:
-		net_warn_ratelimited("%s: Path to destination invalid or inactive!\n",
-				     t->parms.name);
-		break;
+		net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n",
+				    t->parms.name);
+		if (code != ICMPV6_PORT_UNREACH)
+			break;
+		return;
 	case ICMPV6_TIME_EXCEED:
 		if (code == ICMPV6_EXC_HOPLIMIT) {
-			net_warn_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
-					     t->parms.name);
+			net_dbg_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
+					    t->parms.name);
+			break;
 		}
-		break;
+		return;
 	case ICMPV6_PARAMPROB:
 		teli = 0;
 		if (code == ICMPV6_HDR_FIELD)
@@ -421,20 +424,20 @@ static void ip6gre_err(struct sk_buff *s
 		if (teli && teli == be32_to_cpu(info) - 2) {
 			tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
 			if (tel->encap_limit == 0) {
-				net_warn_ratelimited("%s: Too small encapsulation limit or routing loop in tunnel!\n",
-						     t->parms.name);
+				net_dbg_ratelimited("%s: Too small encapsulation limit or routing loop in tunnel!\n",
+						    t->parms.name);
 			}
 		} else {
-			net_warn_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
-					     t->parms.name);
+			net_dbg_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
+					    t->parms.name);
 		}
-		break;
+		return;
 	case ICMPV6_PKT_TOOBIG:
 		mtu = be32_to_cpu(info) - offset;
 		if (mtu < IPV6_MIN_MTU)
 			mtu = IPV6_MIN_MTU;
 		t->dev->mtu = mtu;
-		break;
+		return;
 	}
 
 	if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
@@ -1172,21 +1175,23 @@ static int ip6gre_tunnel_change_mtu(stru
 }
 
 static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
-			unsigned short type,
-			const void *daddr, const void *saddr, unsigned int len)
+			 unsigned short type, const void *daddr,
+			 const void *saddr, unsigned int len)
 {
 	struct ip6_tnl *t = netdev_priv(dev);
-	struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
-	__be16 *p = (__be16 *)(ipv6h+1);
+	struct ipv6hdr *ipv6h;
+	__be16 *p;
 
+	ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen + sizeof(*ipv6h));
 	ip6_flow_hdr(ipv6h, 0, t->fl.u.ip6.flowlabel);
 	ipv6h->hop_limit = t->parms.hop_limit;
 	ipv6h->nexthdr = NEXTHDR_GRE;
 	ipv6h->saddr = t->parms.laddr;
 	ipv6h->daddr = t->parms.raddr;
 
-	p[0]		= t->parms.o_flags;
-	p[1]		= htons(type);
+	p = (__be16 *)(ipv6h + 1);
+	p[0] = t->parms.o_flags;
+	p[1] = htons(type);
 
 	/*
 	 *	Set the source hardware address.
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/ipv6/ip6_vti.c linux-libre-3.16.52-gnu/net/ipv6/ip6_vti.c
--- linux-libre-3.16.51-gnu/net/ipv6/ip6_vti.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/ipv6/ip6_vti.c	2018-01-01 15:52:14.000000000 -0500
@@ -407,6 +407,7 @@ vti6_xmit(struct sk_buff *skb, struct ne
 	struct net_device_stats *stats = &t->dev->stats;
 	struct dst_entry *dst = skb_dst(skb);
 	struct net_device *tdev;
+	int pkt_len = skb->len;
 	int err = -1;
 
 	if (!dst)
@@ -441,7 +442,7 @@ vti6_xmit(struct sk_buff *skb, struct ne
 		struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
 
 		u64_stats_update_begin(&tstats->syncp);
-		tstats->tx_bytes += skb->len;
+		tstats->tx_bytes += pkt_len;
 		tstats->tx_packets++;
 		u64_stats_update_end(&tstats->syncp);
 	} else {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/l2tp/l2tp_core.c linux-libre-3.16.52-gnu/net/l2tp/l2tp_core.c
--- linux-libre-3.16.51-gnu/net/l2tp/l2tp_core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/l2tp/l2tp_core.c	2018-01-01 15:52:14.000000000 -0500
@@ -1771,14 +1771,12 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
 
 /* This function is used by the netlink TUNNEL_DELETE command.
  */
-int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
+void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
 {
-	l2tp_tunnel_inc_refcount(tunnel);
-	if (false == queue_work(l2tp_wq, &tunnel->del_work)) {
-		l2tp_tunnel_dec_refcount(tunnel);
-		return 1;
+	if (!test_and_set_bit(0, &tunnel->dead)) {
+		l2tp_tunnel_inc_refcount(tunnel);
+		queue_work(l2tp_wq, &tunnel->del_work);
 	}
-	return 0;
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/l2tp/l2tp_core.h linux-libre-3.16.52-gnu/net/l2tp/l2tp_core.h
--- linux-libre-3.16.51-gnu/net/l2tp/l2tp_core.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/l2tp/l2tp_core.h	2018-01-01 15:52:14.000000000 -0500
@@ -169,6 +169,9 @@ struct l2tp_tunnel_cfg {
 
 struct l2tp_tunnel {
 	int			magic;		/* Should be L2TP_TUNNEL_MAGIC */
+
+	unsigned long		dead;
+
 	struct rcu_head rcu;
 	rwlock_t		hlist_lock;	/* protect session_hlist */
 	bool			acpt_newsess;	/* Indicates whether this
@@ -266,7 +269,7 @@ int l2tp_tunnel_create(struct net *net,
 		       u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
 		       struct l2tp_tunnel **tunnelp);
 void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
-int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
+void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
 struct l2tp_session *l2tp_session_create(int priv_size,
 					 struct l2tp_tunnel *tunnel,
 					 u32 session_id, u32 peer_session_id,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/l2tp/l2tp_eth.c linux-libre-3.16.52-gnu/net/l2tp/l2tp_eth.c
--- linux-libre-3.16.51-gnu/net/l2tp/l2tp_eth.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/l2tp/l2tp_eth.c	2018-01-01 15:52:14.000000000 -0500
@@ -41,7 +41,6 @@ struct l2tp_eth {
 	struct net_device	*dev;
 	struct sock		*tunnel_sock;
 	struct l2tp_session	*session;
-	struct list_head	list;
 	atomic_long_t		tx_bytes;
 	atomic_long_t		tx_packets;
 	atomic_long_t		tx_dropped;
@@ -55,17 +54,6 @@ struct l2tp_eth_sess {
 	struct net_device	*dev;
 };
 
-/* per-net private data for this module */
-static unsigned int l2tp_eth_net_id;
-struct l2tp_eth_net {
-	struct list_head l2tp_eth_dev_list;
-	spinlock_t l2tp_eth_lock;
-};
-
-static inline struct l2tp_eth_net *l2tp_eth_pernet(struct net *net)
-{
-	return net_generic(net, l2tp_eth_net_id);
-}
 
 static struct lock_class_key l2tp_eth_tx_busylock;
 static int l2tp_eth_dev_init(struct net_device *dev)
@@ -81,12 +69,6 @@ static int l2tp_eth_dev_init(struct net_
 
 static void l2tp_eth_dev_uninit(struct net_device *dev)
 {
-	struct l2tp_eth *priv = netdev_priv(dev);
-	struct l2tp_eth_net *pn = l2tp_eth_pernet(dev_net(dev));
-
-	spin_lock(&pn->l2tp_eth_lock);
-	list_del_init(&priv->list);
-	spin_unlock(&pn->l2tp_eth_lock);
 	dev_put(dev);
 }
 
@@ -216,7 +198,6 @@ static int l2tp_eth_create(struct net *n
 	struct l2tp_eth *priv;
 	struct l2tp_eth_sess *spriv;
 	int rc;
-	struct l2tp_eth_net *pn;
 
 	if (cfg->ifname) {
 		dev = dev_get_by_name(net, cfg->ifname);
@@ -251,7 +232,6 @@ static int l2tp_eth_create(struct net *n
 	priv = netdev_priv(dev);
 	priv->dev = dev;
 	priv->session = session;
-	INIT_LIST_HEAD(&priv->list);
 
 	priv->tunnel_sock = tunnel->sock;
 	session->recv_skb = l2tp_eth_dev_recv;
@@ -272,10 +252,6 @@ static int l2tp_eth_create(struct net *n
 	strlcpy(session->ifname, dev->name, IFNAMSIZ);
 
 	dev_hold(dev);
-	pn = l2tp_eth_pernet(dev_net(dev));
-	spin_lock(&pn->l2tp_eth_lock);
-	list_add(&priv->list, &pn->l2tp_eth_dev_list);
-	spin_unlock(&pn->l2tp_eth_lock);
 
 	return 0;
 
@@ -288,22 +264,6 @@ out:
 	return rc;
 }
 
-static __net_init int l2tp_eth_init_net(struct net *net)
-{
-	struct l2tp_eth_net *pn = net_generic(net, l2tp_eth_net_id);
-
-	INIT_LIST_HEAD(&pn->l2tp_eth_dev_list);
-	spin_lock_init(&pn->l2tp_eth_lock);
-
-	return 0;
-}
-
-static struct pernet_operations l2tp_eth_net_ops = {
-	.init = l2tp_eth_init_net,
-	.id   = &l2tp_eth_net_id,
-	.size = sizeof(struct l2tp_eth_net),
-};
-
 
 static const struct l2tp_nl_cmd_ops l2tp_eth_nl_cmd_ops = {
 	.session_create	= l2tp_eth_create,
@@ -317,25 +277,18 @@ static int __init l2tp_eth_init(void)
 
 	err = l2tp_nl_register_ops(L2TP_PWTYPE_ETH, &l2tp_eth_nl_cmd_ops);
 	if (err)
-		goto out;
-
-	err = register_pernet_device(&l2tp_eth_net_ops);
-	if (err)
-		goto out_unreg;
+		goto err;
 
 	pr_info("L2TP ethernet pseudowire support (L2TPv3)\n");
 
 	return 0;
 
-out_unreg:
-	l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH);
-out:
+err:
 	return err;
 }
 
 static void __exit l2tp_eth_exit(void)
 {
-	unregister_pernet_device(&l2tp_eth_net_ops);
 	l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH);
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/l2tp/l2tp_ip6.c linux-libre-3.16.52-gnu/net/l2tp/l2tp_ip6.c
--- linux-libre-3.16.51-gnu/net/l2tp/l2tp_ip6.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/l2tp/l2tp_ip6.c	2018-01-01 15:52:14.000000000 -0500
@@ -133,6 +133,7 @@ static int l2tp_ip6_recv(struct sk_buff
 	unsigned char *ptr, *optr;
 	struct l2tp_session *session;
 	struct l2tp_tunnel *tunnel = NULL;
+	struct ipv6hdr *iph;
 	int length;
 
 	if (!pskb_may_pull(skb, 4))
@@ -189,22 +190,16 @@ pass_up:
 		goto discard;
 
 	tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
-	tunnel = l2tp_tunnel_find(&init_net, tunnel_id);
-	if (tunnel != NULL)
-		sk = tunnel->sock;
-	else {
-		struct ipv6hdr *iph = ipv6_hdr(skb);
+	iph = ipv6_hdr(skb);
 
-		read_lock_bh(&l2tp_ip6_lock);
-		sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr,
-					    0, tunnel_id);
+	read_lock_bh(&l2tp_ip6_lock);
+	sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr, 0, tunnel_id);
+	if (!sk) {
 		read_unlock_bh(&l2tp_ip6_lock);
-	}
-
-	if (sk == NULL)
 		goto discard;
-
+	}
 	sock_hold(sk);
+	read_unlock_bh(&l2tp_ip6_lock);
 
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_put;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/l2tp/l2tp_ip.c linux-libre-3.16.52-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-3.16.51-gnu/net/l2tp/l2tp_ip.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/l2tp/l2tp_ip.c	2018-01-01 15:52:14.000000000 -0500
@@ -122,6 +122,7 @@ static int l2tp_ip_recv(struct sk_buff *
 	unsigned char *ptr, *optr;
 	struct l2tp_session *session;
 	struct l2tp_tunnel *tunnel = NULL;
+	struct iphdr *iph;
 	int length;
 
 	if (!pskb_may_pull(skb, 4))
@@ -177,21 +178,16 @@ pass_up:
 		goto discard;
 
 	tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
-	tunnel = l2tp_tunnel_find(net, tunnel_id);
-	if (tunnel != NULL)
-		sk = tunnel->sock;
-	else {
-		struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
+	iph = (struct iphdr *)skb_network_header(skb);
 
-		read_lock_bh(&l2tp_ip_lock);
-		sk = __l2tp_ip_bind_lookup(net, iph->daddr, 0, tunnel_id);
+	read_lock_bh(&l2tp_ip_lock);
+	sk = __l2tp_ip_bind_lookup(net, iph->daddr, 0, tunnel_id);
+	if (!sk) {
 		read_unlock_bh(&l2tp_ip_lock);
-	}
-
-	if (sk == NULL)
 		goto discard;
-
+	}
 	sock_hold(sk);
+	read_unlock_bh(&l2tp_ip_lock);
 
 	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_put;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/l2tp/l2tp_ppp.c linux-libre-3.16.52-gnu/net/l2tp/l2tp_ppp.c
--- linux-libre-3.16.51-gnu/net/l2tp/l2tp_ppp.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/l2tp/l2tp_ppp.c	2018-01-01 15:52:14.000000000 -0500
@@ -603,6 +603,7 @@ static int pppol2tp_connect(struct socke
 	u32 tunnel_id, peer_tunnel_id;
 	u32 session_id, peer_session_id;
 	bool drop_refcnt = false;
+	bool drop_tunnel = false;
 	int ver = 2;
 	int fd;
 
@@ -671,7 +672,9 @@ static int pppol2tp_connect(struct socke
 	if (tunnel_id == 0)
 		goto end;
 
-	tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
+	tunnel = l2tp_tunnel_get(sock_net(sk), tunnel_id);
+	if (tunnel)
+		drop_tunnel = true;
 
 	/* Special case: create tunnel context if session_id and
 	 * peer_session_id is 0. Otherwise look up tunnel using supplied
@@ -800,6 +803,8 @@ out_no_ppp:
 end:
 	if (drop_refcnt)
 		l2tp_session_dec_refcount(session);
+	if (drop_tunnel)
+		l2tp_tunnel_dec_refcount(tunnel);
 	release_sock(sk);
 
 	return error;
@@ -1007,6 +1012,9 @@ static int pppol2tp_session_ioctl(struct
 		 session->name, cmd, arg);
 
 	sk = ps->sock;
+	if (!sk)
+		return -EBADR;
+
 	sock_hold(sk);
 
 	switch (cmd) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/netfilter/ipset/ip_set_core.c linux-libre-3.16.52-gnu/net/netfilter/ipset/ip_set_core.c
--- linux-libre-3.16.51-gnu/net/netfilter/ipset/ip_set_core.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/netfilter/ipset/ip_set_core.c	2018-01-01 15:52:14.000000000 -0500
@@ -1982,24 +1982,28 @@ static struct pernet_operations ip_set_n
 static int __init
 ip_set_init(void)
 {
-	int ret = nfnetlink_subsys_register(&ip_set_netlink_subsys);
+	int ret = register_pernet_subsys(&ip_set_net_ops);
+
+	if (ret) {
+		pr_err("ip_set: cannot register pernet_subsys.\n");
+		return ret;
+	}
+
+	ret = nfnetlink_subsys_register(&ip_set_netlink_subsys);
 	if (ret != 0) {
 		pr_err("ip_set: cannot register with nfnetlink.\n");
+		unregister_pernet_subsys(&ip_set_net_ops);
 		return ret;
 	}
+
 	ret = nf_register_sockopt(&so_set);
 	if (ret != 0) {
 		pr_err("SO_SET registry failed: %d\n", ret);
 		nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
+		unregister_pernet_subsys(&ip_set_net_ops);
 		return ret;
 	}
-	ret = register_pernet_subsys(&ip_set_net_ops);
-	if (ret) {
-		pr_err("ip_set: cannot register pernet_subsys.\n");
-		nf_unregister_sockopt(&so_set);
-		nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
-		return ret;
-	}
+
 	pr_info("ip_set: protocol %u\n", IPSET_PROTOCOL);
 	return 0;
 }
@@ -2007,9 +2011,10 @@ ip_set_init(void)
 static void __exit
 ip_set_fini(void)
 {
-	unregister_pernet_subsys(&ip_set_net_ops);
 	nf_unregister_sockopt(&so_set);
 	nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
+
+	unregister_pernet_subsys(&ip_set_net_ops);
 	pr_debug("these are the famous last words\n");
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/netfilter/nfnetlink_cthelper.c linux-libre-3.16.52-gnu/net/netfilter/nfnetlink_cthelper.c
--- linux-libre-3.16.51-gnu/net/netfilter/nfnetlink_cthelper.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/netfilter/nfnetlink_cthelper.c	2018-01-01 15:52:14.000000000 -0500
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/capability.h>
 #include <net/netlink.h>
 #include <net/sock.h>
 
@@ -295,6 +296,9 @@ nfnl_cthelper_new(struct sock *nfnl, str
 	struct nf_conntrack_tuple tuple;
 	int ret = 0, i;
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE])
 		return -EINVAL;
 
@@ -509,6 +513,9 @@ nfnl_cthelper_get(struct sock *nfnl, str
 	struct nf_conntrack_tuple tuple;
 	bool tuple_set = false;
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
 		struct netlink_dump_control c = {
 			.dump = nfnl_cthelper_dump_table,
@@ -581,6 +588,9 @@ nfnl_cthelper_del(struct sock *nfnl, str
 	bool tuple_set = false, found = false;
 	int i, j = 0, ret;
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	if (tb[NFCTH_NAME])
 		helper_name = nla_data(tb[NFCTH_NAME]);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/netfilter/x_tables.c linux-libre-3.16.52-gnu/net/netfilter/x_tables.c
--- linux-libre-3.16.51-gnu/net/netfilter/x_tables.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/netfilter/x_tables.c	2018-01-01 15:52:14.000000000 -0500
@@ -860,7 +860,7 @@ void *xt_copy_counters_from_user(const v
 		if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0)
 			return ERR_PTR(-EFAULT);
 
-		strlcpy(info->name, compat_tmp.name, sizeof(info->name));
+		memcpy(info->name, compat_tmp.name, sizeof(info->name) - 1);
 		info->num_counters = compat_tmp.num_counters;
 		user += sizeof(compat_tmp);
 	} else
@@ -873,9 +873,9 @@ void *xt_copy_counters_from_user(const v
 		if (copy_from_user(info, user, sizeof(*info)) != 0)
 			return ERR_PTR(-EFAULT);
 
-		info->name[sizeof(info->name) - 1] = '\0';
 		user += sizeof(*info);
 	}
+	info->name[sizeof(info->name) - 1] = '\0';
 
 	size = sizeof(struct xt_counters);
 	size *= info->num_counters;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/netfilter/xt_osf.c linux-libre-3.16.52-gnu/net/netfilter/xt_osf.c
--- linux-libre-3.16.51-gnu/net/netfilter/xt_osf.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/netfilter/xt_osf.c	2018-01-01 15:52:14.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 
+#include <linux/capability.h>
 #include <linux/if.h>
 #include <linux/inetdevice.h>
 #include <linux/ip.h>
@@ -69,6 +70,9 @@ static int xt_osf_add_callback(struct so
 	struct xt_osf_finger *kf = NULL, *sf;
 	int err = 0;
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	if (!osf_attrs[OSF_ATTR_FINGER])
 		return -EINVAL;
 
@@ -112,6 +116,9 @@ static int xt_osf_remove_callback(struct
 	struct xt_osf_finger *sf;
 	int err = -ENOENT;
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	if (!osf_attrs[OSF_ATTR_FINGER])
 		return -EINVAL;
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/netlink/af_netlink.c linux-libre-3.16.52-gnu/net/netlink/af_netlink.c
--- linux-libre-3.16.51-gnu/net/netlink/af_netlink.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/netlink/af_netlink.c	2018-01-01 15:52:14.000000000 -0500
@@ -216,6 +216,9 @@ static int __netlink_deliver_tap_skb(str
 	struct sock *sk = skb->sk;
 	int ret = -ENOMEM;
 
+	if (!net_eq(dev_net(dev), sock_net(sk)))
+		return 0;
+
 	dev_hold(dev);
 
 	if (is_vmalloc_addr(skb->head))
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/packet/af_packet.c linux-libre-3.16.52-gnu/net/packet/af_packet.c
--- linux-libre-3.16.51-gnu/net/packet/af_packet.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/packet/af_packet.c	2018-01-01 15:52:14.000000000 -0500
@@ -2432,6 +2432,7 @@ static int packet_snd(struct socket *soc
 	int offset = 0;
 	int vnet_hdr_len;
 	struct packet_sock *po = pkt_sk(sk);
+	bool has_vnet_hdr = false;
 	unsigned short gso_type = 0;
 	int hlen, tlen;
 	int extra_len = 0;
@@ -2466,6 +2467,7 @@ static int packet_snd(struct socket *soc
 		reserve = dev->hard_header_len;
 	if (po->has_vnet_hdr) {
 		vnet_hdr_len = sizeof(vnet_hdr);
+		has_vnet_hdr = true;
 
 		err = -EINVAL;
 		if (len < vnet_hdr_len)
@@ -2557,7 +2559,7 @@ static int packet_snd(struct socket *soc
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
 
-	if (po->has_vnet_hdr) {
+	if (has_vnet_hdr) {
 		if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
 			if (!skb_partial_csum_set(skb, vnet_hdr.csum_start,
 						  vnet_hdr.csum_offset)) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/sched/sch_generic.c linux-libre-3.16.52-gnu/net/sched/sch_generic.c
--- linux-libre-3.16.51-gnu/net/sched/sch_generic.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/sched/sch_generic.c	2018-01-01 15:52:14.000000000 -0500
@@ -621,6 +621,7 @@ void qdisc_reset(struct Qdisc *qdisc)
 		qdisc->gso_skb = NULL;
 		qdisc->q.qlen = 0;
 	}
+	qdisc->qstats.backlog = 0;
 }
 EXPORT_SYMBOL(qdisc_reset);
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/sctp/input.c linux-libre-3.16.52-gnu/net/sctp/input.c
--- linux-libre-3.16.51-gnu/net/sctp/input.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/sctp/input.c	2018-01-01 15:52:14.000000000 -0500
@@ -416,7 +416,7 @@ void sctp_icmp_redirect(struct sock *sk,
 {
 	struct dst_entry *dst;
 
-	if (!t)
+	if (sock_owned_by_user(sk) || !t)
 		return;
 	dst = sctp_transport_dst_check(t);
 	if (dst)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/sctp/sm_sideeffect.c linux-libre-3.16.52-gnu/net/sctp/sm_sideeffect.c
--- linux-libre-3.16.51-gnu/net/sctp/sm_sideeffect.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/sctp/sm_sideeffect.c	2018-01-01 15:52:14.000000000 -0500
@@ -1627,8 +1627,8 @@ static int sctp_cmd_interpreter(sctp_eve
 		case SCTP_CMD_PROCESS_CTSN:
 			/* Dummy up a SACK for processing. */
 			sackh.cum_tsn_ack = cmd->obj.be32;
-			sackh.a_rwnd = asoc->peer.rwnd +
-					asoc->outqueue.outstanding_bytes;
+			sackh.a_rwnd = htonl(asoc->peer.rwnd +
+					     asoc->outqueue.outstanding_bytes);
 			sackh.num_gap_ack_blocks = 0;
 			sackh.num_dup_tsns = 0;
 			chunk->subh.sack_hdr = &sackh;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/unix/diag.c linux-libre-3.16.52-gnu/net/unix/diag.c
--- linux-libre-3.16.51-gnu/net/unix/diag.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/unix/diag.c	2018-01-01 15:52:14.000000000 -0500
@@ -256,6 +256,8 @@ static int unix_diag_get_exact(struct sk
 	err = -ENOENT;
 	if (sk == NULL)
 		goto out_nosk;
+	if (!net_eq(sock_net(sk), net))
+		goto out;
 
 	err = sock_diag_check_cookie(sk, req->udiag_cookie);
 	if (err)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/wireless/nl80211.c linux-libre-3.16.52-gnu/net/wireless/nl80211.c
--- linux-libre-3.16.51-gnu/net/wireless/nl80211.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/wireless/nl80211.c	2018-01-01 15:52:14.000000000 -0500
@@ -464,6 +464,14 @@ nl80211_match_policy[NL80211_SCHED_SCAN_
 	[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
 };
 
+/* policy for packet pattern attributes */
+static const struct nla_policy
+nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
+	[NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
+	[NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
+	[NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
+};
+
 static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
 				     struct netlink_callback *cb,
 				     struct cfg80211_registered_device **rdev,
@@ -8573,7 +8581,7 @@ static int nl80211_set_wowlan(struct sk_
 			u8 *mask_pat;
 
 			nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
-				  nla_len(pat), NULL);
+				  nla_len(pat), nl80211_packet_pattern_policy);
 			err = -EINVAL;
 			if (!pat_tb[NL80211_PKTPAT_MASK] ||
 			    !pat_tb[NL80211_PKTPAT_PATTERN])
@@ -8801,7 +8809,7 @@ static int nl80211_parse_coalesce_rule(s
 		u8 *mask_pat;
 
 		nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
-			  nla_len(pat), NULL);
+			  nla_len(pat), nl80211_packet_pattern_policy);
 		if (!pat_tb[NL80211_PKTPAT_MASK] ||
 		    !pat_tb[NL80211_PKTPAT_PATTERN])
 			return -EINVAL;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/xfrm/xfrm_state.c linux-libre-3.16.52-gnu/net/xfrm/xfrm_state.c
--- linux-libre-3.16.51-gnu/net/xfrm/xfrm_state.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/xfrm/xfrm_state.c	2018-01-01 15:52:14.000000000 -0500
@@ -1877,6 +1877,7 @@ int xfrm_user_policy(struct sock *sk, in
 	if (err >= 0) {
 		xfrm_sk_policy_insert(sk, err, pol);
 		xfrm_pol_put(pol);
+		__sk_dst_reset(sk);
 		err = 0;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/net/xfrm/xfrm_user.c linux-libre-3.16.52-gnu/net/xfrm/xfrm_user.c
--- linux-libre-3.16.51-gnu/net/xfrm/xfrm_user.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/net/xfrm/xfrm_user.c	2018-01-01 15:52:14.000000000 -0500
@@ -1570,7 +1570,8 @@ static int xfrm_dump_policy_done(struct
 	struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
 	struct net *net = sock_net(cb->skb->sk);
 
-	xfrm_policy_walk_done(walk, net);
+	if (cb->args[0])
+		xfrm_policy_walk_done(walk, net);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/big_key.c linux-libre-3.16.52-gnu/security/keys/big_key.c
--- linux-libre-3.16.51-gnu/security/keys/big_key.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/big_key.c	2018-01-01 15:52:14.000000000 -0500
@@ -135,7 +135,7 @@ void big_key_destroy(struct key *key)
 		path->mnt = NULL;
 		path->dentry = NULL;
 	} else {
-		kfree(key->payload.data);
+		kzfree(key->payload.data);
 		key->payload.data = NULL;
 	}
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/encrypted-keys/encrypted.c linux-libre-3.16.52-gnu/security/keys/encrypted-keys/encrypted.c
--- linux-libre-3.16.51-gnu/security/keys/encrypted-keys/encrypted.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/encrypted-keys/encrypted.c	2018-01-01 15:52:14.000000000 -0500
@@ -315,6 +315,13 @@ static struct key *request_user_key(cons
 
 	down_read(&ukey->sem);
 	upayload = ukey->payload.data;
+	if (!upayload) {
+		/* key was revoked before we acquired its semaphore */
+		up_read(&ukey->sem);
+		key_put(ukey);
+		ukey = ERR_PTR(-EKEYREVOKED);
+		goto error;
+	}
 	*master_key = upayload->data;
 	*master_keylen = upayload->datalen;
 error:
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/internal.h linux-libre-3.16.52-gnu/security/keys/internal.h
--- linux-libre-3.16.51-gnu/security/keys/internal.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/internal.h	2018-01-01 15:52:14.000000000 -0500
@@ -137,7 +137,7 @@ extern key_ref_t keyring_search_aux(key_
 extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx);
 extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx);
 
-extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
+extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
 
 extern int install_user_keyrings(void);
 extern int install_thread_keyring_to_cred(struct cred *);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/key.c linux-libre-3.16.52-gnu/security/keys/key.c
--- linux-libre-3.16.51-gnu/security/keys/key.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/key.c	2018-01-01 15:52:14.000000000 -0500
@@ -298,6 +298,8 @@ struct key *key_alloc(struct key_type *t
 		key->flags |= 1 << KEY_FLAG_IN_QUOTA;
 	if (flags & KEY_ALLOC_TRUSTED)
 		key->flags |= 1 << KEY_FLAG_TRUSTED;
+	if (flags & KEY_ALLOC_UID_KEYRING)
+		key->flags |= 1 << KEY_FLAG_UID_KEYRING;
 
 #ifdef KEY_DEBUGGING
 	key->magic = KEY_DEBUG_MAGIC;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/keyctl.c linux-libre-3.16.52-gnu/security/keys/keyctl.c
--- linux-libre-3.16.51-gnu/security/keys/keyctl.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/keyctl.c	2018-01-01 15:52:14.000000000 -0500
@@ -745,7 +745,7 @@ long keyctl_read_key(key_serial_t keyid,
 	if (ret == 0)
 		goto can_read_key;
 	if (ret != -EACCES)
-		goto error;
+		goto error2;
 
 	/* we can't; see if it's searchable from this process's keyrings
 	 * - we automatically take account of the fact that it may be
@@ -1401,11 +1401,9 @@ long keyctl_assume_authority(key_serial_
 	}
 
 	ret = keyctl_change_reqkey_auth(authkey);
-	if (ret < 0)
-		goto error;
+	if (ret == 0)
+		ret = authkey->serial;
 	key_put(authkey);
-
-	ret = authkey->serial;
 error:
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/keyring.c linux-libre-3.16.52-gnu/security/keys/keyring.c
--- linux-libre-3.16.51-gnu/security/keys/keyring.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/keyring.c	2018-01-01 15:52:14.000000000 -0500
@@ -405,7 +405,7 @@ static void keyring_describe(const struc
 }
 
 struct keyring_read_iterator_context {
-	size_t			qty;
+	size_t			buflen;
 	size_t			count;
 	key_serial_t __user	*buffer;
 };
@@ -417,9 +417,9 @@ static int keyring_read_iterator(const v
 	int ret;
 
 	kenter("{%s,%d},,{%zu/%zu}",
-	       key->type->name, key->serial, ctx->count, ctx->qty);
+	       key->type->name, key->serial, ctx->count, ctx->buflen);
 
-	if (ctx->count >= ctx->qty)
+	if (ctx->count >= ctx->buflen)
 		return 1;
 
 	ret = put_user(key->serial, ctx->buffer);
@@ -441,38 +441,33 @@ static long keyring_read(const struct ke
 			 char __user *buffer, size_t buflen)
 {
 	struct keyring_read_iterator_context ctx;
-	unsigned long nr_keys;
-	int ret;
+	long ret;
 
 	kenter("{%d},,%zu", key_serial(keyring), buflen);
 
 	if (buflen & (sizeof(key_serial_t) - 1))
 		return -EINVAL;
 
-	nr_keys = keyring->keys.nr_leaves_on_tree;
-	if (nr_keys == 0)
-		return 0;
-
-	/* Calculate how much data we could return */
-	ctx.qty = nr_keys * sizeof(key_serial_t);
-
-	if (!buffer || !buflen)
-		return ctx.qty;
-
-	if (buflen > ctx.qty)
-		ctx.qty = buflen;
-
-	/* Copy the IDs of the subscribed keys into the buffer */
-	ctx.buffer = (key_serial_t __user *)buffer;
-	ctx.count = 0;
-	ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx);
-	if (ret < 0) {
-		kleave(" = %d [iterate]", ret);
-		return ret;
+	/* Copy as many key IDs as fit into the buffer */
+	if (buffer && buflen) {
+		ctx.buffer = (key_serial_t __user *)buffer;
+		ctx.buflen = buflen;
+		ctx.count = 0;
+		ret = assoc_array_iterate(&keyring->keys,
+					  keyring_read_iterator, &ctx);
+		if (ret < 0) {
+			kleave(" = %ld [iterate]", ret);
+			return ret;
+		}
 	}
 
-	kleave(" = %zu [ok]", ctx.count);
-	return ctx.count;
+	/* Return the size of the buffer needed */
+	ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t);
+	if (ret <= buflen)
+		kleave("= %ld [ok]", ret);
+	else
+		kleave("= %ld [buffer too small]", ret);
+	return ret;
 }
 
 /*
@@ -935,15 +930,15 @@ found:
 /*
  * Find a keyring with the specified name.
  *
- * All named keyrings in the current user namespace are searched, provided they
- * grant Search permission directly to the caller (unless this check is
- * skipped).  Keyrings whose usage points have reached zero or who have been
- * revoked are skipped.
+ * Only keyrings that have nonzero refcount, are not revoked, and are owned by a
+ * user in the current user namespace are considered.  If @uid_keyring is %true,
+ * the keyring additionally must have been allocated as a user or user session
+ * keyring; otherwise, it must grant Search permission directly to the caller.
  *
  * Returns a pointer to the keyring with the keyring's refcount having being
  * incremented on success.  -ENOKEY is returned if a key could not be found.
  */
-struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
+struct key *find_keyring_by_name(const char *name, bool uid_keyring)
 {
 	struct key *keyring;
 	int bucket;
@@ -971,10 +966,15 @@ struct key *find_keyring_by_name(const c
 			if (strcmp(keyring->description, name) != 0)
 				continue;
 
-			if (!skip_perm_check &&
-			    key_permission(make_key_ref(keyring, 0),
-					   KEY_NEED_SEARCH) < 0)
-				continue;
+			if (uid_keyring) {
+				if (!test_bit(KEY_FLAG_UID_KEYRING,
+					      &keyring->flags))
+					continue;
+			} else {
+				if (key_permission(make_key_ref(keyring, 0),
+						   KEY_NEED_SEARCH) < 0)
+					continue;
+			}
 
 			/* we've got a match but we might end up racing with
 			 * key_cleanup() if the keyring is currently 'dead'
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/process_keys.c linux-libre-3.16.52-gnu/security/keys/process_keys.c
--- linux-libre-3.16.51-gnu/security/keys/process_keys.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/process_keys.c	2018-01-01 15:52:14.000000000 -0500
@@ -76,7 +76,9 @@ int install_user_keyrings(void)
 		if (IS_ERR(uid_keyring)) {
 			uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
 						    cred, user_keyring_perm,
-						    KEY_ALLOC_IN_QUOTA, NULL);
+						    KEY_ALLOC_UID_KEYRING |
+							KEY_ALLOC_IN_QUOTA,
+						    NULL);
 			if (IS_ERR(uid_keyring)) {
 				ret = PTR_ERR(uid_keyring);
 				goto error;
@@ -92,7 +94,9 @@ int install_user_keyrings(void)
 			session_keyring =
 				keyring_alloc(buf, user->uid, INVALID_GID,
 					      cred, user_keyring_perm,
-					      KEY_ALLOC_IN_QUOTA, NULL);
+					      KEY_ALLOC_UID_KEYRING |
+						  KEY_ALLOC_IN_QUOTA,
+					      NULL);
 			if (IS_ERR(session_keyring)) {
 				ret = PTR_ERR(session_keyring);
 				goto error_release;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/request_key_auth.c linux-libre-3.16.52-gnu/security/keys/request_key_auth.c
--- linux-libre-3.16.51-gnu/security/keys/request_key_auth.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/request_key_auth.c	2018-01-01 15:52:14.000000000 -0500
@@ -107,6 +107,18 @@ static void request_key_auth_revoke(stru
 	}
 }
 
+static void free_request_key_auth(struct request_key_auth *rka)
+{
+	if (!rka)
+		return;
+	key_put(rka->target_key);
+	key_put(rka->dest_keyring);
+	if (rka->cred)
+		put_cred(rka->cred);
+	kfree(rka->callout_info);
+	kfree(rka);
+}
+
 /*
  * Destroy an instantiation authorisation token key.
  */
@@ -116,15 +128,7 @@ static void request_key_auth_destroy(str
 
 	kenter("{%d}", key->serial);
 
-	if (rka->cred) {
-		put_cred(rka->cred);
-		rka->cred = NULL;
-	}
-
-	key_put(rka->target_key);
-	key_put(rka->dest_keyring);
-	kfree(rka->callout_info);
-	kfree(rka);
+	free_request_key_auth(rka);
 }
 
 /*
@@ -138,22 +142,17 @@ struct key *request_key_auth_new(struct
 	const struct cred *cred = current->cred;
 	struct key *authkey = NULL;
 	char desc[20];
-	int ret;
+	int ret = -ENOMEM;
 
 	kenter("%d,", target->serial);
 
 	/* allocate a auth record */
-	rka = kmalloc(sizeof(*rka), GFP_KERNEL);
-	if (!rka) {
-		kleave(" = -ENOMEM");
-		return ERR_PTR(-ENOMEM);
-	}
+	rka = kzalloc(sizeof(*rka), GFP_KERNEL);
+	if (!rka)
+		goto error;
 	rka->callout_info = kmalloc(callout_len, GFP_KERNEL);
-	if (!rka->callout_info) {
-		kleave(" = -ENOMEM");
-		kfree(rka);
-		return ERR_PTR(-ENOMEM);
-	}
+	if (!rka->callout_info)
+		goto error_free_rka;
 
 	/* see if the calling process is already servicing the key request of
 	 * another process */
@@ -163,8 +162,12 @@ struct key *request_key_auth_new(struct
 
 		/* if the auth key has been revoked, then the key we're
 		 * servicing is already instantiated */
-		if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
-			goto auth_key_revoked;
+		if (test_bit(KEY_FLAG_REVOKED,
+			     &cred->request_key_auth->flags)) {
+			up_read(&cred->request_key_auth->sem);
+			ret = -EKEYREVOKED;
+			goto error_free_rka;
+		}
 
 		irka = cred->request_key_auth->payload.data;
 		rka->cred = get_cred(irka->cred);
@@ -192,32 +195,22 @@ struct key *request_key_auth_new(struct
 			    KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
 	if (IS_ERR(authkey)) {
 		ret = PTR_ERR(authkey);
-		goto error_alloc;
+		goto error_free_rka;
 	}
 
 	/* construct the auth key */
 	ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
 	if (ret < 0)
-		goto error_inst;
+		goto error_put_authkey;
 
 	kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage));
 	return authkey;
 
-auth_key_revoked:
-	up_read(&cred->request_key_auth->sem);
-	kfree(rka->callout_info);
-	kfree(rka);
-	kleave("= -EKEYREVOKED");
-	return ERR_PTR(-EKEYREVOKED);
-
-error_inst:
-	key_revoke(authkey);
+error_put_authkey:
 	key_put(authkey);
-error_alloc:
-	key_put(rka->target_key);
-	key_put(rka->dest_keyring);
-	kfree(rka->callout_info);
-	kfree(rka);
+error_free_rka:
+	free_request_key_auth(rka);
+error:
 	kleave("= %d", ret);
 	return ERR_PTR(ret);
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/request_key.c linux-libre-3.16.52-gnu/security/keys/request_key.c
--- linux-libre-3.16.51-gnu/security/keys/request_key.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/request_key.c	2018-01-01 15:52:14.000000000 -0500
@@ -268,11 +268,12 @@ static int construct_key(struct key *key
  * The keyring selected is returned with an extra reference upon it which the
  * caller must release.
  */
-static void construct_get_dest_keyring(struct key **_dest_keyring)
+static int construct_get_dest_keyring(struct key **_dest_keyring)
 {
 	struct request_key_auth *rka;
 	const struct cred *cred = current_cred();
 	struct key *dest_keyring = *_dest_keyring, *authkey;
+	int ret;
 
 	kenter("%p", dest_keyring);
 
@@ -281,6 +282,8 @@ static void construct_get_dest_keyring(s
 		/* the caller supplied one */
 		key_get(dest_keyring);
 	} else {
+		bool do_perm_check = true;
+
 		/* use a default keyring; falling through the cases until we
 		 * find one that we actually have */
 		switch (cred->jit_keyring) {
@@ -295,8 +298,10 @@ static void construct_get_dest_keyring(s
 					dest_keyring =
 						key_get(rka->dest_keyring);
 				up_read(&authkey->sem);
-				if (dest_keyring)
+				if (dest_keyring) {
+					do_perm_check = false;
 					break;
+				}
 			}
 
 		case KEY_REQKEY_DEFL_THREAD_KEYRING:
@@ -331,11 +336,29 @@ static void construct_get_dest_keyring(s
 		default:
 			BUG();
 		}
+
+		/*
+		 * Require Write permission on the keyring.  This is essential
+		 * because the default keyring may be the session keyring, and
+		 * joining a keyring only requires Search permission.
+		 *
+		 * However, this check is skipped for the "requestor keyring" so
+		 * that /sbin/request-key can itself use request_key() to add
+		 * keys to the original requestor's destination keyring.
+		 */
+		if (dest_keyring && do_perm_check) {
+			ret = key_permission(make_key_ref(dest_keyring, 1),
+					     KEY_NEED_WRITE);
+			if (ret) {
+				key_put(dest_keyring);
+				return ret;
+			}
+		}
 	}
 
 	*_dest_keyring = dest_keyring;
 	kleave(" [dk %d]", key_serial(dest_keyring));
-	return;
+	return 0;
 }
 
 /*
@@ -460,11 +483,15 @@ static struct key *construct_key_and_lin
 	if (ctx->index_key.type == &key_type_keyring)
 		return ERR_PTR(-EPERM);
 	
-	user = key_user_lookup(current_fsuid());
-	if (!user)
-		return ERR_PTR(-ENOMEM);
+	ret = construct_get_dest_keyring(&dest_keyring);
+	if (ret)
+		goto error;
 
-	construct_get_dest_keyring(&dest_keyring);
+	user = key_user_lookup(current_fsuid());
+	if (!user) {
+		ret = -ENOMEM;
+		goto error_put_dest_keyring;
+	}
 
 	ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
 	key_user_put(user);
@@ -479,7 +506,7 @@ static struct key *construct_key_and_lin
 	} else if (ret == -EINPROGRESS) {
 		ret = 0;
 	} else {
-		goto couldnt_alloc_key;
+		goto error_put_dest_keyring;
 	}
 
 	key_put(dest_keyring);
@@ -489,8 +516,9 @@ static struct key *construct_key_and_lin
 construction_failed:
 	key_negate_and_link(key, key_negative_timeout, NULL, NULL);
 	key_put(key);
-couldnt_alloc_key:
+error_put_dest_keyring:
 	key_put(dest_keyring);
+error:
 	kleave(" = %d", ret);
 	return ERR_PTR(ret);
 }
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/keys/trusted.c linux-libre-3.16.52-gnu/security/keys/trusted.c
--- linux-libre-3.16.51-gnu/security/keys/trusted.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/keys/trusted.c	2018-01-01 15:52:14.000000000 -0500
@@ -69,7 +69,7 @@ static int TSS_sha1(const unsigned char
 	}
 
 	ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
-	kfree(sdesc);
+	kzfree(sdesc);
 	return ret;
 }
 
@@ -113,7 +113,7 @@ static int TSS_rawhmac(unsigned char *di
 	if (!ret)
 		ret = crypto_shash_final(&sdesc->shash, digest);
 out:
-	kfree(sdesc);
+	kzfree(sdesc);
 	return ret;
 }
 
@@ -164,7 +164,7 @@ static int TSS_authhmac(unsigned char *d
 				  paramdigest, TPM_NONCE_SIZE, h1,
 				  TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
 out:
-	kfree(sdesc);
+	kzfree(sdesc);
 	return ret;
 }
 
@@ -245,7 +245,7 @@ static int TSS_checkhmac1(unsigned char
 	if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
 		ret = -EINVAL;
 out:
-	kfree(sdesc);
+	kzfree(sdesc);
 	return ret;
 }
 
@@ -346,7 +346,7 @@ static int TSS_checkhmac2(unsigned char
 	if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
 		ret = -EINVAL;
 out:
-	kfree(sdesc);
+	kzfree(sdesc);
 	return ret;
 }
 
@@ -563,7 +563,7 @@ static int tpm_seal(struct tpm_buf *tb,
 		*bloblen = storedsize;
 	}
 out:
-	kfree(td);
+	kzfree(td);
 	return ret;
 }
 
@@ -677,7 +677,7 @@ static int key_seal(struct trusted_key_p
 	if (ret < 0)
 		pr_info("trusted_key: srkseal failed (%d)\n", ret);
 
-	kfree(tb);
+	kzfree(tb);
 	return ret;
 }
 
@@ -702,7 +702,7 @@ static int key_unseal(struct trusted_key
 		/* pull migratable flag out of sealed key */
 		p->migratable = p->key[--p->key_len];
 
-	kfree(tb);
+	kzfree(tb);
 	return ret;
 }
 
@@ -961,12 +961,12 @@ static int trusted_instantiate(struct ke
 	if (!ret && options->pcrlock)
 		ret = pcrlock(options->pcrlock);
 out:
-	kfree(datablob);
-	kfree(options);
+	kzfree(datablob);
+	kzfree(options);
 	if (!ret)
 		rcu_assign_keypointer(key, payload);
 	else
-		kfree(payload);
+		kzfree(payload);
 	return ret;
 }
 
@@ -975,8 +975,7 @@ static void trusted_rcu_free(struct rcu_
 	struct trusted_key_payload *p;
 
 	p = container_of(rcu, struct trusted_key_payload, rcu);
-	memset(p->key, 0, p->key_len);
-	kfree(p);
+	kzfree(p);
 }
 
 /*
@@ -1015,7 +1014,7 @@ static int trusted_update(struct key *ke
 	ret = datablob_parse(datablob, new_p, new_o);
 	if (ret != Opt_update) {
 		ret = -EINVAL;
-		kfree(new_p);
+		kzfree(new_p);
 		goto out;
 	}
 	/* copy old key values, and reseal with new pcrs */
@@ -1028,22 +1027,22 @@ static int trusted_update(struct key *ke
 	ret = key_seal(new_p, new_o);
 	if (ret < 0) {
 		pr_info("trusted_key: key_seal failed (%d)\n", ret);
-		kfree(new_p);
+		kzfree(new_p);
 		goto out;
 	}
 	if (new_o->pcrlock) {
 		ret = pcrlock(new_o->pcrlock);
 		if (ret < 0) {
 			pr_info("trusted_key: pcrlock failed (%d)\n", ret);
-			kfree(new_p);
+			kzfree(new_p);
 			goto out;
 		}
 	}
 	rcu_assign_keypointer(key, new_p);
 	call_rcu(&p->rcu, trusted_rcu_free);
 out:
-	kfree(datablob);
-	kfree(new_o);
+	kzfree(datablob);
+	kzfree(new_o);
 	return ret;
 }
 
@@ -1062,34 +1061,30 @@ static long trusted_read(const struct ke
 	p = rcu_dereference_key(key);
 	if (!p)
 		return -EINVAL;
-	if (!buffer || buflen <= 0)
-		return 2 * p->blob_len;
-	ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
-	if (!ascii_buf)
-		return -ENOMEM;
 
-	bufp = ascii_buf;
-	for (i = 0; i < p->blob_len; i++)
-		bufp = hex_byte_pack(bufp, p->blob[i]);
-	if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
-		kfree(ascii_buf);
-		return -EFAULT;
+	if (buffer && buflen >= 2 * p->blob_len) {
+		ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
+		if (!ascii_buf)
+			return -ENOMEM;
+
+		bufp = ascii_buf;
+		for (i = 0; i < p->blob_len; i++)
+			bufp = hex_byte_pack(bufp, p->blob[i]);
+		if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) {
+			kzfree(ascii_buf);
+			return -EFAULT;
+		}
+		kzfree(ascii_buf);
 	}
-	kfree(ascii_buf);
 	return 2 * p->blob_len;
 }
 
 /*
- * trusted_destroy - before freeing the key, clear the decrypted data
+ * trusted_destroy - clear and free the key's payload
  */
 static void trusted_destroy(struct key *key)
 {
-	struct trusted_key_payload *p = key->payload.data;
-
-	if (!p)
-		return;
-	memset(p->key, 0, p->key_len);
-	kfree(key->payload.data);
+	kzfree(key->payload.data);
 }
 
 struct key_type key_type_trusted = {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/smack/smack_lsm.c linux-libre-3.16.52-gnu/security/smack/smack_lsm.c
--- linux-libre-3.16.51-gnu/security/smack/smack_lsm.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/smack/smack_lsm.c	2018-01-01 15:52:14.000000000 -0500
@@ -163,12 +163,10 @@ static int smk_copy_rules(struct list_he
  */
 static inline unsigned int smk_ptrace_mode(unsigned int mode)
 {
-	switch (mode) {
-	case PTRACE_MODE_READ:
-		return MAY_READ;
-	case PTRACE_MODE_ATTACH:
+	if (mode & PTRACE_MODE_ATTACH)
 		return MAY_READWRITE;
-	}
+	if (mode & PTRACE_MODE_READ)
+		return MAY_READ;
 
 	return 0;
 }
@@ -674,7 +672,7 @@ static int smack_inode_init_security(str
 	}
 
 	if (len)
-		*len = strlen(isp) + 1;
+		*len = strlen(isp);
 
 	return 0;
 }
@@ -1060,7 +1058,7 @@ static int smack_inode_removexattr(struc
  * @inode: the object
  * @name: attribute name
  * @buffer: where to put the result
- * @alloc: unused
+ * @alloc: duplicate memory
  *
  * Returns the size of the attribute or an error code
  */
@@ -1073,43 +1071,38 @@ static int smack_inode_getsecurity(const
 	struct super_block *sbp;
 	struct inode *ip = (struct inode *)inode;
 	char *isp;
-	int ilen;
-	int rc = 0;
 
-	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
+	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
 		isp = smk_of_inode(inode);
-		ilen = strlen(isp) + 1;
-		*buffer = isp;
-		return ilen;
-	}
-
-	/*
-	 * The rest of the Smack xattrs are only on sockets.
-	 */
-	sbp = ip->i_sb;
-	if (sbp->s_magic != SOCKFS_MAGIC)
-		return -EOPNOTSUPP;
+	else {
+		/*
+		 * The rest of the Smack xattrs are only on sockets.
+		 */
+		sbp = ip->i_sb;
+		if (sbp->s_magic != SOCKFS_MAGIC)
+			return -EOPNOTSUPP;
 
-	sock = SOCKET_I(ip);
-	if (sock == NULL || sock->sk == NULL)
-		return -EOPNOTSUPP;
+		sock = SOCKET_I(ip);
+		if (sock == NULL || sock->sk == NULL)
+			return -EOPNOTSUPP;
 
-	ssp = sock->sk->sk_security;
+		ssp = sock->sk->sk_security;
 
-	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
-		isp = ssp->smk_in->smk_known;
-	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
-		isp = ssp->smk_out->smk_known;
-	else
-		return -EOPNOTSUPP;
+		if (strcmp(name, XATTR_SMACK_IPIN) == 0)
+			isp = ssp->smk_in->smk_known;
+		else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
+			isp = ssp->smk_out->smk_known;
+		else
+			return -EOPNOTSUPP;
+	}
 
-	ilen = strlen(isp) + 1;
-	if (rc == 0) {
-		*buffer = isp;
-		rc = ilen;
+	if (alloc) {
+		*buffer = kstrdup(isp, GFP_KERNEL);
+		if (*buffer == NULL)
+			return -ENOMEM;
 	}
 
-	return rc;
+	return strlen(isp);
 }
 
 
diff -druNp --no-dereference linux-libre-3.16.51-gnu/security/yama/yama_lsm.c linux-libre-3.16.52-gnu/security/yama/yama_lsm.c
--- linux-libre-3.16.51-gnu/security/yama/yama_lsm.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/security/yama/yama_lsm.c	2018-01-01 15:52:14.000000000 -0500
@@ -292,7 +292,7 @@ int yama_ptrace_access_check(struct task
 		return rc;
 
 	/* require ptrace target be a child of ptracer on attach */
-	if (mode == PTRACE_MODE_ATTACH) {
+	if (mode & PTRACE_MODE_ATTACH) {
 		switch (ptrace_scope) {
 		case YAMA_SCOPE_DISABLED:
 			/* No additional restrictions. */
@@ -318,7 +318,7 @@ int yama_ptrace_access_check(struct task
 		}
 	}
 
-	if (rc) {
+	if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0) {
 		printk_ratelimited(KERN_NOTICE
 			"ptrace of pid %d was attempted by: %s (pid %d)\n",
 			child->pid, current->comm, current->pid);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/hrtimer.c linux-libre-3.16.52-gnu/sound/core/hrtimer.c
--- linux-libre-3.16.51-gnu/sound/core/hrtimer.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/hrtimer.c	2018-01-01 15:52:14.000000000 -0500
@@ -144,6 +144,7 @@ static int __init snd_hrtimer_init(void)
 	timer->hw = hrtimer_hw;
 	timer->hw.resolution = resolution;
 	timer->hw.ticks = NANO_SEC / resolution;
+	timer->max_instances = 100; /* lower the limit */
 
 	err = snd_timer_global_register(timer);
 	if (err < 0) {
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/seq/oss/seq_oss_midi.c linux-libre-3.16.52-gnu/sound/core/seq/oss/seq_oss_midi.c
--- linux-libre-3.16.51-gnu/sound/core/seq/oss/seq_oss_midi.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/seq/oss/seq_oss_midi.c	2018-01-01 15:52:14.000000000 -0500
@@ -615,9 +615,7 @@ send_midi_event(struct seq_oss_devinfo *
 	if (!dp->timer->running)
 		len = snd_seq_oss_timer_start(dp->timer);
 	if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
-		if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
-			snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,
-					       ev->data.ext.ptr, ev->data.ext.len);
+		snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
 	} else {
 		len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
 		if (len > 0)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/seq/oss/seq_oss_readq.c linux-libre-3.16.52-gnu/sound/core/seq/oss/seq_oss_readq.c
--- linux-libre-3.16.51-gnu/sound/core/seq/oss/seq_oss_readq.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/seq/oss/seq_oss_readq.c	2018-01-01 15:52:14.000000000 -0500
@@ -120,6 +120,35 @@ snd_seq_oss_readq_puts(struct seq_oss_re
 }
 
 /*
+ * put MIDI sysex bytes; the event buffer may be chained, thus it has
+ * to be expanded via snd_seq_dump_var_event().
+ */
+struct readq_sysex_ctx {
+	struct seq_oss_readq *readq;
+	int dev;
+};
+
+static int readq_dump_sysex(void *ptr, void *buf, int count)
+{
+	struct readq_sysex_ctx *ctx = ptr;
+
+	return snd_seq_oss_readq_puts(ctx->readq, ctx->dev, buf, count);
+}
+
+int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
+			    struct snd_seq_event *ev)
+{
+	struct readq_sysex_ctx ctx = {
+		.readq = q,
+		.dev = dev
+	};
+
+	if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
+		return 0;
+	return snd_seq_dump_var_event(ev, readq_dump_sysex, &ctx);
+}
+
+/*
  * copy an event to input queue:
  * return zero if enqueued
  */
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/seq/oss/seq_oss_readq.h linux-libre-3.16.52-gnu/sound/core/seq/oss/seq_oss_readq.h
--- linux-libre-3.16.51-gnu/sound/core/seq/oss/seq_oss_readq.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/seq/oss/seq_oss_readq.h	2018-01-01 15:52:14.000000000 -0500
@@ -44,6 +44,8 @@ void snd_seq_oss_readq_delete(struct seq
 void snd_seq_oss_readq_clear(struct seq_oss_readq *readq);
 unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait);
 int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len);
+int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
+			    struct snd_seq_event *ev);
 int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev);
 int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode);
 int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/seq/seq_clientmgr.c linux-libre-3.16.52-gnu/sound/core/seq/seq_clientmgr.c
--- linux-libre-3.16.51-gnu/sound/core/seq/seq_clientmgr.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/seq/seq_clientmgr.c	2018-01-01 15:52:14.000000000 -0500
@@ -676,7 +676,7 @@ static int deliver_to_subscribers(struct
 	if (atomic)
 		read_lock(&grp->list_lock);
 	else
-		down_read(&grp->list_mutex);
+		down_read_nested(&grp->list_mutex, hop);
 	list_for_each_entry(subs, &grp->list_head, src_list) {
 		/* both ports ready? */
 		if (atomic_read(&subs->ref_count) != 2)
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/seq/seq_virmidi.c linux-libre-3.16.52-gnu/sound/core/seq/seq_virmidi.c
--- linux-libre-3.16.51-gnu/sound/core/seq/seq_virmidi.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/seq/seq_virmidi.c	2018-01-01 15:52:14.000000000 -0500
@@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struc
  * decode input event and put to read buffer of each opened file
  */
 static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
-					 struct snd_seq_event *ev)
+					 struct snd_seq_event *ev,
+					 bool atomic)
 {
 	struct snd_virmidi *vmidi;
 	unsigned char msg[4];
 	int len;
 
-	read_lock(&rdev->filelist_lock);
+	if (atomic)
+		read_lock(&rdev->filelist_lock);
+	else
+		down_read(&rdev->filelist_sem);
 	list_for_each_entry(vmidi, &rdev->filelist, list) {
 		if (!vmidi->trigger)
 			continue;
@@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event
 				snd_rawmidi_receive(vmidi->substream, msg, len);
 		}
 	}
-	read_unlock(&rdev->filelist_lock);
+	if (atomic)
+		read_unlock(&rdev->filelist_lock);
+	else
+		up_read(&rdev->filelist_sem);
 
 	return 0;
 }
@@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmi
 	struct snd_virmidi_dev *rdev;
 
 	rdev = rmidi->private_data;
-	return snd_virmidi_dev_receive_event(rdev, ev);
+	return snd_virmidi_dev_receive_event(rdev, ev, true);
 }
 #endif  /*  0  */
 
@@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struc
 	rdev = private_data;
 	if (!(rdev->flags & SNDRV_VIRMIDI_USE))
 		return 0; /* ignored */
-	return snd_virmidi_dev_receive_event(rdev, ev);
+	return snd_virmidi_dev_receive_event(rdev, ev, atomic);
 }
 
 /*
@@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct
 	struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 	struct snd_virmidi *vmidi;
-	unsigned long flags;
 
 	vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
 	if (vmidi == NULL)
@@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct
 	vmidi->client = rdev->client;
 	vmidi->port = rdev->port;	
 	runtime->private_data = vmidi;
-	write_lock_irqsave(&rdev->filelist_lock, flags);
+	down_write(&rdev->filelist_sem);
+	write_lock_irq(&rdev->filelist_lock);
 	list_add_tail(&vmidi->list, &rdev->filelist);
-	write_unlock_irqrestore(&rdev->filelist_lock, flags);
+	write_unlock_irq(&rdev->filelist_lock);
+	up_write(&rdev->filelist_sem);
 	vmidi->rdev = rdev;
 	return 0;
 }
@@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struc
 	struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
 	struct snd_virmidi *vmidi = substream->runtime->private_data;
 
+	down_write(&rdev->filelist_sem);
 	write_lock_irq(&rdev->filelist_lock);
 	list_del(&vmidi->list);
 	write_unlock_irq(&rdev->filelist_lock);
+	up_write(&rdev->filelist_sem);
 	snd_midi_event_free(vmidi->parser);
 	substream->runtime->private_data = NULL;
 	kfree(vmidi);
@@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *car
 	rdev->rmidi = rmidi;
 	rdev->device = device;
 	rdev->client = -1;
+	init_rwsem(&rdev->filelist_sem);
 	rwlock_init(&rdev->filelist_lock);
 	INIT_LIST_HEAD(&rdev->filelist);
 	rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/timer.c linux-libre-3.16.52-gnu/sound/core/timer.c
--- linux-libre-3.16.51-gnu/sound/core/timer.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/timer.c	2018-01-01 15:52:14.000000000 -0500
@@ -181,7 +181,7 @@ static void snd_timer_request(struct snd
  *
  * call this with register_mutex down.
  */
-static void snd_timer_check_slave(struct snd_timer_instance *slave)
+static int snd_timer_check_slave(struct snd_timer_instance *slave)
 {
 	struct snd_timer *timer;
 	struct snd_timer_instance *master;
@@ -191,16 +191,21 @@ static void snd_timer_check_slave(struct
 		list_for_each_entry(master, &timer->open_list_head, open_list) {
 			if (slave->slave_class == master->slave_class &&
 			    slave->slave_id == master->slave_id) {
+				if (master->timer->num_instances >=
+				    master->timer->max_instances)
+					return -EBUSY;
 				list_move_tail(&slave->open_list,
 					       &master->slave_list_head);
+				master->timer->num_instances++;
 				spin_lock_irq(&slave_active_lock);
 				slave->master = master;
 				slave->timer = master->timer;
 				spin_unlock_irq(&slave_active_lock);
-				return;
+				return 0;
 			}
 		}
 	}
+	return 0;
 }
 
 /*
@@ -209,7 +214,7 @@ static void snd_timer_check_slave(struct
  *
  * call this with register_mutex down.
  */
-static void snd_timer_check_master(struct snd_timer_instance *master)
+static int snd_timer_check_master(struct snd_timer_instance *master)
 {
 	struct snd_timer_instance *slave, *tmp;
 
@@ -217,7 +222,11 @@ static void snd_timer_check_master(struc
 	list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
 		if (slave->slave_class == master->slave_class &&
 		    slave->slave_id == master->slave_id) {
+			if (master->timer->num_instances >=
+			    master->timer->max_instances)
+				return -EBUSY;
 			list_move_tail(&slave->open_list, &master->slave_list_head);
+			master->timer->num_instances++;
 			spin_lock_irq(&slave_active_lock);
 			spin_lock(&master->timer->lock);
 			slave->master = master;
@@ -229,8 +238,11 @@ static void snd_timer_check_master(struc
 			spin_unlock_irq(&slave_active_lock);
 		}
 	}
+	return 0;
 }
 
+static int snd_timer_close_locked(struct snd_timer_instance *timeri);
+
 /*
  * open a timer instance
  * when opening a master, the slave id must be here given.
@@ -241,6 +253,7 @@ int snd_timer_open(struct snd_timer_inst
 {
 	struct snd_timer *timer;
 	struct snd_timer_instance *timeri = NULL;
+	int err;
 
 	if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
 		/* open a slave instance */
@@ -260,10 +273,14 @@ int snd_timer_open(struct snd_timer_inst
 		timeri->slave_id = tid->device;
 		timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
 		list_add_tail(&timeri->open_list, &snd_timer_slave_list);
-		snd_timer_check_slave(timeri);
+		err = snd_timer_check_slave(timeri);
+		if (err < 0) {
+			snd_timer_close_locked(timeri);
+			timeri = NULL;
+		}
 		mutex_unlock(&register_mutex);
 		*ti = timeri;
-		return 0;
+		return err;
 	}
 
 	/* open a master instance */
@@ -289,6 +306,10 @@ int snd_timer_open(struct snd_timer_inst
 			return -EBUSY;
 		}
 	}
+	if (timer->num_instances >= timer->max_instances) {
+		mutex_unlock(&register_mutex);
+		return -EBUSY;
+	}
 	timeri = snd_timer_instance_new(owner, timer);
 	if (!timeri) {
 		mutex_unlock(&register_mutex);
@@ -315,44 +336,36 @@ int snd_timer_open(struct snd_timer_inst
 	}
 
 	list_add_tail(&timeri->open_list, &timer->open_list_head);
-	snd_timer_check_master(timeri);
+	timer->num_instances++;
+	err = snd_timer_check_master(timeri);
+	if (err < 0) {
+		snd_timer_close_locked(timeri);
+		timeri = NULL;
+	}
 	mutex_unlock(&register_mutex);
 	*ti = timeri;
-	return 0;
+	return err;
 }
 
 static int _snd_timer_stop(struct snd_timer_instance *timeri, int event);
 
 /*
  * close a timer instance
+ * call this with register_mutex down.
  */
-int snd_timer_close(struct snd_timer_instance *timeri)
+static int snd_timer_close_locked(struct snd_timer_instance *timeri)
 {
 	struct snd_timer *timer = NULL;
 	struct snd_timer_instance *slave, *tmp;
 
-	if (snd_BUG_ON(!timeri))
-		return -ENXIO;
+	list_del(&timeri->open_list);
 
 	/* force to stop the timer */
 	snd_timer_stop(timeri);
 
-	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
-		/* wait, until the active callback is finished */
-		spin_lock_irq(&slave_active_lock);
-		while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
-			spin_unlock_irq(&slave_active_lock);
-			udelay(10);
-			spin_lock_irq(&slave_active_lock);
-		}
-		spin_unlock_irq(&slave_active_lock);
-		mutex_lock(&register_mutex);
-		list_del(&timeri->open_list);
-		mutex_unlock(&register_mutex);
-	} else {
-		timer = timeri->timer;
-		if (snd_BUG_ON(!timer))
-			goto out;
+	timer = timeri->timer;
+	if (timer) {
+		timer->num_instances--;
 		/* wait, until the active callback is finished */
 		spin_lock_irq(&timer->lock);
 		while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
@@ -361,17 +374,14 @@ int snd_timer_close(struct snd_timer_ins
 			spin_lock_irq(&timer->lock);
 		}
 		spin_unlock_irq(&timer->lock);
-		mutex_lock(&register_mutex);
-		list_del(&timeri->open_list);
-		if (list_empty(&timer->open_list_head) &&
-		    timer->hw.close)
-			timer->hw.close(timer);
+
 		/* remove slave links */
 		spin_lock_irq(&slave_active_lock);
 		spin_lock(&timer->lock);
 		list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
 					 open_list) {
 			list_move_tail(&slave->open_list, &snd_timer_slave_list);
+			timer->num_instances--;
 			slave->master = NULL;
 			slave->timer = NULL;
 			list_del_init(&slave->ack_list);
@@ -379,21 +389,45 @@ int snd_timer_close(struct snd_timer_ins
 		}
 		spin_unlock(&timer->lock);
 		spin_unlock_irq(&slave_active_lock);
-		/* release a card refcount for safe disconnection */
-		if (timer->card)
-			put_device(&timer->card->card_dev);
-		mutex_unlock(&register_mutex);
+
+		/* slave doesn't need to release timer resources below */
+		if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+			timer = NULL;
 	}
- out:
+
 	if (timeri->private_free)
 		timeri->private_free(timeri);
 	kfree(timeri->owner);
 	kfree(timeri);
-	if (timer)
+
+	if (timer) {
+		if (list_empty(&timer->open_list_head) && timer->hw.close)
+			timer->hw.close(timer);
+		/* release a card refcount for safe disconnection */
+		if (timer->card)
+			put_device(&timer->card->card_dev);
 		module_put(timer->module);
+	}
+
 	return 0;
 }
 
+/*
+ * close a timer instance
+ */
+int snd_timer_close(struct snd_timer_instance *timeri)
+{
+	int err;
+
+	if (snd_BUG_ON(!timeri))
+		return -ENXIO;
+
+	mutex_lock(&register_mutex);
+	err = snd_timer_close_locked(timeri);
+	mutex_unlock(&register_mutex);
+	return err;
+}
+
 unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
 {
 	struct snd_timer * timer;
@@ -872,6 +906,7 @@ int snd_timer_new(struct snd_card *card,
 	spin_lock_init(&timer->lock);
 	tasklet_init(&timer->task_queue, snd_timer_tasklet,
 		     (unsigned long)timer);
+	timer->max_instances = 1000; /* default limit per timer */
 	if (card != NULL) {
 		timer->module = card->module;
 		err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/core/timer_compat.c linux-libre-3.16.52-gnu/sound/core/timer_compat.c
--- linux-libre-3.16.51-gnu/sound/core/timer_compat.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/core/timer_compat.c	2018-01-01 15:52:14.000000000 -0500
@@ -106,7 +106,8 @@ enum {
 #endif /* CONFIG_X86_X32 */
 };
 
-static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+static long __snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
+					  unsigned long arg)
 {
 	void __user *argp = compat_ptr(arg);
 
@@ -127,7 +128,7 @@ static long snd_timer_user_ioctl_compat(
 	case SNDRV_TIMER_IOCTL_PAUSE:
 	case SNDRV_TIMER_IOCTL_PAUSE_OLD:
 	case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
-		return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
+		return __snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
 	case SNDRV_TIMER_IOCTL_INFO32:
 		return snd_timer_user_info_compat(file, argp);
 	case SNDRV_TIMER_IOCTL_STATUS32:
@@ -139,3 +140,15 @@ static long snd_timer_user_ioctl_compat(
 	}
 	return -ENOIOCTLCMD;
 }
+
+static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
+					unsigned long arg)
+{
+	struct snd_timer_user *tu = file->private_data;
+	long ret;
+
+	mutex_lock(&tu->ioctl_lock);
+	ret = __snd_timer_user_ioctl_compat(file, cmd, arg);
+	mutex_unlock(&tu->ioctl_lock);
+	return ret;
+}
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/pci/hda/hda_codec.c linux-libre-3.16.52-gnu/sound/pci/hda/hda_codec.c
--- linux-libre-3.16.51-gnu/sound/pci/hda/hda_codec.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/pci/hda/hda_codec.c	2018-01-01 15:52:14.000000000 -0500
@@ -2791,7 +2791,7 @@ static int get_kctl_0dB_offset(struct sn
 			return -1;
 		if (*step_to_check && *step_to_check != step) {
 			snd_printk(KERN_ERR "hda_codec: Mismatching dB step for vmaster slave (%d!=%d)\n",
--				   *step_to_check, step);
+				   *step_to_check, step);
 			return -1;
 		}
 		*step_to_check = step;
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/soc/codecs/adau17x1.c linux-libre-3.16.52-gnu/sound/soc/codecs/adau17x1.c
--- linux-libre-3.16.51-gnu/sound/soc/codecs/adau17x1.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/soc/codecs/adau17x1.c	2018-01-01 15:52:14.000000000 -0500
@@ -88,6 +88,27 @@ static int adau17x1_pll_event(struct snd
 	return 0;
 }
 
+static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+
+	/*
+	 * If we are capturing, toggle the ADOSR bit in Converter Control 0 to
+	 * avoid losing SNR (workaround from ADI). This must be done after
+	 * the ADC(s) have been enabled. According to the data sheet, it is
+	 * normally illegal to set this bit when the sampling rate is 96 kHz,
+	 * but according to ADI it is acceptable for this workaround.
+	 */
+	regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
+		ADAU17X1_CONVERTER0_ADOSR, ADAU17X1_CONVERTER0_ADOSR);
+	regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
+		ADAU17X1_CONVERTER0_ADOSR, 0);
+
+	return 0;
+}
+
 static const char * const adau17x1_mono_stereo_text[] = {
 	"Stereo",
 	"Mono Left Channel (L+R)",
@@ -119,7 +140,8 @@ static const struct snd_soc_dapm_widget
 	SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0,
 		&adau17x1_dac_mode_mux),
 
-	SND_SOC_DAPM_ADC("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0),
+	SND_SOC_DAPM_ADC_E("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0,
+			   adau17x1_adc_fixup, SND_SOC_DAPM_POST_PMU),
 	SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0),
 	SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0),
 	SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0),
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/soc/codecs/adau17x1.h linux-libre-3.16.52-gnu/sound/soc/codecs/adau17x1.h
--- linux-libre-3.16.51-gnu/sound/soc/codecs/adau17x1.h	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/soc/codecs/adau17x1.h	2018-01-01 15:52:14.000000000 -0500
@@ -120,5 +120,7 @@ bool adau17x1_has_dsp(struct adau *adau)
 
 #define ADAU17X1_CONVERTER0_CONVSR_MASK		0x7
 
+#define ADAU17X1_CONVERTER0_ADOSR		BIT(3)
+
 
 #endif
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/usb/caiaq/device.c linux-libre-3.16.52-gnu/sound/usb/caiaq/device.c
--- linux-libre-3.16.51-gnu/sound/usb/caiaq/device.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/usb/caiaq/device.c	2018-01-01 15:52:14.000000000 -0500
@@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caia
 
 	err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
 	if (err)
-		return err;
+		goto err_kill_urb;
 
-	if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ))
-		return -ENODEV;
+	if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) {
+		err = -ENODEV;
+		goto err_kill_urb;
+	}
 
 	usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
 		   cdev->vendor_name, CAIAQ_USB_STR_LEN);
@@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caia
 
 	setup_card(cdev);
 	return 0;
+
+ err_kill_urb:
+	usb_kill_urb(&cdev->ep1_in_urb);
+	return err;
 }
 
 static int snd_probe(struct usb_interface *intf,
diff -druNp --no-dereference linux-libre-3.16.51-gnu/sound/usb/usx2y/usb_stream.c linux-libre-3.16.52-gnu/sound/usb/usx2y/usb_stream.c
--- linux-libre-3.16.51-gnu/sound/usb/usx2y/usb_stream.c	2017-11-26 08:50:43.000000000 -0500
+++ linux-libre-3.16.52-gnu/sound/usb/usx2y/usb_stream.c	2018-01-01 15:52:14.000000000 -0500
@@ -191,7 +191,8 @@ struct usb_stream *usb_stream_new(struct
 	}
 
 	pg = get_order(read_size);
-	sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
+	sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO|
+					  __GFP_NOWARN, pg);
 	if (!sk->s) {
 		snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
 		goto out;
@@ -211,7 +212,8 @@ struct usb_stream *usb_stream_new(struct
 	pg = get_order(write_size);
 
 	sk->write_page =
-		(void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
+		(void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO|
+					 __GFP_NOWARN, pg);
 	if (!sk->write_page) {
 		snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
 		usb_stream_free(sk);
