diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/arm/boot/dts/bcm5301x.dtsi linux-libre-3.16.46-gnu/arch/arm/boot/dts/bcm5301x.dtsi
--- linux-libre-3.16.45-gnu/arch/arm/boot/dts/bcm5301x.dtsi	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/arm/boot/dts/bcm5301x.dtsi	2017-07-18 13:40:42.000000000 -0400
@@ -52,14 +52,14 @@
 		timer@0200 {
 			compatible = "arm,cortex-a9-global-timer";
 			reg = <0x0200 0x100>;
-			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
 			clocks = <&clk_periph>;
 		};
 
 		local-timer@0600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0x0600 0x100>;
-			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts = <GIC_PPI 13 IRQ_TYPE_EDGE_RISING>;
 			clocks = <&clk_periph>;
 		};
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/arm/kvm/mmu.c linux-libre-3.16.46-gnu/arch/arm/kvm/mmu.c
--- linux-libre-3.16.45-gnu/arch/arm/kvm/mmu.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/arm/kvm/mmu.c	2017-07-18 13:40:42.000000000 -0400
@@ -199,6 +199,12 @@ static void unmap_range(struct kvm *kvm,
 		next = kvm_pgd_addr_end(addr, end);
 		if (!pgd_none(*pgd))
 			unmap_puds(kvm, pgd, addr, next);
+		/*
+		 * If the range is too large, release the kvm->mmu_lock
+		 * to prevent starvation and lockup detector warnings.
+		 */
+		if (kvm && next != end)
+			cond_resched_lock(&kvm->mmu_lock);
 	} while (pgd++, addr = next, addr != end);
 }
 
@@ -553,6 +559,7 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm
  */
 static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)
 {
+	assert_spin_locked(&kvm->mmu_lock);
 	unmap_range(kvm, kvm->arch.pgd, start, size);
 }
 
@@ -637,7 +644,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm
 	if (kvm->arch.pgd == NULL)
 		return;
 
+	spin_lock(&kvm->mmu_lock);
 	unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
+	spin_unlock(&kvm->mmu_lock);
+
 	free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER);
 	kvm->arch.pgd = NULL;
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/metag/include/asm/uaccess.h linux-libre-3.16.46-gnu/arch/metag/include/asm/uaccess.h
--- linux-libre-3.16.45-gnu/arch/metag/include/asm/uaccess.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/metag/include/asm/uaccess.h	2017-07-18 13:40:42.000000000 -0400
@@ -192,20 +192,21 @@ extern long __must_check strnlen_user(co
 
 #define strlen_user(str) strnlen_user(str, 32767)
 
-extern unsigned long __must_check __copy_user_zeroing(void *to,
-						      const void __user *from,
-						      unsigned long n);
+extern unsigned long raw_copy_from_user(void *to, const void __user *from,
+					unsigned long n);
 
 static inline unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+	unsigned long res = n;
 	if (likely(access_ok(VERIFY_READ, from, n)))
-		return __copy_user_zeroing(to, from, n);
-	memset(to, 0, n);
-	return n;
+		res = raw_copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
-#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n)
+#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n)
 #define __copy_from_user_inatomic __copy_from_user
 
 extern unsigned long __must_check __copy_user(void __user *to,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/metag/lib/usercopy.c linux-libre-3.16.46-gnu/arch/metag/lib/usercopy.c
--- linux-libre-3.16.45-gnu/arch/metag/lib/usercopy.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/metag/lib/usercopy.c	2017-07-18 13:40:42.000000000 -0400
@@ -29,7 +29,6 @@
 		COPY						 \
 		"1:\n"						 \
 		"	.section .fixup,\"ax\"\n"		 \
-		"	MOV D1Ar1,#0\n"				 \
 		FIXUP						 \
 		"	MOVT    D1Ar1,#HI(1b)\n"		 \
 		"	JUMP    D1Ar1,#LO(1b)\n"		 \
@@ -260,27 +259,31 @@
 		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
 		"22:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
-		"SUB	%3, %3, #32\n"					\
 		"23:\n"							\
-		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
+		"SUB	%3, %3, #32\n"					\
 		"24:\n"							\
+		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
+		"25:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"26:\n"							\
 		"SUB	%3, %3, #32\n"					\
 		"DCACHE	[%1+#-64], D0Ar6\n"				\
 		"BR	$Lloop"id"\n"					\
 									\
 		"MOV	RAPF, %1\n"					\
-		"25:\n"							\
+		"27:\n"							\
 		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"26:\n"							\
+		"28:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"29:\n"							\
 		"SUB	%3, %3, #32\n"					\
-		"27:\n"							\
+		"30:\n"							\
 		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"28:\n"							\
+		"31:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"32:\n"							\
 		"SUB	%0, %0, #8\n"					\
-		"29:\n"							\
+		"33:\n"							\
 		"SETL	[%0++], D0.7, D1.7\n"				\
 		"SUB	%3, %3, #32\n"					\
 		"1:"							\
@@ -312,11 +315,15 @@
 		"	.long 26b,3b\n"					\
 		"	.long 27b,3b\n"					\
 		"	.long 28b,3b\n"					\
-		"	.long 29b,4b\n"					\
+		"	.long 29b,3b\n"					\
+		"	.long 30b,3b\n"					\
+		"	.long 31b,3b\n"					\
+		"	.long 32b,3b\n"					\
+		"	.long 33b,4b\n"					\
 		"	.previous\n"					\
 		: "=r" (to), "=r" (from), "=r" (ret), "=d" (n)		\
 		: "0" (to), "1" (from), "2" (ret), "3" (n)		\
-		: "D1Ar1", "D0Ar2", "memory")
+		: "D1Ar1", "D0Ar2", "cc", "memory")
 
 /*	rewind 'to' and 'from'  pointers when a fault occurs
  *
@@ -342,7 +349,7 @@
 #define __asm_copy_to_user_64bit_rapf_loop(to,	from, ret, n, id)\
 	__asm_copy_user_64bit_rapf_loop(to, from, ret, n, id,		\
 		"LSR	D0Ar2, D0Ar2, #8\n"				\
-		"AND	D0Ar2, D0Ar2, #0x7\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x7\n"				\
 		"ADDZ	D0Ar2, D0Ar2, #4\n"				\
 		"SUB	D0Ar2, D0Ar2, #1\n"				\
 		"MOV	D1Ar1, #4\n"					\
@@ -403,47 +410,55 @@
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
 		"22:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
-		"SUB	%3, %3, #16\n"					\
 		"23:\n"							\
-		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"24:\n"							\
-		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
 		"SUB	%3, %3, #16\n"					\
-		"25:\n"							\
+		"24:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"26:\n"							\
+		"25:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"26:\n"							\
 		"SUB	%3, %3, #16\n"					\
 		"27:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
 		"28:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"29:\n"							\
+		"SUB	%3, %3, #16\n"					\
+		"30:\n"							\
+		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
+		"31:\n"							\
+		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"32:\n"							\
 		"SUB	%3, %3, #16\n"					\
 		"DCACHE	[%1+#-64], D0Ar6\n"				\
 		"BR	$Lloop"id"\n"					\
 									\
 		"MOV	RAPF, %1\n"					\
-		"29:\n"							\
+		"33:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"30:\n"							\
+		"34:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"35:\n"							\
 		"SUB	%3, %3, #16\n"					\
-		"31:\n"							\
+		"36:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"32:\n"							\
+		"37:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"38:\n"							\
 		"SUB	%3, %3, #16\n"					\
-		"33:\n"							\
+		"39:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"34:\n"							\
+		"40:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"41:\n"							\
 		"SUB	%3, %3, #16\n"					\
-		"35:\n"							\
+		"42:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"36:\n"							\
+		"43:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"44:\n"							\
 		"SUB	%0, %0, #4\n"					\
-		"37:\n"							\
+		"45:\n"							\
 		"SETD	[%0++], D0.7\n"					\
 		"SUB	%3, %3, #16\n"					\
 		"1:"							\
@@ -483,11 +498,19 @@
 		"	.long 34b,3b\n"					\
 		"	.long 35b,3b\n"					\
 		"	.long 36b,3b\n"					\
-		"	.long 37b,4b\n"					\
+		"	.long 37b,3b\n"					\
+		"	.long 38b,3b\n"					\
+		"	.long 39b,3b\n"					\
+		"	.long 40b,3b\n"					\
+		"	.long 41b,3b\n"					\
+		"	.long 42b,3b\n"					\
+		"	.long 43b,3b\n"					\
+		"	.long 44b,3b\n"					\
+		"	.long 45b,4b\n"					\
 		"	.previous\n"					\
 		: "=r" (to), "=r" (from), "=r" (ret), "=d" (n)		\
 		: "0" (to), "1" (from), "2" (ret), "3" (n)		\
-		: "D1Ar1", "D0Ar2", "memory")
+		: "D1Ar1", "D0Ar2", "cc", "memory")
 
 /*	rewind 'to' and 'from'  pointers when a fault occurs
  *
@@ -513,7 +536,7 @@
 #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\
 	__asm_copy_user_32bit_rapf_loop(to, from, ret, n, id,		\
 		"LSR	D0Ar2, D0Ar2, #8\n"				\
-		"AND	D0Ar2, D0Ar2, #0x7\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x7\n"				\
 		"ADDZ	D0Ar2, D0Ar2, #4\n"				\
 		"SUB	D0Ar2, D0Ar2, #1\n"				\
 		"MOV	D1Ar1, #4\n"					\
@@ -538,23 +561,31 @@ unsigned long __copy_user(void __user *p
 	if ((unsigned long) src & 1) {
 		__asm_copy_to_user_1(dst, src, retn);
 		n--;
+		if (retn)
+			return retn + n;
 	}
 	if ((unsigned long) dst & 1) {
 		/* Worst case - byte copy */
 		while (n > 0) {
 			__asm_copy_to_user_1(dst, src, retn);
 			n--;
+			if (retn)
+				return retn + n;
 		}
 	}
 	if (((unsigned long) src & 2) && n >= 2) {
 		__asm_copy_to_user_2(dst, src, retn);
 		n -= 2;
+		if (retn)
+			return retn + n;
 	}
 	if ((unsigned long) dst & 2) {
 		/* Second worst case - word copy */
 		while (n >= 2) {
 			__asm_copy_to_user_2(dst, src, retn);
 			n -= 2;
+			if (retn)
+				return retn + n;
 		}
 	}
 
@@ -569,6 +600,8 @@ unsigned long __copy_user(void __user *p
 		while (n >= 8) {
 			__asm_copy_to_user_8x64(dst, src, retn);
 			n -= 8;
+			if (retn)
+				return retn + n;
 		}
 	}
 	if (n >= RAPF_MIN_BUF_SIZE) {
@@ -581,6 +614,8 @@ unsigned long __copy_user(void __user *p
 		while (n >= 8) {
 			__asm_copy_to_user_8x64(dst, src, retn);
 			n -= 8;
+			if (retn)
+				return retn + n;
 		}
 	}
 #endif
@@ -588,11 +623,15 @@ unsigned long __copy_user(void __user *p
 	while (n >= 16) {
 		__asm_copy_to_user_16(dst, src, retn);
 		n -= 16;
+		if (retn)
+			return retn + n;
 	}
 
 	while (n >= 4) {
 		__asm_copy_to_user_4(dst, src, retn);
 		n -= 4;
+		if (retn)
+			return retn + n;
 	}
 
 	switch (n) {
@@ -609,6 +648,10 @@ unsigned long __copy_user(void __user *p
 		break;
 	}
 
+	/*
+	 * If we get here, retn correctly reflects the number of failing
+	 * bytes.
+	 */
 	return retn;
 }
 EXPORT_SYMBOL(__copy_user);
@@ -617,16 +660,14 @@ EXPORT_SYMBOL(__copy_user);
 	__asm_copy_user_cont(to, from, ret,	\
 		"	GETB D1Ar1,[%1++]\n"	\
 		"2:	SETB [%0++],D1Ar1\n",	\
-		"3:	ADD  %2,%2,#1\n"	\
-		"	SETB [%0++],D1Ar1\n",	\
+		"3:	ADD  %2,%2,#1\n",	\
 		"	.long 2b,3b\n")
 
 #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_user_cont(to, from, ret,		\
 		"	GETW D1Ar1,[%1++]\n"		\
 		"2:	SETW [%0++],D1Ar1\n" COPY,	\
-		"3:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
+		"3:	ADD  %2,%2,#2\n" FIXUP,		\
 		"	.long 2b,3b\n" TENTRY)
 
 #define __asm_copy_from_user_2(to, from, ret) \
@@ -636,145 +677,26 @@ EXPORT_SYMBOL(__copy_user);
 	__asm_copy_from_user_2x_cont(to, from, ret,	\
 		"	GETB D1Ar1,[%1++]\n"		\
 		"4:	SETB [%0++],D1Ar1\n",		\
-		"5:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
+		"5:	ADD  %2,%2,#1\n",		\
 		"	.long 4b,5b\n")
 
 #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_user_cont(to, from, ret,		\
 		"	GETD D1Ar1,[%1++]\n"		\
 		"2:	SETD [%0++],D1Ar1\n" COPY,	\
-		"3:	ADD  %2,%2,#4\n"		\
-		"	SETD [%0++],D1Ar1\n" FIXUP,	\
+		"3:	ADD  %2,%2,#4\n" FIXUP,		\
 		"	.long 2b,3b\n" TENTRY)
 
 #define __asm_copy_from_user_4(to, from, ret) \
 	__asm_copy_from_user_4x_cont(to, from, ret, "", "", "")
 
-#define __asm_copy_from_user_5(to, from, ret) \
-	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"4:	SETB [%0++],D1Ar1\n",		\
-		"5:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 4b,5b\n")
-
-#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	GETW D1Ar1,[%1++]\n"		\
-		"4:	SETW [%0++],D1Ar1\n" COPY,	\
-		"5:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 4b,5b\n" TENTRY)
-
-#define __asm_copy_from_user_6(to, from, ret) \
-	__asm_copy_from_user_6x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_7(to, from, ret) \
-	__asm_copy_from_user_6x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"6:	SETB [%0++],D1Ar1\n",		\
-		"7:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 6b,7b\n")
-
-#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	GETD D1Ar1,[%1++]\n"		\
-		"4:	SETD [%0++],D1Ar1\n" COPY,	\
-		"5:	ADD  %2,%2,#4\n"			\
-		"	SETD [%0++],D1Ar1\n" FIXUP,		\
-		"	.long 4b,5b\n" TENTRY)
-
-#define __asm_copy_from_user_8(to, from, ret) \
-	__asm_copy_from_user_8x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_9(to, from, ret) \
-	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"6:	SETB [%0++],D1Ar1\n",		\
-		"7:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 6b,7b\n")
-
-#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	GETW D1Ar1,[%1++]\n"		\
-		"6:	SETW [%0++],D1Ar1\n" COPY,	\
-		"7:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 6b,7b\n" TENTRY)
-
-#define __asm_copy_from_user_10(to, from, ret) \
-	__asm_copy_from_user_10x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_11(to, from, ret)		\
-	__asm_copy_from_user_10x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"8:	SETB [%0++],D1Ar1\n",		\
-		"9:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 8b,9b\n")
-
-#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	GETD D1Ar1,[%1++]\n"		\
-		"6:	SETD [%0++],D1Ar1\n" COPY,	\
-		"7:	ADD  %2,%2,#4\n"		\
-		"	SETD [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 6b,7b\n" TENTRY)
-
-#define __asm_copy_from_user_12(to, from, ret) \
-	__asm_copy_from_user_12x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_13(to, from, ret) \
-	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"8:	SETB [%0++],D1Ar1\n",		\
-		"9:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 8b,9b\n")
-
-#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	GETW D1Ar1,[%1++]\n"		\
-		"8:	SETW [%0++],D1Ar1\n" COPY,	\
-		"9:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 8b,9b\n" TENTRY)
-
-#define __asm_copy_from_user_14(to, from, ret) \
-	__asm_copy_from_user_14x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_15(to, from, ret) \
-	__asm_copy_from_user_14x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"10:	SETB [%0++],D1Ar1\n",		\
-		"11:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 10b,11b\n")
-
-#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	GETD D1Ar1,[%1++]\n"		\
-		"8:	SETD [%0++],D1Ar1\n" COPY,	\
-		"9:	ADD  %2,%2,#4\n"		\
-		"	SETD [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 8b,9b\n" TENTRY)
-
-#define __asm_copy_from_user_16(to, from, ret) \
-	__asm_copy_from_user_16x_cont(to, from, ret, "", "", "")
-
 #define __asm_copy_from_user_8x64(to, from, ret) \
 	asm volatile (				\
 		"	GETL D0Ar2,D1Ar1,[%1++]\n"	\
 		"2:	SETL [%0++],D0Ar2,D1Ar1\n"	\
 		"1:\n"					\
 		"	.section .fixup,\"ax\"\n"	\
-		"	MOV D1Ar1,#0\n"			\
-		"	MOV D0Ar2,#0\n"			\
 		"3:	ADD  %2,%2,#8\n"		\
-		"	SETL [%0++],D0Ar2,D1Ar1\n"	\
 		"	MOVT    D0Ar2,#HI(1b)\n"	\
 		"	JUMP    D0Ar2,#LO(1b)\n"	\
 		"	.previous\n"			\
@@ -789,36 +711,57 @@ EXPORT_SYMBOL(__copy_user);
  *
  *	Rationale:
  *		A fault occurs while reading from user buffer, which is the
- *		source. Since the fault is at a single address, we only
- *		need to rewind by 8 bytes.
+ *		source.
  *		Since we don't write to kernel buffer until we read first,
  *		the kernel buffer is at the right state and needn't be
- *		corrected.
+ *		corrected, but the source must be rewound to the beginning of
+ *		the block, which is LSM_STEP*8 bytes.
+ *		LSM_STEP is bits 10:8 in TXSTATUS which is already read
+ *		and stored in D0Ar2
+ *
+ *		NOTE: If a fault occurs at the last operation in M{G,S}ETL
+ *			LSM_STEP will be 0. ie: we do 4 writes in our case, if
+ *			a fault happens at the 4th write, LSM_STEP will be 0
+ *			instead of 4. The code copes with that.
  */
 #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id)	\
 	__asm_copy_user_64bit_rapf_loop(to, from, ret, n, id,		\
-		"SUB	%1, %1, #8\n")
+		"LSR	D0Ar2, D0Ar2, #5\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x38\n"				\
+		"ADDZ	D0Ar2, D0Ar2, #32\n"				\
+		"SUB	%1, %1, D0Ar2\n")
 
 /*	rewind 'from' pointer when a fault occurs
  *
  *	Rationale:
  *		A fault occurs while reading from user buffer, which is the
- *		source. Since the fault is at a single address, we only
- *		need to rewind by 4 bytes.
+ *		source.
  *		Since we don't write to kernel buffer until we read first,
  *		the kernel buffer is at the right state and needn't be
- *		corrected.
+ *		corrected, but the source must be rewound to the beginning of
+ *		the block, which is LSM_STEP*4 bytes.
+ *		LSM_STEP is bits 10:8 in TXSTATUS which is already read
+ *		and stored in D0Ar2
+ *
+ *		NOTE: If a fault occurs at the last operation in M{G,S}ETL
+ *			LSM_STEP will be 0. ie: we do 4 writes in our case, if
+ *			a fault happens at the 4th write, LSM_STEP will be 0
+ *			instead of 4. The code copes with that.
  */
 #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id)	\
 	__asm_copy_user_32bit_rapf_loop(to, from, ret, n, id,		\
-		"SUB	%1, %1, #4\n")
+		"LSR	D0Ar2, D0Ar2, #6\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x1c\n"				\
+		"ADDZ	D0Ar2, D0Ar2, #16\n"				\
+		"SUB	%1, %1, D0Ar2\n")
 
 
-/* Copy from user to kernel, zeroing the bytes that were inaccessible in
-   userland.  The return-value is the number of bytes that were
-   inaccessible.  */
-unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
-				  unsigned long n)
+/*
+ * Copy from user to kernel. The return-value is the number of bytes that were
+ * inaccessible.
+ */
+unsigned long raw_copy_from_user(void *pdst, const void __user *psrc,
+				 unsigned long n)
 {
 	register char *dst asm ("A0.2") = pdst;
 	register const char __user *src asm ("A1.2") = psrc;
@@ -830,6 +773,8 @@ unsigned long __copy_user_zeroing(void *
 	if ((unsigned long) src & 1) {
 		__asm_copy_from_user_1(dst, src, retn);
 		n--;
+		if (retn)
+			return retn + n;
 	}
 	if ((unsigned long) dst & 1) {
 		/* Worst case - byte copy */
@@ -837,12 +782,14 @@ unsigned long __copy_user_zeroing(void *
 			__asm_copy_from_user_1(dst, src, retn);
 			n--;
 			if (retn)
-				goto copy_exception_bytes;
+				return retn + n;
 		}
 	}
 	if (((unsigned long) src & 2) && n >= 2) {
 		__asm_copy_from_user_2(dst, src, retn);
 		n -= 2;
+		if (retn)
+			return retn + n;
 	}
 	if ((unsigned long) dst & 2) {
 		/* Second worst case - word copy */
@@ -850,16 +797,10 @@ unsigned long __copy_user_zeroing(void *
 			__asm_copy_from_user_2(dst, src, retn);
 			n -= 2;
 			if (retn)
-				goto copy_exception_bytes;
+				return retn + n;
 		}
 	}
 
-	/* We only need one check after the unalignment-adjustments,
-	   because if both adjustments were done, either both or
-	   neither reference had an exception.  */
-	if (retn != 0)
-		goto copy_exception_bytes;
-
 #ifdef USE_RAPF
 	/* 64 bit copy loop */
 	if (!(((unsigned long) src | (unsigned long) dst) & 7)) {
@@ -872,7 +813,7 @@ unsigned long __copy_user_zeroing(void *
 			__asm_copy_from_user_8x64(dst, src, retn);
 			n -= 8;
 			if (retn)
-				goto copy_exception_bytes;
+				return retn + n;
 		}
 	}
 
@@ -888,7 +829,7 @@ unsigned long __copy_user_zeroing(void *
 			__asm_copy_from_user_8x64(dst, src, retn);
 			n -= 8;
 			if (retn)
-				goto copy_exception_bytes;
+				return retn + n;
 		}
 	}
 #endif
@@ -898,7 +839,7 @@ unsigned long __copy_user_zeroing(void *
 		n -= 4;
 
 		if (retn)
-			goto copy_exception_bytes;
+			return retn + n;
 	}
 
 	/* If we get here, there were no memory read faults.  */
@@ -924,21 +865,8 @@ unsigned long __copy_user_zeroing(void *
 	/* If we get here, retn correctly reflects the number of failing
 	   bytes.  */
 	return retn;
-
- copy_exception_bytes:
-	/* We already have "retn" bytes cleared, and need to clear the
-	   remaining "n" bytes.  A non-optimized simple byte-for-byte in-line
-	   memset is preferred here, since this isn't speed-critical code and
-	   we'd rather have this a leaf-function than calling memset.  */
-	{
-		char *endp;
-		for (endp = dst + n; dst < endp; dst++)
-			*dst = 0;
-	}
-
-	return retn + n;
 }
-EXPORT_SYMBOL(__copy_user_zeroing);
+EXPORT_SYMBOL(raw_copy_from_user);
 
 #define __asm_clear_8x64(to, ret) \
 	asm volatile (					\
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/mips/include/asm/spinlock.h linux-libre-3.16.46-gnu/arch/mips/include/asm/spinlock.h
--- linux-libre-3.16.45-gnu/arch/mips/include/asm/spinlock.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/mips/include/asm/spinlock.h	2017-07-18 13:40:42.000000000 -0400
@@ -73,7 +73,7 @@ static inline void arch_spin_lock(arch_s
 		"	andi	%[ticket], %[ticket], 0xffff		\n"
 		"	bne	%[ticket], %[my_ticket], 4f		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
-		"2:							\n"
+		"2:	.insn						\n"
 		"	.subsection 2					\n"
 		"4:	andi	%[ticket], %[ticket], 0xffff		\n"
 		"	sll	%[ticket], 5				\n"
@@ -181,7 +181,7 @@ static inline unsigned int arch_spin_try
 		"	sc	%[ticket], %[ticket_ptr]		\n"
 		"	beqz	%[ticket], 1b				\n"
 		"	 li	%[ticket], 1				\n"
-		"2:							\n"
+		"2:	.insn						\n"
 		"	.subsection 2					\n"
 		"3:	b	2b					\n"
 		"	 li	%[ticket], 0				\n"
@@ -364,7 +364,7 @@ static inline int arch_read_trylock(arch
 		"	.set	reorder					\n"
 		__WEAK_LLSC_MB
 		"	li	%2, 1					\n"
-		"2:							\n"
+		"2:	.insn						\n"
 		: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
 		: "m" (rw->lock)
 		: "memory");
@@ -404,7 +404,7 @@ static inline int arch_write_trylock(arc
 			"	lui	%1, 0x8000			\n"
 			"	sc	%1, %0				\n"
 			"	li	%2, 1				\n"
-			"2:						\n"
+			"2:	.insn					\n"
 			: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
 			: "m" (rw->lock)
 			: "memory");
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/mips/kernel/kgdb.c linux-libre-3.16.46-gnu/arch/mips/kernel/kgdb.c
--- linux-libre-3.16.45-gnu/arch/mips/kernel/kgdb.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/mips/kernel/kgdb.c	2017-07-18 13:40:42.000000000 -0400
@@ -244,9 +244,6 @@ static int compute_signal(int tt)
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
 	int reg;
-	struct thread_info *ti = task_thread_info(p);
-	unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
-	struct pt_regs *regs = (struct pt_regs *)ksp - 1;
 #if (KGDB_GDB_REG_SIZE == 32)
 	u32 *ptr = (u32 *)gdb_regs;
 #else
@@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigne
 #endif
 
 	for (reg = 0; reg < 16; reg++)
-		*(ptr++) = regs->regs[reg];
+		*(ptr++) = 0;
 
 	/* S0 - S7 */
-	for (reg = 16; reg < 24; reg++)
-		*(ptr++) = regs->regs[reg];
+	*(ptr++) = p->thread.reg16;
+	*(ptr++) = p->thread.reg17;
+	*(ptr++) = p->thread.reg18;
+	*(ptr++) = p->thread.reg19;
+	*(ptr++) = p->thread.reg20;
+	*(ptr++) = p->thread.reg21;
+	*(ptr++) = p->thread.reg22;
+	*(ptr++) = p->thread.reg23;
 
 	for (reg = 24; reg < 28; reg++)
 		*(ptr++) = 0;
 
 	/* GP, SP, FP, RA */
-	for (reg = 28; reg < 32; reg++)
-		*(ptr++) = regs->regs[reg];
+	*(ptr++) = (long)p;
+	*(ptr++) = p->thread.reg29;
+	*(ptr++) = p->thread.reg30;
+	*(ptr++) = p->thread.reg31;
 
-	*(ptr++) = regs->cp0_status;
-	*(ptr++) = regs->lo;
-	*(ptr++) = regs->hi;
-	*(ptr++) = regs->cp0_badvaddr;
-	*(ptr++) = regs->cp0_cause;
-	*(ptr++) = regs->cp0_epc;
+	*(ptr++) = p->thread.cp0_status;
+
+	/* lo, hi */
+	*(ptr++) = 0;
+	*(ptr++) = 0;
+
+	/*
+	 * BadVAddr, Cause
+	 * Ideally these would come from the last exception frame up the stack
+	 * but that requires unwinding, otherwise we can't know much for sure.
+	 */
+	*(ptr++) = 0;
+	*(ptr++) = 0;
+
+	/*
+	 * PC
+	 * use return address (RA), i.e. the moment after return from resume()
+	 */
+	*(ptr++) = p->thread.reg31;
 }
 
 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/powerpc/boot/zImage.lds.S linux-libre-3.16.46-gnu/arch/powerpc/boot/zImage.lds.S
--- linux-libre-3.16.45-gnu/arch/powerpc/boot/zImage.lds.S	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/powerpc/boot/zImage.lds.S	2017-07-18 13:40:42.000000000 -0400
@@ -68,6 +68,7 @@ SECTIONS
   }
 
 #ifdef CONFIG_PPC64_BOOT_WRAPPER
+  . = ALIGN(256);
   .got :
   {
     __toc_start = .;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/powerpc/include/asm/ppc_asm.h linux-libre-3.16.46-gnu/arch/powerpc/include/asm/ppc_asm.h
--- linux-libre-3.16.45-gnu/arch/powerpc/include/asm/ppc_asm.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/powerpc/include/asm/ppc_asm.h	2017-07-18 13:40:42.000000000 -0400
@@ -217,13 +217,6 @@ name: \
 	addi r2,r2,(.TOC.-0b)@l; \
 	.localentry name,.-name
 
-#define _KPROBE(name) \
-	.section ".kprobes.text","a"; \
-	.align 2 ; \
-	.type name,@function; \
-	.globl name; \
-name:
-
 #define DOTSYM(a)	a
 
 #else
@@ -247,20 +240,6 @@ GLUE(.,name):
 
 #define _GLOBAL_TOC(name) _GLOBAL(name)
 
-#define _KPROBE(name) \
-	.section ".kprobes.text","a"; \
-	.align 2 ; \
-	.globl name; \
-	.globl GLUE(.,name); \
-	.section ".opd","aw"; \
-name: \
-	.quad GLUE(.,name); \
-	.quad .TOC.@tocbase; \
-	.quad 0; \
-	.previous; \
-	.type GLUE(.,name),@function; \
-GLUE(.,name):
-
 #define DOTSYM(a)	GLUE(.,a)
 
 #endif
@@ -279,13 +258,22 @@ n:
 
 #define _GLOBAL_TOC(name) _GLOBAL(name)
 
-#define _KPROBE(n)	\
-	.section ".kprobes.text","a";	\
-	.globl	n;	\
-n:
-
 #endif
 
+/*
+ * __kprobes (the C annotation) puts the symbol into the .kprobes.text
+ * section, which gets emitted at the end of regular text.
+ *
+ * _ASM_NOKPROBE_SYMBOL and NOKPROBE_SYMBOL just adds the symbol to
+ * a blacklist. The former is for core kprobe functions/data, the
+ * latter is for those that incdentially must be excluded from probing
+ * and allows them to be linked at more optimal location within text.
+ */
+#define _ASM_NOKPROBE_SYMBOL(entry)			\
+	.pushsection "_kprobe_blacklist","aw";		\
+	PPC_LONG (entry) ;				\
+	.popsection
+
 /* 
  * LOAD_REG_IMMEDIATE(rn, expr)
  *   Loads the value of the constant expression 'expr' into register 'rn'
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/powerpc/kernel/align.c linux-libre-3.16.46-gnu/arch/powerpc/kernel/align.c
--- linux-libre-3.16.45-gnu/arch/powerpc/kernel/align.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/powerpc/kernel/align.c	2017-07-18 13:40:42.000000000 -0400
@@ -808,14 +808,25 @@ int fix_alignment(struct pt_regs *regs)
 	nb = aligninfo[instr].len;
 	flags = aligninfo[instr].flags;
 
-	/* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */
-	if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) {
-		nb = 8;
-		flags = LD+SW;
-	} else if (IS_XFORM(instruction) &&
-		   ((instruction >> 1) & 0x3ff) == 660) {
-		nb = 8;
-		flags = ST+SW;
+	/*
+	 * Handle some cases which give overlaps in the DSISR values.
+	 */
+	if (IS_XFORM(instruction)) {
+		switch (get_xop(instruction)) {
+		case 532:	/* ldbrx */
+			nb = 8;
+			flags = LD+SW;
+			break;
+		case 660:	/* stdbrx */
+			nb = 8;
+			flags = ST+SW;
+			break;
+		case 20:	/* lwarx */
+		case 84:	/* ldarx */
+		case 116:	/* lharx */
+		case 276:	/* lqarx */
+			return 0;	/* not emulated ever */
+		}
 	}
 
 	/* Byteswap little endian loads and stores */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/powerpc/kernel/misc_32.S linux-libre-3.16.46-gnu/arch/powerpc/kernel/misc_32.S
--- linux-libre-3.16.45-gnu/arch/powerpc/kernel/misc_32.S	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/powerpc/kernel/misc_32.S	2017-07-18 13:40:42.000000000 -0400
@@ -345,7 +345,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID
  *
  * flush_icache_range(unsigned long start, unsigned long stop)
  */
-_KPROBE(flush_icache_range)
+_GLOBAL(flush_icache_range)
 BEGIN_FTR_SECTION
 	PURGE_PREFETCHED_INS
 	blr				/* for 601, do nothing */
@@ -376,6 +376,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I
 	sync				/* additional sync needed on g4 */
 	isync
 	blr
+_ASM_NOKPROBE_SYMBOL(flush_icache_range)
+
 /*
  * Write any modified data cache blocks out to memory.
  * Does not invalidate the corresponding cache lines (especially for
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/powerpc/kernel/misc_64.S linux-libre-3.16.46-gnu/arch/powerpc/kernel/misc_64.S
--- linux-libre-3.16.45-gnu/arch/powerpc/kernel/misc_64.S	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/powerpc/kernel/misc_64.S	2017-07-18 13:40:42.000000000 -0400
@@ -65,7 +65,7 @@ PPC64_CACHES:
  *   flush all bytes from start through stop-1 inclusive
  */
 
-_KPROBE(flush_icache_range)
+_GLOBAL_TOC(flush_icache_range)
 BEGIN_FTR_SECTION
 	PURGE_PREFETCHED_INS
 	blr
@@ -108,7 +108,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I
 	bdnz	2b
 	isync
 	blr
-	.previous .text
+_ASM_NOKPROBE_SYMBOL(flush_icache_range)
+
 /*
  * Like above, but only do the D-cache.
  *
@@ -116,7 +117,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I
  *
  *    flush all bytes from start to stop-1 inclusive
  */
-_GLOBAL(flush_dcache_range)
+_GLOBAL_TOC(flush_dcache_range)
 
 /*
  * Flush the data cache to memory 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/powerpc/kernel/setup_64.c linux-libre-3.16.46-gnu/arch/powerpc/kernel/setup_64.c
--- linux-libre-3.16.45-gnu/arch/powerpc/kernel/setup_64.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/powerpc/kernel/setup_64.c	2017-07-18 13:40:42.000000000 -0400
@@ -198,6 +198,15 @@ static void fixup_boot_paca(void)
 
 static void cpu_ready_for_interrupts(void)
 {
+	/*
+	 * Fixup HFSCR:TM based on CPU features. The bit is set by our
+	 * early asm init because at that point we haven't updated our
+	 * CPU features from firmware and device-tree. Here we have,
+	 * so let's do it.
+	 */
+	if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP))
+		mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM);
+
 	/* Set IR and DR in PACA MSR */
 	get_paca()->kernel_msr = MSR_KERNEL;
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/s390/boot/compressed/misc.c linux-libre-3.16.46-gnu/arch/s390/boot/compressed/misc.c
--- linux-libre-3.16.45-gnu/arch/s390/boot/compressed/misc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/s390/boot/compressed/misc.c	2017-07-18 13:40:42.000000000 -0400
@@ -142,31 +142,34 @@ static void check_ipl_parmblock(void *st
 
 unsigned long decompress_kernel(void)
 {
-	unsigned long output_addr;
-	unsigned char *output;
+	void *output, *kernel_end;
 
-	output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
-	check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
-	memset(&_bss, 0, &_ebss - &_bss);
-	free_mem_ptr = (unsigned long)&_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-	output = (unsigned char *) output_addr;
+	output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE);
+	kernel_end = output + SZ__bss_start;
+	check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/*
 	 * Move the initrd right behind the end of the decompressed
-	 * kernel image.
+	 * kernel image. This also prevents initrd corruption caused by
+	 * bss clearing since kernel_end will always be located behind the
+	 * current bss section..
 	 */
-	if (INITRD_START && INITRD_SIZE &&
-	    INITRD_START < (unsigned long) output + SZ__bss_start) {
-		check_ipl_parmblock(output + SZ__bss_start,
-				    INITRD_START + INITRD_SIZE);
-		memmove(output + SZ__bss_start,
-			(void *) INITRD_START, INITRD_SIZE);
-		INITRD_START = (unsigned long) output + SZ__bss_start;
+	if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
+		check_ipl_parmblock(kernel_end, INITRD_SIZE);
+		memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
+		INITRD_START = (unsigned long) kernel_end;
 	}
 #endif
 
+	/*
+	 * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be
+	 * initialized afterwards since they reside in bss.
+	 */
+	memset(&_bss, 0, &_ebss - &_bss);
+	free_mem_ptr = (unsigned long) &_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
 	puts("Uncompressing Linux... ");
 	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
 	puts("Ok, booting the kernel.\n");
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/s390/include/asm/pgtable.h linux-libre-3.16.46-gnu/arch/s390/include/asm/pgtable.h
--- linux-libre-3.16.45-gnu/arch/s390/include/asm/pgtable.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/s390/include/asm/pgtable.h	2017-07-18 13:40:42.000000000 -0400
@@ -868,6 +868,8 @@ static inline void set_pte_at(struct mm_
 {
 	pgste_t pgste;
 
+	if (pte_present(entry))
+		pte_val(entry) &= ~_PAGE_UNUSED;
 	if (mm_has_pgste(mm)) {
 		pgste = pgste_get_lock(ptep);
 		pgste_val(pgste) &= ~_PGSTE_GPS_ZERO;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/s390/include/asm/uaccess.h linux-libre-3.16.46-gnu/arch/s390/include/asm/uaccess.h
--- linux-libre-3.16.45-gnu/arch/s390/include/asm/uaccess.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/s390/include/asm/uaccess.h	2017-07-18 13:40:42.000000000 -0400
@@ -148,7 +148,7 @@ unsigned long __must_check __copy_to_use
 		"	jg	2b\n"				\
 		".popsection\n"					\
 		EX_TABLE(0b,3b) EX_TABLE(1b,3b)			\
-		: "=d" (__rc), "=Q" (*(to))			\
+		: "=d" (__rc), "+Q" (*(to))			\
 		: "d" (size), "Q" (*(from)),			\
 		  "d" (__reg0), "K" (-EFAULT)			\
 		: "cc");					\
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/s390/mm/pgtable.c linux-libre-3.16.46-gnu/arch/s390/mm/pgtable.c
--- linux-libre-3.16.45-gnu/arch/s390/mm/pgtable.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/s390/mm/pgtable.c	2017-07-18 13:40:42.000000000 -0400
@@ -1411,11 +1411,28 @@ EXPORT_SYMBOL_GPL(s390_enable_skey);
  */
 bool gmap_test_and_clear_dirty(unsigned long address, struct gmap *gmap)
 {
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
 	pte_t *pte;
 	spinlock_t *ptl;
 	bool dirty = false;
 
-	pte = get_locked_pte(gmap->mm, address, &ptl);
+	pgd = pgd_offset(gmap->mm, address);
+	pud = pud_alloc(gmap->mm, pgd, address);
+	if (!pud)
+		return false;
+	pmd = pmd_alloc(gmap->mm, pud, address);
+	if (!pmd)
+		return false;
+	/* We can't run guests backed by huge pages, but userspace can
+	 * still set them up and then try to migrate them without any
+	 * migration support.
+	 */
+	if (pmd_large(*pmd))
+		return true;
+
+	pte = pte_alloc_map_lock(gmap->mm, pmd, address, &ptl);
 	if (unlikely(!pte))
 		return false;
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/include/asm/elf.h linux-libre-3.16.46-gnu/arch/x86/include/asm/elf.h
--- linux-libre-3.16.45-gnu/arch/x86/include/asm/elf.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/include/asm/elf.h	2017-07-18 13:40:42.000000000 -0400
@@ -277,7 +277,7 @@ struct task_struct;
 
 #define	ARCH_DLINFO_IA32						\
 do {									\
-	if (vdso32_enabled) {						\
+	if (VDSO_CURRENT_BASE) {					\
 		NEW_AUX_ENT(AT_SYSINFO,	VDSO_ENTRY);			\
 		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);	\
 	}								\
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c linux-libre-3.16.46-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c
--- linux-libre-3.16.45-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c	2017-07-18 13:40:42.000000000 -0400
@@ -268,6 +268,8 @@ static void intel_pmu_lbr_read_32(struct
 		cpuc->lbr_entries[i].to		= msr_lastbranch.to;
 		cpuc->lbr_entries[i].mispred	= 0;
 		cpuc->lbr_entries[i].predicted	= 0;
+		cpuc->lbr_entries[i].in_tx	= 0;
+		cpuc->lbr_entries[i].abort	= 0;
 		cpuc->lbr_entries[i].reserved	= 0;
 	}
 	cpuc->lbr_stack.nr = i;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/kernel/ftrace.c linux-libre-3.16.46-gnu/arch/x86/kernel/ftrace.c
--- linux-libre-3.16.45-gnu/arch/x86/kernel/ftrace.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/kernel/ftrace.c	2017-07-18 13:40:42.000000000 -0400
@@ -703,6 +703,18 @@ void prepare_ftrace_return(unsigned long
 	unsigned long return_hooker = (unsigned long)
 				&return_to_handler;
 
+	/*
+	 * When resuming from suspend-to-ram, this function can be indirectly
+	 * called from early CPU startup code while the CPU is in real mode,
+	 * which would fail miserably.  Make sure the stack pointer is a
+	 * virtual address.
+	 *
+	 * This check isn't as accurate as virt_addr_valid(), but it should be
+	 * good enough for this purpose, and it's fast.
+	 */
+	if (unlikely((long)__builtin_frame_address(0) >= 0))
+		return;
+
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
 		return;
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/kernel/kprobes/common.h linux-libre-3.16.46-gnu/arch/x86/kernel/kprobes/common.h
--- linux-libre-3.16.45-gnu/arch/x86/kernel/kprobes/common.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/kernel/kprobes/common.h	2017-07-18 13:40:42.000000000 -0400
@@ -67,7 +67,7 @@
 #endif
 
 /* Ensure if the instruction can be boostable */
-extern int can_boost(kprobe_opcode_t *instruction);
+extern int can_boost(kprobe_opcode_t *instruction, void *addr);
 /* Recover instruction if given address is probed */
 extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
 					 unsigned long addr);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/kernel/kprobes/core.c linux-libre-3.16.46-gnu/arch/x86/kernel/kprobes/core.c
--- linux-libre-3.16.45-gnu/arch/x86/kernel/kprobes/core.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/kernel/kprobes/core.c	2017-07-18 13:40:42.000000000 -0400
@@ -163,12 +163,12 @@ NOKPROBE_SYMBOL(skip_prefixes);
  * Returns non-zero if opcode is boostable.
  * RIP relative instructions are adjusted at copying time in 64 bits mode
  */
-int can_boost(kprobe_opcode_t *opcodes)
+int can_boost(kprobe_opcode_t *opcodes, void *addr)
 {
 	kprobe_opcode_t opcode;
 	kprobe_opcode_t *orig_opcodes = opcodes;
 
-	if (search_exception_tables((unsigned long)opcodes))
+	if (search_exception_tables((unsigned long)addr))
 		return 0;	/* Page fault may occur on this address. */
 
 retry:
@@ -385,7 +385,7 @@ static int arch_copy_kprobe(struct kprob
 	 * __copy_instruction can modify the displacement of the instruction,
 	 * but it doesn't affect boostable check.
 	 */
-	if (can_boost(p->ainsn.insn))
+	if (can_boost(p->ainsn.insn, p->addr))
 		p->ainsn.boostable = 0;
 	else
 		p->ainsn.boostable = -1;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/kernel/kprobes/opt.c linux-libre-3.16.46-gnu/arch/x86/kernel/kprobes/opt.c
--- linux-libre-3.16.45-gnu/arch/x86/kernel/kprobes/opt.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/kernel/kprobes/opt.c	2017-07-18 13:40:42.000000000 -0400
@@ -177,7 +177,7 @@ static int copy_optimized_instructions(u
 
 	while (len < RELATIVEJUMP_SIZE) {
 		ret = __copy_instruction(dest + len, src + len);
-		if (!ret || !can_boost(dest + len))
+		if (!ret || !can_boost(dest + len, src + len))
 			return -EINVAL;
 		len += ret;
 	}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/mm/init.c linux-libre-3.16.46-gnu/arch/x86/mm/init.c
--- linux-libre-3.16.45-gnu/arch/x86/mm/init.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/mm/init.c	2017-07-18 13:40:42.000000000 -0400
@@ -573,21 +573,40 @@ void __init init_mem_mapping(void)
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address
  * is valid. The argument is a physical page number.
  *
- *
- * On x86, access has to be given to the first megabyte of ram because that area
- * contains bios code and data regions used by X and dosemu and similar apps.
- * Access has to be given to non-kernel-ram areas as well, these contain the PCI
- * mmio resources as well as potential bios/acpi data regions.
+ * On x86, access has to be given to the first megabyte of RAM because that
+ * area traditionally contains BIOS code and data regions used by X, dosemu,
+ * and similar apps. Since they map the entire memory range, the whole range
+ * must be allowed (for mapping), but any areas that would otherwise be
+ * disallowed are flagged as being "zero filled" instead of rejected.
+ * Access has to be given to non-kernel-ram areas as well, these contain the
+ * PCI mmio resources as well as potential bios/acpi data regions.
  */
 int devmem_is_allowed(unsigned long pagenr)
 {
-	if (pagenr < 256)
-		return 1;
-	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
+	if (page_is_ram(pagenr)) {
+		/*
+		 * For disallowed memory regions in the low 1MB range,
+		 * request that the page be shown as all zeros.
+		 */
+		if (pagenr < 256)
+			return 2;
+
 		return 0;
-	if (!page_is_ram(pagenr))
-		return 1;
-	return 0;
+	}
+
+	/*
+	 * This must follow RAM test, since System RAM is considered a
+	 * restricted resource under CONFIG_STRICT_IOMEM.
+	 */
+	if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) {
+		/* Low 1MB bypasses iomem restrictions. */
+		if (pagenr < 256)
+			return 1;
+
+		return 0;
+	}
+
+	return 1;
 }
 
 void free_init_pages(char *what, unsigned long begin, unsigned long end)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/pci/xen.c linux-libre-3.16.46-gnu/arch/x86/pci/xen.c
--- linux-libre-3.16.45-gnu/arch/x86/pci/xen.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/pci/xen.c	2017-07-18 13:40:42.000000000 -0400
@@ -228,23 +228,14 @@ static int xen_hvm_setup_msi_irqs(struct
 		return 1;
 
 	list_for_each_entry(msidesc, &dev->msi_list, list) {
-		__read_msi_msg(msidesc, &msg);
-		pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
-			((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
-		if (msg.data != XEN_PIRQ_MSI_DATA ||
-		    xen_irq_from_pirq(pirq) < 0) {
-			pirq = xen_allocate_pirq_msi(dev, msidesc);
-			if (pirq < 0) {
-				irq = -ENODEV;
-				goto error;
-			}
-			xen_msi_compose_msg(dev, pirq, &msg);
-			__write_msi_msg(msidesc, &msg);
-			dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
-		} else {
-			dev_dbg(&dev->dev,
-				"xen: msi already bound to pirq=%d\n", pirq);
+		pirq = xen_allocate_pirq_msi(dev, msidesc);
+		if (pirq < 0) {
+			irq = -ENODEV;
+			goto error;
 		}
+		xen_msi_compose_msg(dev, pirq, &msg);
+		__write_msi_msg(msidesc, &msg);
+		dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
 		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
 					       (type == PCI_CAP_ID_MSI) ? nvec : 1,
 					       (type == PCI_CAP_ID_MSIX) ?
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/platform/intel-mid/device_libs/platform_wdt.c linux-libre-3.16.46-gnu/arch/x86/platform/intel-mid/device_libs/platform_wdt.c
--- linux-libre-3.16.45-gnu/arch/x86/platform/intel-mid/device_libs/platform_wdt.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/platform/intel-mid/device_libs/platform_wdt.c	2017-07-18 13:40:42.000000000 -0400
@@ -17,7 +17,7 @@
 #include <asm/intel-mid.h>
 #include <asm/io_apic.h>
 
-#define TANGIER_EXT_TIMER0_MSI 15
+#define TANGIER_EXT_TIMER0_MSI 12
 
 static struct platform_device wdt_dev = {
 	.name = "intel_mid_wdt",
diff -druNp --no-dereference linux-libre-3.16.45-gnu/arch/x86/vdso/vdso32-setup.c linux-libre-3.16.46-gnu/arch/x86/vdso/vdso32-setup.c
--- linux-libre-3.16.45-gnu/arch/x86/vdso/vdso32-setup.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/arch/x86/vdso/vdso32-setup.c	2017-07-18 13:40:42.000000000 -0400
@@ -31,8 +31,10 @@ static int __init vdso32_setup(char *s)
 {
 	vdso32_enabled = simple_strtoul(s, NULL, 0);
 
-	if (vdso32_enabled > 1)
+	if (vdso32_enabled > 1) {
 		pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n");
+		vdso32_enabled = 0;
+	}
 
 	return 1;
 }
@@ -89,13 +91,18 @@ subsys_initcall(sysenter_setup);
 /* Register vsyscall32 into the ABI table */
 #include <linux/sysctl.h>
 
+static const int zero;
+static const int one = 1;
+
 static struct ctl_table abi_table2[] = {
 	{
 		.procname	= "vsyscall32",
 		.data		= &vdso32_enabled,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= (int *)&zero,
+		.extra2		= (int *)&one,
 	},
 	{}
 };
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/acpi/acpi_platform.c linux-libre-3.16.46-gnu/drivers/acpi/acpi_platform.c
--- linux-libre-3.16.45-gnu/drivers/acpi/acpi_platform.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/acpi/acpi_platform.c	2017-07-18 13:40:42.000000000 -0400
@@ -23,9 +23,11 @@
 ACPI_MODULE_NAME("platform");
 
 static const struct acpi_device_id forbidden_id_list[] = {
-	{"PNP0000", 0},	/* PIC */
-	{"PNP0100", 0},	/* Timer */
-	{"PNP0200", 0},	/* AT DMA Controller */
+	{"PNP0000",  0},	/* PIC */
+	{"PNP0100",  0},	/* Timer */
+	{"PNP0200",  0},	/* AT DMA Controller */
+	{"ACPI0009", 0},	/* IOxAPIC */
+	{"ACPI000A", 0},	/* IOAPIC */
 	{"", 0},
 };
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/acpi/apei/ghes.c linux-libre-3.16.46-gnu/drivers/acpi/apei/ghes.c
--- linux-libre-3.16.45-gnu/drivers/acpi/apei/ghes.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/acpi/apei/ghes.c	2017-07-18 13:40:42.000000000 -0400
@@ -1020,6 +1020,7 @@ static int ghes_remove(struct platform_d
 		if (list_empty(&ghes_sci))
 			unregister_acpi_hed_notifier(&ghes_notifier_sci);
 		mutex_unlock(&ghes_list_mutex);
+		synchronize_rcu();
 		break;
 	case ACPI_HEST_NOTIFY_NMI:
 		mutex_lock(&ghes_list_mutex);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/acpi/Makefile linux-libre-3.16.46-gnu/drivers/acpi/Makefile
--- linux-libre-3.16.45-gnu/drivers/acpi/Makefile	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/acpi/Makefile	2017-07-18 13:40:42.000000000 -0400
@@ -2,7 +2,6 @@
 # Makefile for the Linux ACPI interpreter
 #
 
-ccflags-y			:= -Os
 ccflags-$(CONFIG_ACPI_DEBUG)	+= -DACPI_DEBUG_OUTPUT
 
 #
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/acpi/power.c linux-libre-3.16.46-gnu/drivers/acpi/power.c
--- linux-libre-3.16.45-gnu/drivers/acpi/power.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/acpi/power.c	2017-07-18 13:40:42.000000000 -0400
@@ -201,6 +201,7 @@ static int acpi_power_get_list_state(str
 		return -EINVAL;
 
 	/* The state of the list is 'on' IFF all resources are 'on'. */
+	cur_state = 0;
 	list_for_each_entry(entry, list, node) {
 		struct acpi_power_resource *resource = entry->resource;
 		acpi_handle handle = resource->device.handle;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/block/xen-blkback/blkback.c linux-libre-3.16.46-gnu/drivers/block/xen-blkback/blkback.c
--- linux-libre-3.16.45-gnu/drivers/block/xen-blkback/blkback.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/block/xen-blkback/blkback.c	2017-07-18 13:40:42.000000000 -0400
@@ -1346,33 +1346,34 @@ static int dispatch_rw_block_io(struct x
 static void make_response(struct xen_blkif *blkif, u64 id,
 			  unsigned short op, int st)
 {
-	struct blkif_response  resp;
+	struct blkif_response *resp;
 	unsigned long     flags;
 	union blkif_back_rings *blk_rings = &blkif->blk_rings;
 	int notify;
 
-	resp.id        = id;
-	resp.operation = op;
-	resp.status    = st;
-
 	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
 	/* Place on the response ring for the relevant domain. */
 	switch (blkif->blk_protocol) {
 	case BLKIF_PROTOCOL_NATIVE:
-		memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt),
-		       &resp, sizeof(resp));
+		resp = RING_GET_RESPONSE(&blk_rings->native,
+					 blk_rings->native.rsp_prod_pvt);
 		break;
 	case BLKIF_PROTOCOL_X86_32:
-		memcpy(RING_GET_RESPONSE(&blk_rings->x86_32, blk_rings->x86_32.rsp_prod_pvt),
-		       &resp, sizeof(resp));
+		resp = RING_GET_RESPONSE(&blk_rings->x86_32,
+					 blk_rings->x86_32.rsp_prod_pvt);
 		break;
 	case BLKIF_PROTOCOL_X86_64:
-		memcpy(RING_GET_RESPONSE(&blk_rings->x86_64, blk_rings->x86_64.rsp_prod_pvt),
-		       &resp, sizeof(resp));
+		resp = RING_GET_RESPONSE(&blk_rings->x86_64,
+					 blk_rings->x86_64.rsp_prod_pvt);
 		break;
 	default:
 		BUG();
 	}
+
+	resp->id        = id;
+	resp->operation = op;
+	resp->status    = st;
+
 	blk_rings->common.rsp_prod_pvt++;
 	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify);
 	spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/block/xen-blkback/common.h linux-libre-3.16.46-gnu/drivers/block/xen-blkback/common.h
--- linux-libre-3.16.45-gnu/drivers/block/xen-blkback/common.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/block/xen-blkback/common.h	2017-07-18 13:40:42.000000000 -0400
@@ -70,9 +70,8 @@
 struct blkif_common_request {
 	char dummy;
 };
-struct blkif_common_response {
-	char dummy;
-};
+
+/* i386 protocol version */
 
 struct blkif_x86_32_request_rw {
 	uint8_t        nr_segments;  /* number of segments                   */
@@ -124,14 +123,6 @@ struct blkif_x86_32_request {
 	} u;
 } __attribute__((__packed__));
 
-/* i386 protocol version */
-#pragma pack(push, 4)
-struct blkif_x86_32_response {
-	uint64_t        id;              /* copied from request */
-	uint8_t         operation;       /* copied from request */
-	int16_t         status;          /* BLKIF_RSP_???       */
-};
-#pragma pack(pop)
 /* x86_64 protocol version */
 
 struct blkif_x86_64_request_rw {
@@ -188,18 +179,12 @@ struct blkif_x86_64_request {
 	} u;
 } __attribute__((__packed__));
 
-struct blkif_x86_64_response {
-	uint64_t       __attribute__((__aligned__(8))) id;
-	uint8_t         operation;       /* copied from request */
-	int16_t         status;          /* BLKIF_RSP_???       */
-};
-
 DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
-		  struct blkif_common_response);
+		  struct blkif_response);
 DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
-		  struct blkif_x86_32_response);
+		  struct blkif_response __packed);
 DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
-		  struct blkif_x86_64_response);
+		  struct blkif_response);
 
 union blkif_back_rings {
 	struct blkif_back_ring        native;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/block/zram/zram_drv.c linux-libre-3.16.46-gnu/drivers/block/zram/zram_drv.c
--- linux-libre-3.16.45-gnu/drivers/block/zram/zram_drv.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/block/zram/zram_drv.c	2017-07-18 13:40:42.000000000 -0400
@@ -345,13 +345,13 @@ static int zram_decompress_page(struct z
 
 	if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) {
 		read_unlock(&meta->tb_lock);
-		clear_page(mem);
+		memset(mem, 0, PAGE_SIZE);
 		return 0;
 	}
 
 	cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO);
 	if (size == PAGE_SIZE)
-		copy_page(mem, cmem);
+		memcpy(mem, cmem, PAGE_SIZE);
 	else
 		ret = zcomp_decompress(zram->comp, cmem, size, mem);
 	zs_unmap_object(meta->mem_pool, handle);
@@ -501,7 +501,7 @@ static int zram_bvec_write(struct zram *
 
 	if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) {
 		src = kmap_atomic(page);
-		copy_page(cmem, src);
+		memcpy(cmem, src, PAGE_SIZE);
 		kunmap_atomic(src);
 	} else {
 		memcpy(cmem, src, clen);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/char/lp.c linux-libre-3.16.46-gnu/drivers/char/lp.c
--- linux-libre-3.16.45-gnu/drivers/char/lp.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/char/lp.c	2017-07-18 13:40:42.000000000 -0400
@@ -859,7 +859,11 @@ static int __init lp_setup (char *str)
 	} else if (!strcmp(str, "auto")) {
 		parport_nr[0] = LP_PARPORT_AUTO;
 	} else if (!strcmp(str, "none")) {
-		parport_nr[parport_ptr++] = LP_PARPORT_NONE;
+		if (parport_ptr < LP_NO)
+			parport_nr[parport_ptr++] = LP_PARPORT_NONE;
+		else
+			printk(KERN_INFO "lp: too many ports, %s ignored.\n",
+			       str);
 	} else if (!strcmp(str, "reset")) {
 		reset = 1;
 	}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/char/mem.c linux-libre-3.16.46-gnu/drivers/char/mem.c
--- linux-libre-3.16.45-gnu/drivers/char/mem.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/char/mem.c	2017-07-18 13:40:42.000000000 -0400
@@ -59,6 +59,10 @@ static inline int valid_mmap_phys_addr_r
 #endif
 
 #ifdef CONFIG_STRICT_DEVMEM
+static inline int page_is_allowed(unsigned long pfn)
+{
+	return devmem_is_allowed(pfn);
+}
 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
 {
 	u64 from = ((u64)pfn) << PAGE_SHIFT;
@@ -78,6 +82,10 @@ static inline int range_is_allowed(unsig
 	return 1;
 }
 #else
+static inline int page_is_allowed(unsigned long pfn)
+{
+	return 1;
+}
 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
 {
 	return 1;
@@ -122,23 +130,31 @@ static ssize_t read_mem(struct file *fil
 
 	while (count > 0) {
 		unsigned long remaining;
+		int allowed;
 
 		sz = size_inside_page(p, count);
 
-		if (!range_is_allowed(p >> PAGE_SHIFT, count))
+		allowed = page_is_allowed(p >> PAGE_SHIFT);
+		if (!allowed)
 			return -EPERM;
+		if (allowed == 2) {
+			/* Show zeros for restricted memory. */
+			remaining = clear_user(buf, sz);
+		} else {
+			/*
+			 * On ia64 if a page has been mapped somewhere as
+			 * uncached, then it must also be accessed uncached
+			 * by the kernel or data corruption may occur.
+			 */
+			ptr = xlate_dev_mem_ptr(p);
+			if (!ptr)
+				return -EFAULT;
 
-		/*
-		 * On ia64 if a page has been mapped somewhere as uncached, then
-		 * it must also be accessed uncached by the kernel or data
-		 * corruption may occur.
-		 */
-		ptr = xlate_dev_mem_ptr(p);
-		if (!ptr)
-			return -EFAULT;
+			remaining = copy_to_user(buf, ptr, sz);
+
+			unxlate_dev_mem_ptr(p, ptr);
+		}
 
-		remaining = copy_to_user(buf, ptr, sz);
-		unxlate_dev_mem_ptr(p, ptr);
 		if (remaining)
 			return -EFAULT;
 
@@ -181,30 +197,36 @@ static ssize_t write_mem(struct file *fi
 #endif
 
 	while (count > 0) {
+		int allowed;
+
 		sz = size_inside_page(p, count);
 
-		if (!range_is_allowed(p >> PAGE_SHIFT, sz))
+		allowed = page_is_allowed(p >> PAGE_SHIFT);
+		if (!allowed)
 			return -EPERM;
 
-		/*
-		 * On ia64 if a page has been mapped somewhere as uncached, then
-		 * it must also be accessed uncached by the kernel or data
-		 * corruption may occur.
-		 */
-		ptr = xlate_dev_mem_ptr(p);
-		if (!ptr) {
-			if (written)
-				break;
-			return -EFAULT;
-		}
+		/* Skip actual writing when a page is marked as restricted. */
+		if (allowed == 1) {
+			/*
+			 * On ia64 if a page has been mapped somewhere as
+			 * uncached, then it must also be accessed uncached
+			 * by the kernel or data corruption may occur.
+			 */
+			ptr = xlate_dev_mem_ptr(p);
+			if (!ptr) {
+				if (written)
+					break;
+				return -EFAULT;
+			}
 
-		copied = copy_from_user(ptr, buf, sz);
-		unxlate_dev_mem_ptr(p, ptr);
-		if (copied) {
-			written += sz - copied;
-			if (written)
-				break;
-			return -EFAULT;
+			copied = copy_from_user(ptr, buf, sz);
+			unxlate_dev_mem_ptr(p, ptr);
+			if (copied) {
+				written += sz - copied;
+				if (written)
+					break;
+				return -EFAULT;
+			}
 		}
 
 		buf += sz;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/char/virtio_console.c linux-libre-3.16.46-gnu/drivers/char/virtio_console.c
--- linux-libre-3.16.45-gnu/drivers/char/virtio_console.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/char/virtio_console.c	2017-07-18 13:40:42.000000000 -0400
@@ -2180,14 +2180,16 @@ static int virtcons_freeze(struct virtio
 
 	vdev->config->reset(vdev);
 
-	virtqueue_disable_cb(portdev->c_ivq);
+	if (use_multiport(portdev))
+		virtqueue_disable_cb(portdev->c_ivq);
 	cancel_work_sync(&portdev->control_work);
 	cancel_work_sync(&portdev->config_work);
 	/*
 	 * Once more: if control_work_handler() was running, it would
 	 * enable the cb as the last step.
 	 */
-	virtqueue_disable_cb(portdev->c_ivq);
+	if (use_multiport(portdev))
+		virtqueue_disable_cb(portdev->c_ivq);
 	remove_controlq_data(portdev);
 
 	list_for_each_entry(port, &portdev->ports, list) {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/crypto/caam/ctrl.c linux-libre-3.16.46-gnu/drivers/crypto/caam/ctrl.c
--- linux-libre-3.16.45-gnu/drivers/crypto/caam/ctrl.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/crypto/caam/ctrl.c	2017-07-18 13:40:42.000000000 -0400
@@ -251,7 +251,8 @@ static int deinstantiate_rng(struct devi
 			/* Try to run it through DECO0 */
 			ret = run_descriptor_deco0(ctrldev, desc, &status);
 
-			if (ret || status) {
+			if (ret ||
+			    (status && status != JRSTA_SSRC_JUMP_HALT_CC)) {
 				dev_err(ctrldev,
 					"Failed to deinstantiate RNG4 SH%d\n",
 					sh_idx);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/gpio/gpio-mcp23s08.c linux-libre-3.16.46-gnu/drivers/gpio/gpio-mcp23s08.c
--- linux-libre-3.16.45-gnu/drivers/gpio/gpio-mcp23s08.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/gpio/gpio-mcp23s08.c	2017-07-18 13:40:42.000000000 -0400
@@ -340,8 +340,10 @@ mcp23s08_direction_output(struct gpio_ch
 static irqreturn_t mcp23s08_irq(int irq, void *data)
 {
 	struct mcp23s08 *mcp = data;
-	int intcap, intf, i;
+	int intcap, intf, i, gpio, gpio_orig, intcap_mask;
 	unsigned int child_irq;
+	bool intf_set, intcap_changed, gpio_bit_changed,
+		gpio_set;
 
 	mutex_lock(&mcp->lock);
 	intf = mcp->ops->read(mcp, MCP_INTF);
@@ -359,13 +361,63 @@ static irqreturn_t mcp23s08_irq(int irq,
 	}
 
 	mcp->cache[MCP_INTCAP] = intcap;
+
+	/* This clears the interrupt(configurable on S18) */
+	if ((gpio = mcp->ops->read(mcp, MCP_GPIO)) < 0) {
+		mutex_unlock(&mcp->lock);
+		return IRQ_HANDLED;
+	}
+	gpio_orig = mcp->cache[MCP_GPIO];
+	mcp->cache[MCP_GPIO] = gpio;
 	mutex_unlock(&mcp->lock);
 
+	if (mcp->cache[MCP_INTF] == 0) {
+		/* There is no interrupt pending */
+		return IRQ_HANDLED;
+	}
+
+	dev_dbg(mcp->chip.dev,
+		"intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n",
+		intcap, intf, gpio_orig, gpio);
 
 	for (i = 0; i < mcp->chip.ngpio; i++) {
-		if ((BIT(i) & mcp->cache[MCP_INTF]) &&
-		    ((BIT(i) & intcap & mcp->irq_rise) ||
-		     (mcp->irq_fall & ~intcap & BIT(i)))) {
+		/* We must check all of the inputs on the chip,
+		 * otherwise we may not notice a change on >=2 pins.
+		 *
+		 * On at least the mcp23s17, INTCAP is only updated
+		 * one byte at a time(INTCAPA and INTCAPB are
+		 * not written to at the same time - only on a per-bank
+		 * basis).
+		 *
+		 * INTF only contains the single bit that caused the
+		 * interrupt per-bank.  On the mcp23s17, there is
+		 * INTFA and INTFB.  If two pins are changed on the A
+		 * side at the same time, INTF will only have one bit
+		 * set.  If one pin on the A side and one pin on the B
+		 * side are changed at the same time, INTF will have
+		 * two bits set.  Thus, INTF can't be the only check
+		 * to see if the input has changed.
+		 */
+
+		intf_set = BIT(i) & mcp->cache[MCP_INTF];
+		if (i < 8 && intf_set)
+			intcap_mask = 0x00FF;
+		else if (i >= 8 && intf_set)
+			intcap_mask = 0xFF00;
+		else
+			intcap_mask = 0x00;
+
+		intcap_changed = (intcap_mask &
+			(BIT(i) & mcp->cache[MCP_INTCAP])) !=
+			(intcap_mask & (BIT(i) & gpio_orig));
+		gpio_set = BIT(i) & mcp->cache[MCP_GPIO];
+		gpio_bit_changed = (BIT(i) & gpio_orig) !=
+			(BIT(i) & mcp->cache[MCP_GPIO]);
+
+		if (((gpio_bit_changed || intcap_changed) &&
+			(BIT(i) & mcp->irq_rise) && gpio_set) ||
+		    ((gpio_bit_changed || intcap_changed) &&
+			(BIT(i) & mcp->irq_fall) && !gpio_set)) {
 			child_irq = irq_find_mapping(mcp->irq_domain, i);
 			handle_nested_irq(child_irq);
 		}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/gpu/drm/ttm/ttm_object.c linux-libre-3.16.46-gnu/drivers/gpu/drm/ttm/ttm_object.c
--- linux-libre-3.16.45-gnu/drivers/gpu/drm/ttm/ttm_object.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/gpu/drm/ttm/ttm_object.c	2017-07-18 13:40:42.000000000 -0400
@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_obje
 	if (unlikely(ret != 0))
 		goto out_err0;
 
-	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
+	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
 	if (unlikely(ret != 0))
 		goto out_err1;
 
@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists);
 
 int ttm_ref_object_add(struct ttm_object_file *tfile,
 		       struct ttm_base_object *base,
-		       enum ttm_ref_type ref_type, bool *existed)
+		       enum ttm_ref_type ref_type, bool *existed,
+		       bool require_existed)
 {
 	struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
 	struct ttm_ref_object *ref;
@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object
 		}
 
 		rcu_read_unlock();
+		if (require_existed)
+			return -EPERM;
+
 		ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
 					   false, false);
 		if (unlikely(ret != 0))
@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_ob
 	prime = (struct ttm_prime_object *) dma_buf->priv;
 	base = &prime->base;
 	*handle = base->hash.key;
-	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
+	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
 
 	dma_buf_put(dma_buf);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
--- linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c	2017-07-18 13:40:42.000000000 -0400
@@ -494,7 +494,7 @@ int vmw_fence_create(struct vmw_fence_ma
 		     struct vmw_fence_obj **p_fence)
 {
 	struct vmw_fence_obj *fence;
-	int ret;
+ 	int ret;
 
 	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
 	if (unlikely(fence == NULL))
@@ -662,6 +662,41 @@ void vmw_fence_fifo_up(struct vmw_fence_
 }
 
 
+/**
+ * vmw_fence_obj_lookup - Look up a user-space fence object
+ *
+ * @tfile: A struct ttm_object_file identifying the caller.
+ * @handle: A handle identifying the fence object.
+ * @return: A struct vmw_user_fence base ttm object on success or
+ * an error pointer on failure.
+ *
+ * The fence object is looked up and type-checked. The caller needs
+ * to have opened the fence object first, but since that happens on
+ * creation and fence objects aren't shareable, that's not an
+ * issue currently.
+ */
+static struct ttm_base_object *
+vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle)
+{
+	struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle);
+
+	if (!base) {
+		pr_err("Invalid fence object handle 0x%08lx.\n",
+		       (unsigned long)handle);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (base->refcount_release != vmw_user_fence_base_release) {
+		pr_err("Invalid fence object handle 0x%08lx.\n",
+		       (unsigned long)handle);
+		ttm_base_object_unref(&base);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return base;
+}
+
+
 int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data,
 			     struct drm_file *file_priv)
 {
@@ -687,13 +722,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_
 		arg->kernel_cookie = jiffies + wait_timeout;
 	}
 
-	base = ttm_base_object_lookup(tfile, arg->handle);
-	if (unlikely(base == NULL)) {
-		printk(KERN_ERR "Wait invalid fence object handle "
-		       "0x%08lx.\n",
-		       (unsigned long)arg->handle);
-		return -EINVAL;
-	}
+	base = vmw_fence_obj_lookup(tfile, arg->handle);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 
 	fence = &(container_of(base, struct vmw_user_fence, base)->fence);
 
@@ -732,13 +763,9 @@ int vmw_fence_obj_signaled_ioctl(struct
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
 	struct vmw_private *dev_priv = vmw_priv(dev);
 
-	base = ttm_base_object_lookup(tfile, arg->handle);
-	if (unlikely(base == NULL)) {
-		printk(KERN_ERR "Fence signaled invalid fence object handle "
-		       "0x%08lx.\n",
-		       (unsigned long)arg->handle);
-		return -EINVAL;
-	}
+	base = vmw_fence_obj_lookup(tfile, arg->handle);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 
 	fence = &(container_of(base, struct vmw_user_fence, base)->fence);
 	fman = fence->fman;
@@ -1052,6 +1079,7 @@ int vmw_fence_event_ioctl(struct drm_dev
 		(struct drm_vmw_fence_event_arg *) data;
 	struct vmw_fence_obj *fence = NULL;
 	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+	struct ttm_object_file *tfile = vmw_fp->tfile;
 	struct drm_vmw_fence_rep __user *user_fence_rep =
 		(struct drm_vmw_fence_rep __user *)(unsigned long)
 		arg->fence_rep;
@@ -1065,24 +1093,18 @@ int vmw_fence_event_ioctl(struct drm_dev
 	 */
 	if (arg->handle) {
 		struct ttm_base_object *base =
-			ttm_base_object_lookup_for_ref(dev_priv->tdev,
-						       arg->handle);
+			vmw_fence_obj_lookup(tfile, arg->handle);
+
+		if (IS_ERR(base))
+			return PTR_ERR(base);
 
-		if (unlikely(base == NULL)) {
-			DRM_ERROR("Fence event invalid fence object handle "
-				  "0x%08lx.\n",
-				  (unsigned long)arg->handle);
-			return -EINVAL;
-		}
 		fence = &(container_of(base, struct vmw_user_fence,
 				       base)->fence);
 		(void) vmw_fence_obj_reference(fence);
 
 		if (user_fence_rep != NULL) {
-			bool existed;
-
 			ret = ttm_ref_object_add(vmw_fp->tfile, base,
-						 TTM_REF_USAGE, &existed);
+						 TTM_REF_USAGE, NULL, false);
 			if (unlikely(ret != 0)) {
 				DRM_ERROR("Failed to reference a fence "
 					  "object.\n");
@@ -1125,8 +1147,7 @@ int vmw_fence_event_ioctl(struct drm_dev
 	return 0;
 out_no_create:
 	if (user_fence_rep != NULL)
-		ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
-					  handle, TTM_REF_USAGE);
+		ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE);
 out_no_ref_obj:
 	vmw_fence_obj_unreference(&fence);
 	return ret;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
--- linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c	2017-07-18 13:40:42.000000000 -0400
@@ -106,8 +106,6 @@ int vmw_getparam_ioctl(struct drm_device
 		param->value = dev_priv->max_mob_size;
 		break;
 	default:
-		DRM_ERROR("Illegal vmwgfx get param request: %d\n",
-			  param->param);
 		return -EINVAL;
 	}
 
@@ -161,7 +159,7 @@ int vmw_get_cap_3d_ioctl(struct drm_devi
 	bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS);
 	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
 
-	if (unlikely(arg->pad64 != 0)) {
+	if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) {
 		DRM_ERROR("Illegal GET_3D_CAP argument.\n");
 		return -EINVAL;
 	}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
--- linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c	2017-07-18 13:40:42.000000000 -0400
@@ -587,7 +587,7 @@ static int vmw_user_dmabuf_synccpu_grab(
 		return ret;
 
 	ret = ttm_ref_object_add(tfile, &user_bo->prime.base,
-				 TTM_REF_SYNCCPU_WRITE, &existed);
+				 TTM_REF_SYNCCPU_WRITE, &existed, false);
 	if (ret != 0 || existed)
 		ttm_bo_synccpu_write_release(&user_bo->dma.base);
 
@@ -771,7 +771,7 @@ int vmw_user_dmabuf_reference(struct ttm
 
 	*handle = user_bo->prime.base.hash.key;
 	return ttm_ref_object_add(tfile, &user_bo->prime.base,
-				  TTM_REF_USAGE, NULL);
+				  TTM_REF_USAGE, NULL, false);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
--- linux-libre-3.16.45-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c	2017-07-18 13:40:42.000000000 -0400
@@ -902,17 +902,16 @@ vmw_surface_handle_reference(struct vmw_
 	uint32_t handle;
 	struct ttm_base_object *base;
 	int ret;
+	bool require_exist = false;
 
 	if (handle_type == DRM_VMW_HANDLE_PRIME) {
 		ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
 		if (unlikely(ret != 0))
 			return ret;
 	} else {
-		if (unlikely(drm_is_render_client(file_priv))) {
-			DRM_ERROR("Render client refused legacy "
-				  "surface reference.\n");
-			return -EACCES;
-		}
+		if (unlikely(drm_is_render_client(file_priv)))
+			require_exist = true;
+
 		handle = u_handle;
 	}
 
@@ -934,17 +933,14 @@ vmw_surface_handle_reference(struct vmw_
 
 		/*
 		 * Make sure the surface creator has the same
-		 * authenticating master.
+		 * authenticating master, or is already registered with us.
 		 */
 		if (drm_is_primary_client(file_priv) &&
-		    user_srf->master != file_priv->master) {
-			DRM_ERROR("Trying to reference surface outside of"
-				  " master domain.\n");
-			ret = -EACCES;
-			goto out_bad_resource;
-		}
+		    user_srf->master != file_priv->master)
+			require_exist = true;
 
-		ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
+		ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL,
+					 require_exist);
 		if (unlikely(ret != 0)) {
 			DRM_ERROR("Could not add a reference to a surface.\n");
 			goto out_bad_resource;
@@ -1249,7 +1245,7 @@ int vmw_gb_surface_define_ioctl(struct d
 	int ret;
 	uint32_t size;
 	const struct svga3d_surface_desc *desc;
-	uint32_t backup_handle;
+	uint32_t backup_handle = 0;
 
 	if (req->mip_levels > DRM_VMW_MAX_MIP_LEVELS)
 		return -EINVAL;
@@ -1321,6 +1317,8 @@ int vmw_gb_surface_define_ioctl(struct d
 		ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle,
 					     &res->backup,
 					     &user_srf->backup_base);
+		if (ret == 0)
+			backup_handle = req->buffer_handle;
 	} else if (req->drm_surface_flags &
 		   drm_vmw_surface_flag_create_buffer)
 		ret = vmw_user_dmabuf_alloc(dev_priv, tfile,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/hwmon/asus_atk0110.c linux-libre-3.16.46-gnu/drivers/hwmon/asus_atk0110.c
--- linux-libre-3.16.45-gnu/drivers/hwmon/asus_atk0110.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/hwmon/asus_atk0110.c	2017-07-18 13:40:42.000000000 -0400
@@ -646,6 +646,9 @@ static int atk_read_value(struct atk_sen
 		else
 			err = atk_read_value_new(sensor, value);
 
+		if (err)
+			return err;
+
 		sensor->is_valid = true;
 		sensor->last_updated = jiffies;
 		sensor->cached_value = *value;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/iio/adc/ti_am335x_adc.c linux-libre-3.16.46-gnu/drivers/iio/adc/ti_am335x_adc.c
--- linux-libre-3.16.45-gnu/drivers/iio/adc/ti_am335x_adc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/iio/adc/ti_am335x_adc.c	2017-07-18 13:40:42.000000000 -0400
@@ -123,7 +123,9 @@ static irqreturn_t tiadc_irq_h(int irq,
 {
 	struct iio_dev *indio_dev = private;
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
-	unsigned int status, config;
+	unsigned int status, config, adc_fsm;
+	unsigned short count = 0;
+
 	status = tiadc_readl(adc_dev, REG_IRQSTATUS);
 
 	/*
@@ -137,6 +139,15 @@ static irqreturn_t tiadc_irq_h(int irq,
 		tiadc_writel(adc_dev, REG_CTRL, config);
 		tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
 				| IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
+
+		/* wait for idle state.
+		 * ADC needs to finish the current conversion
+		 * before disabling the module
+		 */
+		do {
+			adc_fsm = tiadc_readl(adc_dev, REG_ADCFSM);
+		} while (adc_fsm != 0x10 && count++ < 100);
+
 		tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
 		return IRQ_HANDLED;
 	} else if (status & IRQENB_FIFO1THRES) {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c linux-libre-3.16.46-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
--- linux-libre-3.16.45-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c	2017-07-18 13:40:42.000000000 -0400
@@ -363,6 +363,8 @@ int hid_sensor_parse_common_attributes(s
 					struct hid_sensor_common *st)
 {
 
+	s32 value;
+	int ret;
 
 	hid_sensor_get_reporting_interval(hsdev, usage_id, st);
 
@@ -387,6 +389,14 @@ int hid_sensor_parse_common_attributes(s
 			st->power_state.index, st->power_state.report_id,
 			st->sensitivity.index, st->sensitivity.report_id);
 
+	ret = sensor_hub_get_feature(hsdev,
+				st->power_state.report_id,
+				st->power_state.index, &value);
+	if (ret < 0)
+		return ret;
+	if (value < 0)
+		return -EINVAL;
+
 	return 0;
 }
 EXPORT_SYMBOL(hid_sensor_parse_common_attributes);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/iio/industrialio-core.c linux-libre-3.16.46-gnu/drivers/iio/industrialio-core.c
--- linux-libre-3.16.45-gnu/drivers/iio/industrialio-core.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/iio/industrialio-core.c	2017-07-18 13:40:42.000000000 -0400
@@ -390,16 +390,15 @@ ssize_t iio_format_value(char *buf, unsi
 		scale_db = true;
 	case IIO_VAL_INT_PLUS_MICRO:
 		if (vals[1] < 0)
-			return sprintf(buf, "-%ld.%06u%s\n", abs(vals[0]),
-					-vals[1],
-				scale_db ? " dB" : "");
+			return sprintf(buf, "-%d.%06u%s\n", abs(vals[0]),
+				       -vals[1], scale_db ? " dB" : "");
 		else
 			return sprintf(buf, "%d.%06u%s\n", vals[0], vals[1],
 				scale_db ? " dB" : "");
 	case IIO_VAL_INT_PLUS_NANO:
 		if (vals[1] < 0)
-			return sprintf(buf, "-%ld.%09u\n", abs(vals[0]),
-					-vals[1]);
+			return sprintf(buf, "-%d.%09u\n", abs(vals[0]),
+				       -vals[1]);
 		else
 			return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
 	case IIO_VAL_FRACTIONAL:
@@ -407,10 +406,9 @@ ssize_t iio_format_value(char *buf, unsi
 		vals[0] = (int)div_s64_rem(tmp, 1000000000, &vals[1]);
 		return sprintf(buf, "%d.%09u\n", vals[0], abs(vals[1]));
 	case IIO_VAL_FRACTIONAL_LOG2:
-		tmp = (s64)vals[0] * 1000000000LL >> vals[1];
-		vals[1] = do_div(tmp, 1000000000LL);
-		vals[0] = tmp;
-		return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
+		tmp = shift_right((s64)vals[0] * 1000000000LL, vals[1]);
+		vals[0] = (int)div_s64_rem(tmp, 1000000000LL, &vals[1]);
+		return sprintf(buf, "%d.%09u\n", vals[0], abs(vals[1]));
 	case IIO_VAL_INT_MULTIPLE:
 	{
 		int i;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-3.16.46-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-3.16.45-gnu/drivers/infiniband/hw/mlx5/main.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/infiniband/hw/mlx5/main.c	2017-07-18 13:40:42.000000000 -0400
@@ -73,7 +73,7 @@ static struct mlx5_profile profile[] = {
 	[2] = {
 		.mask		= MLX5_PROF_MASK_QP_SIZE |
 				  MLX5_PROF_MASK_MR_CACHE,
-		.log_max_qp	= 17,
+		.log_max_qp	= 18,
 		.mr_cache[0]	= {
 			.size	= 500,
 			.limit	= 250
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/infiniband/hw/qib/qib_iba7322.c linux-libre-3.16.46-gnu/drivers/infiniband/hw/qib/qib_iba7322.c
--- linux-libre-3.16.45-gnu/drivers/infiniband/hw/qib/qib_iba7322.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/infiniband/hw/qib/qib_iba7322.c	2017-07-18 13:40:42.000000000 -0400
@@ -7078,7 +7078,7 @@ static void qib_7322_txchk_change(struct
 	unsigned long flags;
 
 	while (wait) {
-		unsigned long shadow;
+		unsigned long shadow = 0;
 		int cstart, previ = -1;
 
 		/*
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/joystick/iforce/iforce-usb.c linux-libre-3.16.46-gnu/drivers/input/joystick/iforce/iforce-usb.c
--- linux-libre-3.16.45-gnu/drivers/input/joystick/iforce/iforce-usb.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/joystick/iforce/iforce-usb.c	2017-07-18 13:40:42.000000000 -0400
@@ -141,6 +141,9 @@ static int iforce_usb_probe(struct usb_i
 
 	interface = intf->cur_altsetting;
 
+	if (interface->desc.bNumEndpoints < 2)
+		return -ENODEV;
+
 	epirq = &interface->endpoint[0].desc;
 	epout = &interface->endpoint[1].desc;
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/misc/cm109.c linux-libre-3.16.46-gnu/drivers/input/misc/cm109.c
--- linux-libre-3.16.45-gnu/drivers/input/misc/cm109.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/misc/cm109.c	2017-07-18 13:40:42.000000000 -0400
@@ -675,6 +675,10 @@ static int cm109_usb_probe(struct usb_in
 	int error = -ENOMEM;
 
 	interface = intf->cur_altsetting;
+
+	if (interface->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	endpoint = &interface->endpoint[0].desc;
 
 	if (!usb_endpoint_is_int_in(endpoint))
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/misc/ims-pcu.c linux-libre-3.16.46-gnu/drivers/input/misc/ims-pcu.c
--- linux-libre-3.16.45-gnu/drivers/input/misc/ims-pcu.c	2017-07-03 11:38:29.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/misc/ims-pcu.c	2017-07-18 17:43:46.000000000 -0400
@@ -1667,6 +1667,10 @@ static int ims_pcu_parse_cdc_data(struct
 		return -EINVAL;
 
 	alt = pcu->ctrl_intf->cur_altsetting;
+
+	if (alt->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	pcu->ep_ctrl = &alt->endpoint[0].desc;
 	pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/misc/yealink.c linux-libre-3.16.46-gnu/drivers/input/misc/yealink.c
--- linux-libre-3.16.45-gnu/drivers/input/misc/yealink.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/misc/yealink.c	2017-07-18 13:40:42.000000000 -0400
@@ -875,6 +875,10 @@ static int usb_probe(struct usb_interfac
 	int ret, pipe, i;
 
 	interface = intf->cur_altsetting;
+
+	if (interface->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	endpoint = &interface->endpoint[0].desc;
 	if (!usb_endpoint_is_int_in(endpoint))
 		return -ENODEV;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/mouse/elantech.c linux-libre-3.16.46-gnu/drivers/input/mouse/elantech.c
--- linux-libre-3.16.45-gnu/drivers/input/mouse/elantech.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/mouse/elantech.c	2017-07-18 13:40:42.000000000 -0400
@@ -1036,6 +1036,7 @@ static int elantech_get_resolution_v4(st
  * Asus UX32VD             0x361f02        00, 15, 0e      clickpad
  * Avatar AVIU-145A2       0x361f00        ?               clickpad
  * Fujitsu LIFEBOOK E544   0x470f00        d0, 12, 09      2 hw buttons
+ * Fujitsu LIFEBOOK E547   0x470f00        50, 12, 09      2 hw buttons
  * Fujitsu LIFEBOOK E554   0x570f01        40, 14, 0c      2 hw buttons
  * Gigabyte U2442          0x450f01        58, 17, 0c      2 hw buttons
  * Lenovo L430             0x350f02        b9, 15, 0c      2 hw buttons (*)
@@ -1396,6 +1397,13 @@ static const struct dmi_system_id elante
 		},
 	},
 	{
+		/* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E547"),
+		},
+	},
+	{
 		/* Fujitsu LIFEBOOK E554  does not work with crc_enabled == 0 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/serio/i8042-x86ia64io.h linux-libre-3.16.46-gnu/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-3.16.45-gnu/drivers/input/serio/i8042-x86ia64io.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/serio/i8042-x86ia64io.h	2017-07-18 13:40:42.000000000 -0400
@@ -120,6 +120,13 @@ static const struct dmi_system_id __init
 		},
 	},
 	{
+		/* Dell Embedded Box PC 3000 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
+		},
+	},
+	{
 		/* OQO Model 01 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
@@ -587,6 +594,13 @@ static const struct dmi_system_id __init
 			DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
 		},
 	},
+	{
+		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
+		},
+	},
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/tablet/hanwang.c linux-libre-3.16.46-gnu/drivers/input/tablet/hanwang.c
--- linux-libre-3.16.45-gnu/drivers/input/tablet/hanwang.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/tablet/hanwang.c	2017-07-18 13:40:42.000000000 -0400
@@ -340,6 +340,9 @@ static int hanwang_probe(struct usb_inte
 	int error;
 	int i;
 
+	if (intf->cur_altsetting->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!hanwang || !input_dev) {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/tablet/kbtab.c linux-libre-3.16.46-gnu/drivers/input/tablet/kbtab.c
--- linux-libre-3.16.45-gnu/drivers/input/tablet/kbtab.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/tablet/kbtab.c	2017-07-18 13:40:42.000000000 -0400
@@ -122,6 +122,9 @@ static int kbtab_probe(struct usb_interf
 	struct input_dev *input_dev;
 	int error = -ENOMEM;
 
+	if (intf->cur_altsetting->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!kbtab || !input_dev)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/input/touchscreen/sur40.c linux-libre-3.16.46-gnu/drivers/input/touchscreen/sur40.c
--- linux-libre-3.16.45-gnu/drivers/input/touchscreen/sur40.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/input/touchscreen/sur40.c	2017-07-18 13:40:42.000000000 -0400
@@ -361,6 +361,9 @@ static int sur40_probe(struct usb_interf
 	if (iface_desc->desc.bInterfaceClass != 0xFF)
 		return -ENODEV;
 
+	if (iface_desc->desc.bNumEndpoints < 5)
+		return -ENODEV;
+
 	/* Use endpoint #4 (0x86). */
 	endpoint = &iface_desc->endpoint[4].desc;
 	if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/isdn/gigaset/bas-gigaset.c linux-libre-3.16.46-gnu/drivers/isdn/gigaset/bas-gigaset.c
--- linux-libre-3.16.45-gnu/drivers/isdn/gigaset/bas-gigaset.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/isdn/gigaset/bas-gigaset.c	2017-07-18 13:40:42.000000000 -0400
@@ -2317,6 +2317,9 @@ static int gigaset_probe(struct usb_inte
 		return -ENODEV;
 	}
 
+	if (hostif->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	dev_info(&udev->dev,
 		 "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n",
 		 __func__, le16_to_cpu(udev->descriptor.idVendor),
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/md/raid10.c linux-libre-3.16.46-gnu/drivers/md/raid10.c
--- linux-libre-3.16.45-gnu/drivers/md/raid10.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/md/raid10.c	2017-07-18 13:40:42.000000000 -0400
@@ -1580,7 +1580,25 @@ static void make_request(struct mddev *m
 			split = bio;
 		}
 
+		/*
+		 * If a bio is splitted, the first part of bio will pass
+		 * barrier but the bio is queued in current->bio_list (see
+		 * generic_make_request). If there is a raise_barrier() called
+		 * here, the second part of bio can't pass barrier. But since
+		 * the first part bio isn't dispatched to underlaying disks
+		 * yet, the barrier is never released, hence raise_barrier will
+		 * alays wait. We have a deadlock.
+		 * Note, this only happens in read path. For write path, the
+		 * first part of bio is dispatched in a schedule() call
+		 * (because of blk plug) or offloaded to raid10d.
+		 * Quitting from the function immediately can change the bio
+		 * order queued in bio_list and avoid the deadlock.
+		 */
 		__make_request(mddev, split);
+		if (split != bio && bio_data_dir(bio) == READ) {
+			generic_make_request(bio);
+			break;
+		}
 	} while (split != bio);
 
 	/* In case raid10d snuck in to freeze_array */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/media/usb/dvb-usb/dvb-usb-firmware.c linux-libre-3.16.46-gnu/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
--- linux-libre-3.16.45-gnu/drivers/media/usb/dvb-usb/dvb-usb-firmware.c	2017-07-03 11:20:48.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/media/usb/dvb-usb/dvb-usb-firmware.c	2017-07-18 17:24:26.000000000 -0400
@@ -35,42 +35,51 @@ static int usb_cypress_writemem(struct u
 
 int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
 {
-	struct hexline hx;
-	u8 reset;
-	int ret,pos=0;
+	struct hexline *hx;
+	u8 *buf;
+	int ret, pos = 0;
+	u16 cpu_cs_register = cypress[type].cpu_cs_register;
+
+	buf = kmalloc(sizeof(*hx), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	hx = (struct hexline *)buf;
 
 	/* stop the CPU */
-	reset = 1;
-	if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+	buf[0] = 1;
+	if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
 		err("could not stop the USB controller CPU.");
 
-	while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
-		deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
-		ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
+	while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
+		deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk);
+		ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
 
-		if (ret != hx.len) {
+		if (ret != hx->len) {
 			err("error while transferring firmware "
 				"(transferred size: %d, block size: %d)",
-				ret,hx.len);
+				ret, hx->len);
 			ret = -EINVAL;
 			break;
 		}
 	}
 	if (ret < 0) {
 		err("firmware download failed at %d with %d",pos,ret);
+		kfree(buf);
 		return ret;
 	}
 
 	if (ret == 0) {
 		/* restart the CPU */
-		reset = 0;
-		if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
+		buf[0] = 0;
+		if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
 			err("could not restart the USB controller CPU.");
 			ret = -EINVAL;
 		}
 	} else
 		ret = -EIO;
 
+	kfree(buf);
+
 	return ret;
 }
 EXPORT_SYMBOL(usb_cypress_load_firmware);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/mmc/host/sdhci.c linux-libre-3.16.46-gnu/drivers/mmc/host/sdhci.c
--- linux-libre-3.16.45-gnu/drivers/mmc/host/sdhci.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/mmc/host/sdhci.c	2017-07-18 13:40:42.000000000 -0400
@@ -1224,7 +1224,9 @@ clock_set:
 			return;
 		}
 		timeout--;
-		mdelay(1);
+		spin_unlock_irq(&host->lock);
+		usleep_range(900, 1100);
+		spin_lock_irq(&host->lock);
 	}
 
 	clk |= SDHCI_CLOCK_CARD_EN;
@@ -1706,6 +1708,9 @@ static void sdhci_enable_sdio_irq(struct
 
 	sdhci_runtime_pm_get(host);
 
+	if (enable)
+		pm_runtime_get_noresume(host->mmc->parent);
+
 	spin_lock_irqsave(&host->lock, flags);
 	if (enable)
 		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
@@ -1715,6 +1720,9 @@ static void sdhci_enable_sdio_irq(struct
 	sdhci_enable_sdio_irq_nolock(host, enable);
 	spin_unlock_irqrestore(&host->lock, flags);
 
+	if (!enable)
+		pm_runtime_put_noidle(host->mmc->parent);
+
 	sdhci_runtime_pm_put(host);
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/mmc/host/sdhci-of-arasan.c linux-libre-3.16.46-gnu/drivers/mmc/host/sdhci-of-arasan.c
--- linux-libre-3.16.45-gnu/drivers/mmc/host/sdhci-of-arasan.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/mmc/host/sdhci-of-arasan.c	2017-07-18 13:40:42.000000000 -0400
@@ -22,12 +22,6 @@
 #include <linux/module.h>
 #include "sdhci-pltfm.h"
 
-#define SDHCI_ARASAN_CLK_CTRL_OFFSET	0x2c
-
-#define CLK_CTRL_TIMEOUT_SHIFT		16
-#define CLK_CTRL_TIMEOUT_MASK		(0xf << CLK_CTRL_TIMEOUT_SHIFT)
-#define CLK_CTRL_TIMEOUT_MIN_EXP	13
-
 /**
  * struct sdhci_arasan_data
  * @clk_ahb:	Pointer to the AHB clock
@@ -38,15 +32,15 @@ struct sdhci_arasan_data {
 
 static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 {
-	u32 div;
 	unsigned long freq;
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 
-	div = readl(host->ioaddr + SDHCI_ARASAN_CLK_CTRL_OFFSET);
-	div = (div & CLK_CTRL_TIMEOUT_MASK) >> CLK_CTRL_TIMEOUT_SHIFT;
+	/* SDHCI timeout clock is in kHz */
+	freq = DIV_ROUND_UP(clk_get_rate(pltfm_host->clk), 1000);
 
-	freq = clk_get_rate(pltfm_host->clk);
-	freq /= 1 << (CLK_CTRL_TIMEOUT_MIN_EXP + div);
+	/* or in MHz */
+	if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
+		freq = DIV_ROUND_UP(freq, 1000);
 
 	return freq;
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/mmc/host/ushc.c linux-libre-3.16.46-gnu/drivers/mmc/host/ushc.c
--- linux-libre-3.16.45-gnu/drivers/mmc/host/ushc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/mmc/host/ushc.c	2017-07-18 13:40:42.000000000 -0400
@@ -426,6 +426,9 @@ static int ushc_probe(struct usb_interfa
 	struct ushc_data *ushc;
 	int ret;
 
+	if (intf->cur_altsetting->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
 	if (mmc == NULL)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/mtd/ubi/upd.c linux-libre-3.16.46-gnu/drivers/mtd/ubi/upd.c
--- linux-libre-3.16.45-gnu/drivers/mtd/ubi/upd.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/mtd/ubi/upd.c	2017-07-18 13:40:42.000000000 -0400
@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *
 			return err;
 	}
 
-	if (bytes == 0) {
-		err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
-		if (err)
-			return err;
+	err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
+	if (err)
+		return err;
 
+	if (bytes == 0) {
 		err = clear_update_marker(ubi, vol, 0);
 		if (err)
 			return err;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c linux-libre-3.16.46-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c
--- linux-libre-3.16.45-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2017-07-18 13:40:42.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Broadcom GENET (Gigabit Ethernet) controller driver
  *
- * Copyright (c) 2014 Broadcom Corporation
+ * Copyright (c) 2014-2017 Broadcom
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -370,6 +370,22 @@ static inline void bcmgenet_rdma_ring_wr
 			genet_dma_ring_regs[r]);
 }
 
+static int bcmgenet_begin(struct net_device *dev)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+
+	/* Turn on the clock */
+	return clk_prepare_enable(priv->clk);
+}
+
+static void bcmgenet_complete(struct net_device *dev)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+
+	/* Turn off the clock */
+	clk_disable_unprepare(priv->clk);
+}
+
 static int bcmgenet_get_settings(struct net_device *dev,
 		struct ethtool_cmd *cmd)
 {
@@ -617,8 +633,9 @@ static const struct bcmgenet_stats bcmge
 	STAT_GENET_RUNT("rx_runt_bytes", mib.rx_runt_bytes),
 	/* Misc UniMAC counters */
 	STAT_GENET_MISC("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt,
-			UMAC_RBUF_OVFL_CNT),
-	STAT_GENET_MISC("rbuf_err_cnt", mib.rbuf_err_cnt, UMAC_RBUF_ERR_CNT),
+			UMAC_RBUF_OVFL_CNT_V1),
+	STAT_GENET_MISC("rbuf_err_cnt", mib.rbuf_err_cnt,
+			UMAC_RBUF_ERR_CNT_V1),
 	STAT_GENET_MISC("mdf_err_cnt", mib.mdf_err_cnt, UMAC_MDF_ERR_CNT),
 };
 
@@ -659,6 +676,45 @@ static void bcmgenet_get_strings(struct
 	}
 }
 
+static u32 bcmgenet_update_stat_misc(struct bcmgenet_priv *priv, u16 offset)
+{
+	u16 new_offset;
+	u32 val;
+
+	switch (offset) {
+	case UMAC_RBUF_OVFL_CNT_V1:
+		if (GENET_IS_V2(priv))
+			new_offset = RBUF_OVFL_CNT_V2;
+		else
+			new_offset = RBUF_OVFL_CNT_V3PLUS;
+
+		val = bcmgenet_rbuf_readl(priv,	new_offset);
+		/* clear if overflowed */
+		if (val == ~0)
+			bcmgenet_rbuf_writel(priv, 0, new_offset);
+		break;
+	case UMAC_RBUF_ERR_CNT_V1:
+		if (GENET_IS_V2(priv))
+			new_offset = RBUF_ERR_CNT_V2;
+		else
+			new_offset = RBUF_ERR_CNT_V3PLUS;
+
+		val = bcmgenet_rbuf_readl(priv,	new_offset);
+		/* clear if overflowed */
+		if (val == ~0)
+			bcmgenet_rbuf_writel(priv, 0, new_offset);
+		break;
+	default:
+		val = bcmgenet_umac_readl(priv, offset);
+		/* clear if overflowed */
+		if (val == ~0)
+			bcmgenet_umac_writel(priv, 0, offset);
+		break;
+	}
+
+	return val;
+}
+
 static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv)
 {
 	int i, j = 0;
@@ -673,19 +729,28 @@ static void bcmgenet_update_mib_counters
 		switch (s->type) {
 		case BCMGENET_STAT_NETDEV:
 			continue;
-		case BCMGENET_STAT_MIB_RX:
-		case BCMGENET_STAT_MIB_TX:
 		case BCMGENET_STAT_RUNT:
-			if (s->type != BCMGENET_STAT_MIB_RX)
-				offset = BCMGENET_STAT_OFFSET;
+			offset += BCMGENET_STAT_OFFSET;
+			/* fall through */
+		case BCMGENET_STAT_MIB_TX:
+			offset += BCMGENET_STAT_OFFSET;
+			/* fall through */
+		case BCMGENET_STAT_MIB_RX:
 			val = bcmgenet_umac_readl(priv, UMAC_MIB_START +
 								j + offset);
+			offset = 0;	/* Reset Offset */
 			break;
 		case BCMGENET_STAT_MISC:
-			val = bcmgenet_umac_readl(priv, s->reg_offset);
-			/* clear if overflowed */
-			if (val == ~0)
-				bcmgenet_umac_writel(priv, 0, s->reg_offset);
+			if (GENET_IS_V1(priv)) {
+				val = bcmgenet_umac_readl(priv, s->reg_offset);
+				/* clear if overflowed */
+				if (val == ~0)
+					bcmgenet_umac_writel(priv, 0,
+							     s->reg_offset);
+			} else {
+				val = bcmgenet_update_stat_misc(priv,
+								s->reg_offset);
+			}
 			break;
 		}
 
@@ -725,6 +790,8 @@ static void bcmgenet_get_ethtool_stats(s
 
 /* standard ethtool support functions. */
 static struct ethtool_ops bcmgenet_ethtool_ops = {
+	.begin			= bcmgenet_begin,
+	.complete		= bcmgenet_complete,
 	.get_strings		= bcmgenet_get_strings,
 	.get_sset_count		= bcmgenet_get_sset_count,
 	.get_ethtool_stats	= bcmgenet_get_ethtool_stats,
@@ -1809,42 +1876,46 @@ static int bcmgenet_poll(struct napi_str
 /* Interrupt bottom half */
 static void bcmgenet_irq_task(struct work_struct *work)
 {
+	unsigned long flags;
+	unsigned int status;
 	struct bcmgenet_priv *priv = container_of(
 			work, struct bcmgenet_priv, bcmgenet_irq_work);
 
 	netif_dbg(priv, intr, priv->dev, "%s\n", __func__);
 
+	spin_lock_irqsave(&priv->lock, flags);
+	status = priv->irq0_stat;
+	priv->irq0_stat = 0;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/* Link UP/DOWN event */
 	if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
-		(priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
+		(status & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN)))
 		phy_mac_interrupt(priv->phydev,
-			priv->irq0_stat & UMAC_IRQ_LINK_UP);
-		priv->irq0_stat &= ~(UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN);
-	}
+			status & UMAC_IRQ_LINK_UP);
 }
 
 /* bcmgenet_isr1: interrupt handler for ring buffer. */
 static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
 {
 	struct bcmgenet_priv *priv = dev_id;
-	unsigned int index;
+	unsigned int index, status;
 
-	/* Save irq status for bottom-half processing. */
-	priv->irq1_stat =
-		bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) &
+	/* Read irq status */
+	status = bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) &
 		~priv->int1_mask;
 	/* clear inerrupts*/
-	bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR);
+	bcmgenet_intrl2_1_writel(priv, status, INTRL2_CPU_CLEAR);
 
 	netif_dbg(priv, intr, priv->dev,
-		"%s: IRQ=0x%x\n", __func__, priv->irq1_stat);
+		"%s: IRQ=0x%x\n", __func__, status);
 	/* Check the MBDONE interrupts.
 	 * packet is done, reclaim descriptors
 	 */
-	if (priv->irq1_stat & 0x0000ffff) {
+	if (status & 0x0000ffff) {
 		index = 0;
 		for (index = 0; index < 16; index++) {
-			if (priv->irq1_stat & (1 << index))
+			if (status & (1 << index))
 				bcmgenet_tx_reclaim(priv->dev,
 						&priv->tx_rings[index]);
 		}
@@ -1856,18 +1927,19 @@ static irqreturn_t bcmgenet_isr1(int irq
 static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
 {
 	struct bcmgenet_priv *priv = dev_id;
+	unsigned int status;
+	unsigned long flags;
 
-	/* Save irq status for bottom-half processing. */
-	priv->irq0_stat =
-		bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) &
+	/* Read irq status */
+	status = bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) &
 		~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
 	/* clear inerrupts*/
-	bcmgenet_intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
+	bcmgenet_intrl2_0_writel(priv, status, INTRL2_CPU_CLEAR);
 
 	netif_dbg(priv, intr, priv->dev,
-		"IRQ=0x%x\n", priv->irq0_stat);
+		"IRQ=0x%x\n", status);
 
-	if (priv->irq0_stat & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE)) {
+	if (status & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE)) {
 		/* We use NAPI(software interrupt throttling, if
 		 * Rx Descriptor throttling is not used.
 		 * Disable interrupt, will be enabled in the poll method.
@@ -1878,28 +1950,27 @@ static irqreturn_t bcmgenet_isr0(int irq
 			__napi_schedule(&priv->napi);
 		}
 	}
-	if (priv->irq0_stat &
+	if (status &
 			(UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) {
 		/* Tx reclaim */
 		bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[DESC_INDEX]);
 	}
-	if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R |
-				UMAC_IRQ_PHY_DET_F |
-				UMAC_IRQ_LINK_UP |
-				UMAC_IRQ_LINK_DOWN |
-				UMAC_IRQ_HFB_SM |
-				UMAC_IRQ_HFB_MM |
-				UMAC_IRQ_MPD_R)) {
-		/* all other interested interrupts handled in bottom half */
-		schedule_work(&priv->bcmgenet_irq_work);
-	}
-
 	if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
-		priv->irq0_stat & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) {
-		priv->irq0_stat &= ~(UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR);
+		status & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) {
 		wake_up(&priv->wq);
 	}
 
+	/* all other interested interrupts handled in bottom half */
+	status &= UMAC_IRQ_LINK_UP | UMAC_IRQ_LINK_DOWN;
+	if (status) {
+		/* Save irq status for bottom-half processing. */
+		spin_lock_irqsave(&priv->lock, flags);
+		priv->irq0_stat |= status;
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+		schedule_work(&priv->bcmgenet_irq_work);
+	}
+
 	return IRQ_HANDLED;
 }
 
@@ -2447,6 +2518,7 @@ static int bcmgenet_probe(struct platfor
 	const void *macaddr;
 	struct resource *r;
 	int err = -EIO;
+	const char *phy_mode_str;
 
 	/* Up to GENET_MAX_MQ_CNT + 1 TX queues and a single RX queue */
 	dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, 1);
@@ -2482,6 +2554,8 @@ static int bcmgenet_probe(struct platfor
 		goto err;
 	}
 
+	spin_lock_init(&priv->lock);
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	dev_set_drvdata(&pdev->dev, dev);
 	ether_addr_copy(dev->dev_addr, macaddr);
@@ -2526,6 +2600,13 @@ static int bcmgenet_probe(struct platfor
 	if (!IS_ERR(priv->clk))
 		clk_prepare_enable(priv->clk);
 
+	/* If this is an internal GPHY, power it on now, before UniMAC is
+	 * brought out of reset as absolutely no UniMAC activity is allowed
+	 */
+	if (dn && !of_property_read_string(dn, "phy-mode", &phy_mode_str) &&
+	    !strcasecmp(phy_mode_str, "internal"))
+		bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
+
 	err = reset_umac(priv);
 	if (err)
 		goto err_clk_disable;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h linux-libre-3.16.46-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h
--- linux-libre-3.16.45-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h	2017-07-18 13:40:42.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Broadcom Corporation
+ * Copyright (c) 2014-2017 Broadcom
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -206,7 +206,9 @@ struct bcmgenet_mib_counters {
 #define  MDIO_REG_SHIFT			16
 #define  MDIO_REG_MASK			0x1F
 
-#define UMAC_RBUF_OVFL_CNT		0x61C
+#define UMAC_RBUF_OVFL_CNT_V1		0x61C
+#define RBUF_OVFL_CNT_V2		0x80
+#define RBUF_OVFL_CNT_V3PLUS		0x94
 
 #define UMAC_MPD_CTRL			0x620
 #define  MPD_EN				(1 << 0)
@@ -216,7 +218,9 @@ struct bcmgenet_mib_counters {
 
 #define UMAC_MPD_PW_MS			0x624
 #define UMAC_MPD_PW_LS			0x628
-#define UMAC_RBUF_ERR_CNT		0x634
+#define UMAC_RBUF_ERR_CNT_V1		0x634
+#define RBUF_ERR_CNT_V2			0x84
+#define RBUF_ERR_CNT_V3PLUS		0x98
 #define UMAC_MDF_ERR_CNT		0x638
 #define UMAC_MDF_CTRL			0x650
 #define UMAC_MDF_ADDR			0x654
@@ -567,8 +571,10 @@ struct bcmgenet_priv {
 	struct work_struct bcmgenet_irq_work;
 	int irq0;
 	int irq1;
+
+	/* shared status */
+	spinlock_t lock;
 	unsigned int irq0_stat;
-	unsigned int irq1_stat;
 
 	/* HW descriptors/checksum variables */
 	bool desc_64b_en;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c linux-libre-3.16.46-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
--- linux-libre-3.16.45-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c	2017-07-18 13:40:42.000000000 -0400
@@ -331,7 +331,7 @@ bnad_debugfs_write_regrd(struct file *fi
 	}
 
 	rc = sscanf(kern_buf, "%x:%x", &addr, &len);
-	if (rc < 2) {
+	if (rc < 2 || len > UINT_MAX >> 2) {
 		pr_warn("bna %s: Failed to read user buffer\n",
 			pci_name(bnad->pcidev));
 		kfree(kern_buf);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/ethernet/toshiba/tc35815.c linux-libre-3.16.46-gnu/drivers/net/ethernet/toshiba/tc35815.c
--- linux-libre-3.16.45-gnu/drivers/net/ethernet/toshiba/tc35815.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/ethernet/toshiba/tc35815.c	2017-07-18 13:40:42.000000000 -0400
@@ -1048,8 +1048,8 @@ tc35815_free_queues(struct net_device *d
 			BUG_ON(lp->tx_skbs[i].skb != skb);
 #endif
 			if (skb) {
-				dev_kfree_skb(skb);
 				pci_unmap_single(lp->pci_dev, lp->tx_skbs[i].skb_dma, skb->len, PCI_DMA_TODEVICE);
+				dev_kfree_skb(skb);
 				lp->tx_skbs[i].skb = NULL;
 				lp->tx_skbs[i].skb_dma = 0;
 			}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/macvlan.c linux-libre-3.16.46-gnu/drivers/net/macvlan.c
--- linux-libre-3.16.45-gnu/drivers/net/macvlan.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/macvlan.c	2017-07-18 13:40:42.000000000 -0400
@@ -942,6 +942,7 @@ static int macvlan_port_create(struct ne
 static void macvlan_port_destroy(struct net_device *dev)
 {
 	struct macvlan_port *port = macvlan_port_get_rtnl(dev);
+	struct sk_buff *skb;
 
 	dev->priv_flags &= ~IFF_MACVLAN_PORT;
 	netdev_rx_handler_unregister(dev);
@@ -950,7 +951,15 @@ static void macvlan_port_destroy(struct
 	 * but we need to cancel it and purge left skbs if any.
 	 */
 	cancel_work_sync(&port->bc_work);
-	__skb_queue_purge(&port->bc_queue);
+
+	while ((skb = __skb_dequeue(&port->bc_queue))) {
+		const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
+
+		if (src)
+			dev_put(src->dev);
+
+		kfree_skb(skb);
+	}
 
 	kfree_rcu(port, rcu);
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/phy/phy.c linux-libre-3.16.46-gnu/drivers/net/phy/phy.c
--- linux-libre-3.16.45-gnu/drivers/net/phy/phy.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/phy/phy.c	2017-07-18 13:40:42.000000000 -0400
@@ -474,7 +474,7 @@ void phy_stop_machine(struct phy_device
 	cancel_delayed_work_sync(&phydev->state_queue);
 
 	mutex_lock(&phydev->lock);
-	if (phydev->state > PHY_UP)
+	if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
 		phydev->state = PHY_UP;
 	mutex_unlock(&phydev->lock);
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/phy/phy_device.c linux-libre-3.16.46-gnu/drivers/net/phy/phy_device.c
--- linux-libre-3.16.45-gnu/drivers/net/phy/phy_device.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/phy/phy_device.c	2017-07-18 13:40:42.000000000 -0400
@@ -1339,7 +1339,7 @@ static struct phy_driver genphy_driver[]
 	.phy_id		= 0xffffffff,
 	.phy_id_mask	= 0xffffffff,
 	.name		= "Generic PHY",
-	.soft_reset	= genphy_soft_reset,
+	.soft_reset	= genphy_no_soft_reset,
 	.config_init	= genphy_config_init,
 	.features	= PHY_GBIT_FEATURES | SUPPORTED_MII |
 			  SUPPORTED_AUI | SUPPORTED_FIBRE |
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/team/team.c linux-libre-3.16.46-gnu/drivers/net/team/team.c
--- linux-libre-3.16.45-gnu/drivers/net/team/team.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/team/team.c	2017-07-18 13:40:42.000000000 -0400
@@ -2319,8 +2319,10 @@ start_again:
 
 	hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
 			  TEAM_CMD_OPTIONS_GET);
-	if (!hdr)
+	if (!hdr) {
+		nlmsg_free(skb);
 		return -EMSGSIZE;
+	}
 
 	if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
 		goto nla_put_failure;
@@ -2587,8 +2589,10 @@ start_again:
 
 	hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
 			  TEAM_CMD_PORT_LIST_GET);
-	if (!hdr)
+	if (!hdr) {
+		nlmsg_free(skb);
 		return -EMSGSIZE;
+	}
 
 	if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
 		goto nla_put_failure;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/usb/cx82310_eth.c linux-libre-3.16.46-gnu/drivers/net/usb/cx82310_eth.c
--- linux-libre-3.16.45-gnu/drivers/net/usb/cx82310_eth.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/usb/cx82310_eth.c	2017-07-18 13:40:42.000000000 -0400
@@ -275,12 +275,9 @@ static struct sk_buff *cx82310_tx_fixup(
 {
 	int len = skb->len;
 
-	if (skb_headroom(skb) < 2) {
-		struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags);
+	if (skb_cow_head(skb, 2)) {
 		dev_kfree_skb_any(skb);
-		skb = skb2;
-		if (!skb)
-			return NULL;
+		return NULL;
 	}
 	skb_push(skb, 2);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/usb/smsc75xx.c linux-libre-3.16.46-gnu/drivers/net/usb/smsc75xx.c
--- linux-libre-3.16.45-gnu/drivers/net/usb/smsc75xx.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/usb/smsc75xx.c	2017-07-18 13:40:42.000000000 -0400
@@ -2198,13 +2198,9 @@ static struct sk_buff *smsc75xx_tx_fixup
 {
 	u32 tx_cmd_a, tx_cmd_b;
 
-	if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
-		struct sk_buff *skb2 =
-			skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
+	if (skb_cow_head(skb, SMSC75XX_TX_OVERHEAD)) {
 		dev_kfree_skb_any(skb);
-		skb = skb2;
-		if (!skb)
-			return NULL;
+		return NULL;
 	}
 
 	tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/usb/sr9700.c linux-libre-3.16.46-gnu/drivers/net/usb/sr9700.c
--- linux-libre-3.16.45-gnu/drivers/net/usb/sr9700.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/usb/sr9700.c	2017-07-18 13:40:42.000000000 -0400
@@ -456,14 +456,9 @@ static struct sk_buff *sr9700_tx_fixup(s
 
 	len = skb->len;
 
-	if (skb_headroom(skb) < SR_TX_OVERHEAD) {
-		struct sk_buff *skb2;
-
-		skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags);
+	if (skb_cow_head(skb, SR_TX_OVERHEAD)) {
 		dev_kfree_skb_any(skb);
-		skb = skb2;
-		if (!skb)
-			return NULL;
+		return NULL;
 	}
 
 	__skb_push(skb, SR_TX_OVERHEAD);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/wimax/i2400m/usb.c linux-libre-3.16.46-gnu/drivers/net/wimax/i2400m/usb.c
--- linux-libre-3.16.45-gnu/drivers/net/wimax/i2400m/usb.c	2017-07-03 11:36:46.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/wimax/i2400m/usb.c	2017-07-18 17:42:28.000000000 -0400
@@ -467,6 +467,9 @@ int i2400mu_probe(struct usb_interface *
 	struct i2400mu *i2400mu;
 	struct usb_device *usb_dev = interface_to_usbdev(iface);
 
+	if (iface->cur_altsetting->desc.bNumEndpoints < 4)
+		return -ENODEV;
+
 	if (usb_dev->speed != USB_SPEED_HIGH)
 		dev_err(dev, "device not connected as high speed\n");
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c linux-libre-3.16.46-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c
--- linux-libre-3.16.45-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c	2017-07-18 13:40:42.000000000 -0400
@@ -901,7 +901,7 @@ static void iwlagn_gain_computation(stru
 		/* bound gain by 2 bits value max, 3rd bit is sign */
 		data->delta_gain_code[i] =
 			min(abs(delta_g),
-			(long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+			(s32) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
 
 		if (delta_g < 0)
 			/*
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/scsi/aacraid/src.c linux-libre-3.16.46-gnu/drivers/scsi/aacraid/src.c
--- linux-libre-3.16.45-gnu/drivers/scsi/aacraid/src.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/scsi/aacraid/src.c	2017-07-18 13:40:42.000000000 -0400
@@ -390,7 +390,7 @@ err_out:
 	return -1;
 
 err_blink:
-	return (status > 16) & 0xFF;
+	return (status >> 16) & 0xFF;
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/scsi/libiscsi.c linux-libre-3.16.46-gnu/drivers/scsi/libiscsi.c
--- linux-libre-3.16.45-gnu/drivers/scsi/libiscsi.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/scsi/libiscsi.c	2017-07-18 13:40:42.000000000 -0400
@@ -560,8 +560,12 @@ static void iscsi_complete_task(struct i
 	WARN_ON_ONCE(task->state == ISCSI_TASK_FREE);
 	task->state = state;
 
-	if (!list_empty(&task->running))
+	spin_lock_bh(&conn->taskqueuelock);
+	if (!list_empty(&task->running)) {
+		pr_debug_once("%s while task on list", __func__);
 		list_del_init(&task->running);
+	}
+	spin_unlock_bh(&conn->taskqueuelock);
 
 	if (conn->task == task)
 		conn->task = NULL;
@@ -783,7 +787,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn
 		if (session->tt->xmit_task(task))
 			goto free_task;
 	} else {
+		spin_lock_bh(&conn->taskqueuelock);
 		list_add_tail(&task->running, &conn->mgmtqueue);
+		spin_unlock_bh(&conn->taskqueuelock);
 		iscsi_conn_queue_work(conn);
 	}
 
@@ -1474,8 +1480,10 @@ void iscsi_requeue_task(struct iscsi_tas
 	 * this may be on the requeue list already if the xmit_task callout
 	 * is handling the r2ts while we are adding new ones
 	 */
+	spin_lock_bh(&conn->taskqueuelock);
 	if (list_empty(&task->running))
 		list_add_tail(&task->running, &conn->requeue);
+	spin_unlock_bh(&conn->taskqueuelock);
 	iscsi_conn_queue_work(conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_requeue_task);
@@ -1512,22 +1520,26 @@ static int iscsi_data_xmit(struct iscsi_
 	 * only have one nop-out as a ping from us and targets should not
 	 * overflow us with nop-ins
 	 */
+	spin_lock_bh(&conn->taskqueuelock);
 check_mgmt:
 	while (!list_empty(&conn->mgmtqueue)) {
 		conn->task = list_entry(conn->mgmtqueue.next,
 					 struct iscsi_task, running);
 		list_del_init(&conn->task->running);
+		spin_unlock_bh(&conn->taskqueuelock);
 		if (iscsi_prep_mgmt_task(conn, conn->task)) {
 			/* regular RX path uses back_lock */
 			spin_lock_bh(&conn->session->back_lock);
 			__iscsi_put_task(conn->task);
 			spin_unlock_bh(&conn->session->back_lock);
 			conn->task = NULL;
+			spin_lock_bh(&conn->taskqueuelock);
 			continue;
 		}
 		rc = iscsi_xmit_task(conn);
 		if (rc)
 			goto done;
+		spin_lock_bh(&conn->taskqueuelock);
 	}
 
 	/* process pending command queue */
@@ -1535,19 +1547,24 @@ check_mgmt:
 		conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task,
 					running);
 		list_del_init(&conn->task->running);
+		spin_unlock_bh(&conn->taskqueuelock);
 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
 			fail_scsi_task(conn->task, DID_IMM_RETRY);
+			spin_lock_bh(&conn->taskqueuelock);
 			continue;
 		}
 		rc = iscsi_prep_scsi_cmd_pdu(conn->task);
 		if (rc) {
 			if (rc == -ENOMEM || rc == -EACCES) {
+				spin_lock_bh(&conn->taskqueuelock);
 				list_add_tail(&conn->task->running,
 					      &conn->cmdqueue);
 				conn->task = NULL;
+				spin_unlock_bh(&conn->taskqueuelock);
 				goto done;
 			} else
 				fail_scsi_task(conn->task, DID_ABORT);
+			spin_lock_bh(&conn->taskqueuelock);
 			continue;
 		}
 		rc = iscsi_xmit_task(conn);
@@ -1558,6 +1575,7 @@ check_mgmt:
 		 * we need to check the mgmt queue for nops that need to
 		 * be sent to aviod starvation
 		 */
+		spin_lock_bh(&conn->taskqueuelock);
 		if (!list_empty(&conn->mgmtqueue))
 			goto check_mgmt;
 	}
@@ -1577,12 +1595,15 @@ check_mgmt:
 		conn->task = task;
 		list_del_init(&conn->task->running);
 		conn->task->state = ISCSI_TASK_RUNNING;
+		spin_unlock_bh(&conn->taskqueuelock);
 		rc = iscsi_xmit_task(conn);
 		if (rc)
 			goto done;
+		spin_lock_bh(&conn->taskqueuelock);
 		if (!list_empty(&conn->mgmtqueue))
 			goto check_mgmt;
 	}
+	spin_unlock_bh(&conn->taskqueuelock);
 	spin_unlock_bh(&conn->session->frwd_lock);
 	return -ENODATA;
 
@@ -1738,7 +1759,9 @@ int iscsi_queuecommand(struct Scsi_Host
 			goto prepd_reject;
 		}
 	} else {
+		spin_lock_bh(&conn->taskqueuelock);
 		list_add_tail(&task->running, &conn->cmdqueue);
+		spin_unlock_bh(&conn->taskqueuelock);
 		iscsi_conn_queue_work(conn);
 	}
 
@@ -2917,6 +2940,7 @@ iscsi_conn_setup(struct iscsi_cls_sessio
 	INIT_LIST_HEAD(&conn->mgmtqueue);
 	INIT_LIST_HEAD(&conn->cmdqueue);
 	INIT_LIST_HEAD(&conn->requeue);
+	spin_lock_init(&conn->taskqueuelock);
 	INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
 
 	/* allocate login_task used for the login/text sequences */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/scsi/libsas/sas_ata.c linux-libre-3.16.46-gnu/drivers/scsi/libsas/sas_ata.c
--- linux-libre-3.16.45-gnu/drivers/scsi/libsas/sas_ata.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/scsi/libsas/sas_ata.c	2017-07-18 13:40:42.000000000 -0400
@@ -219,7 +219,7 @@ static unsigned int sas_ata_qc_issue(str
 		task->num_scatter = qc->n_elem;
 	} else {
 		for_each_sg(qc->sg, sg, qc->n_elem, si)
-			xfer += sg->length;
+			xfer += sg_dma_len(sg);
 
 		task->total_xfer_len = xfer;
 		task->num_scatter = si;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/scsi/lpfc/lpfc_init.c linux-libre-3.16.46-gnu/drivers/scsi/lpfc/lpfc_init.c
--- linux-libre-3.16.45-gnu/drivers/scsi/lpfc/lpfc_init.c	2017-07-03 11:40:44.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/scsi/lpfc/lpfc_init.c	2017-07-18 17:45:43.000000000 -0400
@@ -11255,6 +11255,7 @@ static struct pci_driver lpfc_driver = {
 	.id_table	= lpfc_id_table,
 	.probe		= lpfc_pci_probe_one,
 	.remove		= lpfc_pci_remove_one,
+	.shutdown	= lpfc_pci_remove_one,
 	.suspend        = lpfc_pci_suspend_one,
 	.resume		= lpfc_pci_resume_one,
 	.err_handler    = &lpfc_err_handler,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/scsi/sd.c linux-libre-3.16.46-gnu/drivers/scsi/sd.c
--- linux-libre-3.16.45-gnu/drivers/scsi/sd.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/scsi/sd.c	2017-07-18 13:40:42.000000000 -0400
@@ -1930,6 +1930,22 @@ static void read_capacity_error(struct s
 
 #define READ_CAPACITY_RETRIES_ON_RESET	10
 
+/*
+ * Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set
+ * and the reported logical block size is bigger than 512 bytes. Note
+ * that last_sector is a u64 and therefore logical_to_sectors() is not
+ * applicable.
+ */
+static bool sd_addressable_capacity(u64 lba, unsigned int sector_size)
+{
+	u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9);
+
+	if (sizeof(sector_t) == 4 && last_sector > U32_MAX)
+		return false;
+
+	return true;
+}
+
 static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 						unsigned char *buffer)
 {
@@ -1995,7 +2011,7 @@ static int read_capacity_16(struct scsi_
 		return -ENODEV;
 	}
 
-	if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) {
+	if (!sd_addressable_capacity(lba, sector_size)) {
 		sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
 			"kernel compiled with support for large block "
 			"devices.\n");
@@ -2081,7 +2097,7 @@ static int read_capacity_10(struct scsi_
 		return sector_size;
 	}
 
-	if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
+	if (!sd_addressable_capacity(lba, sector_size)) {
 		sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
 			"kernel compiled with support for large block "
 			"devices.\n");
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/scsi/sr.c linux-libre-3.16.46-gnu/drivers/scsi/sr.c
--- linux-libre-3.16.45-gnu/drivers/scsi/sr.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/scsi/sr.c	2017-07-18 13:40:42.000000000 -0400
@@ -838,6 +838,7 @@ static void get_capabilities(struct scsi
 	unsigned char *buffer;
 	struct scsi_mode_data data;
 	struct scsi_sense_hdr sshdr;
+	unsigned int ms_len = 128;
 	int rc, n;
 
 	static const char *loadmech[] =
@@ -864,10 +865,11 @@ static void get_capabilities(struct scsi
 	scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
 
 	/* ask for mode page 0x2a */
-	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
+	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
 			     SR_TIMEOUT, 3, &data, NULL);
 
-	if (!scsi_status_is_good(rc)) {
+	if (!scsi_status_is_good(rc) || data.length > ms_len ||
+	    data.header_length + data.block_descriptor_length > data.length) {
 		/* failed, drive doesn't have capabilities mode page */
 		cd->cdi.speed = 1;
 		cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/target/iscsi/iscsi_target_parameters.c linux-libre-3.16.46-gnu/drivers/target/iscsi/iscsi_target_parameters.c
--- linux-libre-3.16.45-gnu/drivers/target/iscsi/iscsi_target_parameters.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/target/iscsi/iscsi_target_parameters.c	2017-07-18 13:40:42.000000000 -0400
@@ -804,22 +804,6 @@ static void iscsi_check_proposer_for_opt
 		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
 			SET_PSTATE_REPLY_OPTIONAL(param);
 		/*
-		 * The GlobalSAN iSCSI Initiator for MacOSX does
-		 * not respond to MaxBurstLength, FirstBurstLength,
-		 * DefaultTime2Wait or DefaultTime2Retain parameter keys.
-		 * So, we set them to 'reply optional' here, and assume the
-		 * the defaults from iscsi_parameters.h if the initiator
-		 * is not RFC compliant and the keys are not negotiated.
-		 */
-		if (!strcmp(param->name, MAXBURSTLENGTH))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		if (!strcmp(param->name, FIRSTBURSTLENGTH))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		if (!strcmp(param->name, DEFAULTTIME2WAIT))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		if (!strcmp(param->name, DEFAULTTIME2RETAIN))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		/*
 		 * Required for gPXE iSCSI boot client
 		 */
 		if (!strcmp(param->name, MAXCONNECTIONS))
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/target/iscsi/iscsi_target_util.c linux-libre-3.16.46-gnu/drivers/target/iscsi/iscsi_target_util.c
--- linux-libre-3.16.45-gnu/drivers/target/iscsi/iscsi_target_util.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/target/iscsi/iscsi_target_util.c	2017-07-18 13:40:42.000000000 -0400
@@ -729,21 +729,23 @@ void iscsit_free_cmd(struct iscsi_cmd *c
 {
 	struct se_cmd *se_cmd = NULL;
 	int rc;
+	bool op_scsi = false;
 	/*
 	 * Determine if a struct se_cmd is associated with
 	 * this struct iscsi_cmd.
 	 */
 	switch (cmd->iscsi_opcode) {
 	case ISCSI_OP_SCSI_CMD:
-		se_cmd = &cmd->se_cmd;
-		__iscsit_free_cmd(cmd, true, shutdown);
+		op_scsi = true;
 		/*
 		 * Fallthrough
 		 */
 	case ISCSI_OP_SCSI_TMFUNC:
-		rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
-		if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
-			__iscsit_free_cmd(cmd, true, shutdown);
+		se_cmd = &cmd->se_cmd;
+		__iscsit_free_cmd(cmd, op_scsi, shutdown);
+		rc = transport_generic_free_cmd(se_cmd, shutdown);
+		if (!rc && shutdown && se_cmd->se_sess) {
+			__iscsit_free_cmd(cmd, op_scsi, shutdown);
 			target_put_sess_cmd(se_cmd->se_sess, se_cmd);
 		}
 		break;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/target/target_core_pscsi.c linux-libre-3.16.46-gnu/drivers/target/target_core_pscsi.c
--- linux-libre-3.16.45-gnu/drivers/target/target_core_pscsi.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/target/target_core_pscsi.c	2017-07-18 13:40:42.000000000 -0400
@@ -157,7 +157,7 @@ static void pscsi_tape_read_blocksize(st
 
 	buf = kzalloc(12, GFP_KERNEL);
 	if (!buf)
-		return;
+		goto out_free;
 
 	memset(cdb, 0, MAX_COMMAND_SIZE);
 	cdb[0] = MODE_SENSE;
@@ -172,9 +172,10 @@ static void pscsi_tape_read_blocksize(st
 	 * If MODE_SENSE still returns zero, set the default value to 1024.
 	 */
 	sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]);
+out_free:
 	if (!sdev->sector_size)
 		sdev->sector_size = 1024;
-out_free:
+
 	kfree(buf);
 }
 
@@ -317,9 +318,10 @@ static int pscsi_add_device_to_list(stru
 				sd->lun, sd->queue_depth);
 	}
 
-	dev->dev_attrib.hw_block_size = sd->sector_size;
+	dev->dev_attrib.hw_block_size =
+		min_not_zero((int)sd->sector_size, 512);
 	dev->dev_attrib.hw_max_sectors =
-		min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q));
+		min_not_zero((unsigned int)sd->host->max_sectors, queue_max_hw_sectors(q));
 	dev->dev_attrib.hw_queue_depth = sd->queue_depth;
 
 	/*
@@ -342,8 +344,10 @@ static int pscsi_add_device_to_list(stru
 	/*
 	 * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE.
 	 */
-	if (sd->type == TYPE_TAPE)
+	if (sd->type == TYPE_TAPE) {
 		pscsi_tape_read_blocksize(dev, sd);
+		dev->dev_attrib.hw_block_size = sd->sector_size;
+	}
 	return 0;
 }
 
@@ -409,7 +413,7 @@ static int pscsi_create_type_disk(struct
 /*
  * Called with struct Scsi_Host->host_lock called.
  */
-static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd)
+static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd)
 	__releases(sh->host_lock)
 {
 	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
@@ -436,28 +440,6 @@ static int pscsi_create_type_rom(struct
 	return 0;
 }
 
-/*
- * Called with struct Scsi_Host->host_lock called.
- */
-static int pscsi_create_type_other(struct se_device *dev,
-		struct scsi_device *sd)
-	__releases(sh->host_lock)
-{
-	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
-	struct Scsi_Host *sh = sd->host;
-	int ret;
-
-	spin_unlock_irq(sh->host_lock);
-	ret = pscsi_add_device_to_list(dev, sd);
-	if (ret)
-		return ret;
-
-	pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n",
-		phv->phv_host_id, scsi_device_type(sd->type), sh->host_no,
-		sd->channel, sd->id, sd->lun);
-	return 0;
-}
-
 static int pscsi_configure_device(struct se_device *dev)
 {
 	struct se_hba *hba = dev->se_hba;
@@ -545,11 +527,8 @@ static int pscsi_configure_device(struct
 		case TYPE_DISK:
 			ret = pscsi_create_type_disk(dev, sd);
 			break;
-		case TYPE_ROM:
-			ret = pscsi_create_type_rom(dev, sd);
-			break;
 		default:
-			ret = pscsi_create_type_other(dev, sd);
+			ret = pscsi_create_type_nondisk(dev, sd);
 			break;
 		}
 
@@ -606,8 +585,7 @@ static void pscsi_free_device(struct se_
 		else if (pdv->pdv_lld_host)
 			scsi_host_put(pdv->pdv_lld_host);
 
-		if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM))
-			scsi_device_put(sd);
+		scsi_device_put(sd);
 
 		pdv->pdv_sd = NULL;
 	}
@@ -1125,7 +1103,6 @@ static sector_t pscsi_get_blocks(struct
 	if (pdv->pdv_bd && pdv->pdv_bd->bd_part)
 		return pdv->pdv_bd->bd_part->nr_sects;
 
-	dump_stack();
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/target/target_core_sbc.c linux-libre-3.16.46-gnu/drivers/target/target_core_sbc.c
--- linux-libre-3.16.45-gnu/drivers/target/target_core_sbc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/target/target_core_sbc.c	2017-07-18 13:40:42.000000000 -0400
@@ -950,9 +950,15 @@ sbc_parse_cdb(struct se_cmd *cmd, struct
 			return ret;
 		break;
 	case VERIFY:
+	case VERIFY_16:
 		size = 0;
-		sectors = transport_get_sectors_10(cdb);
-		cmd->t_task_lba = transport_lba_32(cdb);
+		if (cdb[0] == VERIFY) {
+			sectors = transport_get_sectors_10(cdb);
+			cmd->t_task_lba = transport_lba_32(cdb);
+		} else {
+			sectors = transport_get_sectors_16(cdb);
+			cmd->t_task_lba = transport_lba_64(cdb);
+		}
 		cmd->execute_cmd = sbc_emulate_noop;
 		goto check_lba;
 	case REZERO_UNIT:
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/tty/serial/mxs-auart.c linux-libre-3.16.46-gnu/drivers/tty/serial/mxs-auart.c
--- linux-libre-3.16.45-gnu/drivers/tty/serial/mxs-auart.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/tty/serial/mxs-auart.c	2017-07-18 13:40:42.000000000 -0400
@@ -90,6 +90,8 @@
 #define AUART_CTRL2_TXE				(1 << 8)
 #define AUART_CTRL2_UARTEN			(1 << 0)
 
+#define AUART_LINECTRL_BAUD_DIV_MAX		0x003fffc0
+#define AUART_LINECTRL_BAUD_DIV_MIN		0x000000ec
 #define AUART_LINECTRL_BAUD_DIVINT_SHIFT	16
 #define AUART_LINECTRL_BAUD_DIVINT_MASK		0xffff0000
 #define AUART_LINECTRL_BAUD_DIVINT(v)		(((v) & 0xffff) << 16)
@@ -566,7 +568,7 @@ static void mxs_auart_settermios(struct
 {
 	struct mxs_auart_port *s = to_auart_port(u);
 	u32 bm, ctrl, ctrl2, div;
-	unsigned int cflag, baud;
+	unsigned int cflag, baud, baud_min, baud_max;
 
 	cflag = termios->c_cflag;
 
@@ -656,8 +658,10 @@ static void mxs_auart_settermios(struct
 	}
 
 	/* set baud rate */
-	baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
-	div = u->uartclk * 32 / baud;
+	baud_min = DIV_ROUND_UP(u->uartclk * 32, AUART_LINECTRL_BAUD_DIV_MAX);
+	baud_max = u->uartclk * 32 / AUART_LINECTRL_BAUD_DIV_MIN;
+	baud = uart_get_baud_rate(u, termios, old, baud_min, baud_max);
+	div = DIV_ROUND_CLOSEST(u->uartclk * 32, baud);
 	ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
 	ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/class/usbtmc.c linux-libre-3.16.46-gnu/drivers/usb/class/usbtmc.c
--- linux-libre-3.16.45-gnu/drivers/usb/class/usbtmc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/class/usbtmc.c	2017-07-18 13:40:42.000000000 -0400
@@ -1104,7 +1104,7 @@ static int usbtmc_probe(struct usb_inter
 
 	dev_dbg(&intf->dev, "%s called\n", __func__);
 
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data) {
 		dev_err(&intf->dev, "Unable to allocate kernel memory\n");
 		return -ENOMEM;
@@ -1164,6 +1164,12 @@ static int usbtmc_probe(struct usb_inter
 		}
 	}
 
+	if (!data->bulk_out || !data->bulk_in) {
+		dev_err(&intf->dev, "bulk endpoints not found\n");
+		retcode = -ENODEV;
+		goto err_put;
+	}
+
 	retcode = get_capabilities(data);
 	if (retcode)
 		dev_err(&intf->dev, "can't read capabilities\n");
@@ -1187,6 +1193,7 @@ static int usbtmc_probe(struct usb_inter
 error_register:
 	sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
 	sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
+err_put:
 	kref_put(&data->kref, usbtmc_delete);
 	return retcode;
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/core/config.c linux-libre-3.16.46-gnu/drivers/usb/core/config.c
--- linux-libre-3.16.45-gnu/drivers/usb/core/config.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/core/config.c	2017-07-18 13:40:42.000000000 -0400
@@ -245,6 +245,16 @@ static int usb_parse_endpoint(struct dev
 
 			/*
 			 * Adjust bInterval for quirked devices.
+			 */
+			/*
+			 * This quirk fixes bIntervals reported in ms.
+			 */
+			if (to_usb_device(ddev)->quirks &
+				USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
+				n = clamp(fls(d->bInterval) + 3, i, j);
+				i = j = n;
+			}
+			/*
 			 * This quirk fixes bIntervals reported in
 			 * linear microframes.
 			 */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/core/hcd.c linux-libre-3.16.46-gnu/drivers/usb/core/hcd.c
--- linux-libre-3.16.45-gnu/drivers/usb/core/hcd.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/core/hcd.c	2017-07-18 13:40:42.000000000 -0400
@@ -497,8 +497,10 @@ static int rh_call_control (struct usb_h
 	 */
 	tbuf_size =  max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
 	tbuf = kzalloc(tbuf_size, GFP_KERNEL);
-	if (!tbuf)
-		return -ENOMEM;
+	if (!tbuf) {
+		status = -ENOMEM;
+		goto err_alloc;
+	}
 
 	bufp = tbuf;
 
@@ -701,6 +703,7 @@ error:
 	}
 
 	kfree(tbuf);
+ err_alloc:
 
 	/* any errors get returned through the urb completion */
 	spin_lock_irq(&hcd_root_hub_lock);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/core/hub.c linux-libre-3.16.46-gnu/drivers/usb/core/hub.c
--- linux-libre-3.16.45-gnu/drivers/usb/core/hub.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/core/hub.c	2017-07-18 13:40:42.000000000 -0400
@@ -4148,7 +4148,7 @@ static void hub_set_initial_usb2_lpm_pol
 	struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
 	int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
 
-	if (!udev->usb2_hw_lpm_capable)
+	if (!udev->usb2_hw_lpm_capable || !udev->bos)
 		return;
 
 	if (hub)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/core/quirks.c linux-libre-3.16.46-gnu/drivers/usb/core/quirks.c
--- linux-libre-3.16.45-gnu/drivers/usb/core/quirks.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/core/quirks.c	2017-07-18 13:40:42.000000000 -0400
@@ -167,6 +167,14 @@ static const struct usb_device_id usb_qu
 	/* M-Systems Flash Disk Pioneers */
 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Baum Vario Ultra */
+	{ USB_DEVICE(0x0904, 0x6101), .driver_info =
+			USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+	{ USB_DEVICE(0x0904, 0x6102), .driver_info =
+			USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+	{ USB_DEVICE(0x0904, 0x6103), .driver_info =
+			USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+
 	/* Keytouch QWERTY Panel keyboard */
 	{ USB_DEVICE(0x0926, 0x3333), .driver_info =
 			USB_QUIRK_CONFIG_INTF_STRINGS },
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/dwc3/gadget.h linux-libre-3.16.46-gnu/drivers/usb/dwc3/gadget.h
--- linux-libre-3.16.45-gnu/drivers/usb/dwc3/gadget.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/dwc3/gadget.h	2017-07-18 13:40:42.000000000 -0400
@@ -28,23 +28,23 @@ struct dwc3;
 #define gadget_to_dwc(g)	(container_of(g, struct dwc3, gadget))
 
 /* DEPCFG parameter 1 */
-#define DWC3_DEPCFG_INT_NUM(n)		((n) << 0)
+#define DWC3_DEPCFG_INT_NUM(n)		(((n) & 0x1f) << 0)
 #define DWC3_DEPCFG_XFER_COMPLETE_EN	(1 << 8)
 #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	(1 << 9)
 #define DWC3_DEPCFG_XFER_NOT_READY_EN	(1 << 10)
 #define DWC3_DEPCFG_FIFO_ERROR_EN	(1 << 11)
 #define DWC3_DEPCFG_STREAM_EVENT_EN	(1 << 13)
-#define DWC3_DEPCFG_BINTERVAL_M1(n)	((n) << 16)
+#define DWC3_DEPCFG_BINTERVAL_M1(n)	(((n) & 0xff) << 16)
 #define DWC3_DEPCFG_STREAM_CAPABLE	(1 << 24)
-#define DWC3_DEPCFG_EP_NUMBER(n)	((n) << 25)
+#define DWC3_DEPCFG_EP_NUMBER(n)	(((n) & 0x1f) << 25)
 #define DWC3_DEPCFG_BULK_BASED		(1 << 30)
 #define DWC3_DEPCFG_FIFO_BASED		(1 << 31)
 
 /* DEPCFG parameter 0 */
-#define DWC3_DEPCFG_EP_TYPE(n)		((n) << 1)
-#define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	((n) << 3)
-#define DWC3_DEPCFG_FIFO_NUMBER(n)	((n) << 17)
-#define DWC3_DEPCFG_BURST_SIZE(n)	((n) << 22)
+#define DWC3_DEPCFG_EP_TYPE(n)		(((n) & 0x3) << 1)
+#define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	(((n) & 0x7ff) << 3)
+#define DWC3_DEPCFG_FIFO_NUMBER(n)	(((n) & 0x1f) << 17)
+#define DWC3_DEPCFG_BURST_SIZE(n)	(((n) & 0xf) << 22)
 #define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
 /* This applies for core versions earlier than 1.94a */
 #define DWC3_DEPCFG_IGN_SEQ_NUM		(1 << 31)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/gadget/f_acm.c linux-libre-3.16.46-gnu/drivers/usb/gadget/f_acm.c
--- linux-libre-3.16.45-gnu/drivers/usb/gadget/f_acm.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/gadget/f_acm.c	2017-07-18 13:40:42.000000000 -0400
@@ -535,13 +535,15 @@ static int acm_notify_serial_state(struc
 {
 	struct usb_composite_dev *cdev = acm->port.func.config->cdev;
 	int			status;
+	__le16			serial_state;
 
 	spin_lock(&acm->lock);
 	if (acm->notify_req) {
 		DBG(cdev, "acm ttyGS%d serial state %04x\n",
 				acm->port_num, acm->serial_state);
+		serial_state = cpu_to_le16(acm->serial_state);
 		status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE,
-				0, &acm->serial_state, sizeof(acm->serial_state));
+				0, &serial_state, sizeof(acm->serial_state));
 	} else {
 		acm->pending = true;
 		status = 0;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/gadget/f_fs.c linux-libre-3.16.46-gnu/drivers/usb/gadget/f_fs.c
--- linux-libre-3.16.45-gnu/drivers/usb/gadget/f_fs.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/gadget/f_fs.c	2017-07-18 13:40:42.000000000 -0400
@@ -1619,11 +1619,14 @@ static int ffs_func_eps_enable(struct ff
 	spin_lock_irqsave(&func->ffs->eps_lock, flags);
 	do {
 		struct usb_endpoint_descriptor *ds;
+		struct usb_ss_ep_comp_descriptor *comp_desc = NULL;
+		int needs_comp_desc = false;
 		int desc_idx;
 
-		if (ffs->gadget->speed == USB_SPEED_SUPER)
+		if (ffs->gadget->speed == USB_SPEED_SUPER) {
 			desc_idx = 2;
-		else if (ffs->gadget->speed == USB_SPEED_HIGH)
+			needs_comp_desc = true;
+		} else if (ffs->gadget->speed == USB_SPEED_HIGH)
 			desc_idx = 1;
 		else
 			desc_idx = 0;
@@ -1640,6 +1643,14 @@ static int ffs_func_eps_enable(struct ff
 
 		ep->ep->driver_data = ep;
 		ep->ep->desc = ds;
+
+		comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
+				USB_DT_ENDPOINT_SIZE);
+		ep->ep->maxburst = comp_desc->bMaxBurst + 1;
+
+		if (needs_comp_desc)
+			ep->ep->comp_desc = comp_desc;
+
 		ret = usb_ep_enable(ep->ep);
 		if (likely(!ret)) {
 			epfile->ep = ep;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/gadget/f_uvc.c linux-libre-3.16.46-gnu/drivers/usb/gadget/f_uvc.c
--- linux-libre-3.16.45-gnu/drivers/usb/gadget/f_uvc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/gadget/f_uvc.c	2017-07-18 13:40:42.000000000 -0400
@@ -611,19 +611,21 @@ uvc_function_bind(struct usb_configurati
 		max_packet_size = streaming_maxpacket / 3;
 	}
 
-	uvc_fs_streaming_ep.wMaxPacketSize = min(streaming_maxpacket, 1023U);
+	uvc_fs_streaming_ep.wMaxPacketSize =
+		cpu_to_le16(min(streaming_maxpacket, 1023U));
 	uvc_fs_streaming_ep.bInterval = streaming_interval;
 
-	uvc_hs_streaming_ep.wMaxPacketSize = max_packet_size;
-	uvc_hs_streaming_ep.wMaxPacketSize |= ((max_packet_mult - 1) << 11);
+	uvc_hs_streaming_ep.wMaxPacketSize =
+		cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11));
 	uvc_hs_streaming_ep.bInterval = streaming_interval;
 
-	uvc_ss_streaming_ep.wMaxPacketSize = max_packet_size;
+	uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
 	uvc_ss_streaming_ep.bInterval = streaming_interval;
 	uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
 	uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst;
 	uvc_ss_streaming_comp.wBytesPerInterval =
-		max_packet_size * max_packet_mult * streaming_maxburst;
+		cpu_to_le16(max_packet_size * max_packet_mult *
+			    (streaming_maxburst + 1));
 
 	/* Allocate endpoints. */
 	ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/host/xhci.c linux-libre-3.16.46-gnu/drivers/usb/host/xhci.c
--- linux-libre-3.16.45-gnu/drivers/usb/host/xhci.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/host/xhci.c	2017-07-18 13:40:42.000000000 -0400
@@ -1533,20 +1533,33 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
 	struct xhci_ring *ep_ring;
 	struct xhci_virt_ep *ep;
 	struct xhci_command *command;
+	struct xhci_virt_device *vdev;
 
 	xhci = hcd_to_xhci(hcd);
 	spin_lock_irqsave(&xhci->lock, flags);
 	/* Make sure the URB hasn't completed or been unlinked already */
 	ret = usb_hcd_check_unlink_urb(hcd, urb, status);
-	if (ret || !urb->hcpriv)
+	if (ret)
 		goto done;
+
+	/* give back URB now if we can't queue it for cancel */
+	vdev = xhci->devs[urb->dev->slot_id];
+	urb_priv = urb->hcpriv;
+	if (!vdev || !urb_priv)
+		goto err_giveback;
+
+	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+	ep = &vdev->eps[ep_index];
+	ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
+	if (!ep || !ep_ring)
+		goto err_giveback;
+
 	temp = readl(&xhci->op_regs->status);
 	if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
 		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 				"HW died, freeing TD.");
-		urb_priv = urb->hcpriv;
 		for (i = urb_priv->td_cnt;
-		     i < urb_priv->length && xhci->devs[urb->dev->slot_id];
+		     i < urb_priv->length;
 		     i++) {
 			td = urb_priv->td[i];
 			if (!list_empty(&td->td_list))
@@ -1554,23 +1567,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
 			if (!list_empty(&td->cancelled_td_list))
 				list_del_init(&td->cancelled_td_list);
 		}
-
-		usb_hcd_unlink_urb_from_ep(hcd, urb);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
-		xhci_urb_free_priv(xhci, urb_priv);
-		return ret;
-	}
-
-	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-	ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
-	ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
-	if (!ep_ring) {
-		ret = -EINVAL;
-		goto done;
+		goto err_giveback;
 	}
 
-	urb_priv = urb->hcpriv;
 	i = urb_priv->td_cnt;
 	if (i < urb_priv->length)
 		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
@@ -1604,6 +1603,14 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
 done:
 	spin_unlock_irqrestore(&xhci->lock, flags);
 	return ret;
+
+err_giveback:
+	if (urb_priv)
+		xhci_urb_free_priv(xhci, urb_priv);
+	usb_hcd_unlink_urb_from_ep(hcd, urb);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+	usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
+	return ret;
 }
 
 /* Drop an endpoint from a new bandwidth configuration for this device.
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/misc/idmouse.c linux-libre-3.16.46-gnu/drivers/usb/misc/idmouse.c
--- linux-libre-3.16.45-gnu/drivers/usb/misc/idmouse.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/misc/idmouse.c	2017-07-18 13:40:42.000000000 -0400
@@ -346,6 +346,9 @@ static int idmouse_probe(struct usb_inte
 	if (iface_desc->desc.bInterfaceClass != 0x0A)
 		return -ENODEV;
 
+	if (iface_desc->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	/* allocate memory for our device state and initialize it */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/misc/iowarrior.c linux-libre-3.16.46-gnu/drivers/usb/misc/iowarrior.c
--- linux-libre-3.16.45-gnu/drivers/usb/misc/iowarrior.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/misc/iowarrior.c	2017-07-18 13:40:42.000000000 -0400
@@ -804,6 +804,14 @@ static int iowarrior_probe(struct usb_in
 		goto error;
 	}
 
+	if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56) {
+		if (!dev->int_out_endpoint) {
+			dev_err(&interface->dev, "no interrupt-out endpoint found\n");
+			retval = -ENODEV;
+			goto error;
+		}
+	}
+
 	/* we have to check the report_size often, so remember it in the endianness suitable for our machine */
 	dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);
 	if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/misc/uss720.c linux-libre-3.16.46-gnu/drivers/usb/misc/uss720.c
--- linux-libre-3.16.45-gnu/drivers/usb/misc/uss720.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/misc/uss720.c	2017-07-18 13:40:42.000000000 -0400
@@ -715,6 +715,11 @@ static int uss720_probe(struct usb_inter
 
 	interface = intf->cur_altsetting;
 
+	if (interface->desc.bNumEndpoints < 3) {
+		usb_put_dev(usbdev);
+		return -ENODEV;
+	}
+
 	/*
 	 * Allocate parport interface 
 	 */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/serial/digi_acceleport.c linux-libre-3.16.46-gnu/drivers/usb/serial/digi_acceleport.c
--- linux-libre-3.16.45-gnu/drivers/usb/serial/digi_acceleport.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/serial/digi_acceleport.c	2017-07-18 13:40:42.000000000 -0400
@@ -1501,7 +1501,7 @@ static int digi_read_oob_callback(struct
 		return -1;
 
 	/* handle each oob command */
-	for (i = 0; i < urb->actual_length - 4; i += 4) {
+	for (i = 0; i < urb->actual_length - 3; i += 4) {
 		opcode = buf[i];
 		line = buf[i + 1];
 		status = buf[i + 2];
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/serial/io_ti.c linux-libre-3.16.46-gnu/drivers/usb/serial/io_ti.c
--- linux-libre-3.16.45-gnu/drivers/usb/serial/io_ti.c	2017-07-03 11:42:59.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/serial/io_ti.c	2017-07-18 17:47:20.000000000 -0400
@@ -1550,6 +1550,12 @@ static void edge_interrupt_callback(stru
 	function    = TIUMP_GET_FUNC_FROM_CODE(data[0]);
 	dev_dbg(dev, "%s - port_number %d, function %d, info 0x%x\n", __func__,
 		port_number, function, data[1]);
+
+	if (port_number >= edge_serial->serial->num_ports) {
+		dev_err(dev, "bad port number %d\n", port_number);
+		goto exit;
+	}
+
 	port = edge_serial->serial->port[port_number];
 	edge_port = usb_get_serial_port_data(port);
 	if (!edge_port) {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/serial/option.c linux-libre-3.16.46-gnu/drivers/usb/serial/option.c
--- linux-libre-3.16.45-gnu/drivers/usb/serial/option.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/serial/option.c	2017-07-18 13:40:42.000000000 -0400
@@ -234,6 +234,14 @@ static void option_instat_callback(struc
 #define BANDRICH_PRODUCT_1012			0x1012
 
 #define QUALCOMM_VENDOR_ID			0x05C6
+/* These Quectel products use Qualcomm's vendor ID */
+#define QUECTEL_PRODUCT_UC20			0x9003
+#define QUECTEL_PRODUCT_UC15			0x9090
+
+#define QUECTEL_VENDOR_ID			0x2c7c
+/* These Quectel products use Quectel's vendor ID */
+#define QUECTEL_PRODUCT_EC21			0x0121
+#define QUECTEL_PRODUCT_EC25			0x0125
 
 #define SIERRA_VENDOR_ID			0x1199
 
@@ -1180,7 +1188,14 @@ static const struct usb_device_id option
 	  .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */
 	{ USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x9041, 0xff),
 	  .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC7305/MC7355 */
-	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
+	/* Quectel products using Qualcomm vendor ID */
+	{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
+	{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
+	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+	/* Quectel products using Quectel vendor ID */
+	{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
+	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+	{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25),
 	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/serial/qcserial.c linux-libre-3.16.46-gnu/drivers/usb/serial/qcserial.c
--- linux-libre-3.16.45-gnu/drivers/usb/serial/qcserial.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/serial/qcserial.c	2017-07-18 13:40:42.000000000 -0400
@@ -167,6 +167,8 @@ static const struct usb_device_id id_tab
 	{DEVICE_SWI(0x413c, 0x81a9)},	/* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81b1)},	/* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
 	{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 */
 
 	/* Huawei devices */
 	{DEVICE_HWI(0x03f0, 0x581d)},	/* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/serial/safe_serial.c linux-libre-3.16.46-gnu/drivers/usb/serial/safe_serial.c
--- linux-libre-3.16.45-gnu/drivers/usb/serial/safe_serial.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/serial/safe_serial.c	2017-07-18 13:40:42.000000000 -0400
@@ -205,6 +205,11 @@ static void safe_process_read_urb(struct
 	if (!safe)
 		goto out;
 
+	if (length < 2) {
+		dev_err(&port->dev, "malformed packet\n");
+		return;
+	}
+
 	fcs = fcs_compute10(data, length, CRC10_INITFCS);
 	if (fcs) {
 		dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/usb/wusbcore/wa-hc.c linux-libre-3.16.46-gnu/drivers/usb/wusbcore/wa-hc.c
--- linux-libre-3.16.45-gnu/drivers/usb/wusbcore/wa-hc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/usb/wusbcore/wa-hc.c	2017-07-18 13:40:42.000000000 -0400
@@ -39,6 +39,9 @@ int wa_create(struct wahc *wa, struct us
 	int result;
 	struct device *dev = &iface->dev;
 
+	if (iface->cur_altsetting->desc.bNumEndpoints < 3)
+		return -ENODEV;
+
 	result = wa_rpipes_create(wa);
 	if (result < 0)
 		goto error_rpipes_create;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/uwb/hwa-rc.c linux-libre-3.16.46-gnu/drivers/uwb/hwa-rc.c
--- linux-libre-3.16.45-gnu/drivers/uwb/hwa-rc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/uwb/hwa-rc.c	2017-07-18 13:40:42.000000000 -0400
@@ -825,6 +825,9 @@ static int hwarc_probe(struct usb_interf
 	struct hwarc *hwarc;
 	struct device *dev = &iface->dev;
 
+	if (iface->cur_altsetting->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	result = -ENOMEM;
 	uwb_rc = uwb_rc_alloc();
 	if (uwb_rc == NULL) {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/uwb/i1480/dfu/usb.c linux-libre-3.16.46-gnu/drivers/uwb/i1480/dfu/usb.c
--- linux-libre-3.16.45-gnu/drivers/uwb/i1480/dfu/usb.c	2017-07-03 11:43:55.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/uwb/i1480/dfu/usb.c	2017-07-18 17:47:55.000000000 -0400
@@ -362,6 +362,9 @@ int i1480_usb_probe(struct usb_interface
 				 result);
 	}
 
+	if (iface->cur_altsetting->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	result = -ENOMEM;
 	i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL);
 	if (i1480_usb == NULL) {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/video/fbdev/xen-fbfront.c linux-libre-3.16.46-gnu/drivers/video/fbdev/xen-fbfront.c
--- linux-libre-3.16.45-gnu/drivers/video/fbdev/xen-fbfront.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/video/fbdev/xen-fbfront.c	2017-07-18 13:40:42.000000000 -0400
@@ -644,7 +644,6 @@ static void xenfb_backend_changed(struct
 		break;
 
 	case XenbusStateInitWait:
-InitWait:
 		xenbus_switch_state(dev, XenbusStateConnected);
 		break;
 
@@ -655,7 +654,8 @@ InitWait:
 		 * get Connected twice here.
 		 */
 		if (dev->state != XenbusStateConnected)
-			goto InitWait; /* no InitWait seen yet, fudge it */
+			/* no InitWait seen yet, fudge it */
+			xenbus_switch_state(dev, XenbusStateConnected);
 
 		if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
 				 "request-update", "%d", &val) < 0)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/virtio/virtio_balloon.c linux-libre-3.16.46-gnu/drivers/virtio/virtio_balloon.c
--- linux-libre-3.16.45-gnu/drivers/virtio/virtio_balloon.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/virtio/virtio_balloon.c	2017-07-18 13:40:42.000000000 -0400
@@ -218,12 +218,14 @@ static void update_balloon_stats(struct
 	all_vm_events(events);
 	si_meminfo(&i);
 
+#ifdef CONFIG_VM_EVENT_COUNTERS
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
 				pages_to_bytes(events[PSWPIN]));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
 				pages_to_bytes(events[PSWPOUT]));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]);
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]);
+#endif
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE,
 				pages_to_bytes(i.freeram));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
@@ -346,6 +348,8 @@ static int init_vqs(struct virtio_balloo
 		 * Prime this virtqueue with one buffer so the hypervisor can
 		 * use it to signal us later (it can't be broken yet!).
 		 */
+		update_balloon_stats(vb);
+
 		sg_init_one(&sg, vb->stats, sizeof vb->stats);
 		if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
 		    < 0)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/drivers/xen/xen-acpi-processor.c linux-libre-3.16.46-gnu/drivers/xen/xen-acpi-processor.c
--- linux-libre-3.16.45-gnu/drivers/xen/xen-acpi-processor.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/drivers/xen/xen-acpi-processor.c	2017-07-18 13:40:42.000000000 -0400
@@ -27,10 +27,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/syscore_ops.h>
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 #include <xen/xen.h>
-#include <xen/xen-ops.h>
 #include <xen/interface/platform.h>
 #include <asm/xen/hypercall.h>
 
@@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(
 	return rc;
 }
 
-static int xen_acpi_processor_resume(struct notifier_block *nb,
-				     unsigned long action, void *data)
+static void xen_acpi_processor_resume_worker(struct work_struct *dummy)
 {
+	int rc;
+
 	bitmap_zero(acpi_ids_done, nr_acpi_bits);
-	return xen_upload_processor_pm_data();
+
+	rc = xen_upload_processor_pm_data();
+	if (rc != 0)
+		pr_info("ACPI data upload failed, error = %d\n", rc);
 }
 
-struct notifier_block xen_acpi_processor_resume_nb = {
-	.notifier_call = xen_acpi_processor_resume,
+static void xen_acpi_processor_resume(void)
+{
+	static DECLARE_WORK(wq, xen_acpi_processor_resume_worker);
+
+	/*
+	 * xen_upload_processor_pm_data() calls non-atomic code.
+	 * However, the context for xen_acpi_processor_resume is syscore
+	 * with only the boot CPU online and in an atomic context.
+	 *
+	 * So defer the upload for some point safer.
+	 */
+	schedule_work(&wq);
+}
+
+static struct syscore_ops xap_syscore_ops = {
+	.resume	= xen_acpi_processor_resume,
 };
 
 static int __init xen_acpi_processor_init(void)
@@ -527,7 +545,7 @@ static int __init xen_acpi_processor_ini
 	if (rc)
 		goto err_unregister;
 
-	xen_resume_notifier_register(&xen_acpi_processor_resume_nb);
+	register_syscore_ops(&xap_syscore_ops);
 
 	return 0;
 err_unregister:
@@ -546,7 +564,7 @@ static void __exit xen_acpi_processor_ex
 {
 	int i;
 
-	xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb);
+	unregister_syscore_ops(&xap_syscore_ops);
 	kfree(acpi_ids_done);
 	kfree(acpi_id_present);
 	kfree(acpi_id_cst_present);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/ceph/inode.c linux-libre-3.16.46-gnu/fs/ceph/inode.c
--- linux-libre-3.16.45-gnu/fs/ceph/inode.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/ceph/inode.c	2017-07-18 13:40:42.000000000 -0400
@@ -1875,12 +1875,6 @@ int ceph_setattr(struct dentry *dentry,
 	if (inode_dirty_flags)
 		__mark_inode_dirty(inode, inode_dirty_flags);
 
-	if (ia_valid & ATTR_MODE) {
-		err = posix_acl_chmod(inode, attr->ia_mode);
-		if (err)
-			goto out_put;
-	}
-
 	if (mask) {
 		req->r_inode = inode;
 		ihold(inode);
@@ -1893,12 +1887,16 @@ int ceph_setattr(struct dentry *dentry,
 	     ceph_cap_string(dirtied), mask);
 
 	ceph_mdsc_put_request(req);
-	if (mask & CEPH_SETATTR_SIZE)
+
+	if (err >= 0 && (mask & CEPH_SETATTR_SIZE))
 		__ceph_do_pending_vmtruncate(inode);
+
+	if (err >= 0 && (attr->ia_valid & ATTR_MODE))
+		err = posix_acl_chmod(inode, attr->ia_mode);
+
 	return err;
 out:
 	spin_unlock(&ci->i_ceph_lock);
-out_put:
 	ceph_mdsc_put_request(req);
 	return err;
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/cifsglob.h linux-libre-3.16.46-gnu/fs/cifs/cifsglob.h
--- linux-libre-3.16.45-gnu/fs/cifs/cifsglob.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/cifsglob.h	2017-07-18 13:40:42.000000000 -0400
@@ -223,6 +223,7 @@ struct smb_version_operations {
 	/* verify the message */
 	int (*check_message)(char *, unsigned int);
 	bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
+	int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *);
 	void (*downgrade_oplock)(struct TCP_Server_Info *,
 					struct cifsInodeInfo *, bool);
 	/* process transaction2 response */
@@ -872,7 +873,6 @@ struct cifs_tcon {
 	bool need_reconnect:1; /* connection reset, tid now invalid */
 #ifdef CONFIG_CIFS_SMB2
 	bool print:1;		/* set if connection to printer share */
-	bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
 	__le32 capabilities;
 	__u32 share_flags;
 	__u32 maximal_access;
@@ -1246,12 +1246,19 @@ struct mid_q_entry {
 	void *callback_data;	  /* general purpose pointer for callback */
 	void *resp_buf;		/* pointer to received SMB header */
 	int mid_state;	/* wish this were enum but can not pass to wait_event */
+	unsigned int mid_flags;
 	__le16 command;		/* smb command code */
 	bool large_buf:1;	/* if valid response, is pointer to large buf */
 	bool multiRsp:1;	/* multiple trans2 responses for one request  */
 	bool multiEnd:1;	/* both received */
 };
 
+struct close_cancelled_open {
+	struct cifs_fid         fid;
+	struct cifs_tcon        *tcon;
+	struct work_struct      work;
+};
+
 /*	Make code in transport.c a little cleaner by moving
 	update of optional stats into function below */
 #ifdef CONFIG_CIFS_STATS2
@@ -1383,6 +1390,9 @@ static inline void free_dfs_info_array(s
 #define   MID_RESPONSE_MALFORMED 0x10
 #define   MID_SHUTDOWN		 0x20
 
+/* Flags */
+#define   MID_WAIT_CANCELLED	 1 /* Cancelled while waiting for response */
+
 /* Types of response buffer returned from SendReceive2 */
 #define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
 #define   CIFS_SMALL_BUFFER     1
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/cifssmb.c linux-libre-3.16.46-gnu/fs/cifs/cifssmb.c
--- linux-libre-3.16.45-gnu/fs/cifs/cifssmb.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/cifssmb.c	2017-07-18 13:40:42.000000000 -0400
@@ -1427,6 +1427,8 @@ cifs_readv_discard(struct TCP_Server_Inf
 
 	length = discard_remaining_data(server);
 	dequeue_mid(mid, rdata->result);
+	mid->resp_buf = server->smallbuf;
+	server->smallbuf = NULL;
 	return length;
 }
 
@@ -1542,6 +1544,8 @@ cifs_readv_receive(struct TCP_Server_Inf
 		return cifs_readv_discard(server, mid);
 
 	dequeue_mid(mid, false);
+	mid->resp_buf = server->smallbuf;
+	server->smallbuf = NULL;
 	return length;
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/connect.c linux-libre-3.16.46-gnu/fs/cifs/connect.c
--- linux-libre-3.16.45-gnu/fs/cifs/connect.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/connect.c	2017-07-18 13:40:42.000000000 -0400
@@ -911,10 +911,19 @@ cifs_demultiplex_thread(void *p)
 
 		server->lstrp = jiffies;
 		if (mid_entry != NULL) {
+			if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) &&
+			     mid_entry->mid_state == MID_RESPONSE_RECEIVED &&
+					server->ops->handle_cancelled_mid)
+				server->ops->handle_cancelled_mid(
+							mid_entry->resp_buf,
+							server);
+
 			if (!mid_entry->multiRsp || mid_entry->multiEnd)
 				mid_entry->callback(mid_entry);
-		} else if (!server->ops->is_oplock_break ||
-			   !server->ops->is_oplock_break(buf, server)) {
+		} else if (server->ops->is_oplock_break &&
+			   server->ops->is_oplock_break(buf, server)) {
+			cifs_dbg(FYI, "Received oplock break\n");
+		} else {
 			cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
 				 atomic_read(&midCount));
 			cifs_dump_mem("Received Data is: ", buf,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/smb1ops.c linux-libre-3.16.46-gnu/fs/cifs/smb1ops.c
--- linux-libre-3.16.45-gnu/fs/cifs/smb1ops.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/smb1ops.c	2017-07-18 13:40:42.000000000 -0400
@@ -1015,6 +1015,15 @@ cifs_dir_needs_close(struct cifsFileInfo
 	return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle;
 }
 
+static bool
+cifs_can_echo(struct TCP_Server_Info *server)
+{
+	if (server->tcpStatus == CifsGood)
+		return true;
+
+	return false;
+}
+
 struct smb_version_operations smb1_operations = {
 	.send_cancel = send_nt_cancel,
 	.compare_fids = cifs_compare_fids,
@@ -1048,6 +1057,7 @@ struct smb_version_operations smb1_opera
 	.get_dfs_refer = CIFSGetDFSRefer,
 	.qfs_tcon = cifs_qfs_tcon,
 	.is_path_accessible = cifs_is_path_accessible,
+	.can_echo = cifs_can_echo,
 	.query_path_info = cifs_query_path_info,
 	.query_file_info = cifs_query_file_info,
 	.get_srv_inum = cifs_get_srv_inum,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/smb2misc.c linux-libre-3.16.46-gnu/fs/cifs/smb2misc.c
--- linux-libre-3.16.45-gnu/fs/cifs/smb2misc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/smb2misc.c	2017-07-18 13:40:42.000000000 -0400
@@ -607,3 +607,47 @@ smb2_is_valid_oplock_break(char *buffer,
 	cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
 	return false;
 }
+
+void
+smb2_cancelled_close_fid(struct work_struct *work)
+{
+	struct close_cancelled_open *cancelled = container_of(work,
+					struct close_cancelled_open, work);
+
+	cifs_dbg(VFS, "Close unmatched open\n");
+
+	SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid,
+		   cancelled->fid.volatile_fid);
+	cifs_put_tcon(cancelled->tcon);
+	kfree(cancelled);
+}
+
+int
+smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
+{
+	struct smb2_hdr *hdr = (struct smb2_hdr *)buffer;
+	struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
+	struct cifs_tcon *tcon;
+	struct close_cancelled_open *cancelled;
+
+	if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS)
+		return 0;
+
+	cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
+	if (!cancelled)
+		return -ENOMEM;
+
+	tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId);
+	if (!tcon) {
+		kfree(cancelled);
+		return -ENOENT;
+	}
+
+	cancelled->fid.persistent_fid = rsp->PersistentFileId;
+	cancelled->fid.volatile_fid = rsp->VolatileFileId;
+	cancelled->tcon = tcon;
+	INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
+	queue_work(cifsiod_wq, &cancelled->work);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/smb2ops.c linux-libre-3.16.46-gnu/fs/cifs/smb2ops.c
--- linux-libre-3.16.45-gnu/fs/cifs/smb2ops.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/smb2ops.c	2017-07-18 13:40:42.000000000 -0400
@@ -1163,6 +1163,7 @@ struct smb_version_operations smb20_oper
 	.clear_stats = smb2_clear_stats,
 	.print_stats = smb2_print_stats,
 	.is_oplock_break = smb2_is_valid_oplock_break,
+	.handle_cancelled_mid = smb2_handle_cancelled_mid,
 	.downgrade_oplock = smb2_downgrade_oplock,
 	.need_neg = smb2_need_neg,
 	.negotiate = smb2_negotiate,
@@ -1239,6 +1240,7 @@ struct smb_version_operations smb21_oper
 	.clear_stats = smb2_clear_stats,
 	.print_stats = smb2_print_stats,
 	.is_oplock_break = smb2_is_valid_oplock_break,
+	.handle_cancelled_mid = smb2_handle_cancelled_mid,
 	.downgrade_oplock = smb2_downgrade_oplock,
 	.need_neg = smb2_need_neg,
 	.negotiate = smb2_negotiate,
@@ -1316,6 +1318,7 @@ struct smb_version_operations smb30_oper
 	.print_stats = smb2_print_stats,
 	.dump_share_caps = smb2_dump_share_caps,
 	.is_oplock_break = smb2_is_valid_oplock_break,
+	.handle_cancelled_mid = smb2_handle_cancelled_mid,
 	.downgrade_oplock = smb2_downgrade_oplock,
 	.need_neg = smb2_need_neg,
 	.negotiate = smb2_negotiate,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/smb2pdu.c linux-libre-3.16.46-gnu/fs/cifs/smb2pdu.c
--- linux-libre-3.16.45-gnu/fs/cifs/smb2pdu.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/smb2pdu.c	2017-07-18 13:40:42.000000000 -0400
@@ -843,9 +843,6 @@ SMB2_tcon(const unsigned int xid, struct
 	else
 		return -EIO;
 
-	if (tcon && tcon->bad_network_name)
-		return -ENOENT;
-
 	unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
 	if (unc_path == NULL)
 		return -ENOMEM;
@@ -857,6 +854,10 @@ SMB2_tcon(const unsigned int xid, struct
 		return -EINVAL;
 	}
 
+	/* SMB2 TREE_CONNECT request must be called with TreeId == 0 */
+	if (tcon)
+		tcon->tid = 0;
+
 	rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req);
 	if (rc) {
 		kfree(unc_path);
@@ -935,8 +936,6 @@ tcon_exit:
 tcon_error_exit:
 	if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) {
 		cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
-		if (tcon)
-			tcon->bad_network_name = true;
 	}
 	goto tcon_exit;
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/smb2proto.h linux-libre-3.16.46-gnu/fs/cifs/smb2proto.h
--- linux-libre-3.16.45-gnu/fs/cifs/smb2proto.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/smb2proto.h	2017-07-18 13:40:42.000000000 -0400
@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_re
 			      struct smb_rqst *rqst);
 extern struct mid_q_entry *smb2_setup_async_request(
 			struct TCP_Server_Info *server, struct smb_rqst *rqst);
+extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
+					   __u64 ses_id);
+extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server,
+						__u64 ses_id, __u32  tid);
 extern int smb2_calc_signature(struct smb_rqst *rqst,
 				struct TCP_Server_Info *server);
 extern int smb3_calc_signature(struct smb_rqst *rqst,
@@ -151,6 +155,9 @@ extern int SMB2_set_compression(const un
 extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
 			     const u64 persistent_fid, const u64 volatile_fid,
 			     const __u8 oplock_level);
+extern int smb2_handle_cancelled_mid(char *buffer,
+					struct TCP_Server_Info *server);
+void smb2_cancelled_close_fid(struct work_struct *work);
 extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
 			 u64 persistent_file_id, u64 volatile_file_id,
 			 struct kstatfs *FSData);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/smb2transport.c linux-libre-3.16.46-gnu/fs/cifs/smb2transport.c
--- linux-libre-3.16.45-gnu/fs/cifs/smb2transport.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/smb2transport.c	2017-07-18 13:40:42.000000000 -0400
@@ -115,22 +115,68 @@ smb3_crypto_shash_allocate(struct TCP_Se
 }
 
 static struct cifs_ses *
-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
+smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
 {
 	struct cifs_ses *ses;
 
-	spin_lock(&cifs_tcp_ses_lock);
 	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
-		if (ses->Suid != smb2hdr->SessionId)
+		if (ses->Suid != ses_id)
 			continue;
-		spin_unlock(&cifs_tcp_ses_lock);
 		return ses;
 	}
+
+	return NULL;
+}
+
+struct cifs_ses *
+smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
+{
+	struct cifs_ses *ses;
+
+	spin_lock(&cifs_tcp_ses_lock);
+	ses = smb2_find_smb_ses_unlocked(server, ses_id);
 	spin_unlock(&cifs_tcp_ses_lock);
 
+	return ses;
+}
+
+static struct cifs_tcon *
+smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
+{
+	struct cifs_tcon *tcon;
+
+	list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+		if (tcon->tid != tid)
+			continue;
+		++tcon->tc_count;
+		return tcon;
+	}
+
 	return NULL;
 }
 
+/*
+ * Obtain tcon corresponding to the tid in the given
+ * cifs_ses
+ */
+
+struct cifs_tcon *
+smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
+{
+	struct cifs_ses *ses;
+	struct cifs_tcon *tcon;
+
+	spin_lock(&cifs_tcp_ses_lock);
+	ses = smb2_find_smb_ses_unlocked(server, ses_id);
+	if (!ses) {
+		spin_unlock(&cifs_tcp_ses_lock);
+		return NULL;
+	}
+	tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
+	spin_unlock(&cifs_tcp_ses_lock);
+
+	return tcon;
+}
 
 int
 smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
@@ -143,7 +189,7 @@ smb2_calc_signature(struct smb_rqst *rqs
 	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
 	struct cifs_ses *ses;
 
-	ses = smb2_find_smb_ses(smb2_pdu, server);
+	ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
 	if (!ses) {
 		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
 		return 0;
@@ -314,7 +360,7 @@ smb3_calc_signature(struct smb_rqst *rqs
 	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
 	struct cifs_ses *ses;
 
-	ses = smb2_find_smb_ses(smb2_pdu, server);
+	ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
 	if (!ses) {
 		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
 		return 0;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/cifs/transport.c linux-libre-3.16.46-gnu/fs/cifs/transport.c
--- linux-libre-3.16.45-gnu/fs/cifs/transport.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/cifs/transport.c	2017-07-18 13:40:42.000000000 -0400
@@ -773,9 +773,11 @@ SendReceive2(const unsigned int xid, str
 
 	rc = wait_for_response(ses->server, midQ);
 	if (rc != 0) {
+		cifs_dbg(FYI, "Cancelling wait for mid %llu\n",	midQ->mid);
 		send_cancel(ses->server, buf, midQ);
 		spin_lock(&GlobalMid_Lock);
 		if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
+			midQ->mid_flags |= MID_WAIT_CANCELLED;
 			midQ->callback = DeleteMidQEntry;
 			spin_unlock(&GlobalMid_Lock);
 			cifs_small_buf_release(buf);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/exec.c linux-libre-3.16.46-gnu/fs/exec.c
--- linux-libre-3.16.45-gnu/fs/exec.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/exec.c	2017-07-18 13:40:42.000000000 -0400
@@ -205,8 +205,26 @@ static struct page *get_arg_page(struct
 
 	if (write) {
 		unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+		unsigned long ptr_size;
 		struct rlimit *rlim;
 
+		/*
+		 * Since the stack will hold pointers to the strings, we
+		 * must account for them as well.
+		 *
+		 * The size calculation is the entire vma while each arg page is
+		 * built, so each time we get here it's calculating how far it
+		 * is currently (rather than each call being just the newly
+		 * added size from the arg page).  As a result, we need to
+		 * always add the entire size of the pointers, so that on the
+		 * last call to get_arg_page() we'll actually have the entire
+		 * correct size.
+		 */
+		ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
+		if (ptr_size > ULONG_MAX - size)
+			goto fail;
+		size += ptr_size;
+
 		acct_arg_size(bprm, size / PAGE_SIZE);
 
 		/*
@@ -224,13 +242,15 @@ static struct page *get_arg_page(struct
 		 *    to work from.
 		 */
 		rlim = current->signal->rlim;
-		if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
-			put_page(page);
-			return NULL;
-		}
+		if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4)
+			goto fail;
 	}
 
 	return page;
+
+fail:
+	put_page(page);
+	return NULL;
 }
 
 static void put_arg_page(struct page *page)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/ext4/inline.c linux-libre-3.16.46-gnu/fs/ext4/inline.c
--- linux-libre-3.16.45-gnu/fs/ext4/inline.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/ext4/inline.c	2017-07-18 13:40:42.000000000 -0400
@@ -1158,10 +1158,9 @@ static int ext4_finish_convert_inline_di
 	set_buffer_uptodate(dir_block);
 	err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
 	if (err)
-		goto out;
+		return err;
 	set_buffer_verified(dir_block);
-out:
-	return err;
+	return ext4_mark_inode_dirty(handle, inode);
 }
 
 static int ext4_convert_inline_data_nolock(handle_t *handle,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/ext4/xattr.c linux-libre-3.16.46-gnu/fs/ext4/xattr.c
--- linux-libre-3.16.45-gnu/fs/ext4/xattr.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/ext4/xattr.c	2017-07-18 13:40:42.000000000 -0400
@@ -139,31 +139,26 @@ static __le32 ext4_xattr_block_csum(stru
 }
 
 static int ext4_xattr_block_csum_verify(struct inode *inode,
-					sector_t block_nr,
-					struct ext4_xattr_header *hdr)
-{
-	if (ext4_has_metadata_csum(inode->i_sb) &&
-	    (hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr)))
-		return 0;
-	return 1;
-}
-
-static void ext4_xattr_block_csum_set(struct inode *inode,
-				      sector_t block_nr,
-				      struct ext4_xattr_header *hdr)
+					struct buffer_head *bh)
 {
-	if (!ext4_has_metadata_csum(inode->i_sb))
-		return;
+	struct ext4_xattr_header *hdr = BHDR(bh);
+	int ret = 1;
 
-	hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr);
+	if (ext4_has_metadata_csum(inode->i_sb)) {
+		lock_buffer(bh);
+		ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
+							bh->b_blocknr, hdr));
+		unlock_buffer(bh);
+	}
+	return ret;
 }
 
-static inline int ext4_handle_dirty_xattr_block(handle_t *handle,
-						struct inode *inode,
-						struct buffer_head *bh)
+static void ext4_xattr_block_csum_set(struct inode *inode,
+				      struct buffer_head *bh)
 {
-	ext4_xattr_block_csum_set(inode, bh->b_blocknr, BHDR(bh));
-	return ext4_handle_dirty_metadata(handle, inode, bh);
+	if (ext4_has_metadata_csum(inode->i_sb))
+		BHDR(bh)->h_checksum = ext4_xattr_block_csum(inode,
+						bh->b_blocknr, BHDR(bh));
 }
 
 static inline const struct xattr_handler *
@@ -224,7 +219,7 @@ ext4_xattr_check_block(struct inode *ino
 	if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
 	    BHDR(bh)->h_blocks != cpu_to_le32(1))
 		return -EIO;
-	if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh)))
+	if (!ext4_xattr_block_csum_verify(inode, bh))
 		return -EIO;
 	error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
 				       bh->b_data);
@@ -568,23 +563,22 @@ ext4_xattr_release_block(handle_t *handl
 		le32_add_cpu(&BHDR(bh)->h_refcount, -1);
 		if (ce)
 			mb_cache_entry_release(ce);
+		ext4_xattr_block_csum_set(inode, bh);
 		/*
 		 * Beware of this ugliness: Releasing of xattr block references
 		 * from different inodes can race and so we have to protect
 		 * from a race where someone else frees the block (and releases
 		 * its journal_head) before we are done dirtying the buffer. In
 		 * nojournal mode this race is harmless and we actually cannot
-		 * call ext4_handle_dirty_xattr_block() with locked buffer as
+		 * call ext4_handle_dirty_metadata() with locked buffer as
 		 * that function can call sync_dirty_buffer() so for that case
 		 * we handle the dirtying after unlocking the buffer.
 		 */
 		if (ext4_handle_valid(handle))
-			error = ext4_handle_dirty_xattr_block(handle, inode,
-							      bh);
+			error = ext4_handle_dirty_metadata(handle, inode, bh);
 		unlock_buffer(bh);
 		if (!ext4_handle_valid(handle))
-			error = ext4_handle_dirty_xattr_block(handle, inode,
-							      bh);
+			error = ext4_handle_dirty_metadata(handle, inode, bh);
 		if (IS_SYNC(inode))
 			ext4_handle_sync(handle);
 		dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
@@ -812,13 +806,14 @@ ext4_xattr_block_set(handle_t *handle, s
 				ext4_xattr_cache_insert(ext4_mb_cache,
 					bs->bh);
 			}
+			ext4_xattr_block_csum_set(inode, bs->bh);
 			unlock_buffer(bs->bh);
 			if (error == -EIO)
 				goto bad_block;
 			if (!error)
-				error = ext4_handle_dirty_xattr_block(handle,
-								      inode,
-								      bs->bh);
+				error = ext4_handle_dirty_metadata(handle,
+								   inode,
+								   bs->bh);
 			if (error)
 				goto cleanup;
 			goto inserted;
@@ -887,10 +882,11 @@ inserted:
 				le32_add_cpu(&BHDR(new_bh)->h_refcount, 1);
 				ea_bdebug(new_bh, "reusing; refcount now=%d",
 					le32_to_cpu(BHDR(new_bh)->h_refcount));
+				ext4_xattr_block_csum_set(inode, new_bh);
 				unlock_buffer(new_bh);
-				error = ext4_handle_dirty_xattr_block(handle,
-								      inode,
-								      new_bh);
+				error = ext4_handle_dirty_metadata(handle,
+								   inode,
+								   new_bh);
 				if (error)
 					goto cleanup_dquot;
 			}
@@ -945,11 +941,12 @@ getblk_failed:
 				goto getblk_failed;
 			}
 			memcpy(new_bh->b_data, s->base, new_bh->b_size);
+			ext4_xattr_block_csum_set(inode, new_bh);
 			set_buffer_uptodate(new_bh);
 			unlock_buffer(new_bh);
 			ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
-			error = ext4_handle_dirty_xattr_block(handle,
-							      inode, new_bh);
+			error = ext4_handle_dirty_metadata(handle, inode,
+							   new_bh);
 			if (error)
 				goto cleanup;
 		}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/fs/nfs/nfs4proc.c linux-libre-3.16.46-gnu/fs/nfs/nfs4proc.c
--- linux-libre-3.16.45-gnu/fs/nfs/nfs4proc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/fs/nfs/nfs4proc.c	2017-07-18 13:40:42.000000000 -0400
@@ -1980,8 +1980,6 @@ static int nfs4_opendata_access(struct r
 	if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0)
 		return 0;
 
-	/* even though OPEN succeeded, access is denied. Close the file */
-	nfs4_close_state(state, fmode);
 	return -EACCES;
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/drm/ttm/ttm_object.h linux-libre-3.16.46-gnu/include/drm/ttm/ttm_object.h
--- linux-libre-3.16.45-gnu/include/drm/ttm/ttm_object.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/drm/ttm/ttm_object.h	2017-07-18 13:40:42.000000000 -0400
@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct
  * @ref_type: The type of reference.
  * @existed: Upon completion, indicates that an identical reference object
  * already existed, and the refcount was upped on that object instead.
+ * @require_existed: Fail with -EPERM if an identical ref object didn't
+ * already exist.
  *
  * Checks that the base object is shareable and adds a ref object to it.
  *
@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct
  */
 extern int ttm_ref_object_add(struct ttm_object_file *tfile,
 			      struct ttm_base_object *base,
-			      enum ttm_ref_type ref_type, bool *existed);
+			      enum ttm_ref_type ref_type, bool *existed,
+			      bool require_existed);
 
 extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
 				  struct ttm_base_object *base);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/linux/kernel.h linux-libre-3.16.46-gnu/include/linux/kernel.h
--- linux-libre-3.16.45-gnu/include/linux/kernel.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/linux/kernel.h	2017-07-18 13:40:42.000000000 -0400
@@ -183,28 +183,31 @@ extern int _cond_resched(void);
 
 #define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
 
-/*
- * abs() handles unsigned and signed longs, ints, shorts and chars.  For all
- * input types abs() returns a signed long.
- * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64()
- * for those.
+/**
+ * abs - return absolute value of an argument
+ * @x: the value.  If it is unsigned type, it is converted to signed type first.
+ *     char is treated as if it was signed (regardless of whether it really is)
+ *     but the macro's return type is preserved as char.
+ *
+ * Return: an absolute value of x.
  */
-#define abs(x) ({						\
-		long ret;					\
-		if (sizeof(x) == sizeof(long)) {		\
-			long __x = (x);				\
-			ret = (__x < 0) ? -__x : __x;		\
-		} else {					\
-			int __x = (x);				\
-			ret = (__x < 0) ? -__x : __x;		\
-		}						\
-		ret;						\
-	})
+#define abs(x)	__abs_choose_expr(x, long long,				\
+		__abs_choose_expr(x, long,				\
+		__abs_choose_expr(x, int,				\
+		__abs_choose_expr(x, short,				\
+		__abs_choose_expr(x, char,				\
+		__builtin_choose_expr(					\
+			__builtin_types_compatible_p(typeof(x), char),	\
+			(char)({ signed char __x = (x); __x<0?-__x:__x; }), \
+			((void)0)))))))
 
-#define abs64(x) ({				\
-		s64 __x = (x);			\
-		(__x < 0) ? -__x : __x;		\
-	})
+#define __abs_choose_expr(x, type, other) __builtin_choose_expr(	\
+	__builtin_types_compatible_p(typeof(x),   signed type) ||	\
+	__builtin_types_compatible_p(typeof(x), unsigned type),		\
+	({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
+
+/* Deprecated, use abs instead. */
+#define abs64(x) abs((s64)(x))
 
 /**
  * reciprocal_scale - "scale" a value into range [0, ep_ro)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/linux/kvm_host.h linux-libre-3.16.46-gnu/include/linux/kvm_host.h
--- linux-libre-3.16.45-gnu/include/linux/kvm_host.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/linux/kvm_host.h	2017-07-18 13:40:42.000000000 -0400
@@ -177,8 +177,8 @@ int kvm_io_bus_read(struct kvm *kvm, enu
 		    void *val);
 int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
 			    int len, struct kvm_io_device *dev);
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
-			      struct kvm_io_device *dev);
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+			       struct kvm_io_device *dev);
 
 #ifdef CONFIG_KVM_ASYNC_PF
 struct kvm_async_pf {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/linux/phy.h linux-libre-3.16.46-gnu/include/linux/phy.h
--- linux-libre-3.16.45-gnu/include/linux/phy.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/linux/phy.h	2017-07-18 13:40:42.000000000 -0400
@@ -692,6 +692,10 @@ int genphy_read_status(struct phy_device
 int genphy_suspend(struct phy_device *phydev);
 int genphy_resume(struct phy_device *phydev);
 int genphy_soft_reset(struct phy_device *phydev);
+static inline int genphy_no_soft_reset(struct phy_device *phydev)
+{
+	return 0;
+}
 void phy_driver_unregister(struct phy_driver *drv);
 void phy_drivers_unregister(struct phy_driver *drv, int n);
 int phy_driver_register(struct phy_driver *new_driver);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/linux/skbuff.h linux-libre-3.16.46-gnu/include/linux/skbuff.h
--- linux-libre-3.16.45-gnu/include/linux/skbuff.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/linux/skbuff.h	2017-07-18 13:40:42.000000000 -0400
@@ -2307,6 +2307,13 @@ static inline int skb_clone_writable(con
 	       skb_headroom(skb) + len <= skb->hdr_len;
 }
 
+static inline int skb_try_make_writable(struct sk_buff *skb,
+					unsigned int write_len)
+{
+	return skb_cloned(skb) && !skb_clone_writable(skb, write_len) &&
+	       pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+}
+
 static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom,
 			    int cloned)
 {
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/linux/usb/quirks.h linux-libre-3.16.46-gnu/include/linux/usb/quirks.h
--- linux-libre-3.16.45-gnu/include/linux/usb/quirks.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/linux/usb/quirks.h	2017-07-18 13:40:42.000000000 -0400
@@ -50,4 +50,10 @@
 /* device can't handle Link Power Management */
 #define USB_QUIRK_NO_LPM			BIT(10)
 
+/*
+ * Device reports its bInterval as linear frames instead of the
+ * USB 2.0 calculation.
+ */
+#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL	BIT(11)
+
 #endif /* __LINUX_USB_QUIRKS_H */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/scsi/libiscsi.h linux-libre-3.16.46-gnu/include/scsi/libiscsi.h
--- linux-libre-3.16.45-gnu/include/scsi/libiscsi.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/scsi/libiscsi.h	2017-07-18 13:40:42.000000000 -0400
@@ -196,6 +196,7 @@ struct iscsi_conn {
 	struct iscsi_task	*task;		/* xmit task in progress */
 
 	/* xmit */
+	spinlock_t		taskqueuelock;  /* protects the next three lists */
 	struct list_head	mgmtqueue;	/* mgmt (control) xmit queue */
 	struct list_head	cmdqueue;	/* data-path cmd queue */
 	struct list_head	requeue;	/* tasks needing another run */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/include/trace/events/syscalls.h linux-libre-3.16.46-gnu/include/trace/events/syscalls.h
--- linux-libre-3.16.45-gnu/include/trace/events/syscalls.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/include/trace/events/syscalls.h	2017-07-18 13:40:42.000000000 -0400
@@ -1,5 +1,6 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM raw_syscalls
+#undef TRACE_INCLUDE_FILE
 #define TRACE_INCLUDE_FILE syscalls
 
 #if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/kernel/events/core.c linux-libre-3.16.46-gnu/kernel/events/core.c
--- linux-libre-3.16.45-gnu/kernel/events/core.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/kernel/events/core.c	2017-07-18 13:40:42.000000000 -0400
@@ -8177,7 +8177,7 @@ int perf_event_init_context(struct task_
 		ret = inherit_task_group(event, parent, parent_ctx,
 					 child, ctxn, &inherited_all);
 		if (ret)
-			break;
+			goto out_unlock;
 	}
 
 	/*
@@ -8193,7 +8193,7 @@ int perf_event_init_context(struct task_
 		ret = inherit_task_group(event, parent, parent_ctx,
 					 child, ctxn, &inherited_all);
 		if (ret)
-			break;
+			goto out_unlock;
 	}
 
 	raw_spin_lock_irqsave(&parent_ctx->lock, flags);
@@ -8221,6 +8221,7 @@ int perf_event_init_context(struct task_
 	}
 
 	raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);
+out_unlock:
 	mutex_unlock(&parent_ctx->mutex);
 
 	perf_unpin_context(parent_ctx);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/kernel/futex.c linux-libre-3.16.46-gnu/kernel/futex.c
--- linux-libre-3.16.45-gnu/kernel/futex.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/kernel/futex.c	2017-07-18 13:40:42.000000000 -0400
@@ -2578,7 +2578,6 @@ static int futex_wait_requeue_pi(u32 __u
 {
 	struct hrtimer_sleeper timeout, *to = NULL;
 	struct rt_mutex_waiter rt_waiter;
-	struct rt_mutex *pi_mutex = NULL;
 	struct futex_hash_bucket *hb;
 	union futex_key key2 = FUTEX_KEY_INIT;
 	struct futex_q q = futex_q_init;
@@ -2662,6 +2661,8 @@ static int futex_wait_requeue_pi(u32 __u
 		if (q.pi_state && (q.pi_state->owner != current)) {
 			spin_lock(q.lock_ptr);
 			ret = fixup_pi_state_owner(uaddr2, &q, current);
+			if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current)
+				rt_mutex_unlock(&q.pi_state->pi_mutex);
 			/*
 			 * Drop the reference to the pi state which
 			 * the requeue_pi() code acquired for us.
@@ -2670,6 +2671,8 @@ static int futex_wait_requeue_pi(u32 __u
 			spin_unlock(q.lock_ptr);
 		}
 	} else {
+		struct rt_mutex *pi_mutex;
+
 		/*
 		 * We have been woken up by futex_unlock_pi(), a timeout, or a
 		 * signal.  futex_unlock_pi() will not destroy the lock_ptr nor
@@ -2693,18 +2696,19 @@ static int futex_wait_requeue_pi(u32 __u
 		if (res)
 			ret = (res < 0) ? res : 0;
 
+		/*
+		 * If fixup_pi_state_owner() faulted and was unable to handle
+		 * the fault, unlock the rt_mutex and return the fault to
+		 * userspace.
+		 */
+		if (ret && rt_mutex_owner(pi_mutex) == current)
+			rt_mutex_unlock(pi_mutex);
+
 		/* Unqueue and drop the lock. */
 		unqueue_me_pi(&q);
 	}
 
-	/*
-	 * If fixup_pi_state_owner() faulted and was unable to handle the
-	 * fault, unlock the rt_mutex and return the fault to userspace.
-	 */
-	if (ret == -EFAULT) {
-		if (pi_mutex && rt_mutex_owner(pi_mutex) == current)
-			rt_mutex_unlock(pi_mutex);
-	} else if (ret == -EINTR) {
+	if (ret == -EINTR) {
 		/*
 		 * We've already been requeued, but cannot restart by calling
 		 * futex_lock_pi() directly. We could restart this syscall, but
diff -druNp --no-dereference linux-libre-3.16.45-gnu/kernel/ptrace.c linux-libre-3.16.46-gnu/kernel/ptrace.c
--- linux-libre-3.16.45-gnu/kernel/ptrace.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/kernel/ptrace.c	2017-07-18 13:40:42.000000000 -0400
@@ -150,11 +150,17 @@ static void ptrace_unfreeze_traced(struc
 
 	WARN_ON(!task->ptrace || task->parent != current);
 
+	/*
+	 * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely.
+	 * Recheck state under the lock to close this race.
+	 */
 	spin_lock_irq(&task->sighand->siglock);
-	if (__fatal_signal_pending(task))
-		wake_up_state(task, __TASK_TRACED);
-	else
-		task->state = TASK_TRACED;
+	if (task->state == __TASK_TRACED) {
+		if (__fatal_signal_pending(task))
+			wake_up_state(task, __TASK_TRACED);
+		else
+			task->state = TASK_TRACED;
+	}
 	spin_unlock_irq(&task->sighand->siglock);
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/kernel/sched/proc.c linux-libre-3.16.46-gnu/kernel/sched/proc.c
--- linux-libre-3.16.45-gnu/kernel/sched/proc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/kernel/sched/proc.c	2017-07-18 13:40:42.000000000 -0400
@@ -205,8 +205,9 @@ void calc_load_exit_idle(void)
 	struct rq *this_rq = this_rq();
 
 	/*
-	 * If we're still before the sample window, we're done.
+	 * If we're still before the pending sample window, we're done.
 	 */
+	this_rq->calc_load_update = calc_load_update;
 	if (time_before(jiffies, this_rq->calc_load_update))
 		return;
 
@@ -215,7 +216,6 @@ void calc_load_exit_idle(void)
 	 * accounted through the nohz accounting, so skip the entire deal and
 	 * sync up for the next window.
 	 */
-	this_rq->calc_load_update = calc_load_update;
 	if (time_before(jiffies, this_rq->calc_load_update + 10))
 		this_rq->calc_load_update += LOAD_FREQ;
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/kernel/trace/ring_buffer.c linux-libre-3.16.46-gnu/kernel/trace/ring_buffer.c
--- linux-libre-3.16.45-gnu/kernel/trace/ring_buffer.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/kernel/trace/ring_buffer.c	2017-07-18 13:40:42.000000000 -0400
@@ -3463,11 +3463,23 @@ EXPORT_SYMBOL_GPL(ring_buffer_iter_reset
 int ring_buffer_iter_empty(struct ring_buffer_iter *iter)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
+	struct buffer_page *reader;
+	struct buffer_page *head_page;
+	struct buffer_page *commit_page;
+	unsigned commit;
 
 	cpu_buffer = iter->cpu_buffer;
 
-	return iter->head_page == cpu_buffer->commit_page &&
-		iter->head == rb_commit_index(cpu_buffer);
+	/* Remember, trace recording is off when iterator is in use */
+	reader = cpu_buffer->reader_page;
+	head_page = cpu_buffer->head_page;
+	commit_page = cpu_buffer->commit_page;
+	commit = rb_page_commit(commit_page);
+
+	return ((iter->head_page == commit_page && iter->head == commit) ||
+		(iter->head_page == reader && commit_page == head_page &&
+		 head_page->read == commit &&
+		 iter->head == rb_page_commit(cpu_buffer->reader_page)));
 }
 EXPORT_SYMBOL_GPL(ring_buffer_iter_empty);
 
@@ -4899,9 +4911,9 @@ static __init int test_ringbuffer(void)
 		rb_data[cpu].cnt = cpu;
 		rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu],
 						 "rbtester/%d", cpu);
-		if (WARN_ON(!rb_threads[cpu])) {
+		if (WARN_ON(IS_ERR(rb_threads[cpu]))) {
 			pr_cont("FAILED\n");
-			ret = -1;
+			ret = PTR_ERR(rb_threads[cpu]);
 			goto out_free;
 		}
 
@@ -4911,9 +4923,9 @@ static __init int test_ringbuffer(void)
 
 	/* Now create the rb hammer! */
 	rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer");
-	if (WARN_ON(!rb_hammer)) {
+	if (WARN_ON(IS_ERR(rb_hammer))) {
 		pr_cont("FAILED\n");
-		ret = -1;
+		ret = PTR_ERR(rb_hammer);
 		goto out_free;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/kernel/trace/trace.c linux-libre-3.16.46-gnu/kernel/trace/trace.c
--- linux-libre-3.16.45-gnu/kernel/trace/trace.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/kernel/trace/trace.c	2017-07-18 13:40:42.000000000 -0400
@@ -5775,11 +5775,13 @@ ftrace_trace_snapshot_callback(struct ft
 		return ret;
 
  out_reg:
-	ret = register_ftrace_function_probe(glob, ops, count);
+	ret = alloc_snapshot(&global_trace);
+	if (ret < 0)
+		goto out;
 
-	if (ret >= 0)
-		alloc_snapshot(&global_trace);
+	ret = register_ftrace_function_probe(glob, ops, count);
 
+ out:
 	return ret < 0 ? ret : 0;
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/Makefile linux-libre-3.16.46-gnu/Makefile
--- linux-libre-3.16.45-gnu/Makefile	2017-07-03 11:17:09.000000000 -0400
+++ linux-libre-3.16.46-gnu/Makefile	2017-07-18 17:20:12.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 16
-SUBLEVEL = 45
+SUBLEVEL = 46
 EXTRAVERSION =-gnu
 NAME = Museum of Fishiegoodies
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/9p/client.c linux-libre-3.16.46-gnu/net/9p/client.c
--- linux-libre-3.16.45-gnu/net/9p/client.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/9p/client.c	2017-07-18 13:40:42.000000000 -0400
@@ -2107,6 +2107,10 @@ int p9_client_readdir(struct p9_fid *fid
 		trace_9p_protocol_dump(clnt, req->rc);
 		goto free_and_error;
 	}
+	if (rsize < count) {
+		pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
+		count = rsize;
+	}
 
 	p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/batman-adv/fragmentation.c linux-libre-3.16.46-gnu/net/batman-adv/fragmentation.c
--- linux-libre-3.16.45-gnu/net/batman-adv/fragmentation.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/batman-adv/fragmentation.c	2017-07-18 13:40:42.000000000 -0400
@@ -377,7 +377,7 @@ out:
  * batadv_frag_create - create a fragment from skb
  * @skb: skb to create fragment from
  * @frag_head: header to use in new fragment
- * @mtu: size of new fragment
+ * @fragment_size: size of new fragment
  *
  * Split the passed skb into two fragments: A new one with size matching the
  * passed mtu and the old one with the rest. The new skb contains data from the
@@ -387,11 +387,11 @@ out:
  */
 static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
 					  struct batadv_frag_packet *frag_head,
-					  unsigned int mtu)
+					  unsigned int fragment_size)
 {
 	struct sk_buff *skb_fragment;
 	unsigned header_size = sizeof(*frag_head);
-	unsigned fragment_size = mtu - header_size;
+	unsigned int mtu = fragment_size + header_size;
 
 	skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
 	if (!skb_fragment)
@@ -429,7 +429,7 @@ bool batadv_frag_send_packet(struct sk_b
 	struct sk_buff *skb_fragment;
 	unsigned mtu = neigh_node->if_incoming->net_dev->mtu;
 	unsigned header_size = sizeof(frag_header);
-	unsigned max_fragment_size, max_packet_size;
+	unsigned int max_fragment_size, num_fragments;
 	bool ret = false;
 
 	/* To avoid merge and refragmentation at next-hops we never send
@@ -437,10 +437,15 @@ bool batadv_frag_send_packet(struct sk_b
 	 */
 	mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
 	max_fragment_size = mtu - header_size;
-	max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS;
+
+	if (skb->len == 0 || max_fragment_size == 0)
+		return -EINVAL;
+
+	num_fragments = (skb->len - 1) / max_fragment_size + 1;
+	max_fragment_size = (skb->len - 1) / num_fragments + 1;
 
 	/* Don't even try to fragment, if we need more than 16 fragments */
-	if (skb->len > max_packet_size)
+	if (num_fragments > BATADV_FRAG_MAX_FRAGMENTS)
 		goto out_err;
 
 	bat_priv = orig_node->bat_priv;
@@ -465,7 +470,8 @@ bool batadv_frag_send_packet(struct sk_b
 		if (unlikely(frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1))
 			goto out_err;
 
-		skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
+		skb_fragment = batadv_frag_create(skb, &frag_header,
+						  max_fragment_size);
 		if (!skb_fragment)
 			goto out_err;
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ceph/messenger.c linux-libre-3.16.46-gnu/net/ceph/messenger.c
--- linux-libre-3.16.45-gnu/net/ceph/messenger.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ceph/messenger.c	2017-07-18 13:40:42.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/inet.h>
 #include <linux/kthread.h>
 #include <linux/net.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/socket.h>
 #include <linux/string.h>
@@ -476,11 +477,16 @@ static int ceph_tcp_connect(struct ceph_
 {
 	struct sockaddr_storage *paddr = &con->peer_addr.in_addr;
 	struct socket *sock;
+	unsigned int noio_flag;
 	int ret;
 
 	BUG_ON(con->sock);
+
+	/* sock_create_kern() allocates with GFP_KERNEL */
+	noio_flag = memalloc_noio_save();
 	ret = sock_create_kern(con->peer_addr.in_addr.ss_family, SOCK_STREAM,
 			       IPPROTO_TCP, &sock);
+	memalloc_noio_restore(noio_flag);
 	if (ret)
 		return ret;
 	sock->sk->sk_allocation = GFP_NOFS;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ceph/osdmap.c linux-libre-3.16.46-gnu/net/ceph/osdmap.c
--- linux-libre-3.16.45-gnu/net/ceph/osdmap.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ceph/osdmap.c	2017-07-18 13:40:42.000000000 -0400
@@ -1240,7 +1240,6 @@ static int decode_new_up_state_weight(vo
 		if ((map->osd_state[osd] & CEPH_OSD_EXISTS) &&
 		    (xorstate & CEPH_OSD_EXISTS)) {
 			pr_info("osd%d does not exist\n", osd);
-			map->osd_weight[osd] = CEPH_OSD_IN;
 			ret = set_primary_affinity(map, osd,
 						   CEPH_OSD_DEFAULT_PRIMARY_AFFINITY);
 			if (ret)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/core/sock.c linux-libre-3.16.46-gnu/net/core/sock.c
--- linux-libre-3.16.45-gnu/net/core/sock.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/core/sock.c	2017-07-18 13:40:42.000000000 -0400
@@ -1448,6 +1448,11 @@ static void __sk_free(struct sock *sk)
 		pr_debug("%s: optmem leakage (%d bytes) detected\n",
 			 __func__, atomic_read(&sk->sk_omem_alloc));
 
+	if (sk->sk_frag.page) {
+		put_page(sk->sk_frag.page);
+		sk->sk_frag.page = NULL;
+	}
+
 	if (sk->sk_peer_cred)
 		put_cred(sk->sk_peer_cred);
 	put_pid(sk->sk_peer_pid);
@@ -2685,11 +2690,6 @@ void sk_common_release(struct sock *sk)
 
 	sk_refcnt_debug_release(sk);
 
-	if (sk->sk_frag.page) {
-		put_page(sk->sk_frag.page);
-		sk->sk_frag.page = NULL;
-	}
-
 	sock_put(sk);
 }
 EXPORT_SYMBOL(sk_common_release);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/dccp/ipv4.c linux-libre-3.16.46-gnu/net/dccp/ipv4.c
--- linux-libre-3.16.45-gnu/net/dccp/ipv4.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/dccp/ipv4.c	2017-07-18 13:40:42.000000000 -0400
@@ -264,7 +264,8 @@ static void dccp_v4_err(struct sk_buff *
 
 	switch (type) {
 	case ICMP_REDIRECT:
-		dccp_do_redirect(skb, sk);
+		if (!sock_owned_by_user(sk))
+			dccp_do_redirect(skb, sk);
 		goto out;
 	case ICMP_SOURCE_QUENCH:
 		/* Just silently ignore these. */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/dccp/ipv6.c linux-libre-3.16.46-gnu/net/dccp/ipv6.c
--- linux-libre-3.16.45-gnu/net/dccp/ipv6.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/dccp/ipv6.c	2017-07-18 13:40:42.000000000 -0400
@@ -132,10 +132,12 @@ static void dccp_v6_err(struct sk_buff *
 	np = inet6_sk(sk);
 
 	if (type == NDISC_REDIRECT) {
-		struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
+		if (!sock_owned_by_user(sk)) {
+			struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
 
-		if (dst)
-			dst->ops->redirect(dst, sk, skb);
+			if (dst)
+				dst->ops->redirect(dst, sk, skb);
+		}
 		goto out;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv4/ip_output.c linux-libre-3.16.46-gnu/net/ipv4/ip_output.c
--- linux-libre-3.16.45-gnu/net/ipv4/ip_output.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv4/ip_output.c	2017-07-18 13:40:42.000000000 -0400
@@ -887,7 +887,7 @@ static int __ip_append_data(struct sock
 	cork->length += length;
 	if (((length > mtu) || (skb && skb_is_gso(skb))) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
-	    (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
+	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
 	    (sk->sk_type == SOCK_DGRAM)) {
 		err = ip_ufo_append_data(sk, queue, getfrag, from, length,
 					 hh_len, fragheaderlen, transhdrlen,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-libre-3.16.46-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c
--- linux-libre-3.16.45-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c	2017-07-18 13:40:42.000000000 -0400
@@ -1260,16 +1260,6 @@ static const struct nf_conntrack_expect_
 	.timeout	= 180,
 };
 
-static struct nf_conntrack_helper snmp_helper __read_mostly = {
-	.me			= THIS_MODULE,
-	.help			= help,
-	.expect_policy		= &snmp_exp_policy,
-	.name			= "snmp",
-	.tuple.src.l3num	= AF_INET,
-	.tuple.src.u.udp.port	= cpu_to_be16(SNMP_PORT),
-	.tuple.dst.protonum	= IPPROTO_UDP,
-};
-
 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
 	.me			= THIS_MODULE,
 	.help			= help,
@@ -1288,17 +1278,10 @@ static struct nf_conntrack_helper snmp_t
 
 static int __init nf_nat_snmp_basic_init(void)
 {
-	int ret = 0;
-
 	BUG_ON(nf_nat_snmp_hook != NULL);
 	RCU_INIT_POINTER(nf_nat_snmp_hook, help);
 
-	ret = nf_conntrack_helper_register(&snmp_trap_helper);
-	if (ret < 0) {
-		nf_conntrack_helper_unregister(&snmp_helper);
-		return ret;
-	}
-	return ret;
+	return nf_conntrack_helper_register(&snmp_trap_helper);
 }
 
 static void __exit nf_nat_snmp_basic_fini(void)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv4/tcp_ipv4.c linux-libre-3.16.46-gnu/net/ipv4/tcp_ipv4.c
--- linux-libre-3.16.45-gnu/net/ipv4/tcp_ipv4.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv4/tcp_ipv4.c	2017-07-18 13:40:42.000000000 -0400
@@ -391,7 +391,8 @@ void tcp_v4_err(struct sk_buff *icmp_skb
 
 	switch (type) {
 	case ICMP_REDIRECT:
-		do_redirect(icmp_skb, sk);
+		if (!sock_owned_by_user(sk))
+			do_redirect(icmp_skb, sk);
 		goto out;
 	case ICMP_SOURCE_QUENCH:
 		/* Just silently ignore these. */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv6/af_inet6.c linux-libre-3.16.46-gnu/net/ipv6/af_inet6.c
--- linux-libre-3.16.45-gnu/net/ipv6/af_inet6.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv6/af_inet6.c	2017-07-18 13:40:42.000000000 -0400
@@ -899,8 +899,6 @@ static int __init inet6_init(void)
 	if (err)
 		goto igmp_fail;
 
-	ipv6_stub = &ipv6_stub_impl;
-
 	err = ipv6_netfilter_init();
 	if (err)
 		goto netfilter_fail;
@@ -964,6 +962,10 @@ static int __init inet6_init(void)
 	if (err)
 		goto sysctl_fail;
 #endif
+
+	/* ensure that ipv6 stubs are visible only after ipv6 is ready */
+	wmb();
+	ipv6_stub = &ipv6_stub_impl;
 out:
 	return err;
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv6/ip6_fib.c linux-libre-3.16.46-gnu/net/ipv6/ip6_fib.c
--- linux-libre-3.16.45-gnu/net/ipv6/ip6_fib.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv6/ip6_fib.c	2017-07-18 13:40:42.000000000 -0400
@@ -862,6 +862,8 @@ add:
 			ins = &rt->dst.rt6_next;
 			iter = *ins;
 			while (iter) {
+				if (iter->rt6i_metric > rt->rt6i_metric)
+					break;
 				if (rt6_qualify_for_ecmp(iter)) {
 					*ins = iter->dst.rt6_next;
 					fib6_purge_rt(iter, fn, info->nl_net);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv6/ip6_output.c linux-libre-3.16.46-gnu/net/ipv6/ip6_output.c
--- linux-libre-3.16.45-gnu/net/ipv6/ip6_output.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv6/ip6_output.c	2017-07-18 13:40:42.000000000 -0400
@@ -1294,7 +1294,7 @@ emsgsize:
 	if (((length > mtu) ||
 	     (skb && skb_is_gso(skb))) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
-	    (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
+	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
 	    (sk->sk_type == SOCK_DGRAM)) {
 		err = ip6_ufo_append_data(sk, getfrag, from, length,
 					  hh_len, fragheaderlen, exthdrlen,
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv6/ndisc.c linux-libre-3.16.46-gnu/net/ipv6/ndisc.c
--- linux-libre-3.16.45-gnu/net/ipv6/ndisc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv6/ndisc.c	2017-07-18 13:40:42.000000000 -0400
@@ -1608,7 +1608,8 @@ static int ndisc_netdev_event(struct not
 		idev = in6_dev_get(dev);
 		if (!idev)
 			break;
-		if (idev->cnf.ndisc_notify)
+		if (idev->cnf.ndisc_notify ||
+		    net->ipv6.devconf_all->ndisc_notify)
 			ndisc_send_unsol_na(dev);
 		in6_dev_put(idev);
 		break;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv6/route.c linux-libre-3.16.46-gnu/net/ipv6/route.c
--- linux-libre-3.16.45-gnu/net/ipv6/route.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv6/route.c	2017-07-18 13:40:42.000000000 -0400
@@ -2582,6 +2582,8 @@ static int rt6_fill_node(struct net *net
 	}
 	else if (rt->rt6i_flags & RTF_LOCAL)
 		rtm->rtm_type = RTN_LOCAL;
+	else if (rt->rt6i_flags & RTF_ANYCAST)
+		rtm->rtm_type = RTN_ANYCAST;
 	else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
 		rtm->rtm_type = RTN_LOCAL;
 	else
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/ipv6/tcp_ipv6.c linux-libre-3.16.46-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-3.16.45-gnu/net/ipv6/tcp_ipv6.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/ipv6/tcp_ipv6.c	2017-07-18 13:40:42.000000000 -0400
@@ -386,10 +386,12 @@ static void tcp_v6_err(struct sk_buff *s
 	np = inet6_sk(sk);
 
 	if (type == NDISC_REDIRECT) {
-		struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
+		if (!sock_owned_by_user(sk)) {
+			struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
 
-		if (dst)
-			dst->ops->redirect(dst, sk, skb);
+			if (dst)
+				dst->ops->redirect(dst, sk, skb);
+		}
 		goto out;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/key/af_key.c linux-libre-3.16.46-gnu/net/key/af_key.c
--- linux-libre-3.16.45-gnu/net/key/af_key.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/key/af_key.c	2017-07-18 13:40:42.000000000 -0400
@@ -63,6 +63,7 @@ struct pfkey_sock {
 		} u;
 		struct sk_buff	*skb;
 	} dump;
+	struct mutex dump_lock;
 };
 
 static inline struct pfkey_sock *pfkey_sk(struct sock *sk)
@@ -139,6 +140,7 @@ static int pfkey_create(struct net *net,
 {
 	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 	struct sock *sk;
+	struct pfkey_sock *pfk;
 	int err;
 
 	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -153,6 +155,9 @@ static int pfkey_create(struct net *net,
 	if (sk == NULL)
 		goto out;
 
+	pfk = pfkey_sk(sk);
+	mutex_init(&pfk->dump_lock);
+
 	sock->ops = &pfkey_ops;
 	sock_init_data(sock, sk);
 
@@ -281,13 +286,23 @@ static int pfkey_do_dump(struct pfkey_so
 	struct sadb_msg *hdr;
 	int rc;
 
+	mutex_lock(&pfk->dump_lock);
+	if (!pfk->dump.dump) {
+		rc = 0;
+		goto out;
+	}
+
 	rc = pfk->dump.dump(pfk);
-	if (rc == -ENOBUFS)
-		return 0;
+	if (rc == -ENOBUFS) {
+		rc = 0;
+		goto out;
+	}
 
 	if (pfk->dump.skb) {
-		if (!pfkey_can_dump(&pfk->sk))
-			return 0;
+		if (!pfkey_can_dump(&pfk->sk)) {
+			rc = 0;
+			goto out;
+		}
 
 		hdr = (struct sadb_msg *) pfk->dump.skb->data;
 		hdr->sadb_msg_seq = 0;
@@ -298,6 +313,9 @@ static int pfkey_do_dump(struct pfkey_so
 	}
 
 	pfkey_terminate_dump(pfk);
+
+out:
+	mutex_unlock(&pfk->dump_lock);
 	return rc;
 }
 
@@ -1795,19 +1813,26 @@ static int pfkey_dump(struct sock *sk, s
 	struct xfrm_address_filter *filter = NULL;
 	struct pfkey_sock *pfk = pfkey_sk(sk);
 
-	if (pfk->dump.dump != NULL)
+	mutex_lock(&pfk->dump_lock);
+	if (pfk->dump.dump != NULL) {
+		mutex_unlock(&pfk->dump_lock);
 		return -EBUSY;
+	}
 
 	proto = pfkey_satype2proto(hdr->sadb_msg_satype);
-	if (proto == 0)
+	if (proto == 0) {
+		mutex_unlock(&pfk->dump_lock);
 		return -EINVAL;
+	}
 
 	if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
 		struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
 
 		filter = kmalloc(sizeof(*filter), GFP_KERNEL);
-		if (filter == NULL)
+		if (filter == NULL) {
+			mutex_unlock(&pfk->dump_lock);
 			return -ENOMEM;
+		}
 
 		memcpy(&filter->saddr, &xfilter->sadb_x_filter_saddr,
 		       sizeof(xfrm_address_t));
@@ -1823,6 +1848,7 @@ static int pfkey_dump(struct sock *sk, s
 	pfk->dump.dump = pfkey_dump_sa;
 	pfk->dump.done = pfkey_dump_sa_done;
 	xfrm_state_walk_init(&pfk->dump.u.state, proto, filter);
+	mutex_unlock(&pfk->dump_lock);
 
 	return pfkey_do_dump(pfk);
 }
@@ -2681,14 +2707,18 @@ static int pfkey_spddump(struct sock *sk
 {
 	struct pfkey_sock *pfk = pfkey_sk(sk);
 
-	if (pfk->dump.dump != NULL)
+	mutex_lock(&pfk->dump_lock);
+	if (pfk->dump.dump != NULL) {
+		mutex_unlock(&pfk->dump_lock);
 		return -EBUSY;
+	}
 
 	pfk->dump.msg_version = hdr->sadb_msg_version;
 	pfk->dump.msg_portid = hdr->sadb_msg_pid;
 	pfk->dump.dump = pfkey_dump_sp;
 	pfk->dump.done = pfkey_dump_sp_done;
 	xfrm_policy_walk_init(&pfk->dump.u.policy, XFRM_POLICY_TYPE_MAIN);
+	mutex_unlock(&pfk->dump_lock);
 
 	return pfkey_do_dump(pfk);
 }
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_core.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_core.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_core.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_core.c	2017-07-18 13:40:42.000000000 -0400
@@ -277,7 +277,57 @@ struct l2tp_session *l2tp_session_find(s
 }
 EXPORT_SYMBOL_GPL(l2tp_session_find);
 
-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
+/* Like l2tp_session_find() but takes a reference on the returned session.
+ * Optionally calls session->ref() too if do_ref is true.
+ */
+struct l2tp_session *l2tp_session_get(struct net *net,
+				      struct l2tp_tunnel *tunnel,
+				      u32 session_id, bool do_ref)
+{
+	struct hlist_head *session_list;
+	struct l2tp_session *session;
+
+	if (!tunnel) {
+		struct l2tp_net *pn = l2tp_pernet(net);
+
+		session_list = l2tp_session_id_hash_2(pn, session_id);
+
+		rcu_read_lock_bh();
+		hlist_for_each_entry_rcu(session, session_list, global_hlist) {
+			if (session->session_id == session_id) {
+				l2tp_session_inc_refcount(session);
+				if (do_ref && session->ref)
+					session->ref(session);
+				rcu_read_unlock_bh();
+
+				return session;
+			}
+		}
+		rcu_read_unlock_bh();
+
+		return NULL;
+	}
+
+	session_list = l2tp_session_id_hash(tunnel, session_id);
+	read_lock_bh(&tunnel->hlist_lock);
+	hlist_for_each_entry(session, session_list, hlist) {
+		if (session->session_id == session_id) {
+			l2tp_session_inc_refcount(session);
+			if (do_ref && session->ref)
+				session->ref(session);
+			read_unlock_bh(&tunnel->hlist_lock);
+
+			return session;
+		}
+	}
+	read_unlock_bh(&tunnel->hlist_lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(l2tp_session_get);
+
+struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
+					  bool do_ref)
 {
 	int hash;
 	struct l2tp_session *session;
@@ -287,6 +337,9 @@ struct l2tp_session *l2tp_session_find_n
 	for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
 		hlist_for_each_entry(session, &tunnel->session_hlist[hash], hlist) {
 			if (++count > nth) {
+				l2tp_session_inc_refcount(session);
+				if (do_ref && session->ref)
+					session->ref(session);
 				read_unlock_bh(&tunnel->hlist_lock);
 				return session;
 			}
@@ -297,12 +350,13 @@ struct l2tp_session *l2tp_session_find_n
 
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(l2tp_session_find_nth);
+EXPORT_SYMBOL_GPL(l2tp_session_get_nth);
 
 /* Lookup a session by interface name.
  * This is very inefficient but is only used by management interfaces.
  */
-struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname)
+struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
+						bool do_ref)
 {
 	struct l2tp_net *pn = l2tp_pernet(net);
 	int hash;
@@ -312,7 +366,11 @@ struct l2tp_session *l2tp_session_find_b
 	for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++) {
 		hlist_for_each_entry_rcu(session, &pn->l2tp_session_hlist[hash], global_hlist) {
 			if (!strcmp(session->ifname, ifname)) {
+				l2tp_session_inc_refcount(session);
+				if (do_ref && session->ref)
+					session->ref(session);
 				rcu_read_unlock_bh();
+
 				return session;
 			}
 		}
@@ -322,7 +380,49 @@ struct l2tp_session *l2tp_session_find_b
 
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(l2tp_session_find_by_ifname);
+EXPORT_SYMBOL_GPL(l2tp_session_get_by_ifname);
+
+static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel,
+				      struct l2tp_session *session)
+{
+	struct l2tp_session *session_walk;
+	struct hlist_head *g_head;
+	struct hlist_head *head;
+	struct l2tp_net *pn;
+
+	head = l2tp_session_id_hash(tunnel, session->session_id);
+
+	write_lock_bh(&tunnel->hlist_lock);
+	hlist_for_each_entry(session_walk, head, hlist)
+		if (session_walk->session_id == session->session_id)
+			goto exist;
+
+	if (tunnel->version == L2TP_HDR_VER_3) {
+		pn = l2tp_pernet(tunnel->l2tp_net);
+		g_head = l2tp_session_id_hash_2(l2tp_pernet(tunnel->l2tp_net),
+						session->session_id);
+
+		spin_lock_bh(&pn->l2tp_session_hlist_lock);
+		hlist_for_each_entry(session_walk, g_head, global_hlist)
+			if (session_walk->session_id == session->session_id)
+				goto exist_glob;
+
+		hlist_add_head_rcu(&session->global_hlist, g_head);
+		spin_unlock_bh(&pn->l2tp_session_hlist_lock);
+	}
+
+	hlist_add_head(&session->hlist, head);
+	write_unlock_bh(&tunnel->hlist_lock);
+
+	return 0;
+
+exist_glob:
+	spin_unlock_bh(&pn->l2tp_session_hlist_lock);
+exist:
+	write_unlock_bh(&tunnel->hlist_lock);
+
+	return -EEXIST;
+}
 
 /* Lookup a tunnel by id
  */
@@ -632,6 +732,9 @@ discard:
  * a data (not control) frame before coming here. Fields up to the
  * session-id have already been parsed and ptr points to the data
  * after the session-id.
+ *
+ * session->ref() must have been called prior to l2tp_recv_common().
+ * session->deref() will be called automatically after skb is processed.
  */
 void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
 		      unsigned char *ptr, unsigned char *optr, u16 hdrflags,
@@ -641,14 +744,6 @@ void l2tp_recv_common(struct l2tp_sessio
 	int offset;
 	u32 ns, nr;
 
-	/* The ref count is increased since we now hold a pointer to
-	 * the session. Take care to decrement the refcnt when exiting
-	 * this function from now on...
-	 */
-	l2tp_session_inc_refcount(session);
-	if (session->ref)
-		(*session->ref)(session);
-
 	/* Parse and check optional cookie */
 	if (session->peer_cookie_len > 0) {
 		if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) {
@@ -801,8 +896,6 @@ void l2tp_recv_common(struct l2tp_sessio
 	/* Try to dequeue as many skbs from reorder_q as we can. */
 	l2tp_recv_dequeue(session);
 
-	l2tp_session_dec_refcount(session);
-
 	return;
 
 discard:
@@ -811,8 +904,6 @@ discard:
 
 	if (session->deref)
 		(*session->deref)(session);
-
-	l2tp_session_dec_refcount(session);
 }
 EXPORT_SYMBOL(l2tp_recv_common);
 
@@ -919,8 +1010,14 @@ static int l2tp_udp_recv_core(struct l2t
 	}
 
 	/* Find the session context */
-	session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id);
+	session = l2tp_session_get(tunnel->l2tp_net, tunnel, session_id, true);
 	if (!session || !session->recv_skb) {
+		if (session) {
+			if (session->deref)
+				session->deref(session);
+			l2tp_session_dec_refcount(session);
+		}
+
 		/* Not found? Pass to userspace to deal with */
 		l2tp_info(tunnel, L2TP_MSG_DATA,
 			  "%s: no session found (%u/%u). Passing up.\n",
@@ -929,6 +1026,7 @@ static int l2tp_udp_recv_core(struct l2t
 	}
 
 	l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook);
+	l2tp_session_dec_refcount(session);
 
 	return 0;
 
@@ -1775,6 +1873,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_set_heade
 struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
 {
 	struct l2tp_session *session;
+	int err;
 
 	session = kzalloc(sizeof(struct l2tp_session) + priv_size, GFP_KERNEL);
 	if (session != NULL) {
@@ -1830,6 +1929,13 @@ struct l2tp_session *l2tp_session_create
 
 		l2tp_session_set_header_len(session, tunnel->version);
 
+		err = l2tp_session_add_to_tunnel(tunnel, session);
+		if (err) {
+			kfree(session);
+
+			return ERR_PTR(err);
+		}
+
 		/* Bump the reference count. The session context is deleted
 		 * only when this drops to zero.
 		 */
@@ -1839,28 +1945,14 @@ struct l2tp_session *l2tp_session_create
 		/* Ensure tunnel socket isn't deleted */
 		sock_hold(tunnel->sock);
 
-		/* Add session to the tunnel's hash list */
-		write_lock_bh(&tunnel->hlist_lock);
-		hlist_add_head(&session->hlist,
-			       l2tp_session_id_hash(tunnel, session_id));
-		write_unlock_bh(&tunnel->hlist_lock);
-
-		/* And to the global session list if L2TPv3 */
-		if (tunnel->version != L2TP_HDR_VER_2) {
-			struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
-
-			spin_lock_bh(&pn->l2tp_session_hlist_lock);
-			hlist_add_head_rcu(&session->global_hlist,
-					   l2tp_session_id_hash_2(pn, session_id));
-			spin_unlock_bh(&pn->l2tp_session_hlist_lock);
-		}
-
 		/* Ignore management session in session count value */
 		if (session->session_id != 0)
 			atomic_inc(&l2tp_session_count);
+
+		return session;
 	}
 
-	return session;
+	return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL_GPL(l2tp_session_create);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_core.h linux-libre-3.16.46-gnu/net/l2tp/l2tp_core.h
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_core.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_core.h	2017-07-18 13:40:42.000000000 -0400
@@ -240,11 +240,16 @@ out:
 	return tunnel;
 }
 
+struct l2tp_session *l2tp_session_get(struct net *net,
+				      struct l2tp_tunnel *tunnel,
+				      u32 session_id, bool do_ref);
 struct l2tp_session *l2tp_session_find(struct net *net,
 				       struct l2tp_tunnel *tunnel,
 				       u32 session_id);
-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
-struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);
+struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
+					  bool do_ref);
+struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
+						bool do_ref);
 struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
 struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_debugfs.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_debugfs.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_debugfs.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_debugfs.c	2017-07-18 13:40:42.000000000 -0400
@@ -53,7 +53,7 @@ static void l2tp_dfs_next_tunnel(struct
 
 static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd)
 {
-	pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx);
+	pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true);
 	pd->session_idx++;
 
 	if (pd->session == NULL) {
@@ -238,10 +238,14 @@ static int l2tp_dfs_seq_show(struct seq_
 	}
 
 	/* Show the tunnel or session context */
-	if (pd->session == NULL)
+	if (!pd->session) {
 		l2tp_dfs_seq_tunnel_show(m, pd->tunnel);
-	else
+	} else {
 		l2tp_dfs_seq_session_show(m, pd->session);
+		if (pd->session->deref)
+			pd->session->deref(pd->session);
+		l2tp_session_dec_refcount(pd->session);
+	}
 
 out:
 	return 0;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_eth.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_eth.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_eth.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_eth.c	2017-07-18 13:40:42.000000000 -0400
@@ -222,12 +222,6 @@ static int l2tp_eth_create(struct net *n
 		goto out;
 	}
 
-	session = l2tp_session_find(net, tunnel, session_id);
-	if (session) {
-		rc = -EEXIST;
-		goto out;
-	}
-
 	if (cfg->ifname) {
 		dev = dev_get_by_name(net, cfg->ifname);
 		if (dev) {
@@ -241,8 +235,8 @@ static int l2tp_eth_create(struct net *n
 
 	session = l2tp_session_create(sizeof(*spriv), tunnel, session_id,
 				      peer_session_id, cfg);
-	if (!session) {
-		rc = -ENOMEM;
+	if (IS_ERR(session)) {
+		rc = PTR_ERR(session);
 		goto out;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_ip6.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_ip6.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_ip6.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_ip6.c	2017-07-18 13:40:42.000000000 -0400
@@ -153,19 +153,19 @@ static int l2tp_ip6_recv(struct sk_buff
 	}
 
 	/* Ok, this is a data packet. Lookup the session. */
-	session = l2tp_session_find(&init_net, NULL, session_id);
-	if (session == NULL)
+	session = l2tp_session_get(&init_net, NULL, session_id, true);
+	if (!session)
 		goto discard;
 
 	tunnel = session->tunnel;
-	if (tunnel == NULL)
-		goto discard;
+	if (!tunnel)
+		goto discard_sess;
 
 	/* Trace packet contents, if enabled */
 	if (tunnel->debug & L2TP_MSG_DATA) {
 		length = min(32u, skb->len);
 		if (!pskb_may_pull(skb, length))
-			goto discard;
+			goto discard_sess;
 
 		/* Point to L2TP header */
 		optr = ptr = skb->data;
@@ -176,6 +176,8 @@ static int l2tp_ip6_recv(struct sk_buff
 
 	l2tp_recv_common(session, skb, ptr, optr, 0, skb->len,
 			 tunnel->recv_payload_hook);
+	l2tp_session_dec_refcount(session);
+
 	return 0;
 
 pass_up:
@@ -211,6 +213,12 @@ pass_up:
 
 	return sk_receive_skb(sk, skb, 1);
 
+discard_sess:
+	if (session->deref)
+		session->deref(session);
+	l2tp_session_dec_refcount(session);
+	goto discard;
+
 discard_put:
 	sock_put(sk);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_ip.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_ip.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_ip.c	2017-07-18 13:40:42.000000000 -0400
@@ -142,19 +142,19 @@ static int l2tp_ip_recv(struct sk_buff *
 	}
 
 	/* Ok, this is a data packet. Lookup the session. */
-	session = l2tp_session_find(net, NULL, session_id);
-	if (session == NULL)
+	session = l2tp_session_get(net, NULL, session_id, true);
+	if (!session)
 		goto discard;
 
 	tunnel = session->tunnel;
-	if (tunnel == NULL)
-		goto discard;
+	if (!tunnel)
+		goto discard_sess;
 
 	/* Trace packet contents, if enabled */
 	if (tunnel->debug & L2TP_MSG_DATA) {
 		length = min(32u, skb->len);
 		if (!pskb_may_pull(skb, length))
-			goto discard;
+			goto discard_sess;
 
 		/* Point to L2TP header */
 		optr = ptr = skb->data;
@@ -164,6 +164,7 @@ static int l2tp_ip_recv(struct sk_buff *
 	}
 
 	l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook);
+	l2tp_session_dec_refcount(session);
 
 	return 0;
 
@@ -199,6 +200,12 @@ pass_up:
 
 	return sk_receive_skb(sk, skb, 1);
 
+discard_sess:
+	if (session->deref)
+		session->deref(session);
+	l2tp_session_dec_refcount(session);
+	goto discard;
+
 discard_put:
 	sock_put(sk);
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_netlink.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_netlink.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_netlink.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_netlink.c	2017-07-18 13:40:42.000000000 -0400
@@ -43,7 +43,8 @@ static struct genl_family l2tp_nl_family
 /* Accessed under genl lock */
 static const struct l2tp_nl_cmd_ops *l2tp_nl_cmd_ops[__L2TP_PWTYPE_MAX];
 
-static struct l2tp_session *l2tp_nl_session_find(struct genl_info *info)
+static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info,
+						bool do_ref)
 {
 	u32 tunnel_id;
 	u32 session_id;
@@ -54,14 +55,15 @@ static struct l2tp_session *l2tp_nl_sess
 
 	if (info->attrs[L2TP_ATTR_IFNAME]) {
 		ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
-		session = l2tp_session_find_by_ifname(net, ifname);
+		session = l2tp_session_get_by_ifname(net, ifname, do_ref);
 	} else if ((info->attrs[L2TP_ATTR_SESSION_ID]) &&
 		   (info->attrs[L2TP_ATTR_CONN_ID])) {
 		tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
 		session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
 		tunnel = l2tp_tunnel_find(net, tunnel_id);
 		if (tunnel)
-			session = l2tp_session_find(net, tunnel, session_id);
+			session = l2tp_session_get(net, tunnel, session_id,
+						   do_ref);
 	}
 
 	return session;
@@ -549,7 +551,7 @@ static int l2tp_nl_cmd_session_delete(st
 	struct l2tp_session *session;
 	u16 pw_type;
 
-	session = l2tp_nl_session_find(info);
+	session = l2tp_nl_session_get(info, true);
 	if (session == NULL) {
 		ret = -ENODEV;
 		goto out;
@@ -560,6 +562,10 @@ static int l2tp_nl_cmd_session_delete(st
 		if (l2tp_nl_cmd_ops[pw_type] && l2tp_nl_cmd_ops[pw_type]->session_delete)
 			ret = (*l2tp_nl_cmd_ops[pw_type]->session_delete)(session);
 
+	if (session->deref)
+		session->deref(session);
+	l2tp_session_dec_refcount(session);
+
 out:
 	return ret;
 }
@@ -569,7 +575,7 @@ static int l2tp_nl_cmd_session_modify(st
 	int ret = 0;
 	struct l2tp_session *session;
 
-	session = l2tp_nl_session_find(info);
+	session = l2tp_nl_session_get(info, false);
 	if (session == NULL) {
 		ret = -ENODEV;
 		goto out;
@@ -601,6 +607,8 @@ static int l2tp_nl_cmd_session_modify(st
 	if (info->attrs[L2TP_ATTR_MRU])
 		session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
 
+	l2tp_session_dec_refcount(session);
+
 out:
 	return ret;
 }
@@ -686,29 +694,34 @@ static int l2tp_nl_cmd_session_get(struc
 	struct sk_buff *msg;
 	int ret;
 
-	session = l2tp_nl_session_find(info);
+	session = l2tp_nl_session_get(info, false);
 	if (session == NULL) {
 		ret = -ENODEV;
-		goto out;
+		goto err;
 	}
 
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg) {
 		ret = -ENOMEM;
-		goto out;
+		goto err_ref;
 	}
 
 	ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq,
 				   0, session);
 	if (ret < 0)
-		goto err_out;
+		goto err_ref_msg;
 
-	return genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
+	ret = genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
 
-err_out:
-	nlmsg_free(msg);
+	l2tp_session_dec_refcount(session);
 
-out:
+	return ret;
+
+err_ref_msg:
+	nlmsg_free(msg);
+err_ref:
+	l2tp_session_dec_refcount(session);
+err:
 	return ret;
 }
 
@@ -727,7 +740,7 @@ static int l2tp_nl_cmd_session_dump(stru
 				goto out;
 		}
 
-		session = l2tp_session_find_nth(tunnel, si);
+		session = l2tp_session_get_nth(tunnel, si, false);
 		if (session == NULL) {
 			ti++;
 			tunnel = NULL;
@@ -737,8 +750,11 @@ static int l2tp_nl_cmd_session_dump(stru
 
 		if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid,
 					 cb->nlh->nlmsg_seq, NLM_F_MULTI,
-					 session) <= 0)
+					 session) <= 0) {
+			l2tp_session_dec_refcount(session);
 			break;
+		}
+		l2tp_session_dec_refcount(session);
 
 		si++;
 	}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/l2tp/l2tp_ppp.c linux-libre-3.16.46-gnu/net/l2tp/l2tp_ppp.c
--- linux-libre-3.16.45-gnu/net/l2tp/l2tp_ppp.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/l2tp/l2tp_ppp.c	2017-07-18 13:40:42.000000000 -0400
@@ -469,6 +469,10 @@ static void pppol2tp_session_close(struc
 static void pppol2tp_session_destruct(struct sock *sk)
 {
 	struct l2tp_session *session = sk->sk_user_data;
+
+	skb_queue_purge(&sk->sk_receive_queue);
+	skb_queue_purge(&sk->sk_write_queue);
+
 	if (session) {
 		sk->sk_user_data = NULL;
 		BUG_ON(session->magic != L2TP_SESSION_MAGIC);
@@ -507,9 +511,6 @@ static int pppol2tp_release(struct socke
 		l2tp_session_queue_purge(session);
 		sock_put(sk);
 	}
-	skb_queue_purge(&sk->sk_receive_queue);
-	skb_queue_purge(&sk->sk_write_queue);
-
 	release_sock(sk);
 
 	/* This will delete the session context via
@@ -601,6 +602,7 @@ static int pppol2tp_connect(struct socke
 	int error = 0;
 	u32 tunnel_id, peer_tunnel_id;
 	u32 session_id, peer_session_id;
+	bool drop_refcnt = false;
 	int ver = 2;
 	int fd;
 
@@ -702,36 +704,36 @@ static int pppol2tp_connect(struct socke
 	if (tunnel->peer_tunnel_id == 0)
 		tunnel->peer_tunnel_id = peer_tunnel_id;
 
-	/* Create session if it doesn't already exist. We handle the
-	 * case where a session was previously created by the netlink
-	 * interface by checking that the session doesn't already have
-	 * a socket and its tunnel socket are what we expect. If any
-	 * of those checks fail, return EEXIST to the caller.
-	 */
-	session = l2tp_session_find(sock_net(sk), tunnel, session_id);
-	if (session == NULL) {
-		/* Default MTU must allow space for UDP/L2TP/PPP
-		 * headers.
+	session = l2tp_session_get(sock_net(sk), tunnel, session_id, false);
+	if (session) {
+		drop_refcnt = true;
+		ps = l2tp_session_priv(session);
+
+		/* Using a pre-existing session is fine as long as it hasn't
+		 * been connected yet.
 		 */
-		cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD;
+		if (ps->sock) {
+			error = -EEXIST;
+			goto end;
+		}
 
-		/* Allocate and initialize a new session context. */
-		session = l2tp_session_create(sizeof(struct pppol2tp_session),
-					      tunnel, session_id,
-					      peer_session_id, &cfg);
-		if (session == NULL) {
-			error = -ENOMEM;
+		/* consistency checks */
+		if (ps->tunnel_sock != tunnel->sock) {
+			error = -EEXIST;
 			goto end;
 		}
 	} else {
-		ps = l2tp_session_priv(session);
-		error = -EEXIST;
-		if (ps->sock != NULL)
-			goto end;
+		/* Default MTU must allow space for UDP/L2TP/PPP headers */
+		cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
+		cfg.mru = cfg.mtu;
 
-		/* consistency checks */
-		if (ps->tunnel_sock != tunnel->sock)
+		session = l2tp_session_create(sizeof(struct pppol2tp_session),
+					      tunnel, session_id,
+					      peer_session_id, &cfg);
+		if (IS_ERR(session)) {
+			error = PTR_ERR(session);
 			goto end;
+		}
 	}
 
 	/* Associate session with its PPPoL2TP socket */
@@ -796,6 +798,8 @@ out_no_ppp:
 		  session->name);
 
 end:
+	if (drop_refcnt)
+		l2tp_session_dec_refcount(session);
 	release_sock(sk);
 
 	return error;
@@ -823,12 +827,6 @@ static int pppol2tp_session_create(struc
 	if (tunnel->sock == NULL)
 		goto out;
 
-	/* Check that this session doesn't already exist */
-	error = -EEXIST;
-	session = l2tp_session_find(net, tunnel, session_id);
-	if (session != NULL)
-		goto out;
-
 	/* Default MTU values. */
 	if (cfg->mtu == 0)
 		cfg->mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
@@ -836,12 +834,13 @@ static int pppol2tp_session_create(struc
 		cfg->mru = cfg->mtu;
 
 	/* Allocate and initialize a new session context. */
-	error = -ENOMEM;
 	session = l2tp_session_create(sizeof(struct pppol2tp_session),
 				      tunnel, session_id,
 				      peer_session_id, cfg);
-	if (session == NULL)
+	if (IS_ERR(session)) {
+		error = PTR_ERR(session);
 		goto out;
+	}
 
 	ps = l2tp_session_priv(session);
 	ps->tunnel_sock = tunnel->sock;
@@ -1159,11 +1158,18 @@ static int pppol2tp_tunnel_ioctl(struct
 		if (stats.session_id != 0) {
 			/* resend to session ioctl handler */
 			struct l2tp_session *session =
-				l2tp_session_find(sock_net(sk), tunnel, stats.session_id);
-			if (session != NULL)
-				err = pppol2tp_session_ioctl(session, cmd, arg);
-			else
+				l2tp_session_get(sock_net(sk), tunnel,
+						 stats.session_id, true);
+
+			if (session) {
+				err = pppol2tp_session_ioctl(session, cmd,
+							     arg);
+				if (session->deref)
+					session->deref(session);
+				l2tp_session_dec_refcount(session);
+			} else {
 				err = -EBADR;
+			}
 			break;
 		}
 #ifdef CONFIG_XFRM
@@ -1396,8 +1402,6 @@ static int pppol2tp_setsockopt(struct so
 	} else
 		err = pppol2tp_session_setsockopt(sk, session, optname, val);
 
-	err = 0;
-
 end_put_sess:
 	sock_put(sk);
 end:
@@ -1520,8 +1524,13 @@ static int pppol2tp_getsockopt(struct so
 
 		err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
 		sock_put(ps->tunnel_sock);
-	} else
+		if (err)
+			goto end_put_sess;
+	} else {
 		err = pppol2tp_session_getsockopt(sk, session, optname, &val);
+		if (err)
+			goto end_put_sess;
+	}
 
 	err = -EFAULT;
 	if (put_user(len, optlen))
@@ -1573,7 +1582,7 @@ static void pppol2tp_next_tunnel(struct
 
 static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd)
 {
-	pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx);
+	pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true);
 	pd->session_idx++;
 
 	if (pd->session == NULL) {
@@ -1700,10 +1709,14 @@ static int pppol2tp_seq_show(struct seq_
 
 	/* Show the tunnel or session context.
 	 */
-	if (pd->session == NULL)
+	if (!pd->session) {
 		pppol2tp_seq_tunnel_show(m, pd->tunnel);
-	else
+	} else {
 		pppol2tp_seq_session_show(m, pd->session);
+		if (pd->session->deref)
+			pd->session->deref(pd->session);
+		l2tp_session_dec_refcount(pd->session);
+	}
 
 out:
 	return 0;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/mac80211/rx.c linux-libre-3.16.46-gnu/net/mac80211/rx.c
--- linux-libre-3.16.45-gnu/net/mac80211/rx.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/mac80211/rx.c	2017-07-18 13:40:42.000000000 -0400
@@ -3140,6 +3140,30 @@ static bool prepare_for_handlers(struct
 			if (!ieee80211_is_beacon(hdr->frame_control))
 				return false;
 			status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
+		} else {
+			/*
+			 * 802.11-2016 Table 9-26 says that for data frames,
+			 * A1 must be the BSSID - we've checked that already
+			 * but may have accepted the wildcard
+			 * (ff:ff:ff:ff:ff:ff).
+			 *
+			 * It also says:
+			 *	The BSSID of the Data frame is determined as
+			 *      follows:
+			 *	a) If the STA is contained within an AP or is
+			 *         associated with an AP, the BSSID is the
+			 *         address currently in use by the STA
+			 *         contained in the AP.
+			 *
+			 * So we should not accept data frames with an address
+			 * that's multicast.
+			 *
+			 * Accepting it also opens a security problem because
+			 * stations could encrypt it with the GTK and inject
+			 * traffic that way.
+			 */
+			if (ieee80211_is_data(hdr->frame_control) && multicast)
+				return false;
 		}
 		break;
 	case NL80211_IFTYPE_WDS:
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/sched/act_csum.c linux-libre-3.16.46-gnu/net/sched/act_csum.c
--- linux-libre-3.16.45-gnu/net/sched/act_csum.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/sched/act_csum.c	2017-07-18 13:40:42.000000000 -0400
@@ -104,9 +104,7 @@ static void *tcf_csum_skb_nextlayer(stru
 	int hl = ihl + jhl;
 
 	if (!pskb_may_pull(skb, ipl + ntkoff) || (ipl < hl) ||
-	    (skb_cloned(skb) &&
-	     !skb_clone_writable(skb, hl + ntkoff) &&
-	     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+	    skb_try_make_writable(skb, hl + ntkoff))
 		return NULL;
 	else
 		return (void *)(skb_network_header(skb) + ihl);
@@ -364,9 +362,7 @@ static int tcf_csum_ipv4(struct sk_buff
 	}
 
 	if (update_flags & TCA_CSUM_UPDATE_FLAG_IPV4HDR) {
-		if (skb_cloned(skb) &&
-		    !skb_clone_writable(skb, sizeof(*iph) + ntkoff) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		if (skb_try_make_writable(skb, sizeof(*iph) + ntkoff))
 			goto fail;
 
 		ip_send_check(ip_hdr(skb));
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/sched/act_nat.c linux-libre-3.16.46-gnu/net/sched/act_nat.c
--- linux-libre-3.16.45-gnu/net/sched/act_nat.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/sched/act_nat.c	2017-07-18 13:40:42.000000000 -0400
@@ -125,9 +125,7 @@ static int tcf_nat(struct sk_buff *skb,
 		addr = iph->daddr;
 
 	if (!((old_addr ^ addr) & mask)) {
-		if (skb_cloned(skb) &&
-		    !skb_clone_writable(skb, sizeof(*iph) + noff) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		if (skb_try_make_writable(skb, sizeof(*iph) + noff))
 			goto drop;
 
 		new_addr &= mask;
@@ -155,9 +153,7 @@ static int tcf_nat(struct sk_buff *skb,
 		struct tcphdr *tcph;
 
 		if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) ||
-		    (skb_cloned(skb) &&
-		     !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) &&
-		     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+		    skb_try_make_writable(skb, ihl + sizeof(*tcph) + noff))
 			goto drop;
 
 		tcph = (void *)(skb_network_header(skb) + ihl);
@@ -169,9 +165,7 @@ static int tcf_nat(struct sk_buff *skb,
 		struct udphdr *udph;
 
 		if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) ||
-		    (skb_cloned(skb) &&
-		     !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) &&
-		     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+		    skb_try_make_writable(skb, ihl + sizeof(*udph) + noff))
 			goto drop;
 
 		udph = (void *)(skb_network_header(skb) + ihl);
@@ -211,10 +205,8 @@ static int tcf_nat(struct sk_buff *skb,
 		if ((old_addr ^ addr) & mask)
 			break;
 
-		if (skb_cloned(skb) &&
-		    !skb_clone_writable(skb, ihl + sizeof(*icmph) +
-					     sizeof(*iph) + noff) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		if (skb_try_make_writable(skb, ihl + sizeof(*icmph) +
+					  sizeof(*iph) + noff))
 			goto drop;
 
 		icmph = (void *)(skb_network_header(skb) + ihl);
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/sched/sch_dsmark.c linux-libre-3.16.46-gnu/net/sched/sch_dsmark.c
--- linux-libre-3.16.45-gnu/net/sched/sch_dsmark.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/sched/sch_dsmark.c	2017-07-18 13:40:42.000000000 -0400
@@ -197,9 +197,13 @@ static int dsmark_enqueue(struct sk_buff
 	pr_debug("%s(skb %p,sch %p,[qdisc %p])\n", __func__, skb, sch, p);
 
 	if (p->set_tc_index) {
+		int wlen = skb_network_offset(skb);
+
 		switch (skb->protocol) {
 		case htons(ETH_P_IP):
-			if (skb_cow_head(skb, sizeof(struct iphdr)))
+			wlen += sizeof(struct iphdr);
+			if (!pskb_may_pull(skb, wlen) ||
+			    skb_try_make_writable(skb, wlen))
 				goto drop;
 
 			skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
@@ -207,7 +211,9 @@ static int dsmark_enqueue(struct sk_buff
 			break;
 
 		case htons(ETH_P_IPV6):
-			if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
+			wlen += sizeof(struct ipv6hdr);
+			if (!pskb_may_pull(skb, wlen) ||
+			    skb_try_make_writable(skb, wlen))
 				goto drop;
 
 			skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/unix/garbage.c linux-libre-3.16.46-gnu/net/unix/garbage.c
--- linux-libre-3.16.45-gnu/net/unix/garbage.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/unix/garbage.c	2017-07-18 13:40:42.000000000 -0400
@@ -152,6 +152,7 @@ void unix_notinflight(struct user_struct
 	if (s) {
 		struct unix_sock *u = unix_sk(s);
 
+		BUG_ON(!atomic_long_read(&u->inflight));
 		BUG_ON(list_empty(&u->link));
 		if (atomic_long_dec_and_test(&u->inflight))
 			list_del_init(&u->link);
@@ -358,6 +359,14 @@ void unix_gc(void)
 	}
 	list_del(&cursor);
 
+	/* Now gc_candidates contains only garbage.  Restore original
+	 * inflight counters for these as well, and remove the skbuffs
+	 * which are creating the cycle(s).
+	 */
+	skb_queue_head_init(&hitlist);
+	list_for_each_entry(u, &gc_candidates, link)
+		scan_children(&u->sk, inc_inflight, &hitlist);
+
 	/*
 	 * not_cycle_list contains those sockets which do not make up a
 	 * cycle.  Restore these to the inflight list.
@@ -368,15 +377,6 @@ void unix_gc(void)
 		list_move_tail(&u->link, &gc_inflight_list);
 	}
 
-	/*
-	 * Now gc_candidates contains only garbage.  Restore original
-	 * inflight counters for these as well, and remove the skbuffs
-	 * which are creating the cycle(s).
-	 */
-	skb_queue_head_init(&hitlist);
-	list_for_each_entry(u, &gc_candidates, link)
-	scan_children(&u->sk, inc_inflight, &hitlist);
-
 	spin_unlock(&unix_gc_lock);
 
 	/* Here we are. Hitlist is filled. Die. */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/wireless/nl80211.c linux-libre-3.16.46-gnu/net/wireless/nl80211.c
--- linux-libre-3.16.45-gnu/net/wireless/nl80211.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/wireless/nl80211.c	2017-07-18 13:40:42.000000000 -0400
@@ -471,21 +471,17 @@ static int nl80211_prepare_wdev_dump(str
 {
 	int err;
 
-	rtnl_lock();
-
 	if (!cb->args[0]) {
 		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
 				  nl80211_fam.attrbuf, nl80211_fam.maxattr,
 				  nl80211_policy);
 		if (err)
-			goto out_unlock;
+			return err;
 
 		*wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
 						   nl80211_fam.attrbuf);
-		if (IS_ERR(*wdev)) {
-			err = PTR_ERR(*wdev);
-			goto out_unlock;
-		}
+		if (IS_ERR(*wdev))
+			return PTR_ERR(*wdev);
 		*rdev = wiphy_to_rdev((*wdev)->wiphy);
 		/* 0 is the first index - add 1 to parse only once */
 		cb->args[0] = (*rdev)->wiphy_idx + 1;
@@ -495,10 +491,8 @@ static int nl80211_prepare_wdev_dump(str
 		struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
 		struct wireless_dev *tmp;
 
-		if (!wiphy) {
-			err = -ENODEV;
-			goto out_unlock;
-		}
+		if (!wiphy)
+			return -ENODEV;
 		*rdev = wiphy_to_rdev(wiphy);
 		*wdev = NULL;
 
@@ -509,21 +503,11 @@ static int nl80211_prepare_wdev_dump(str
 			}
 		}
 
-		if (!*wdev) {
-			err = -ENODEV;
-			goto out_unlock;
-		}
+		if (!*wdev)
+			return -ENODEV;
 	}
 
 	return 0;
- out_unlock:
-	rtnl_unlock();
-	return err;
-}
-
-static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
-{
-	rtnl_unlock();
 }
 
 /* IE validation */
@@ -3727,9 +3711,10 @@ static int nl80211_dump_station(struct s
 	int sta_idx = cb->args[2];
 	int err;
 
+	rtnl_lock();
 	err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
 	if (err)
-		return err;
+		goto out_err;
 
 	if (!wdev->netdev) {
 		err = -EINVAL;
@@ -3765,7 +3750,7 @@ static int nl80211_dump_station(struct s
 	cb->args[2] = sta_idx;
 	err = skb->len;
  out_err:
-	nl80211_finish_wdev_dump(rdev);
+	rtnl_unlock();
 
 	return err;
 }
@@ -4443,9 +4428,10 @@ static int nl80211_dump_mpath(struct sk_
 	int path_idx = cb->args[2];
 	int err;
 
+	rtnl_lock();
 	err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
 	if (err)
-		return err;
+		goto out_err;
 
 	if (!rdev->ops->dump_mpath) {
 		err = -EOPNOTSUPP;
@@ -4479,7 +4465,7 @@ static int nl80211_dump_mpath(struct sk_
 	cb->args[2] = path_idx;
 	err = skb->len;
  out_err:
-	nl80211_finish_wdev_dump(rdev);
+	rtnl_unlock();
 	return err;
 }
 
@@ -6157,9 +6143,12 @@ static int nl80211_dump_scan(struct sk_b
 	int start = cb->args[2], idx = 0;
 	int err;
 
+	rtnl_lock();
 	err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
-	if (err)
+	if (err) {
+		rtnl_unlock();
 		return err;
+	}
 
 	wdev_lock(wdev);
 	spin_lock_bh(&rdev->bss_lock);
@@ -6182,7 +6171,7 @@ static int nl80211_dump_scan(struct sk_b
 	wdev_unlock(wdev);
 
 	cb->args[2] = idx;
-	nl80211_finish_wdev_dump(rdev);
+	rtnl_unlock();
 
 	return skb->len;
 }
@@ -6255,9 +6244,10 @@ static int nl80211_dump_survey(struct sk
 	int survey_idx = cb->args[2];
 	int res;
 
+	rtnl_lock();
 	res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
 	if (res)
-		return res;
+		goto out_err;
 
 	if (!wdev->netdev) {
 		res = -EINVAL;
@@ -6303,7 +6293,7 @@ static int nl80211_dump_survey(struct sk
 	cb->args[2] = survey_idx;
 	res = skb->len;
  out_err:
-	nl80211_finish_wdev_dump(rdev);
+	rtnl_unlock();
 	return res;
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/net/xfrm/xfrm_policy.c linux-libre-3.16.46-gnu/net/xfrm/xfrm_policy.c
--- linux-libre-3.16.45-gnu/net/xfrm/xfrm_policy.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/net/xfrm/xfrm_policy.c	2017-07-18 13:40:42.000000000 -0400
@@ -2878,6 +2878,11 @@ static int __net_init xfrm_net_init(stru
 {
 	int rv;
 
+	/* Initialize the per-net locks here */
+	spin_lock_init(&net->xfrm.xfrm_state_lock);
+	rwlock_init(&net->xfrm.xfrm_policy_lock);
+	mutex_init(&net->xfrm.xfrm_cfg_mutex);
+
 	rv = xfrm_statistics_init(net);
 	if (rv < 0)
 		goto out_statistics;
@@ -2894,11 +2899,6 @@ static int __net_init xfrm_net_init(stru
 	if (rv < 0)
 		goto out;
 
-	/* Initialize the per-net locks here */
-	spin_lock_init(&net->xfrm.xfrm_state_lock);
-	rwlock_init(&net->xfrm.xfrm_policy_lock);
-	mutex_init(&net->xfrm.xfrm_cfg_mutex);
-
 	return 0;
 
 out:
diff -druNp --no-dereference linux-libre-3.16.45-gnu/security/keys/gc.c linux-libre-3.16.46-gnu/security/keys/gc.c
--- linux-libre-3.16.45-gnu/security/keys/gc.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/security/keys/gc.c	2017-07-18 13:40:42.000000000 -0400
@@ -46,7 +46,7 @@ static unsigned long key_gc_flags;
  * immediately unlinked.
  */
 struct key_type key_type_dead = {
-	.name = "dead",
+	.name = ".dead",
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/core/seq/seq_clientmgr.c linux-libre-3.16.46-gnu/sound/core/seq/seq_clientmgr.c
--- linux-libre-3.16.45-gnu/sound/core/seq/seq_clientmgr.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/core/seq/seq_clientmgr.c	2017-07-18 13:40:42.000000000 -0400
@@ -1921,6 +1921,7 @@ static int snd_seq_ioctl_set_client_pool
 	     info.output_pool != client->pool->size)) {
 		if (snd_seq_write_pool_allocated(client)) {
 			/* remove all existing cells */
+			snd_seq_pool_mark_closing(client->pool);
 			snd_seq_queue_client_leave_cells(client->number);
 			snd_seq_pool_done(client->pool);
 		}
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/core/seq/seq_fifo.c linux-libre-3.16.46-gnu/sound/core/seq/seq_fifo.c
--- linux-libre-3.16.45-gnu/sound/core/seq/seq_fifo.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/core/seq/seq_fifo.c	2017-07-18 13:40:42.000000000 -0400
@@ -70,6 +70,9 @@ void snd_seq_fifo_delete(struct snd_seq_
 		return;
 	*fifo = NULL;
 
+	if (f->pool)
+		snd_seq_pool_mark_closing(f->pool);
+
 	snd_seq_fifo_clear(f);
 
 	/* wake up clients if any */
@@ -262,6 +265,10 @@ int snd_seq_fifo_resize(struct snd_seq_f
 	/* NOTE: overflow flag is not cleared */
 	spin_unlock_irqrestore(&f->lock, flags);
 
+	/* close the old pool and wait until all users are gone */
+	snd_seq_pool_mark_closing(oldpool);
+	snd_use_lock_sync(&f->use_lock);
+
 	/* release cells in old pool */
 	for (cell = oldhead; cell; cell = next) {
 		next = cell->next;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/core/seq/seq_lock.c linux-libre-3.16.46-gnu/sound/core/seq/seq_lock.c
--- linux-libre-3.16.45-gnu/sound/core/seq/seq_lock.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/core/seq/seq_lock.c	2017-07-18 13:40:42.000000000 -0400
@@ -28,19 +28,16 @@
 /* wait until all locks are released */
 void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
 {
-	int max_count = 5 * HZ;
+	int warn_count = 5 * HZ;
 
 	if (atomic_read(lockp) < 0) {
 		pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
 		return;
 	}
 	while (atomic_read(lockp) > 0) {
-		if (max_count == 0) {
-			pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
-			break;
-		}
+		if (warn_count-- == 0)
+			pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line);
 		schedule_timeout_uninterruptible(1);
-		max_count--;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/core/seq/seq_memory.c linux-libre-3.16.46-gnu/sound/core/seq/seq_memory.c
--- linux-libre-3.16.45-gnu/sound/core/seq/seq_memory.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/core/seq/seq_memory.c	2017-07-18 13:40:42.000000000 -0400
@@ -414,6 +414,18 @@ int snd_seq_pool_init(struct snd_seq_poo
 	return 0;
 }
 
+/* refuse the further insertion to the pool */
+void snd_seq_pool_mark_closing(struct snd_seq_pool *pool)
+{
+	unsigned long flags;
+
+	if (snd_BUG_ON(!pool))
+		return;
+	spin_lock_irqsave(&pool->lock, flags);
+	pool->closing = 1;
+	spin_unlock_irqrestore(&pool->lock, flags);
+}
+
 /* remove events */
 int snd_seq_pool_done(struct snd_seq_pool *pool)
 {
@@ -424,10 +436,6 @@ int snd_seq_pool_done(struct snd_seq_poo
 		return -EINVAL;
 
 	/* wait for closing all threads */
-	spin_lock_irqsave(&pool->lock, flags);
-	pool->closing = 1;
-	spin_unlock_irqrestore(&pool->lock, flags);
-
 	if (waitqueue_active(&pool->output_sleep))
 		wake_up(&pool->output_sleep);
 
@@ -484,6 +492,7 @@ int snd_seq_pool_delete(struct snd_seq_p
 	*ppool = NULL;
 	if (pool == NULL)
 		return 0;
+	snd_seq_pool_mark_closing(pool);
 	snd_seq_pool_done(pool);
 	kfree(pool);
 	return 0;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/core/seq/seq_memory.h linux-libre-3.16.46-gnu/sound/core/seq/seq_memory.h
--- linux-libre-3.16.45-gnu/sound/core/seq/seq_memory.h	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/core/seq/seq_memory.h	2017-07-18 13:40:42.000000000 -0400
@@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(st
 int snd_seq_pool_init(struct snd_seq_pool *pool);
 
 /* done pool - free events */
+void snd_seq_pool_mark_closing(struct snd_seq_pool *pool);
 int snd_seq_pool_done(struct snd_seq_pool *pool);
 
 /* create pool */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/core/timer.c linux-libre-3.16.46-gnu/sound/core/timer.c
--- linux-libre-3.16.45-gnu/sound/core/timer.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/core/timer.c	2017-07-18 13:40:42.000000000 -0400
@@ -1636,6 +1636,7 @@ static int snd_timer_user_tselect(struct
 	if (err < 0)
 		goto __err;
 
+	tu->qhead = tu->qtail = tu->qused = 0;
 	kfree(tu->queue);
 	tu->queue = NULL;
 	kfree(tu->tqueue);
@@ -1976,6 +1977,7 @@ static ssize_t snd_timer_user_read(struc
 
 	tu = file->private_data;
 	unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read);
+	mutex_lock(&tu->ioctl_lock);
 	spin_lock_irq(&tu->qlock);
 	while ((long)count - result >= unit) {
 		while (!tu->qused) {
@@ -1991,7 +1993,9 @@ static ssize_t snd_timer_user_read(struc
 			add_wait_queue(&tu->qchange_sleep, &wait);
 
 			spin_unlock_irq(&tu->qlock);
+			mutex_unlock(&tu->ioctl_lock);
 			schedule();
+			mutex_lock(&tu->ioctl_lock);
 			spin_lock_irq(&tu->qlock);
 
 			remove_wait_queue(&tu->qchange_sleep, &wait);
@@ -2011,7 +2015,6 @@ static ssize_t snd_timer_user_read(struc
 		tu->qused--;
 		spin_unlock_irq(&tu->qlock);
 
-		mutex_lock(&tu->ioctl_lock);
 		if (tu->tread) {
 			if (copy_to_user(buffer, &tu->tqueue[qhead],
 					 sizeof(struct snd_timer_tread)))
@@ -2021,7 +2024,6 @@ static ssize_t snd_timer_user_read(struc
 					 sizeof(struct snd_timer_read)))
 				err = -EFAULT;
 		}
-		mutex_unlock(&tu->ioctl_lock);
 
 		spin_lock_irq(&tu->qlock);
 		if (err < 0)
@@ -2031,6 +2033,7 @@ static ssize_t snd_timer_user_read(struc
 	}
  _error:
 	spin_unlock_irq(&tu->qlock);
+	mutex_unlock(&tu->ioctl_lock);
 	return result > 0 ? result : err;
 }
 
diff -druNp --no-dereference linux-libre-3.16.45-gnu/sound/pci/ctxfi/cthw20k1.c linux-libre-3.16.46-gnu/sound/pci/ctxfi/cthw20k1.c
--- linux-libre-3.16.45-gnu/sound/pci/ctxfi/cthw20k1.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/sound/pci/ctxfi/cthw20k1.c	2017-07-18 13:40:42.000000000 -0400
@@ -1904,7 +1904,7 @@ static int hw_card_start(struct hw *hw)
 		return err;
 
 	/* Set DMA transfer mask */
-	if (dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
+	if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
 		dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
 	} else {
 		dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
diff -druNp --no-dereference linux-libre-3.16.45-gnu/tools/perf/util/symbol.c linux-libre-3.16.46-gnu/tools/perf/util/symbol.c
--- linux-libre-3.16.45-gnu/tools/perf/util/symbol.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/tools/perf/util/symbol.c	2017-07-18 13:40:42.000000000 -0400
@@ -188,7 +188,7 @@ void symbols__fixup_end(struct rb_root *
 
 	/* Last entry */
 	if (curr->end == curr->start)
-		curr->end = roundup(curr->start, 4096);
+		curr->end = roundup(curr->start, 4096) + 4096;
 }
 
 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
diff -druNp --no-dereference linux-libre-3.16.45-gnu/tools/power/cpupower/utils/helpers/cpuid.c linux-libre-3.16.46-gnu/tools/power/cpupower/utils/helpers/cpuid.c
--- linux-libre-3.16.45-gnu/tools/power/cpupower/utils/helpers/cpuid.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/tools/power/cpupower/utils/helpers/cpuid.c	2017-07-18 13:40:42.000000000 -0400
@@ -156,6 +156,7 @@ out:
 					 */
 			case 0x2C:	/* Westmere EP - Gulftown */
 				cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
+				break;
 			case 0x2A:	/* SNB */
 			case 0x2D:	/* SNB Xeon */
 			case 0x3A:	/* IVB */
diff -druNp --no-dereference linux-libre-3.16.45-gnu/virt/kvm/eventfd.c linux-libre-3.16.46-gnu/virt/kvm/eventfd.c
--- linux-libre-3.16.45-gnu/virt/kvm/eventfd.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/virt/kvm/eventfd.c	2017-07-18 13:40:42.000000000 -0400
@@ -794,7 +794,8 @@ kvm_deassign_ioeventfd_idx(struct kvm *k
 			continue;
 
 		kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
-		kvm->buses[bus_idx]->ioeventfd_count--;
+		if (kvm->buses[bus_idx])
+			kvm->buses[bus_idx]->ioeventfd_count--;
 		ioeventfd_release(p);
 		ret = 0;
 		break;
diff -druNp --no-dereference linux-libre-3.16.45-gnu/virt/kvm/kvm_main.c linux-libre-3.16.46-gnu/virt/kvm/kvm_main.c
--- linux-libre-3.16.45-gnu/virt/kvm/kvm_main.c	2017-07-02 12:13:04.000000000 -0400
+++ linux-libre-3.16.46-gnu/virt/kvm/kvm_main.c	2017-07-18 13:40:42.000000000 -0400
@@ -606,8 +606,11 @@ static void kvm_destroy_vm(struct kvm *k
 	list_del(&kvm->vm_list);
 	spin_unlock(&kvm_lock);
 	kvm_free_irq_routing(kvm);
-	for (i = 0; i < KVM_NR_BUSES; i++)
-		kvm_io_bus_destroy(kvm->buses[i]);
+	for (i = 0; i < KVM_NR_BUSES; i++) {
+		if (kvm->buses[i])
+			kvm_io_bus_destroy(kvm->buses[i]);
+		kvm->buses[i] = NULL;
+	}
 	kvm_coalesced_mmio_free(kvm);
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
 	mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
@@ -2906,6 +2909,8 @@ int kvm_io_bus_write(struct kvm *kvm, en
 	};
 
 	bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
+	if (!bus)
+		return -ENOMEM;
 	r = __kvm_io_bus_write(bus, &range, val);
 	return r < 0 ? r : 0;
 }
@@ -2923,6 +2928,8 @@ int kvm_io_bus_write_cookie(struct kvm *
 	};
 
 	bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
+	if (!bus)
+		return -ENOMEM;
 
 	/* First try the device referenced by cookie. */
 	if ((cookie >= 0) && (cookie < bus->dev_count) &&
@@ -2973,6 +2980,8 @@ int kvm_io_bus_read(struct kvm *kvm, enu
 	};
 
 	bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
+	if (!bus)
+		return -ENOMEM;
 	r = __kvm_io_bus_read(bus, &range, val);
 	return r < 0 ? r : 0;
 }
@@ -2985,6 +2994,9 @@ int kvm_io_bus_register_dev(struct kvm *
 	struct kvm_io_bus *new_bus, *bus;
 
 	bus = kvm->buses[bus_idx];
+	if (!bus)
+		return -ENOMEM;
+
 	/* exclude ioeventfd which is limited by maximum fd */
 	if (bus->dev_count - bus->ioeventfd_count > NR_IOBUS_DEVS - 1)
 		return -ENOSPC;
@@ -3004,37 +3016,41 @@ int kvm_io_bus_register_dev(struct kvm *
 }
 
 /* Caller must hold slots_lock. */
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
-			      struct kvm_io_device *dev)
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+			       struct kvm_io_device *dev)
 {
-	int i, r;
+	int i;
 	struct kvm_io_bus *new_bus, *bus;
 
 	bus = kvm->buses[bus_idx];
-	r = -ENOENT;
+	if (!bus)
+		return;
+
 	for (i = 0; i < bus->dev_count; i++)
 		if (bus->range[i].dev == dev) {
-			r = 0;
 			break;
 		}
 
-	if (r)
-		return r;
+	if (i == bus->dev_count)
+		return;
 
 	new_bus = kzalloc(sizeof(*bus) + ((bus->dev_count - 1) *
 			  sizeof(struct kvm_io_range)), GFP_KERNEL);
-	if (!new_bus)
-		return -ENOMEM;
+	if (!new_bus)  {
+		pr_err("kvm: failed to shrink bus, removing it completely\n");
+		goto broken;
+	}
 
 	memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range));
 	new_bus->dev_count--;
 	memcpy(new_bus->range + i, bus->range + i + 1,
 	       (new_bus->dev_count - i) * sizeof(struct kvm_io_range));
 
+broken:
 	rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
 	synchronize_srcu_expedited(&kvm->srcu);
 	kfree(bus);
-	return r;
+	return;
 }
 
 static struct notifier_block kvm_cpu_notifier = {
