diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/alpha/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/alpha/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/alpha/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/alpha/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -371,14 +371,6 @@ __copy_tofrom_user_nocheck(void *to, con
 	return __cu_len;
 }
 
-extern inline long
-__copy_tofrom_user(void *to, const void *from, long len, const void __user *validate)
-{
-	if (__access_ok((unsigned long)validate, len, get_fs()))
-		len = __copy_tofrom_user_nocheck(to, from, len);
-	return len;
-}
-
 #define __copy_to_user(to,from,n)					\
 ({									\
 	__chk_user_ptr(to);						\
@@ -393,17 +385,22 @@ __copy_tofrom_user(void *to, const void
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
-
 extern inline long
 copy_to_user(void __user *to, const void *from, long n)
 {
-	return __copy_tofrom_user((__force void *)to, from, n, to);
+	if (likely(__access_ok((unsigned long)to, n, get_fs())))
+		n = __copy_tofrom_user_nocheck((__force void *)to, from, n);
+	return n;
 }
 
 extern inline long
 copy_from_user(void *to, const void __user *from, long n)
 {
-	return __copy_tofrom_user(to, (__force void *)from, n, from);
+	if (likely(__access_ok((unsigned long)from, n, get_fs())))
+		n = __copy_tofrom_user_nocheck(to, (__force void *)from, n);
+	else
+		memset(to, 0, n);
+	return n;
 }
 
 extern void __do_clear_user(void);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/arm/common/sa1111.c linux-libre-3.2.84-gnu1/arch/arm/common/sa1111.c
--- linux-libre-3.2.83-gnu1/arch/arm/common/sa1111.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/arm/common/sa1111.c	2016-11-19 20:01:45.000000000 -0500
@@ -878,9 +878,9 @@ struct sa1111_save_data {
 
 #ifdef CONFIG_PM
 
-static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
+static int sa1111_suspend_noirq(struct device *dev)
 {
-	struct sa1111 *sachip = platform_get_drvdata(dev);
+	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	unsigned long flags;
 	unsigned int val;
@@ -938,9 +938,9 @@ static int sa1111_suspend(struct platfor
  *	restored by their respective drivers, and must be called
  *	via LDM after this function.
  */
-static int sa1111_resume(struct platform_device *dev)
+static int sa1111_resume_noirq(struct device *dev)
 {
-	struct sa1111 *sachip = platform_get_drvdata(dev);
+	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	unsigned long flags, id;
 	void __iomem *base;
@@ -956,7 +956,7 @@ static int sa1111_resume(struct platform
 	id = sa1111_readl(sachip->base + SA1111_SKID);
 	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
 		__sa1111_remove(sachip);
-		platform_set_drvdata(dev, NULL);
+		dev_set_drvdata(dev, NULL);
 		kfree(save);
 		return 0;
 	}
@@ -1002,8 +1002,8 @@ static int sa1111_resume(struct platform
 }
 
 #else
-#define sa1111_suspend NULL
-#define sa1111_resume  NULL
+#define sa1111_suspend_noirq NULL
+#define sa1111_resume_noirq  NULL
 #endif
 
 static int __devinit sa1111_probe(struct platform_device *pdev)
@@ -1037,6 +1037,11 @@ static int sa1111_remove(struct platform
 	return 0;
 }
 
+static struct dev_pm_ops sa1111_pm_ops = {
+	.suspend_noirq = sa1111_suspend_noirq,
+	.resume_noirq = sa1111_resume_noirq,
+};
+
 /*
  *	Not sure if this should be on the system bus or not yet.
  *	We really want some way to register a system device at
@@ -1049,10 +1054,9 @@ static int sa1111_remove(struct platform
 static struct platform_driver sa1111_device_driver = {
 	.probe		= sa1111_probe,
 	.remove		= sa1111_remove,
-	.suspend	= sa1111_suspend,
-	.resume		= sa1111_resume,
 	.driver		= {
 		.name	= "sa1111",
+		.pm	= &sa1111_pm_ops,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/arm/kernel/sys_oabi-compat.c linux-libre-3.2.84-gnu1/arch/arm/kernel/sys_oabi-compat.c
--- linux-libre-3.2.83-gnu1/arch/arm/kernel/sys_oabi-compat.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/arm/kernel/sys_oabi-compat.c	2016-11-19 20:01:45.000000000 -0500
@@ -275,8 +275,12 @@ asmlinkage long sys_oabi_epoll_wait(int
 	mm_segment_t fs;
 	long ret, err, i;
 
-	if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
+	if (maxevents <= 0 ||
+			maxevents > (INT_MAX/sizeof(*kbuf)) ||
+			maxevents > (INT_MAX/sizeof(*events)))
 		return -EINVAL;
+	if (!access_ok(VERIFY_WRITE, events, sizeof(*events) * maxevents))
+		return -EFAULT;
 	kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
 	if (!kbuf)
 		return -ENOMEM;
@@ -313,6 +317,8 @@ asmlinkage long sys_oabi_semtimedop(int
 
 	if (nsops < 1 || nsops > SEMOPM)
 		return -EINVAL;
+	if (!access_ok(VERIFY_READ, tsops, sizeof(*tsops) * nsops))
+		return -EFAULT;
 	sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
 	if (!sops)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c linux-libre-3.2.84-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
--- linux-libre-3.2.83-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2016-11-19 20:01:45.000000000 -0500
@@ -1470,8 +1470,20 @@ static struct omap_hwmod omap3xxx_dss_di
  * display serial interface controller
  */
 
+static struct omap_hwmod_class_sysconfig omap3xxx_dsi_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
 static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
 	.name = "dsi",
+	.sysc	= &omap3xxx_dsi_sysc,
 };
 
 static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/avr32/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/avr32/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/avr32/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/avr32/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -74,7 +74,7 @@ extern __kernel_size_t __copy_user(void
 
 extern __kernel_size_t copy_to_user(void __user *to, const void *from,
 				    __kernel_size_t n);
-extern __kernel_size_t copy_from_user(void *to, const void __user *from,
+extern __kernel_size_t ___copy_from_user(void *to, const void __user *from,
 				      __kernel_size_t n);
 
 static inline __kernel_size_t __copy_to_user(void __user *to, const void *from,
@@ -88,6 +88,15 @@ static inline __kernel_size_t __copy_fro
 {
 	return __copy_user(to, (const void __force *)from, n);
 }
+static inline __kernel_size_t copy_from_user(void *to,
+					       const void __user *from,
+					       __kernel_size_t n)
+{
+	size_t res = ___copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
+}
 
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/avr32/kernel/avr32_ksyms.c linux-libre-3.2.84-gnu1/arch/avr32/kernel/avr32_ksyms.c
--- linux-libre-3.2.83-gnu1/arch/avr32/kernel/avr32_ksyms.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/avr32/kernel/avr32_ksyms.c	2016-11-19 20:01:45.000000000 -0500
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(copy_page);
 /*
  * Userspace access stuff.
  */
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(___copy_from_user);
 EXPORT_SYMBOL(copy_to_user);
 EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(strncpy_from_user);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/avr32/lib/copy_user.S linux-libre-3.2.84-gnu1/arch/avr32/lib/copy_user.S
--- linux-libre-3.2.83-gnu1/arch/avr32/lib/copy_user.S	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/avr32/lib/copy_user.S	2016-11-19 20:01:45.000000000 -0500
@@ -23,13 +23,13 @@
 	 */
 	.text
 	.align	1
-	.global	copy_from_user
-	.type	copy_from_user, @function
-copy_from_user:
+	.global	___copy_from_user
+	.type	___copy_from_user, @function
+___copy_from_user:
 	branch_if_kernel r8, __copy_user
 	ret_if_privileged r8, r11, r10, r10
 	rjmp	__copy_user
-	.size	copy_from_user, . - copy_from_user
+	.size	___copy_from_user, . - ___copy_from_user
 
 	.global	copy_to_user
 	.type	copy_to_user, @function
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/avr32/mach-at32ap/pio.c linux-libre-3.2.84-gnu1/arch/avr32/mach-at32ap/pio.c
--- linux-libre-3.2.83-gnu1/arch/avr32/mach-at32ap/pio.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/avr32/mach-at32ap/pio.c	2016-11-19 20:01:45.000000000 -0500
@@ -435,7 +435,7 @@ void __init at32_init_pio(struct platfor
 	struct resource *regs;
 	struct pio_device *pio;
 
-	if (pdev->id > MAX_NR_PIO_DEVICES) {
+	if (pdev->id >= MAX_NR_PIO_DEVICES) {
 		dev_err(&pdev->dev, "only %d PIO devices supported\n",
 			MAX_NR_PIO_DEVICES);
 		return;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/blackfin/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/blackfin/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/blackfin/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/blackfin/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -194,11 +194,12 @@ static inline int bad_user_access_length
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-	if (access_ok(VERIFY_READ, from, n))
+	if (likely(access_ok(VERIFY_READ, from, n))) {
 		memcpy(to, (const void __force *)from, n);
-	else
-		return n;
-	return 0;
+		return 0;
+	}
+	memset(to, 0, n);
+	return n;
 }
 
 static inline unsigned long __must_check
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/cris/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/cris/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/cris/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/cris/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -176,30 +176,6 @@ extern unsigned long __copy_user(void __
 extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n);
 extern unsigned long __do_clear_user(void __user *to, unsigned long n);
 
-static inline unsigned long
-__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-	if (access_ok(VERIFY_WRITE, to, n))
-		return __copy_user(to,from,n);
-	return n;
-}
-
-static inline unsigned long
-__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
-{
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_user_zeroing(to,from,n);
-	return n;
-}
-
-static inline unsigned long
-__generic_clear_user(void __user *to, unsigned long n)
-{
-	if (access_ok(VERIFY_WRITE, to, n))
-		return __do_clear_user(to,n);
-	return n;
-}
-
 static inline long
 __strncpy_from_user(char *dst, const char __user *src, long count)
 {
@@ -262,7 +238,7 @@ __constant_copy_from_user(void *to, cons
 	else if (n == 24)
 		__asm_copy_from_user_24(to, from, ret);
 	else
-		ret = __generic_copy_from_user(to, from, n);
+		ret = __copy_user_zeroing(to, from, n);
 
 	return ret;
 }
@@ -312,7 +288,7 @@ __constant_copy_to_user(void __user *to,
 	else if (n == 24)
 		__asm_copy_to_user_24(to, from, ret);
 	else
-		ret = __generic_copy_to_user(to, from, n);
+		ret = __copy_user(to, from, n);
 
 	return ret;
 }
@@ -344,26 +320,43 @@ __constant_clear_user(void __user *to, u
 	else if (n == 24)
 		__asm_clear_24(to, ret);
 	else
-		ret = __generic_clear_user(to, n);
+		ret = __do_clear_user(to, n);
 
 	return ret;
 }
 
 
-#define clear_user(to, n)			\
-(__builtin_constant_p(n) ?			\
- __constant_clear_user(to, n) :			\
- __generic_clear_user(to, n))
+static inline size_t clear_user(void __user *to, size_t n)
+{
+	if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+		return n;
+	if (__builtin_constant_p(n))
+		return __constant_clear_user(to, n);
+	else
+		return __do_clear_user(to, n);
+}
 
-#define copy_from_user(to, from, n)		\
-(__builtin_constant_p(n) ?			\
- __constant_copy_from_user(to, from, n) :	\
- __generic_copy_from_user(to, from, n))
+static inline size_t copy_from_user(void *to, const void __user *from, size_t n)
+{
+	if (unlikely(!access_ok(VERIFY_READ, from, n))) {
+		memset(to, 0, n);
+		return n;
+	}
+	if (__builtin_constant_p(n))
+		return __constant_copy_from_user(to, from, n);
+	else
+		return __copy_user_zeroing(to, from, n);
+}
 
-#define copy_to_user(to, from, n)		\
-(__builtin_constant_p(n) ?			\
- __constant_copy_to_user(to, from, n) :		\
- __generic_copy_to_user(to, from, n))
+static inline size_t copy_to_user(void __user *to, const void *from, size_t n)
+{
+	if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+		return n;
+	if (__builtin_constant_p(n))
+		return __constant_copy_to_user(to, from, n);
+	else
+		return __copy_user(to, from, n);
+}
 
 /* We let the __ versions of copy_from/to_user inline, because they're often
  * used in fast paths and have only a small space overhead.
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/frv/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/frv/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/frv/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/frv/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -263,19 +263,25 @@ do {							\
 extern long __memset_user(void *dst, unsigned long count);
 extern long __memcpy_user(void *dst, const void *src, unsigned long count);
 
-#define clear_user(dst,count)			__memset_user(____force(dst), (count))
+#define __clear_user(dst,count)			__memset_user(____force(dst), (count))
 #define __copy_from_user_inatomic(to, from, n)	__memcpy_user((to), ____force(from), (n))
 #define __copy_to_user_inatomic(to, from, n)	__memcpy_user(____force(to), (from), (n))
 
 #else
 
-#define clear_user(dst,count)			(memset(____force(dst), 0, (count)), 0)
+#define __clear_user(dst,count)			(memset(____force(dst), 0, (count)), 0)
 #define __copy_from_user_inatomic(to, from, n)	(memcpy((to), ____force(from), (n)), 0)
 #define __copy_to_user_inatomic(to, from, n)	(memcpy(____force(to), (from), (n)), 0)
 
 #endif
 
-#define __clear_user clear_user
+static inline unsigned long __must_check
+clear_user(void __user *to, unsigned long n)
+{
+	if (likely(__access_ok(to, n)))
+		n = __clear_user(to, n);
+	return n;
+}
 
 static inline unsigned long __must_check
 __copy_to_user(void __user *to, const void *from, unsigned long n)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/hexagon/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/hexagon/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/hexagon/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/hexagon/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -102,7 +102,8 @@ static inline long hexagon_strncpy_from_
 {
 	long res = __strnlen_user(src, n);
 
-	/* return from strnlen can't be zero -- that would be rubbish. */
+	if (unlikely(!res))
+		return -EFAULT;
 
 	if (res > n) {
 		copy_from_user(dst, src, n);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/ia64/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/ia64/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/ia64/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/ia64/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -262,17 +262,15 @@ __copy_from_user (void *to, const void _
 	__cu_len;									\
 })
 
-#define copy_from_user(to, from, n)							\
-({											\
-	void *__cu_to = (to);								\
-	const void __user *__cu_from = (from);						\
-	long __cu_len = (n);								\
-											\
-	__chk_user_ptr(__cu_from);							\
-	if (__access_ok(__cu_from, __cu_len, get_fs()))					\
-		__cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len);	\
-	__cu_len;									\
-})
+static inline unsigned long
+copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	if (likely(__access_ok(from, n, get_fs())))
+		n = __copy_user((__force void __user *) to, from, n);
+	else
+		memset(to, 0, n);
+	return n;
+}
 
 #define __copy_in_user(to, from, size)	__copy_user((to), (from), (size))
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/m32r/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/m32r/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/m32r/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/m32r/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -215,7 +215,7 @@ extern int fixup_exception(struct pt_reg
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
 	long __gu_err = 0;						\
-	unsigned long __gu_val;						\
+	unsigned long __gu_val = 0;					\
 	might_sleep();							\
 	__get_user_size(__gu_val,(ptr),(size),__gu_err);		\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/microblaze/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/microblaze/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/microblaze/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/microblaze/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -218,7 +218,7 @@ extern long __user_bad(void);
 
 #define __get_user(x, ptr)						\
 ({									\
-	unsigned long __gu_val;						\
+	unsigned long __gu_val = 0;					\
 	/*unsigned long __gu_ptr = (unsigned long)(ptr);*/		\
 	long __gu_err;							\
 	switch (sizeof(*(ptr))) {					\
@@ -364,10 +364,13 @@ extern long __user_bad(void);
 static inline long copy_from_user(void *to,
 		const void __user *from, unsigned long n)
 {
+	unsigned long res = n;
 	might_sleep();
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_from_user(to, from, n);
-	return n;
+	if (likely(access_ok(VERIFY_READ, from, n)))
+		res = __copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 #define __copy_to_user(to, from, n)	\
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/mips/kernel/scall64-n32.S linux-libre-3.2.84-gnu1/arch/mips/kernel/scall64-n32.S
--- linux-libre-3.2.83-gnu1/arch/mips/kernel/scall64-n32.S	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/mips/kernel/scall64-n32.S	2016-11-19 20:01:45.000000000 -0500
@@ -366,7 +366,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_ni_syscall			/* available, was setaltroot */
 	PTR	sys_add_key
 	PTR	sys_request_key
-	PTR	sys_keyctl			/* 6245 */
+	PTR	compat_sys_keyctl		/* 6245 */
 	PTR	sys_set_thread_area
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/mips/kernel/scall64-o32.S linux-libre-3.2.84-gnu1/arch/mips/kernel/scall64-o32.S
--- linux-libre-3.2.83-gnu1/arch/mips/kernel/scall64-o32.S	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/mips/kernel/scall64-o32.S	2016-11-19 20:01:45.000000000 -0500
@@ -486,7 +486,7 @@ sys_call_table:
 	PTR	sys_ni_syscall			/* available, was setaltroot */
 	PTR	sys_add_key			/* 4280 */
 	PTR	sys_request_key
-	PTR	sys_keyctl
+	PTR	compat_sys_keyctl
 	PTR	sys_set_thread_area
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch		/* 4285 */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/mips/mm/sc-rm7k.c linux-libre-3.2.84-gnu1/arch/mips/mm/sc-rm7k.c
--- linux-libre-3.2.83-gnu1/arch/mips/mm/sc-rm7k.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/mips/mm/sc-rm7k.c	2016-11-19 20:01:45.000000000 -0500
@@ -162,7 +162,7 @@ static void rm7k_tc_disable(void)
 	local_irq_save(flags);
 	blast_rm7k_tcache();
 	clear_c0_config(RM7K_CONF_TE);
-	local_irq_save(flags);
+	local_irq_restore(flags);
 }
 
 static void rm7k_sc_disable(void)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/mn10300/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/mn10300/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/mn10300/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/mn10300/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -181,6 +181,7 @@ struct __large_struct { unsigned long bu
 		"2:\n"						\
 		"	.section	.fixup,\"ax\"\n"	\
 		"3:\n\t"					\
+		"	mov		0,%1\n"			\
 		"	mov		%3,%0\n"		\
 		"	jmp		2b\n"			\
 		"	.previous\n"				\
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/mn10300/lib/usercopy.c linux-libre-3.2.84-gnu1/arch/mn10300/lib/usercopy.c
--- linux-libre-3.2.83-gnu1/arch/mn10300/lib/usercopy.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/mn10300/lib/usercopy.c	2016-11-19 20:01:45.000000000 -0500
@@ -9,7 +9,8 @@
  * as published by the Free Software Foundation; either version
  * 2 of the Licence, or (at your option) any later version.
  */
-#include <asm/uaccess.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
 
 unsigned long
 __generic_copy_to_user(void *to, const void *from, unsigned long n)
@@ -24,6 +25,8 @@ __generic_copy_from_user(void *to, const
 {
 	if (access_ok(VERIFY_READ, from, n))
 		__copy_user_zeroing(to, from, n);
+	else
+		memset(to, 0, n);
 	return n;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/openrisc/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/openrisc/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/openrisc/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/openrisc/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -274,28 +274,20 @@ __copy_tofrom_user(void *to, const void
 static inline unsigned long
 copy_from_user(void *to, const void *from, unsigned long n)
 {
-	unsigned long over;
+	unsigned long res = n;
 
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_tofrom_user(to, from, n);
-	if ((unsigned long)from < TASK_SIZE) {
-		over = (unsigned long)from + n - TASK_SIZE;
-		return __copy_tofrom_user(to, from, n - over) + over;
-	}
-	return n;
+	if (likely(access_ok(VERIFY_READ, from, n)))
+		res = __copy_tofrom_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 static inline unsigned long
 copy_to_user(void *to, const void *from, unsigned long n)
 {
-	unsigned long over;
-
-	if (access_ok(VERIFY_WRITE, to, n))
-		return __copy_tofrom_user(to, from, n);
-	if ((unsigned long)to < TASK_SIZE) {
-		over = (unsigned long)to + n - TASK_SIZE;
-		return __copy_tofrom_user(to, from, n - over) + over;
-	}
+	if (likely(access_ok(VERIFY_WRITE, to, n)))
+		n = __copy_tofrom_user(to, from, n);
 	return n;
 }
 
@@ -304,13 +296,8 @@ extern unsigned long __clear_user(void *
 static inline __must_check unsigned long
 clear_user(void *addr, unsigned long size)
 {
-
-	if (access_ok(VERIFY_WRITE, addr, size))
-		return __clear_user(addr, size);
-	if ((unsigned long)addr < TASK_SIZE) {
-		unsigned long over = (unsigned long)addr + size - TASK_SIZE;
-		return __clear_user(addr, size - over) + over;
-	}
+	if (likely(access_ok(VERIFY_WRITE, addr, size)))
+		size = __clear_user(addr, size);
 	return size;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/parisc/include/asm/errno.h linux-libre-3.2.84-gnu1/arch/parisc/include/asm/errno.h
--- linux-libre-3.2.83-gnu1/arch/parisc/include/asm/errno.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/parisc/include/asm/errno.h	2016-11-19 20:01:45.000000000 -0500
@@ -97,10 +97,10 @@
 #define	ENOTCONN	235	/* Transport endpoint is not connected */
 #define	ESHUTDOWN	236	/* Cannot send after transport endpoint shutdown */
 #define	ETOOMANYREFS	237	/* Too many references: cannot splice */
-#define EREFUSED	ECONNREFUSED	/* for HP's NFS apparently */
 #define	ETIMEDOUT	238	/* Connection timed out */
 #define	ECONNREFUSED	239	/* Connection refused */
-#define EREMOTERELEASE	240	/* Remote peer released connection */
+#define	EREFUSED	ECONNREFUSED	/* for HP's NFS apparently */
+#define	EREMOTERELEASE	240	/* Remote peer released connection */
 #define	EHOSTDOWN	241	/* Host is down */
 #define	EHOSTUNREACH	242	/* No route to host */
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/parisc/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/parisc/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/parisc/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/parisc/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -10,6 +10,8 @@
 #include <asm/errno.h>
 #include <asm-generic/uaccess-unaligned.h>
 
+#include <linux/string.h>
+
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
 
@@ -255,13 +257,14 @@ static inline unsigned long __must_check
                                           unsigned long n)
 {
         int sz = __compiletime_object_size(to);
-        int ret = -EFAULT;
+        unsigned long ret = n;
 
         if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n))
                 ret = __copy_from_user(to, from, n);
         else
                 copy_from_user_overflow();
-
+	if (unlikely(ret))
+		memset(to + (n - ret), 0, ret);
         return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/powerpc/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/powerpc/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/powerpc/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/powerpc/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -332,30 +332,17 @@ extern unsigned long __copy_tofrom_user(
 static inline unsigned long copy_from_user(void *to,
 		const void __user *from, unsigned long n)
 {
-	unsigned long over;
-
-	if (access_ok(VERIFY_READ, from, n))
+	if (likely(access_ok(VERIFY_READ, from, n)))
 		return __copy_tofrom_user((__force void __user *)to, from, n);
-	if ((unsigned long)from < TASK_SIZE) {
-		over = (unsigned long)from + n - TASK_SIZE;
-		return __copy_tofrom_user((__force void __user *)to, from,
-				n - over) + over;
-	}
+	memset(to, 0, n);
 	return n;
 }
 
 static inline unsigned long copy_to_user(void __user *to,
 		const void *from, unsigned long n)
 {
-	unsigned long over;
-
 	if (access_ok(VERIFY_WRITE, to, n))
 		return __copy_tofrom_user(to, (__force void __user *)from, n);
-	if ((unsigned long)to < TASK_SIZE) {
-		over = (unsigned long)to + n - TASK_SIZE;
-		return __copy_tofrom_user(to, (__force void __user *)from,
-				n - over) + over;
-	}
 	return n;
 }
 
@@ -446,10 +433,6 @@ static inline unsigned long clear_user(v
 	might_sleep();
 	if (likely(access_ok(VERIFY_WRITE, addr, size)))
 		return __clear_user(addr, size);
-	if ((unsigned long)addr < TASK_SIZE) {
-		unsigned long over = (unsigned long)addr + size - TASK_SIZE;
-		return __clear_user(addr, size - over) + over;
-	}
 	return size;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/powerpc/mm/numa.c linux-libre-3.2.84-gnu1/arch/powerpc/mm/numa.c
--- linux-libre-3.2.83-gnu1/arch/powerpc/mm/numa.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/powerpc/mm/numa.c	2016-11-19 20:01:45.000000000 -0500
@@ -1275,17 +1275,33 @@ int hot_add_scn_to_nid(unsigned long scn
 static u64 hot_add_drconf_memory_max(void)
 {
         struct device_node *memory = NULL;
+	struct device_node *dn = NULL;
         unsigned int drconf_cell_cnt = 0;
         u64 lmb_size = 0;
         const u32 *dm = 0;
+	const __be64 *lrdr = NULL;
+	struct of_drconf_cell drmem;
+
+	dn = of_find_node_by_path("/rtas");
+	if (dn) {
+		lrdr = of_get_property(dn, "ibm,lrdr-capacity", NULL);
+		of_node_put(dn);
+		if (lrdr)
+			return be64_to_cpup(lrdr);
+	}
 
         memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
         if (memory) {
                 drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
                 lmb_size = of_get_lmb_size(memory);
+
+		/* Advance to the last cell, each cell has 6 32 bit integers */
+		dm += (drconf_cell_cnt - 1) * 6;
+		read_drconf_cell(&drmem, &dm);
                 of_node_put(memory);
+		return drmem.base_addr + lmb_size;
         }
-        return lmb_size * drconf_cell_cnt;
+	return 0;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/s390/include/asm/auxvec.h linux-libre-3.2.84-gnu1/arch/s390/include/asm/auxvec.h
--- linux-libre-3.2.83-gnu1/arch/s390/include/asm/auxvec.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/s390/include/asm/auxvec.h	2016-11-19 20:01:45.000000000 -0500
@@ -3,4 +3,6 @@
 
 #define AT_SYSINFO_EHDR		33
 
+#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
+
 #endif
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/s390/include/asm/elf.h linux-libre-3.2.84-gnu1/arch/s390/include/asm/elf.h
--- linux-libre-3.2.83-gnu1/arch/s390/include/asm/elf.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/s390/include/asm/elf.h	2016-11-19 20:01:45.000000000 -0500
@@ -199,6 +199,7 @@ do {								\
 
 #define STACK_RND_MASK	0x7ffUL
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO							    \
 do {									    \
 	if (vdso_enabled)						    \
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/s390/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/s390/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/s390/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/s390/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -147,28 +147,28 @@ extern int __put_user_bad(void) __attrib
 	__chk_user_ptr(ptr);					\
 	switch (sizeof(*(ptr))) {				\
 	case 1: {						\
-		unsigned char __x;				\
+		unsigned char __x = 0;				\
 		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
 					 ptr, &__x);		\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 2: {						\
-		unsigned short __x;				\
+		unsigned short __x = 0;				\
 		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
 					 ptr, &__x);		\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 4: {						\
-		unsigned int __x;				\
+		unsigned int __x = 0;				\
 		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
 					 ptr, &__x);		\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 8: {						\
-		unsigned long long __x;				\
+		unsigned long long __x = 0;			\
 		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
 					 ptr, &__x);		\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/score/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/score/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/score/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/score/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -158,7 +158,7 @@ do {									\
 		__get_user_asm(val, "lw", ptr);				\
 		 break;							\
 	case 8: 							\
-		if ((copy_from_user((void *)&val, ptr, 8)) == 0)	\
+		if (__copy_from_user((void *)&val, ptr, 8) == 0)	\
 			__gu_err = 0;					\
 		else							\
 			__gu_err = -EFAULT;				\
@@ -183,6 +183,8 @@ do {									\
 									\
 	if (likely(access_ok(VERIFY_READ, __gu_ptr, size)))		\
 		__get_user_common((x), size, __gu_ptr);			\
+	else								\
+		(x) = 0;						\
 									\
 	__gu_err;							\
 })
@@ -196,6 +198,7 @@ do {									\
 		"2:\n"							\
 		".section .fixup,\"ax\"\n"				\
 		"3:li	%0, %4\n"					\
+		"li	%1, 0\n"					\
 		"j	2b\n"						\
 		".previous\n"						\
 		".section __ex_table,\"a\"\n"				\
@@ -293,35 +296,34 @@ extern int __copy_tofrom_user(void *to,
 static inline unsigned long
 copy_from_user(void *to, const void *from, unsigned long len)
 {
-	unsigned long over;
+	unsigned long res = len;
 
-	if (access_ok(VERIFY_READ, from, len))
-		return __copy_tofrom_user(to, from, len);
+	if (likely(access_ok(VERIFY_READ, from, len)))
+		res = __copy_tofrom_user(to, from, len);
 
-	if ((unsigned long)from < TASK_SIZE) {
-		over = (unsigned long)from + len - TASK_SIZE;
-		return __copy_tofrom_user(to, from, len - over) + over;
-	}
-	return len;
+	if (unlikely(res))
+		memset(to + (len - res), 0, res);
+
+	return res;
 }
 
 static inline unsigned long
 copy_to_user(void *to, const void *from, unsigned long len)
 {
-	unsigned long over;
-
-	if (access_ok(VERIFY_WRITE, to, len))
-		return __copy_tofrom_user(to, from, len);
+	if (likely(access_ok(VERIFY_WRITE, to, len)))
+		len = __copy_tofrom_user(to, from, len);
 
-	if ((unsigned long)to < TASK_SIZE) {
-		over = (unsigned long)to + len - TASK_SIZE;
-		return __copy_tofrom_user(to, from, len - over) + over;
-	}
 	return len;
 }
 
-#define __copy_from_user(to, from, len)	\
-		__copy_tofrom_user((to), (from), (len))
+static inline unsigned long
+__copy_from_user(void *to, const void *from, unsigned long len)
+{
+	unsigned long left = __copy_tofrom_user(to, from, len);
+	if (unlikely(left))
+		memset(to + (len - left), 0, left);
+	return left;
+}
 
 #define __copy_to_user(to, from, len)		\
 		__copy_tofrom_user((to), (from), (len))
@@ -335,17 +337,17 @@ __copy_to_user_inatomic(void *to, const
 static inline unsigned long
 __copy_from_user_inatomic(void *to, const void *from, unsigned long len)
 {
-	return __copy_from_user(to, from, len);
+	return __copy_tofrom_user(to, from, len);
 }
 
-#define __copy_in_user(to, from, len)	__copy_from_user(to, from, len)
+#define __copy_in_user(to, from, len)	__copy_tofrom_user(to, from, len)
 
 static inline unsigned long
 copy_in_user(void *to, const void *from, unsigned long len)
 {
 	if (access_ok(VERIFY_READ, from, len) &&
 		      access_ok(VERFITY_WRITE, to, len))
-		return copy_from_user(to, from, len);
+		return __copy_tofrom_user(to, from, len);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/sh/include/asm/uaccess_64.h linux-libre-3.2.84-gnu1/arch/sh/include/asm/uaccess_64.h
--- linux-libre-3.2.83-gnu1/arch/sh/include/asm/uaccess_64.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/sh/include/asm/uaccess_64.h	2016-11-19 20:01:45.000000000 -0500
@@ -24,6 +24,7 @@
 #define __get_user_size(x,ptr,size,retval)			\
 do {								\
 	retval = 0;						\
+	x = 0;							\
 	switch (size) {						\
 	case 1:							\
 		retval = __get_user_asm_b((void *)&x,		\
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/sh/include/asm/uaccess.h linux-libre-3.2.84-gnu1/arch/sh/include/asm/uaccess.h
--- linux-libre-3.2.83-gnu1/arch/sh/include/asm/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/sh/include/asm/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -175,7 +175,10 @@ copy_from_user(void *to, const void __us
 	__kernel_size_t __copy_size = (__kernel_size_t) n;
 
 	if (__copy_size && __access_ok(__copy_from, __copy_size))
-		return __copy_user(to, from, __copy_size);
+		__copy_size = __copy_user(to, from, __copy_size);
+
+	if (unlikely(__copy_size))
+		memset(to + (n - __copy_size), 0, __copy_size);
 
 	return __copy_size;
 }
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/sparc/include/asm/uaccess_32.h linux-libre-3.2.84-gnu1/arch/sparc/include/asm/uaccess_32.h
--- linux-libre-3.2.83-gnu1/arch/sparc/include/asm/uaccess_32.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/sparc/include/asm/uaccess_32.h	2016-11-19 20:01:45.000000000 -0500
@@ -264,8 +264,10 @@ static inline unsigned long copy_from_us
 {
 	if (n && __access_ok((unsigned long) from, n))
 		return __copy_user((__force void __user *) to, from, n);
-	else
+	else {
+		memset(to, 0, n);
 		return n;
+	}
 }
 
 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/x86/ia32/ia32entry.S linux-libre-3.2.84-gnu1/arch/x86/ia32/ia32entry.S
--- linux-libre-3.2.83-gnu1/arch/x86/ia32/ia32entry.S	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/x86/ia32/ia32entry.S	2016-11-19 20:01:45.000000000 -0500
@@ -791,7 +791,7 @@ ia32_sys_call_table:
 	.quad quiet_ni_syscall		/* 285: sys_altroot */
 	.quad sys_add_key
 	.quad sys_request_key
-	.quad sys_keyctl
+	.quad compat_sys_keyctl
 	.quad sys_ioprio_set
 	.quad sys_ioprio_get		/* 290 */
 	.quad sys_inotify_init
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/x86/include/asm/tlbflush.h linux-libre-3.2.84-gnu1/arch/x86/include/asm/tlbflush.h
--- linux-libre-3.2.83-gnu1/arch/x86/include/asm/tlbflush.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/x86/include/asm/tlbflush.h	2016-11-19 20:01:45.000000000 -0500
@@ -17,7 +17,14 @@
 
 static inline void __native_flush_tlb(void)
 {
+	/*
+	 * If current->mm == NULL then we borrow a mm which may change during a
+	 * task switch and therefore we must not be preempted while we write CR3
+	 * back:
+	 */
+	preempt_disable();
 	native_write_cr3(native_read_cr3());
+	preempt_enable();
 }
 
 static inline void __native_flush_tlb_global(void)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/x86/kernel/apic/apic.c linux-libre-3.2.84-gnu1/arch/x86/kernel/apic/apic.c
--- linux-libre-3.2.83-gnu1/arch/x86/kernel/apic/apic.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/x86/kernel/apic/apic.c	2016-11-19 20:01:45.000000000 -0500
@@ -1481,6 +1481,9 @@ void __init enable_IR_x2apic(void)
 	int ret, x2apic_enabled = 0;
 	int dmar_table_init_ret;
 
+	if (skip_ioapic_setup)
+		return;
+
 	dmar_table_init_ret = dmar_table_init();
 	if (dmar_table_init_ret && !x2apic_supported())
 		return;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/x86/kernel/early-quirks.c linux-libre-3.2.84-gnu1/arch/x86/kernel/early-quirks.c
--- linux-libre-3.2.83-gnu1/arch/x86/kernel/early-quirks.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/x86/kernel/early-quirks.c	2016-11-19 20:01:45.000000000 -0500
@@ -11,13 +11,20 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/pci_ids.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/io.h>
+
+#define dev_err(msg)  pr_err("pci 0000:%02x:%02x.%d: %s", bus, slot, func, msg)
 
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
@@ -73,6 +80,13 @@ static void __init nvidia_bugs(int num,
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_X86_IO_APIC
 	/*
+	 * Only applies to Nvidia root ports (bus 0) and not to
+	 * Nvidia graphics cards with PCI ports on secondary buses.
+	 */
+	if (num)
+		return;
+
+	/*
 	 * All timer overrides on Nvidia are
 	 * wrong unless HPET is enabled.
 	 * Unfortunately that's not true on many Asus boards.
@@ -192,6 +206,62 @@ static void __init ati_bugs_contd(int nu
 }
 #endif
 
+#define BCM4331_MMIO_SIZE	16384
+#define BCM4331_PM_CAP		0x40
+#define bcma_aread32(reg)	ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
+#define bcma_awrite32(reg, val)	iowrite32(val, mmio + 1 * BCMA_CORE_SIZE + reg)
+
+static void __init apple_airport_reset(int bus, int slot, int func)
+{
+	void __iomem *mmio;
+	u16 pmcsr;
+	u64 addr;
+	int i;
+
+	if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc."))
+		return;
+
+	/* Card may have been put into PCI_D3hot by grub quirk */
+	pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+
+	if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+		write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL, pmcsr);
+		mdelay(10);
+
+		pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+			dev_err("Cannot power up Apple AirPort card\n");
+			return;
+		}
+	}
+
+	addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
+	addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
+	addr &= PCI_BASE_ADDRESS_MEM_MASK;
+
+	mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
+	if (!mmio) {
+		dev_err("Cannot iomap Apple AirPort card\n");
+		return;
+	}
+
+	pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
+
+	for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
+		udelay(10);
+
+	bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(1);
+
+	bcma_awrite32(BCMA_RESET_CTL, 0);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(10);
+
+	early_iounmap(mmio, BCM4331_MMIO_SIZE);
+}
+
 #define QFLAG_APPLY_ONCE 	0x1
 #define QFLAG_APPLIED		0x2
 #define QFLAG_DONE		(QFLAG_APPLY_ONCE|QFLAG_APPLIED)
@@ -204,12 +274,6 @@ struct chipset {
 	void (*f)(int num, int slot, int func);
 };
 
-/*
- * Only works for devices on the root bus. If you add any devices
- * not on bus 0 readd another loop level in early_quirks(). But
- * be careful because at least the Nvidia quirk here relies on
- * only matching on bus 0.
- */
 static struct chipset early_qrk[] __initdata = {
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 	  PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
@@ -221,9 +285,13 @@ static struct chipset early_qrk[] __init
 	  PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
 	  PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
+	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
+	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
 	{}
 };
 
+static void __init early_pci_scan_bus(int bus);
+
 /**
  * check_dev_quirk - apply early quirks to a given PCI device
  * @num: bus number
@@ -232,7 +300,7 @@ static struct chipset early_qrk[] __init
  *
  * Check the vendor & device ID against the early quirks table.
  *
- * If the device is single function, let early_quirks() know so we don't
+ * If the device is single function, let early_pci_scan_bus() know so we don't
  * poke at this device again.
  */
 static int __init check_dev_quirk(int num, int slot, int func)
@@ -241,6 +309,7 @@ static int __init check_dev_quirk(int nu
 	u16 vendor;
 	u16 device;
 	u8 type;
+	u8 sec;
 	int i;
 
 	class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
@@ -268,25 +337,36 @@ static int __init check_dev_quirk(int nu
 
 	type = read_pci_config_byte(num, slot, func,
 				    PCI_HEADER_TYPE);
+
+	if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
+		sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
+		if (sec > num)
+			early_pci_scan_bus(sec);
+	}
+
 	if (!(type & 0x80))
 		return -1;
 
 	return 0;
 }
 
-void __init early_quirks(void)
+static void __init early_pci_scan_bus(int bus)
 {
 	int slot, func;
 
-	if (!early_pci_allowed())
-		return;
-
 	/* Poor man's PCI discovery */
-	/* Only scan the root bus */
 	for (slot = 0; slot < 32; slot++)
 		for (func = 0; func < 8; func++) {
 			/* Only probe function 0 on single fn devices */
-			if (check_dev_quirk(0, slot, func))
+			if (check_dev_quirk(bus, slot, func))
 				break;
 		}
 }
+
+void __init early_quirks(void)
+{
+	if (!early_pci_allowed())
+		return;
+
+	early_pci_scan_bus(0);
+}
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/x86/kernel/paravirt.c linux-libre-3.2.84-gnu1/arch/x86/kernel/paravirt.c
--- linux-libre-3.2.83-gnu1/arch/x86/kernel/paravirt.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/x86/kernel/paravirt.c	2016-11-19 20:01:45.000000000 -0500
@@ -52,12 +52,12 @@ asm (".pushsection .entry.text, \"ax\"\n
      ".popsection");
 
 /* identity function, which can be inlined */
-u32 _paravirt_ident_32(u32 x)
+u32 notrace _paravirt_ident_32(u32 x)
 {
 	return x;
 }
 
-u64 _paravirt_ident_64(u64 x)
+u64 notrace _paravirt_ident_64(u64 x)
 {
 	return x;
 }
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/arch/x86/kvm/vmx.c linux-libre-3.2.84-gnu1/arch/x86/kvm/vmx.c
--- linux-libre-3.2.83-gnu1/arch/x86/kvm/vmx.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/arch/x86/kvm/vmx.c	2016-11-19 20:01:45.000000000 -0500
@@ -4999,22 +4999,27 @@ static void nested_free_vmcs02(struct vc
 
 /*
  * Free all VMCSs saved for this vcpu, except the one pointed by
- * vmx->loaded_vmcs. These include the VMCSs in vmcs02_pool (except the one
- * currently used, if running L2), and vmcs01 when running L2.
+ * vmx->loaded_vmcs. We must be running L1, so vmx->loaded_vmcs
+ * must be &vmx->vmcs01.
  */
 static void nested_free_all_saved_vmcss(struct vcpu_vmx *vmx)
 {
 	struct vmcs02_list *item, *n;
+
+	WARN_ON(vmx->loaded_vmcs != &vmx->vmcs01);
 	list_for_each_entry_safe(item, n, &vmx->nested.vmcs02_pool, list) {
-		if (vmx->loaded_vmcs != &item->vmcs02)
-			free_loaded_vmcs(&item->vmcs02);
+		/*
+		 * Something will leak if the above WARN triggers.  Better than
+		 * a use-after-free.
+		 */
+		if (vmx->loaded_vmcs == &item->vmcs02)
+			continue;
+
+		free_loaded_vmcs(&item->vmcs02);
 		list_del(&item->list);
 		kfree(item);
+		vmx->nested.vmcs02_num--;
 	}
-	vmx->nested.vmcs02_num = 0;
-
-	if (vmx->loaded_vmcs != &vmx->vmcs01)
-		free_loaded_vmcs(&vmx->vmcs01);
 }
 
 /*
@@ -6307,13 +6312,44 @@ static void __noclone vmx_vcpu_run(struc
 #undef R
 #undef Q
 
+static void vmx_load_vmcs01(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	int cpu;
+
+	if (vmx->loaded_vmcs == &vmx->vmcs01)
+		return;
+
+	cpu = get_cpu();
+	vmx->loaded_vmcs = &vmx->vmcs01;
+	vmx_vcpu_put(vcpu);
+	vmx_vcpu_load(vcpu, cpu);
+	vcpu->cpu = cpu;
+	put_cpu();
+}
+
+/*
+ * Ensure that the current vmcs of the logical processor is the
+ * vmcs01 of the vcpu before calling free_nested().
+ */
+static void vmx_free_vcpu_nested(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+       vcpu_load(vcpu);
+       vmx_load_vmcs01(vcpu);
+       free_nested(vmx);
+       vcpu_put(vcpu);
+}
+
 static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 
 	free_vpid(vmx);
+	leave_guest_mode(vcpu);
+	vmx_free_vcpu_nested(vcpu);
 	free_loaded_vmcs(vmx->loaded_vmcs);
-	free_nested(vmx);
 	kfree(vmx->guest_msrs);
 	kvm_vcpu_uninit(vcpu);
 	kmem_cache_free(kvm_vcpu_cache, vmx);
@@ -7059,18 +7095,12 @@ void load_vmcs12_host_state(struct kvm_v
 static void nested_vmx_vmexit(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	int cpu;
 	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 
 	leave_guest_mode(vcpu);
 	prepare_vmcs12(vcpu, vmcs12);
 
-	cpu = get_cpu();
-	vmx->loaded_vmcs = &vmx->vmcs01;
-	vmx_vcpu_put(vcpu);
-	vmx_vcpu_load(vcpu, cpu);
-	vcpu->cpu = cpu;
-	put_cpu();
+	vmx_load_vmcs01(vcpu);
 
 	/* if no vmcs02 cache requested, remove the one we used */
 	if (VMCS02_POOL_SIZE == 0)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/block/genhd.c linux-libre-3.2.84-gnu1/block/genhd.c
--- linux-libre-3.2.83-gnu1/block/genhd.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/block/genhd.c	2016-11-19 20:01:45.000000000 -0500
@@ -829,6 +829,7 @@ static void disk_seqf_stop(struct seq_fi
 	if (iter) {
 		class_dev_iter_exit(iter);
 		kfree(iter);
+		seqf->private = NULL;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/crypto/blkcipher.c linux-libre-3.2.84-gnu1/crypto/blkcipher.c
--- linux-libre-3.2.83-gnu1/crypto/blkcipher.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/crypto/blkcipher.c	2016-11-19 20:01:45.000000000 -0500
@@ -238,6 +238,8 @@ static int blkcipher_walk_next(struct bl
 		return blkcipher_walk_done(desc, walk, -EINVAL);
 	}
 
+	bsize = min(walk->blocksize, n);
+
 	walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
 			 BLKCIPHER_WALK_DIFF);
 	if (!scatterwalk_aligned(&walk->in, alignmask) ||
@@ -250,7 +252,6 @@ static int blkcipher_walk_next(struct bl
 		}
 	}
 
-	bsize = min(walk->blocksize, n);
 	n = scatterwalk_clamp(&walk->in, n);
 	n = scatterwalk_clamp(&walk->out, n);
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/crypto/cryptd.c linux-libre-3.2.84-gnu1/crypto/cryptd.c
--- linux-libre-3.2.83-gnu1/crypto/cryptd.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/crypto/cryptd.c	2016-11-19 20:01:45.000000000 -0500
@@ -565,9 +565,14 @@ static int cryptd_hash_export(struct aha
 
 static int cryptd_hash_import(struct ahash_request *req, const void *in)
 {
-	struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct shash_desc *desc = cryptd_shash_desc(req);
 
-	return crypto_shash_import(&rctx->desc, in);
+	desc->tfm = ctx->child;
+	desc->flags = req->base.flags;
+
+	return crypto_shash_import(desc, in);
 }
 
 static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/crypto/gcm.c linux-libre-3.2.84-gnu1/crypto/gcm.c
--- linux-libre-3.2.83-gnu1/crypto/gcm.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/crypto/gcm.c	2016-11-19 20:01:45.000000000 -0500
@@ -711,7 +711,9 @@ static struct crypto_instance *crypto_gc
 
 	ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type,
 				    CRYPTO_ALG_TYPE_HASH,
-				    CRYPTO_ALG_TYPE_AHASH_MASK);
+				    CRYPTO_ALG_TYPE_AHASH_MASK |
+				    crypto_requires_sync(algt->type,
+							 algt->mask));
 	err = PTR_ERR(ghash_alg);
 	if (IS_ERR(ghash_alg))
 		return ERR_PTR(err);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/crypto/scatterwalk.c linux-libre-3.2.84-gnu1/crypto/scatterwalk.c
--- linux-libre-3.2.83-gnu1/crypto/scatterwalk.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/crypto/scatterwalk.c	2016-11-19 20:01:45.000000000 -0500
@@ -68,7 +68,8 @@ static void scatterwalk_pagedone(struct
 
 void scatterwalk_done(struct scatter_walk *walk, int out, int more)
 {
-	if (!(scatterwalk_pagelen(walk) & (PAGE_SIZE - 1)) || !more)
+	if (!more || walk->offset >= walk->sg->offset + walk->sg->length ||
+	    !(walk->offset & (PAGE_SIZE - 1)))
 		scatterwalk_pagedone(walk, out, more);
 }
 EXPORT_SYMBOL_GPL(scatterwalk_done);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/Documentation/filesystems/porting linux-libre-3.2.84-gnu1/Documentation/filesystems/porting
--- linux-libre-3.2.83-gnu1/Documentation/filesystems/porting	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/Documentation/filesystems/porting	2016-11-19 20:01:45.000000000 -0500
@@ -288,8 +288,8 @@ implementing on-disk size changes.  Star
 and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
 be in order of zeroing blocks using block_truncate_page or similar helpers,
 size update and on finally on-disk truncation which should not fail.
-inode_change_ok now includes the size checks for ATTR_SIZE and must be called
-in the beginning of ->setattr unconditionally.
+setattr_prepare (which used to be inode_change_ok) now includes the size checks
+for ATTR_SIZE and must be called in the beginning of ->setattr unconditionally.
 
 [mandatory]
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/bcma/bcma_private.h linux-libre-3.2.84-gnu1/drivers/bcma/bcma_private.h
--- linux-libre-3.2.83-gnu1/drivers/bcma/bcma_private.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/bcma/bcma_private.h	2016-11-19 20:01:45.000000000 -0500
@@ -8,8 +8,6 @@
 #include <linux/bcma/bcma.h>
 #include <linux/delay.h>
 
-#define BCMA_CORE_SIZE		0x1000
-
 struct bcma_bus;
 
 /* main.c */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/bluetooth/ath3k.c linux-libre-3.2.84-gnu1/drivers/bluetooth/ath3k.c
--- linux-libre-3.2.83-gnu1/drivers/bluetooth/ath3k.c	2016-10-21 11:18:15.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/bluetooth/ath3k.c	2016-11-20 23:12:02.000000000 -0500
@@ -118,6 +118,8 @@ static struct usb_device_id ath3k_table[
 	{ USB_DEVICE(0x13d3, 0x3432) },
 	{ USB_DEVICE(0x13d3, 0x3472) },
 	{ USB_DEVICE(0x13d3, 0x3474) },
+	{ USB_DEVICE(0x13d3, 0x3487) },
+	{ USB_DEVICE(0x13d3, 0x3490) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE02C) },
@@ -182,6 +184,8 @@ static struct usb_device_id ath3k_blist_
 	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3487), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3490), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU22 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/bluetooth/btusb.c linux-libre-3.2.84-gnu1/drivers/bluetooth/btusb.c
--- linux-libre-3.2.83-gnu1/drivers/bluetooth/btusb.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/bluetooth/btusb.c	2016-11-19 20:01:45.000000000 -0500
@@ -203,6 +203,8 @@ static struct usb_device_id blacklist_ta
 	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3487), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3490), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/char/tpm/tpm_tis.c linux-libre-3.2.84-gnu1/drivers/char/tpm/tpm_tis.c
--- linux-libre-3.2.83-gnu1/drivers/char/tpm/tpm_tis.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/char/tpm/tpm_tis.c	2016-11-19 20:01:45.000000000 -0500
@@ -176,16 +176,15 @@ static int get_burstcount(struct tpm_chi
 {
 	unsigned long stop;
 	int burstcnt;
+	u32 value;
 
 	/* wait for burstcount */
 	/* which timeout value, spec has 2 answers (c & d) */
 	stop = jiffies + chip->vendor.timeout_d;
 	do {
-		burstcnt = ioread8(chip->vendor.iobase +
-				   TPM_STS(chip->vendor.locality) + 1);
-		burstcnt += ioread8(chip->vendor.iobase +
-				    TPM_STS(chip->vendor.locality) +
-				    2) << 8;
+		value = ioread32(chip->vendor.iobase +
+				 TPM_STS(chip->vendor.locality));
+		burstcnt = (value >> 8) & 0xFFFF;
 		if (burstcnt)
 			return burstcnt;
 		msleep(TPM_TIMEOUT);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/firewire/net.c linux-libre-3.2.84-gnu1/drivers/firewire/net.c
--- linux-libre-3.2.83-gnu1/drivers/firewire/net.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/firewire/net.c	2016-11-19 20:01:45.000000000 -0500
@@ -677,6 +677,9 @@ static int fwnet_incoming_packet(struct
 	int retval;
 	u16 ether_type;
 
+	if (len <= RFC2374_UNFRAG_HDR_SIZE)
+		return 0;
+
 	hdr.w0 = be32_to_cpu(buf[0]);
 	lf = fwnet_get_hdr_lf(&hdr);
 	if (lf == RFC2374_HDR_UNFRAG) {
@@ -702,7 +705,12 @@ static int fwnet_incoming_packet(struct
 		return fwnet_finish_incoming_packet(net, skb, source_node_id,
 						    is_broadcast, ether_type);
 	}
+
 	/* A datagram fragment has been received, now the fun begins. */
+
+	if (len <= RFC2374_FRAG_HDR_SIZE)
+		return 0;
+
 	hdr.w1 = ntohl(buf[1]);
 	buf += 2;
 	len -= RFC2374_FRAG_HDR_SIZE;
@@ -716,6 +724,9 @@ static int fwnet_incoming_packet(struct
 	datagram_label = fwnet_get_hdr_dgl(&hdr);
 	dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
 
+	if (fg_off + len > dg_size)
+		return 0;
+
 	spin_lock_irqsave(&dev->lock, flags);
 
 	peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation);
@@ -822,6 +833,22 @@ static void fwnet_receive_packet(struct
 	fw_send_response(card, r, rcode);
 }
 
+static int gasp_source_id(__be32 *p)
+{
+	return be32_to_cpu(p[0]) >> 16;
+}
+
+static u32 gasp_specifier_id(__be32 *p)
+{
+	return (be32_to_cpu(p[0]) & 0xffff) << 8 |
+	       (be32_to_cpu(p[1]) & 0xff000000) >> 24;
+}
+
+static u32 gasp_version(__be32 *p)
+{
+	return be32_to_cpu(p[1]) & 0xffffff;
+}
+
 static void fwnet_receive_broadcast(struct fw_iso_context *context,
 		u32 cycle, size_t header_length, void *header, void *data)
 {
@@ -832,9 +859,6 @@ static void fwnet_receive_broadcast(stru
 	__be32 *buf_ptr;
 	int retval;
 	u32 length;
-	u16 source_node_id;
-	u32 specifier_id;
-	u32 ver;
 	unsigned long offset;
 	unsigned long flags;
 
@@ -852,17 +876,13 @@ static void fwnet_receive_broadcast(stru
 
 	spin_unlock_irqrestore(&dev->lock, flags);
 
-	specifier_id =    (be32_to_cpu(buf_ptr[0]) & 0xffff) << 8
-			| (be32_to_cpu(buf_ptr[1]) & 0xff000000) >> 24;
-	ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
-	source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
-
-	if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) {
-		buf_ptr += 2;
-		length -= IEEE1394_GASP_HDR_SIZE;
-		fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
+	if (length > IEEE1394_GASP_HDR_SIZE &&
+	    gasp_specifier_id(buf_ptr) == IANA_SPECIFIER_ID &&
+	    gasp_version(buf_ptr) == RFC2734_SW_VERSION)
+		fwnet_incoming_packet(dev, buf_ptr + 2,
+				      length - IEEE1394_GASP_HDR_SIZE,
+				      gasp_source_id(buf_ptr),
 				      context->card->generation, true);
-	}
 
 	packet.payload_length = dev->rcv_buffer_size;
 	packet.interrupt = 1;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/gpu/drm/drm_crtc.c linux-libre-3.2.84-gnu1/drivers/gpu/drm/drm_crtc.c
--- linux-libre-3.2.83-gnu1/drivers/gpu/drm/drm_crtc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/gpu/drm/drm_crtc.c	2016-11-19 20:01:45.000000000 -0500
@@ -2675,6 +2675,9 @@ int drm_mode_page_flip_ioctl(struct drm_
 	unsigned long flags;
 	int ret = -EINVAL;
 
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
 	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
 	    page_flip->reserved != 0)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/gpu/drm/drm_edid.c linux-libre-3.2.84-gnu1/drivers/gpu/drm/drm_edid.c
--- linux-libre-3.2.83-gnu1/drivers/gpu/drm/drm_edid.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/gpu/drm/drm_edid.c	2016-11-19 20:01:45.000000000 -0500
@@ -68,6 +68,8 @@
 #define EDID_QUIRK_DETAILED_SYNC_PP		(1 << 6)
 /* Force reduced-blanking timings for detailed modes */
 #define EDID_QUIRK_FORCE_REDUCED_BLANKING	(1 << 7)
+/* Force 6bpc */
+#define EDID_QUIRK_FORCE_6BPC			(1 << 10)
 
 struct detailed_mode_closure {
 	struct drm_connector *connector;
@@ -94,6 +96,9 @@ static struct edid_quirk {
 	/* Unknown Acer */
 	{ "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
 
+	/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
+	{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
+
 	/* Belinea 10 15 55 */
 	{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
 	{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
@@ -1752,6 +1757,9 @@ int drm_add_edid_modes(struct drm_connec
 
 	drm_add_display_info(edid, &connector->display_info);
 
+	if (quirks & EDID_QUIRK_FORCE_6BPC)
+		connector->display_info.bpc = 6;
+
 	return num_modes;
 }
 EXPORT_SYMBOL(drm_add_edid_modes);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c linux-libre-3.2.84-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c
--- linux-libre-3.2.83-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c	2016-11-19 20:01:45.000000000 -0500
@@ -1138,7 +1138,7 @@ bool radeon_atom_get_clock_info(struct d
 		    le16_to_cpu(firmware_info->info.usReferenceClock);
 		p1pll->reference_div = 0;
 
-		if (crev < 2)
+		if ((frev < 2) && (crev < 2))
 			p1pll->pll_out_min =
 				le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
 		else
@@ -1147,7 +1147,7 @@ bool radeon_atom_get_clock_info(struct d
 		p1pll->pll_out_max =
 		    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
 
-		if (crev >= 4) {
+		if (((frev < 2) && (crev >= 4)) || (frev >= 2)) {
 			p1pll->lcd_pll_out_min =
 				le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
 			if (p1pll->lcd_pll_out_min == 0)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c linux-libre-3.2.84-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c
--- linux-libre-3.2.83-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c	2016-11-19 20:01:45.000000000 -0500
@@ -1589,7 +1589,6 @@ radeon_add_atom_connector(struct drm_dev
 						      1);
 			/* no HPD on analog connectors */
 			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 			connector->interlace_allowed = true;
 			connector->doublescan_allowed = true;
 			break;
@@ -1787,8 +1786,10 @@ radeon_add_atom_connector(struct drm_dev
 	}
 
 	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-		if (i2c_bus->valid)
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+		if (i2c_bus->valid) {
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+			                    DRM_CONNECTOR_POLL_DISCONNECT;
+		}
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
 
@@ -1860,7 +1861,6 @@ radeon_add_legacy_connector(struct drm_d
 					      1);
 		/* no HPD on analog connectors */
 		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 		connector->interlace_allowed = true;
 		connector->doublescan_allowed = true;
 		break;
@@ -1945,10 +1945,13 @@ radeon_add_legacy_connector(struct drm_d
 	}
 
 	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-		if (i2c_bus->valid)
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+		if (i2c_bus->valid) {
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+			                    DRM_CONNECTOR_POLL_DISCONNECT;
+		}
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
+
 	connector->display_info.subpixel_order = subpixel_order;
 	drm_sysfs_connector_add(connector);
 	if (connector_type == DRM_MODE_CONNECTOR_LVDS) {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c linux-libre-3.2.84-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c
--- linux-libre-3.2.83-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c	2016-11-19 20:01:45.000000000 -0500
@@ -248,8 +248,8 @@ static int radeon_move_blit(struct ttm_b
 	if (unlikely(r)) {
 		return r;
 	}
-	old_start = old_mem->start << PAGE_SHIFT;
-	new_start = new_mem->start << PAGE_SHIFT;
+	old_start = (u64)old_mem->start << PAGE_SHIFT;
+	new_start = (u64)new_mem->start << PAGE_SHIFT;
 
 	switch (old_mem->mem_type) {
 	case TTM_PL_VRAM:
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/hwmon/adt7411.c linux-libre-3.2.84-gnu1/drivers/hwmon/adt7411.c
--- linux-libre-3.2.83-gnu1/drivers/hwmon/adt7411.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/hwmon/adt7411.c	2016-11-19 20:01:45.000000000 -0500
@@ -31,6 +31,7 @@
 
 #define ADT7411_REG_CFG1			0x18
 #define ADT7411_CFG1_START_MONITOR		(1 << 0)
+#define ADT7411_CFG1_RESERVED_BIT3		(1 << 3)
 
 #define ADT7411_REG_CFG2			0x19
 #define ADT7411_CFG2_DISABLE_AVG		(1 << 5)
@@ -291,8 +292,10 @@ static int __devinit adt7411_probe(struc
 	mutex_init(&data->device_lock);
 	mutex_init(&data->update_lock);
 
+	/* According to the datasheet, we must only write 1 to bit 3 */
 	ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
-				 ADT7411_CFG1_START_MONITOR, 1);
+				 ADT7411_CFG1_RESERVED_BIT3
+				 | ADT7411_CFG1_START_MONITOR, 1);
 	if (ret < 0)
 		goto exit_free;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/i2c/busses/i2c-eg20t.c linux-libre-3.2.84-gnu1/drivers/i2c/busses/i2c-eg20t.c
--- linux-libre-3.2.83-gnu1/drivers/i2c/busses/i2c-eg20t.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/i2c/busses/i2c-eg20t.c	2016-11-19 20:01:45.000000000 -0500
@@ -893,13 +893,6 @@ static int __devinit pch_i2c_probe(struc
 	/* Set the number of I2C channel instance */
 	adap_info->ch_num = id->driver_data;
 
-	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, adap_info);
-	if (ret) {
-		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
-	}
-
 	for (i = 0; i < adap_info->ch_num; i++) {
 		pch_adap = &adap_info->pch_data[i].pch_adapter;
 		adap_info->pch_i2c_suspended = false;
@@ -916,6 +909,17 @@ static int __devinit pch_i2c_probe(struc
 		adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
 
 		pch_adap->dev.parent = &pdev->dev;
+	}
+
+	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
+		  KBUILD_MODNAME, adap_info);
+	if (ret) {
+		pch_pci_err(pdev, "request_irq FAILED\n");
+		goto err_request_irq;
+	}
+
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
 
 		pch_i2c_init(&adap_info->pch_data[i]);
 		ret = i2c_add_adapter(pch_adap);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/infiniband/core/multicast.c linux-libre-3.2.84-gnu1/drivers/infiniband/core/multicast.c
--- linux-libre-3.2.83-gnu1/drivers/infiniband/core/multicast.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/infiniband/core/multicast.c	2016-11-19 20:01:45.000000000 -0500
@@ -106,7 +106,6 @@ struct mcast_group {
 	atomic_t		refcount;
 	enum mcast_group_state	state;
 	struct ib_sa_query	*query;
-	int			query_id;
 	u16			pkey_index;
 	u8			leave_state;
 	int			retries;
@@ -339,11 +338,7 @@ static int send_join(struct mcast_group
 				       member->multicast.comp_mask,
 				       3000, GFP_KERNEL, join_handler, group,
 				       &group->query);
-	if (ret >= 0) {
-		group->query_id = ret;
-		ret = 0;
-	}
-	return ret;
+	return (ret > 0) ? 0 : ret;
 }
 
 static int send_leave(struct mcast_group *group, u8 leave_state)
@@ -363,11 +358,7 @@ static int send_leave(struct mcast_group
 				       IB_SA_MCMEMBER_REC_JOIN_STATE,
 				       3000, GFP_KERNEL, leave_handler,
 				       group, &group->query);
-	if (ret >= 0) {
-		group->query_id = ret;
-		ret = 0;
-	}
-	return ret;
+	return (ret > 0) ? 0 : ret;
 }
 
 static void join_group(struct mcast_group *group, struct mcast_member *member,
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c
--- linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2016-11-19 20:01:45.000000000 -0500
@@ -1288,6 +1288,8 @@ void ipoib_cm_destroy_tx(struct ipoib_cm
 	}
 }
 
+#define QPN_AND_OPTIONS_OFFSET	4
+
 static void ipoib_cm_tx_start(struct work_struct *work)
 {
 	struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
@@ -1296,6 +1298,7 @@ static void ipoib_cm_tx_start(struct wor
 	struct ipoib_neigh *neigh;
 	struct ipoib_cm_tx *p;
 	unsigned long flags;
+	struct ipoib_path *path;
 	int ret;
 
 	struct ib_sa_path_rec pathrec;
@@ -1308,7 +1311,19 @@ static void ipoib_cm_tx_start(struct wor
 		p = list_entry(priv->cm.start_list.next, typeof(*p), list);
 		list_del_init(&p->list);
 		neigh = p->neigh;
+
 		qpn = IPOIB_QPN(neigh->neighbour->ha);
+		/*
+		 * As long as the search is with these 2 locks,
+		 * path existence indicates its validity.
+		 */
+		path = __path_find(dev, neigh->neighbour->ha + QPN_AND_OPTIONS_OFFSET);
+		if (!path) {
+			pr_info("%s ignore not valid path %pI6\n",
+				__func__,
+				neigh->neighbour->ha + QPN_AND_OPTIONS_OFFSET);
+			goto free_neigh;
+		}
 		memcpy(&pathrec, &p->path->pathrec, sizeof pathrec);
 
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -1320,6 +1335,7 @@ static void ipoib_cm_tx_start(struct wor
 		spin_lock_irqsave(&priv->lock, flags);
 
 		if (ret) {
+free_neigh:
 			neigh = p->neigh;
 			if (neigh) {
 				neigh->cm = NULL;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib.h linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib.h
--- linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib.h	2016-11-19 20:01:45.000000000 -0500
@@ -434,6 +434,7 @@ void ipoib_send(struct net_device *dev,
 		struct ipoib_ah *address, u32 qpn);
 void ipoib_reap_ah(struct work_struct *work);
 
+struct ipoib_path *__path_find(struct net_device *dev, void *gid);
 void ipoib_mark_paths_invalid(struct net_device *dev);
 void ipoib_flush_paths(struct net_device *dev);
 struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2016-11-19 20:01:45.000000000 -0500
@@ -973,8 +973,17 @@ static void __ipoib_ib_dev_flush(struct
 	}
 
 	if (level == IPOIB_FLUSH_LIGHT) {
+		int oper_up;
 		ipoib_mark_paths_invalid(dev);
+		/* Set IPoIB operation as down to prevent races between:
+		 * the flush flow which leaves MCG and on the fly joins
+		 * which can happen during that time. mcast restart task
+		 * should deal with join requests we missed.
+		 */
+		oper_up = test_and_clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
 		ipoib_mcast_dev_flush(dev);
+		if (oper_up)
+			set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
 	}
 
 	if (level >= IPOIB_FLUSH_NORMAL)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-libre-3.2.83-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2016-11-19 20:01:45.000000000 -0500
@@ -208,7 +208,7 @@ static int ipoib_change_mtu(struct net_d
 	return 0;
 }
 
-static struct ipoib_path *__path_find(struct net_device *dev, void *gid)
+struct ipoib_path *__path_find(struct net_device *dev, void *gid)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct rb_node *n = priv->path_tree.rb_node;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/input/joystick/xpad.c linux-libre-3.2.84-gnu1/drivers/input/joystick/xpad.c
--- linux-libre-3.2.83-gnu1/drivers/input/joystick/xpad.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/input/joystick/xpad.c	2016-11-19 20:01:45.000000000 -0500
@@ -825,6 +825,9 @@ static int xpad_probe(struct usb_interfa
 	struct usb_endpoint_descriptor *ep_irq_in;
 	int i, error;
 
+	if (intf->cur_altsetting->desc.bNumEndpoints != 2)
+		return -ENODEV;
+
 	for (i = 0; xpad_device[i].idVendor; i++) {
 		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
 		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/input/serio/i8042.c linux-libre-3.2.84-gnu1/drivers/input/serio/i8042.c
--- linux-libre-3.2.83-gnu1/drivers/input/serio/i8042.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/input/serio/i8042.c	2016-11-19 20:01:45.000000000 -0500
@@ -1223,6 +1223,7 @@ static int __init i8042_create_kbd_port(
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
 	serio->close		= i8042_port_close;
+	serio->ps2_cmd_mutex	= &i8042_mutex;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
 	strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
@@ -1248,6 +1249,7 @@ static int __init i8042_create_aux_port(
 	serio->write		= i8042_aux_write;
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
+	serio->ps2_cmd_mutex	= &i8042_mutex;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
 	if (idx < 0) {
@@ -1310,21 +1312,6 @@ static void __devexit i8042_unregister_p
 	}
 }
 
-/*
- * Checks whether port belongs to i8042 controller.
- */
-bool i8042_check_port_owner(const struct serio *port)
-{
-	int i;
-
-	for (i = 0; i < I8042_NUM_PORTS; i++)
-		if (i8042_ports[i].serio == port)
-			return true;
-
-	return false;
-}
-EXPORT_SYMBOL(i8042_check_port_owner);
-
 static void i8042_free_irqs(void)
 {
 	if (i8042_aux_irq_registered)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/input/serio/libps2.c linux-libre-3.2.84-gnu1/drivers/input/serio/libps2.c
--- linux-libre-3.2.83-gnu1/drivers/input/serio/libps2.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/input/serio/libps2.c	2016-11-19 20:01:45.000000000 -0500
@@ -57,19 +57,17 @@ EXPORT_SYMBOL(ps2_sendbyte);
 
 void ps2_begin_command(struct ps2dev *ps2dev)
 {
-	mutex_lock(&ps2dev->cmd_mutex);
+	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
 
-	if (i8042_check_port_owner(ps2dev->serio))
-		i8042_lock_chip();
+	mutex_lock(m);
 }
 EXPORT_SYMBOL(ps2_begin_command);
 
 void ps2_end_command(struct ps2dev *ps2dev)
 {
-	if (i8042_check_port_owner(ps2dev->serio))
-		i8042_unlock_chip();
+	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
 
-	mutex_unlock(&ps2dev->cmd_mutex);
+	mutex_unlock(m);
 }
 EXPORT_SYMBOL(ps2_end_command);
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/md/dm-flakey.c linux-libre-3.2.84-gnu1/drivers/md/dm-flakey.c
--- linux-libre-3.2.83-gnu1/drivers/md/dm-flakey.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/md/dm-flakey.c	2016-11-19 20:01:45.000000000 -0500
@@ -279,10 +279,16 @@ static int flakey_map(struct dm_target *
 		map_context->ll = 1;
 
 		/*
-		 * Map reads as normal.
+		 * Map reads as normal only if corrupt_bio_byte set.
 		 */
-		if (bio_data_dir(bio) == READ)
-			goto map_bio;
+		if (bio_data_dir(bio) == READ) {
+			/* If flags were specified, only corrupt those that match. */
+			if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) &&
+			    all_corrupt_bio_flags_match(bio, fc))
+				goto map_bio;
+			else
+				return -EIO;
+		}
 
 		/*
 		 * Drop writes?
@@ -321,12 +327,13 @@ static int flakey_end_io(struct dm_targe
 
 	/*
 	 * Corrupt successful READs while in down state.
-	 * If flags were specified, only corrupt those that match.
 	 */
-	if (fc->corrupt_bio_byte && !error && bio_submitted_while_down &&
-	    (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) &&
-	    all_corrupt_bio_flags_match(bio, fc))
-		corrupt_bio_data(bio, fc);
+	if (!error && bio_submitted_while_down && (bio_data_dir(bio) == READ)) {
+		if (fc->corrupt_bio_byte)
+			corrupt_bio_data(bio, fc);
+		else
+			return -EIO;
+	}
 
 	return error;
 }
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/media/video/usbvision/usbvision-video.c linux-libre-3.2.84-gnu1/drivers/media/video/usbvision/usbvision-video.c
--- linux-libre-3.2.83-gnu1/drivers/media/video/usbvision/usbvision-video.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/media/video/usbvision/usbvision-video.c	2016-11-19 20:01:45.000000000 -0500
@@ -1502,13 +1502,6 @@ static int __devinit usbvision_probe(str
 	printk(KERN_INFO "%s: %s found\n", __func__,
 				usbvision_device_data[model].model_string);
 
-	/*
-	 * this is a security check.
-	 * an exploit using an incorrect bInterfaceNumber is known
-	 */
-	if (ifnum >= USB_MAXINTERFACES || !dev->actconfig->interface[ifnum])
-		return -ENODEV;
-
 	if (usbvision_device_data[model].interface >= 0)
 		interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
 	else if (ifnum < dev->actconfig->desc.bNumInterfaces)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/mtd/maps/pmcmsp-flash.c linux-libre-3.2.84-gnu1/drivers/mtd/maps/pmcmsp-flash.c
--- linux-libre-3.2.83-gnu1/drivers/mtd/maps/pmcmsp-flash.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/mtd/maps/pmcmsp-flash.c	2016-11-19 20:01:45.000000000 -0500
@@ -75,15 +75,15 @@ static int __init init_msp_flash(void)
 
 	printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt);
 
-	msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL);
+	msp_flash = kcalloc(fcnt, sizeof(*msp_flash), GFP_KERNEL);
 	if (!msp_flash)
 		return -ENOMEM;
 
-	msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL);
+	msp_parts = kcalloc(fcnt, sizeof(*msp_parts), GFP_KERNEL);
 	if (!msp_parts)
 		goto free_msp_flash;
 
-	msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL);
+	msp_maps = kcalloc(fcnt, sizeof(*msp_maps), GFP_KERNEL);
 	if (!msp_maps)
 		goto free_msp_parts;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/mtd/nand/davinci_nand.c linux-libre-3.2.84-gnu1/drivers/mtd/nand/davinci_nand.c
--- linux-libre-3.2.83-gnu1/drivers/mtd/nand/davinci_nand.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/mtd/nand/davinci_nand.c	2016-11-19 20:01:45.000000000 -0500
@@ -239,6 +239,9 @@ static void nand_davinci_hwctl_4bit(stru
 	unsigned long flags;
 	u32 val;
 
+	/* Reset ECC hardware */
+	davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET);
+
 	spin_lock_irqsave(&davinci_nand_lock, flags);
 
 	/* Start 4-bit ECC calculation for read/write */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/mtd/nand/nand_base.c linux-libre-3.2.84-gnu1/drivers/mtd/nand/nand_base.c
--- linux-libre-3.2.83-gnu1/drivers/mtd/nand/nand_base.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/mtd/nand/nand_base.c	2016-11-19 20:01:45.000000000 -0500
@@ -2229,7 +2229,7 @@ static int nand_do_write_ops(struct mtd_
 		uint8_t *wbuf = buf;
 
 		/* Partial page write? */
-		if (unlikely(column || writelen < (mtd->writesize - 1))) {
+		if (unlikely(column || writelen < mtd->writesize)) {
 			cached = 0;
 			bytes = min_t(int, bytes - column, (int) writelen);
 			chip->pagebuf = -1;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/mtd/ubi/build.c linux-libre-3.2.84-gnu1/drivers/mtd/ubi/build.c
--- linux-libre-3.2.83-gnu1/drivers/mtd/ubi/build.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/mtd/ubi/build.c	2016-11-19 20:01:45.000000000 -0500
@@ -974,6 +974,9 @@ int ubi_attach_mtd_dev(struct mtd_info *
 			goto out_detach;
 	}
 
+	/* Make device "available" before it becomes accessible via sysfs */
+	ubi_devices[ubi_num] = ubi;
+
 	err = uif_init(ubi, &ref);
 	if (err)
 		goto out_detach;
@@ -1017,7 +1020,6 @@ int ubi_attach_mtd_dev(struct mtd_info *
 	wake_up_process(ubi->bgt_thread);
 	spin_unlock(&ubi->wl_lock);
 
-	ubi_devices[ubi_num] = ubi;
 	ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL);
 	return ubi_num;
 
@@ -1028,6 +1030,7 @@ out_uif:
 	ubi_assert(ref);
 	uif_close(ubi);
 out_detach:
+	ubi_devices[ubi_num] = NULL;
 	ubi_wl_close(ubi);
 	free_internal_volumes(ubi);
 	vfree(ubi->vtbl);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/net/can/dev.c linux-libre-3.2.84-gnu1/drivers/net/can/dev.c
--- linux-libre-3.2.83-gnu1/drivers/net/can/dev.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/net/can/dev.c	2016-11-19 20:01:45.000000000 -0500
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
+#include <linux/workqueue.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/netlink.h>
@@ -361,9 +362,8 @@ EXPORT_SYMBOL_GPL(can_free_echo_skb);
 /*
  * CAN device restart for bus-off recovery
  */
-void can_restart(unsigned long data)
+void can_restart(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)data;
 	struct can_priv *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &dev->stats;
 	struct sk_buff *skb;
@@ -403,6 +403,14 @@ restart:
 		dev_err(dev->dev.parent, "Error %d during restart", err);
 }
 
+static void can_restart_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct can_priv *priv = container_of(dwork, struct can_priv, restart_work);
+
+	can_restart(priv->dev);
+}
+
 int can_restart_now(struct net_device *dev)
 {
 	struct can_priv *priv = netdev_priv(dev);
@@ -416,8 +424,8 @@ int can_restart_now(struct net_device *d
 	if (priv->state != CAN_STATE_BUS_OFF)
 		return -EBUSY;
 
-	/* Runs as soon as possible in the timer context */
-	mod_timer(&priv->restart_timer, jiffies);
+	cancel_delayed_work_sync(&priv->restart_work);
+	can_restart(dev);
 
 	return 0;
 }
@@ -439,8 +447,8 @@ void can_bus_off(struct net_device *dev)
 	priv->can_stats.bus_off++;
 
 	if (priv->restart_ms)
-		mod_timer(&priv->restart_timer,
-			  jiffies + (priv->restart_ms * HZ) / 1000);
+		schedule_delayed_work(&priv->restart_work,
+				      msecs_to_jiffies(priv->restart_ms));
 }
 EXPORT_SYMBOL_GPL(can_bus_off);
 
@@ -515,6 +523,7 @@ struct net_device *alloc_candev(int size
 		return NULL;
 
 	priv = netdev_priv(dev);
+	priv->dev = dev;
 
 	if (echo_skb_max) {
 		priv->echo_skb_max = echo_skb_max;
@@ -524,7 +533,7 @@ struct net_device *alloc_candev(int size
 
 	priv->state = CAN_STATE_STOPPED;
 
-	init_timer(&priv->restart_timer);
+	INIT_DELAYED_WORK(&priv->restart_work, can_restart_work);
 
 	return dev;
 }
@@ -558,8 +567,6 @@ int open_candev(struct net_device *dev)
 	if (!netif_carrier_ok(dev))
 		netif_carrier_on(dev);
 
-	setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(open_candev);
@@ -574,7 +581,7 @@ void close_candev(struct net_device *dev
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	del_timer_sync(&priv->restart_timer);
+	cancel_delayed_work_sync(&priv->restart_work);
 	can_flush_echo_skb(dev);
 }
 EXPORT_SYMBOL_GPL(close_candev);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/net/ethernet/ethoc.c linux-libre-3.2.84-gnu1/drivers/net/ethernet/ethoc.c
--- linux-libre-3.2.83-gnu1/drivers/net/ethernet/ethoc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/net/ethernet/ethoc.c	2016-11-19 20:01:45.000000000 -0500
@@ -976,7 +976,7 @@ static int __devinit ethoc_probe(struct
 	if (!priv->iobase) {
 		dev_err(&pdev->dev, "cannot remap I/O memory space\n");
 		ret = -ENXIO;
-		goto error;
+		goto free;
 	}
 
 	if (netdev->mem_end) {
@@ -985,7 +985,7 @@ static int __devinit ethoc_probe(struct
 		if (!priv->membase) {
 			dev_err(&pdev->dev, "cannot remap memory space\n");
 			ret = -ENXIO;
-			goto error;
+			goto free;
 		}
 	} else {
 		/* Allocate buffer memory */
@@ -996,7 +996,7 @@ static int __devinit ethoc_probe(struct
 			dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
 				buffer_size);
 			ret = -ENOMEM;
-			goto error;
+			goto free;
 		}
 		netdev->mem_end = netdev->mem_start + buffer_size;
 		priv->dma_alloc = buffer_size;
@@ -1007,7 +1007,7 @@ static int __devinit ethoc_probe(struct
 		128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ);
 	if (num_bd < 4) {
 		ret = -ENODEV;
-		goto error;
+		goto free;
 	}
 	/* num_tx must be a power of two */
 	priv->num_tx = rounddown_pow_of_two(num_bd >> 1);
@@ -1019,7 +1019,7 @@ static int __devinit ethoc_probe(struct
 	priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void*), GFP_KERNEL);
 	if (!priv->vma) {
 		ret = -ENOMEM;
-		goto error;
+		goto free;
 	}
 
 	/* Allow the platform setup code to pass in a MAC address. */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/net/ppp/ppp_generic.c linux-libre-3.2.84-gnu1/drivers/net/ppp/ppp_generic.c
--- linux-libre-3.2.83-gnu1/drivers/net/ppp/ppp_generic.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/net/ppp/ppp_generic.c	2016-11-19 20:01:45.000000000 -0500
@@ -2275,8 +2275,6 @@ ppp_unregister_channel(struct ppp_channe
 	spin_lock_bh(&pn->all_channels_lock);
 	list_del(&pch->list);
 	spin_unlock_bh(&pn->all_channels_lock);
-	put_net(pch->chan_net);
-	pch->chan_net = NULL;
 
 	pch->file.dead = 1;
 	wake_up_interruptible(&pch->file.rwait);
@@ -2883,6 +2881,9 @@ ppp_disconnect_channel(struct channel *p
  */
 static void ppp_destroy_channel(struct channel *pch)
 {
+	put_net(pch->chan_net);
+	pch->chan_net = NULL;
+
 	atomic_dec(&channel_count);
 
 	if (!pch->file.dead) {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/net/wireless/brcm80211/brcmsmac/stf.c linux-libre-3.2.84-gnu1/drivers/net/wireless/brcm80211/brcmsmac/stf.c
--- linux-libre-3.2.83-gnu1/drivers/net/wireless/brcm80211/brcmsmac/stf.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/net/wireless/brcm80211/brcmsmac/stf.c	2016-11-19 20:01:45.000000000 -0500
@@ -86,7 +86,7 @@ void
 brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
 			    u16 chanspec)
 {
-	struct tx_power power;
+	struct tx_power power = { };
 	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
 
 	/* Clear previous settings */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/pps/clients/pps_parport.c linux-libre-3.2.84-gnu1/drivers/pps/clients/pps_parport.c
--- linux-libre-3.2.83-gnu1/drivers/pps/clients/pps_parport.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/pps/clients/pps_parport.c	2016-11-19 20:01:45.000000000 -0500
@@ -194,7 +194,7 @@ static void parport_detach(struct parpor
 	struct pps_client_pp *device;
 
 	/* FIXME: oooh, this is ugly! */
-	if (strcmp(pardev->name, KBUILD_MODNAME))
+	if (!pardev || strcmp(pardev->name, KBUILD_MODNAME))
 		/* not our port */
 		return;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/s390/block/dasd.c linux-libre-3.2.84-gnu1/drivers/s390/block/dasd.c
--- linux-libre-3.2.83-gnu1/drivers/s390/block/dasd.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/s390/block/dasd.c	2016-11-19 20:01:45.000000000 -0500
@@ -1593,9 +1593,18 @@ void dasd_int_handler(struct ccw_device
 	unsigned long long now;
 	int expires;
 
+	cqr = (struct dasd_ccw_req *) intparm;
 	if (IS_ERR(irb)) {
 		switch (PTR_ERR(irb)) {
 		case -EIO:
+			if (cqr && cqr->status == DASD_CQR_CLEAR_PENDING) {
+				device = (struct dasd_device *) cqr->startdev;
+				cqr->status = DASD_CQR_CLEARED;
+				dasd_device_clear_timer(device);
+				wake_up(&dasd_flush_wq);
+				dasd_schedule_device_bh(device);
+				return;
+			}
 			break;
 		case -ETIMEDOUT:
 			DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
@@ -1611,7 +1620,6 @@ void dasd_int_handler(struct ccw_device
 	}
 
 	now = get_clock();
-	cqr = (struct dasd_ccw_req *) intparm;
 	/* check for conditions that should be handled immediately */
 	if (!cqr ||
 	    !(scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/scsi/aacraid/commctrl.c linux-libre-3.2.84-gnu1/drivers/scsi/aacraid/commctrl.c
--- linux-libre-3.2.83-gnu1/drivers/scsi/aacraid/commctrl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/scsi/aacraid/commctrl.c	2016-11-19 20:01:45.000000000 -0500
@@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev
 	struct fib *fibptr;
 	struct hw_fib * hw_fib = (struct hw_fib *)0;
 	dma_addr_t hw_fib_pa = (dma_addr_t)0LL;
-	unsigned size;
+	unsigned int size, osize;
 	int retval;
 
 	if (dev->in_reset) {
@@ -87,7 +87,8 @@ static int ioctl_send_fib(struct aac_dev
 	 *	will not overrun the buffer when we copy the memory. Return
 	 *	an error if we would.
 	 */
-	size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr);
+	osize = size = le16_to_cpu(kfib->header.Size) +
+		sizeof(struct aac_fibhdr);
 	if (size < le16_to_cpu(kfib->header.SenderSize))
 		size = le16_to_cpu(kfib->header.SenderSize);
 	if (size > dev->max_fib_size) {
@@ -118,6 +119,14 @@ static int ioctl_send_fib(struct aac_dev
 		goto cleanup;
 	}
 
+	/* Sanity check the second copy */
+	if ((osize != le16_to_cpu(kfib->header.Size) +
+		sizeof(struct aac_fibhdr))
+		|| (size < le16_to_cpu(kfib->header.SenderSize))) {
+		retval = -EINVAL;
+		goto cleanup;
+	}
+
 	if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
 		aac_adapter_interrupt(dev);
 		/*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c linux-libre-3.2.84-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-libre-3.2.83-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c	2016-11-19 20:01:45.000000000 -0500
@@ -1803,7 +1803,8 @@ static int arcmsr_iop_message_xfer(struc
 
 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
 		unsigned char *ver_addr;
-		int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
+		uint32_t user_len;
+		int32_t my_empty_len, wqbuf_firstindex, wqbuf_lastindex;
 		uint8_t *pQbuffer, *ptmpuserbuffer;
 
 		ver_addr = kmalloc(1032, GFP_ATOMIC);
@@ -1820,6 +1821,11 @@ static int arcmsr_iop_message_xfer(struc
 		}
 		ptmpuserbuffer = ver_addr;
 		user_len = pcmdmessagefld->cmdmessage.Length;
+		if (user_len > 1032) {
+			retvalue = ARCMSR_MESSAGE_FAIL;
+			kfree(ver_addr);
+			goto message_out;
+		}
 		memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
 		wqbuf_lastindex = acb->wqbuf_lastindex;
 		wqbuf_firstindex = acb->wqbuf_firstindex;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/scsi/megaraid/megaraid_sas_base.c linux-libre-3.2.84-gnu1/drivers/scsi/megaraid/megaraid_sas_base.c
--- linux-libre-3.2.83-gnu1/drivers/scsi/megaraid/megaraid_sas_base.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/scsi/megaraid/megaraid_sas_base.c	2016-11-19 20:01:45.000000000 -0500
@@ -3508,7 +3508,7 @@ static int megasas_init_fw(struct megasa
 	/* Find first memory bar */
 	bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
 	instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
-	if (pci_request_selected_regions(instance->pdev, instance->bar,
+	if (pci_request_selected_regions(instance->pdev, 1<<instance->bar,
 					 "megasas: LSI")) {
 		printk(KERN_DEBUG "megasas: IO memory region busy!\n");
 		return -EBUSY;
@@ -3661,7 +3661,7 @@ fail_ready_state:
 	iounmap(instance->reg_set);
 
       fail_ioremap:
-	pci_release_selected_regions(instance->pdev, instance->bar);
+	pci_release_selected_regions(instance->pdev, 1<<instance->bar);
 
 	return -EINVAL;
 }
@@ -3682,7 +3682,7 @@ static void megasas_release_mfi(struct m
 
 	iounmap(instance->reg_set);
 
-	pci_release_selected_regions(instance->pdev, instance->bar);
+	pci_release_selected_regions(instance->pdev, 1<<instance->bar);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/scsi/megaraid/megaraid_sas_fusion.c linux-libre-3.2.84-gnu1/drivers/scsi/megaraid/megaraid_sas_fusion.c
--- linux-libre-3.2.83-gnu1/drivers/scsi/megaraid/megaraid_sas_fusion.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/scsi/megaraid/megaraid_sas_fusion.c	2016-11-19 20:01:45.000000000 -0500
@@ -2026,7 +2026,7 @@ megasas_release_fusion(struct megasas_in
 
 	iounmap(instance->reg_set);
 
-	pci_release_selected_regions(instance->pdev, instance->bar);
+	pci_release_selected_regions(instance->pdev, 1<<instance->bar);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/staging/iio/accel/kxsd9.c linux-libre-3.2.84-gnu1/drivers/staging/iio/accel/kxsd9.c
--- linux-libre-3.2.83-gnu1/drivers/staging/iio/accel/kxsd9.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/staging/iio/accel/kxsd9.c	2016-11-19 20:01:45.000000000 -0500
@@ -163,11 +163,13 @@ static int kxsd9_read_raw(struct iio_dev
 		if (ret < 0)
 			goto error_ret;
 		*val = ret;
+		ret = IIO_VAL_INT;
 		break;
 	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
 		ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
 		if (ret < 0)
 			goto error_ret;
+		*val = 0;
 		*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
 		ret = IIO_VAL_INT_PLUS_MICRO;
 		break;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/staging/pohmelfs/Kconfig linux-libre-3.2.84-gnu1/drivers/staging/pohmelfs/Kconfig
--- linux-libre-3.2.83-gnu1/drivers/staging/pohmelfs/Kconfig	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/staging/pohmelfs/Kconfig	2016-11-19 20:01:45.000000000 -0500
@@ -1,5 +1,6 @@
 config POHMELFS
 	tristate "POHMELFS filesystem support"
+	depends on BROKEN
 	depends on NET
 	select CONNECTOR
 	select CRYPTO
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/tty/serial/samsung.c linux-libre-3.2.84-gnu1/drivers/tty/serial/samsung.c
--- linux-libre-3.2.83-gnu1/drivers/tty/serial/samsung.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/tty/serial/samsung.c	2016-11-19 20:01:45.000000000 -0500
@@ -1237,8 +1237,6 @@ int s3c24xx_serial_probe(struct platform
 	dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
 
 	ourport = &s3c24xx_serial_ports[probe_index];
-	probe_index++;
-
 	dbg("%s: initialising port %p...\n", __func__, ourport);
 
 	ret = s3c24xx_serial_init_port(ourport, info, dev);
@@ -1275,6 +1273,8 @@ int __devexit s3c24xx_serial_remove(stru
 		uart_remove_one_port(&s3c24xx_uart_drv, port);
 	}
 
+	probe_index++;
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/tty/vt/keyboard.c linux-libre-3.2.84-gnu1/drivers/tty/vt/keyboard.c
--- linux-libre-3.2.83-gnu1/drivers/tty/vt/keyboard.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/tty/vt/keyboard.c	2016-11-19 20:01:45.000000000 -0500
@@ -386,34 +386,22 @@ static void to_utf8(struct vc_data *vc,
  */
 void compute_shiftstate(void)
 {
-	unsigned int i, j, k, sym, val;
+	unsigned int k, sym, val;
 
 	shift_state = 0;
 	memset(shift_down, 0, sizeof(shift_down));
 
-	for (i = 0; i < ARRAY_SIZE(key_down); i++) {
-
-		if (!key_down[i])
+	for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
+		sym = U(key_maps[0][k]);
+		if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
 			continue;
 
-		k = i * BITS_PER_LONG;
-
-		for (j = 0; j < BITS_PER_LONG; j++, k++) {
-
-			if (!test_bit(k, key_down))
-				continue;
-
-			sym = U(key_maps[0][k]);
-			if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
-				continue;
-
-			val = KVAL(sym);
-			if (val == KVAL(K_CAPSSHIFT))
-				val = KVAL(K_SHIFT);
+		val = KVAL(sym);
+		if (val == KVAL(K_CAPSSHIFT))
+			val = KVAL(K_SHIFT);
 
-			shift_down[val]++;
-			shift_state |= (1 << val);
-		}
+		shift_down[val]++;
+		shift_state |= BIT(val);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/class/cdc-acm.c linux-libre-3.2.84-gnu1/drivers/usb/class/cdc-acm.c
--- linux-libre-3.2.83-gnu1/drivers/usb/class/cdc-acm.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/class/cdc-acm.c	2016-11-19 20:01:45.000000000 -0500
@@ -1156,7 +1156,6 @@ made_compressed_probe:
 	spin_lock_init(&acm->write_lock);
 	spin_lock_init(&acm->read_lock);
 	mutex_init(&acm->mutex);
-	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
 	acm->is_int_ep = usb_endpoint_xfer_int(epread);
 	if (acm->is_int_ep)
 		acm->bInterval = epread->bInterval;
@@ -1205,14 +1204,14 @@ made_compressed_probe:
 		urb->transfer_dma = rb->dma;
 		if (acm->is_int_ep) {
 			usb_fill_int_urb(urb, acm->dev,
-					 acm->rx_endpoint,
+					 usb_rcvintpipe(usb_dev, epread->bEndpointAddress),
 					 rb->base,
 					 acm->readsize,
 					 acm_read_bulk_callback, rb,
 					 acm->bInterval);
 		} else {
 			usb_fill_bulk_urb(urb, acm->dev,
-					  acm->rx_endpoint,
+					  usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
 					  rb->base,
 					  acm->readsize,
 					  acm_read_bulk_callback, rb);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/class/cdc-acm.h linux-libre-3.2.84-gnu1/drivers/usb/class/cdc-acm.h
--- linux-libre-3.2.83-gnu1/drivers/usb/class/cdc-acm.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/class/cdc-acm.h	2016-11-19 20:01:45.000000000 -0500
@@ -95,7 +95,6 @@ struct acm {
 	struct urb *read_urbs[ACM_NR];
 	struct acm_rb read_buffers[ACM_NR];
 	int rx_buflimit;
-	int rx_endpoint;
 	spinlock_t read_lock;
 	int write_used;					/* number of non-empty write buffers */
 	int transmitting;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/core/config.c linux-libre-3.2.84-gnu1/drivers/usb/core/config.c
--- linux-libre-3.2.83-gnu1/drivers/usb/core/config.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/core/config.c	2016-11-19 20:01:45.000000000 -0500
@@ -144,6 +144,31 @@ static void usb_parse_ss_endpoint_compan
 	}
 }
 
+static const unsigned short low_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 8,
+	[USB_ENDPOINT_XFER_ISOC] = 0,
+	[USB_ENDPOINT_XFER_BULK] = 0,
+	[USB_ENDPOINT_XFER_INT] = 8,
+};
+static const unsigned short full_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 64,
+	[USB_ENDPOINT_XFER_ISOC] = 1023,
+	[USB_ENDPOINT_XFER_BULK] = 64,
+	[USB_ENDPOINT_XFER_INT] = 64,
+};
+static const unsigned short high_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 64,
+	[USB_ENDPOINT_XFER_ISOC] = 1024,
+	[USB_ENDPOINT_XFER_BULK] = 512,
+	[USB_ENDPOINT_XFER_INT] = 1024,
+};
+static const unsigned short super_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 512,
+	[USB_ENDPOINT_XFER_ISOC] = 1024,
+	[USB_ENDPOINT_XFER_BULK] = 1024,
+	[USB_ENDPOINT_XFER_INT] = 1024,
+};
+
 static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
     int asnum, struct usb_host_interface *ifp, int num_ep,
     unsigned char *buffer, int size)
@@ -152,6 +177,8 @@ static int usb_parse_endpoint(struct dev
 	struct usb_endpoint_descriptor *d;
 	struct usb_host_endpoint *endpoint;
 	int n, i, j, retval;
+	unsigned int maxp;
+	const unsigned short *maxpacket_maxes;
 
 	d = (struct usb_endpoint_descriptor *) buffer;
 	buffer += d->bLength;
@@ -186,8 +213,10 @@ static int usb_parse_endpoint(struct dev
 	memcpy(&endpoint->desc, d, n);
 	INIT_LIST_HEAD(&endpoint->urb_list);
 
-	/* Fix up bInterval values outside the legal range. Use 32 ms if no
-	 * proper value can be guessed. */
+	/*
+	 * Fix up bInterval values outside the legal range.
+	 * Use 10 or 8 ms if no proper value can be guessed.
+	 */
 	i = 0;		/* i = min, j = max, n = default */
 	j = 255;
 	if (usb_endpoint_xfer_int(d)) {
@@ -195,13 +224,15 @@ static int usb_parse_endpoint(struct dev
 		switch (to_usb_device(ddev)->speed) {
 		case USB_SPEED_SUPER:
 		case USB_SPEED_HIGH:
-			/* Many device manufacturers are using full-speed
+			/*
+			 * Many device manufacturers are using full-speed
 			 * bInterval values in high-speed interrupt endpoint
-			 * descriptors. Try to fix those and fall back to a
-			 * 32 ms default value otherwise. */
+			 * descriptors. Try to fix those and fall back to an
+			 * 8-ms default value otherwise.
+			 */
 			n = fls(d->bInterval*8);
 			if (n == 0)
-				n = 9;	/* 32 ms = 2^(9-1) uframes */
+				n = 7;	/* 8 ms = 2^(7-1) uframes */
 			j = 16;
 
 			/*
@@ -216,10 +247,12 @@ static int usb_parse_endpoint(struct dev
 			}
 			break;
 		default:		/* USB_SPEED_FULL or _LOW */
-			/* For low-speed, 10 ms is the official minimum.
+			/*
+			 * For low-speed, 10 ms is the official minimum.
 			 * But some "overclocked" devices might want faster
-			 * polling so we'll allow it. */
-			n = 32;
+			 * polling so we'll allow it.
+			 */
+			n = 10;
 			break;
 		}
 	} else if (usb_endpoint_xfer_isoc(d)) {
@@ -227,10 +260,10 @@ static int usb_parse_endpoint(struct dev
 		j = 16;
 		switch (to_usb_device(ddev)->speed) {
 		case USB_SPEED_HIGH:
-			n = 9;		/* 32 ms = 2^(9-1) uframes */
+			n = 7;		/* 8 ms = 2^(7-1) uframes */
 			break;
 		default:		/* USB_SPEED_FULL */
-			n = 6;		/* 32 ms = 2^(6-1) frames */
+			n = 4;		/* 8 ms = 2^(4-1) frames */
 			break;
 		}
 	}
@@ -258,6 +291,41 @@ static int usb_parse_endpoint(struct dev
 			endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
 	}
 
+	/* Validate the wMaxPacketSize field */
+	maxp = usb_endpoint_maxp(&endpoint->desc);
+
+	/* Find the highest legal maxpacket size for this endpoint */
+	i = 0;		/* additional transactions per microframe */
+	switch (to_usb_device(ddev)->speed) {
+	case USB_SPEED_LOW:
+		maxpacket_maxes = low_speed_maxpacket_maxes;
+		break;
+	case USB_SPEED_FULL:
+		maxpacket_maxes = full_speed_maxpacket_maxes;
+		break;
+	case USB_SPEED_HIGH:
+		/* Bits 12..11 are allowed only for HS periodic endpoints */
+		if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) {
+			i = maxp & (BIT(12) | BIT(11));
+			maxp &= ~i;
+		}
+		/* fallthrough */
+	default:
+		maxpacket_maxes = high_speed_maxpacket_maxes;
+		break;
+	case USB_SPEED_SUPER:
+		maxpacket_maxes = super_speed_maxpacket_maxes;
+		break;
+	}
+	j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)];
+
+	if (maxp > j) {
+		dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n",
+		    cfgno, inum, asnum, d->bEndpointAddress, maxp, j);
+		maxp = j;
+		endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp);
+	}
+
 	/*
 	 * Some buggy high speed devices have bulk endpoints using
 	 * maxpacket sizes other than 512.  High speed HCDs may not
@@ -265,9 +333,6 @@ static int usb_parse_endpoint(struct dev
 	 */
 	if (to_usb_device(ddev)->speed == USB_SPEED_HIGH
 			&& usb_endpoint_xfer_bulk(d)) {
-		unsigned maxp;
-
-		maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff;
 		if (maxp != 512)
 			dev_warn(ddev, "config %d interface %d altsetting %d "
 				"bulk endpoint 0x%X has invalid maxpacket %d\n",
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/core/devio.c linux-libre-3.2.84-gnu1/drivers/usb/core/devio.c
--- linux-libre-3.2.83-gnu1/drivers/usb/core/devio.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/core/devio.c	2016-11-19 20:01:45.000000000 -0500
@@ -1281,11 +1281,17 @@ static int proc_do_submiturb(struct dev_
 	as->urb->setup_packet = (unsigned char *)dr;
 	as->urb->start_frame = uurb->start_frame;
 	as->urb->number_of_packets = uurb->number_of_packets;
-	if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
-			ps->dev->speed == USB_SPEED_HIGH)
-		as->urb->interval = 1 << min(15, ep->desc.bInterval - 1);
-	else
-		as->urb->interval = ep->desc.bInterval;
+
+	if (ep->desc.bInterval) {
+		if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
+				ps->dev->speed == USB_SPEED_HIGH ||
+				ps->dev->speed >= USB_SPEED_SUPER)
+			as->urb->interval = 1 <<
+					min(15, ep->desc.bInterval - 1);
+		else
+			as->urb->interval = ep->desc.bInterval;
+	}
+
 	as->urb->context = as;
 	as->urb->complete = async_completed;
 	for (totlen = u = 0; u < uurb->number_of_packets; u++) {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/gadget/fsl_qe_udc.c linux-libre-3.2.84-gnu1/drivers/usb/gadget/fsl_qe_udc.c
--- linux-libre-3.2.83-gnu1/drivers/usb/gadget/fsl_qe_udc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/gadget/fsl_qe_udc.c	2016-11-19 20:01:45.000000000 -0500
@@ -1883,11 +1883,8 @@ static int qe_get_frame(struct usb_gadge
 
 	tmp = in_be16(&udc_controller->usb_param->frame_n);
 	if (tmp & 0x8000)
-		tmp = tmp & 0x07ff;
-	else
-		tmp = -EINVAL;
-
-	return (int)tmp;
+		return tmp & 0x07ff;
+	return -EINVAL;
 }
 
 /* Tries to wake up the host connected to this gadget
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/host/xhci-hub.c linux-libre-3.2.84-gnu1/drivers/usb/host/xhci-hub.c
--- linux-libre-3.2.83-gnu1/drivers/usb/host/xhci-hub.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/host/xhci-hub.c	2016-11-19 20:01:45.000000000 -0500
@@ -278,6 +278,9 @@ static int xhci_stop_device(struct xhci_
 
 	ret = 0;
 	virt_dev = xhci->devs[slot_id];
+	if (!virt_dev)
+		return -ENODEV;
+
 	cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
 	if (!cmd) {
 		xhci_dbg(xhci, "Couldn't allocate command structure.\n");
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/host/xhci-pci.c linux-libre-3.2.84-gnu1/drivers/usb/host/xhci-pci.c
--- linux-libre-3.2.83-gnu1/drivers/usb/host/xhci-pci.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/host/xhci-pci.c	2016-11-19 20:01:45.000000000 -0500
@@ -252,12 +252,13 @@ static void xhci_pci_remove(struct pci_d
 		usb_remove_hcd(xhci->shared_hcd);
 		usb_put_hcd(xhci->shared_hcd);
 	}
-	usb_hcd_pci_remove(dev);
 
 	/* Workaround for spurious wakeups at shutdown with HSW */
 	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
 		pci_set_power_state(dev, PCI_D3hot);
 
+	usb_hcd_pci_remove(dev);
+
 	kfree(xhci);
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/renesas_usbhs/fifo.c linux-libre-3.2.84-gnu1/drivers/usb/renesas_usbhs/fifo.c
--- linux-libre-3.2.83-gnu1/drivers/usb/renesas_usbhs/fifo.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/renesas_usbhs/fifo.c	2016-11-19 20:01:45.000000000 -0500
@@ -760,15 +760,22 @@ static void usbhsf_dma_prepare_tasklet(u
 {
 	struct usbhs_pkt *pkt = (struct usbhs_pkt *)data;
 	struct usbhs_pipe *pipe = pkt->pipe;
-	struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe);
+	struct usbhs_fifo *fifo;
 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
 	struct scatterlist sg;
 	struct dma_async_tx_descriptor *desc;
-	struct dma_chan *chan = usbhsf_dma_chan_get(fifo, pkt);
+	struct dma_chan *chan;
 	struct device *dev = usbhs_priv_to_dev(priv);
 	enum dma_data_direction dir;
 	dma_cookie_t cookie;
+	unsigned long flags;
+
+	usbhs_lock(priv, flags);
+	fifo = usbhs_pipe_to_fifo(pipe);
+	if (!fifo)
+		goto xfer_work_end;
 
+	chan = usbhsf_dma_chan_get(fifo, pkt);
 	dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 
 	sg_init_table(&sg, 1);
@@ -781,7 +788,7 @@ static void usbhsf_dma_prepare_tasklet(u
 						  DMA_PREP_INTERRUPT |
 						  DMA_CTRL_ACK);
 	if (!desc)
-		return;
+		goto xfer_work_end;
 
 	desc->callback		= usbhsf_dma_complete;
 	desc->callback_param	= pipe;
@@ -789,7 +796,7 @@ static void usbhsf_dma_prepare_tasklet(u
 	cookie = desc->tx_submit(desc);
 	if (cookie < 0) {
 		dev_err(dev, "Failed to submit dma descriptor\n");
-		return;
+		goto xfer_work_end;
 	}
 
 	dev_dbg(dev, "  %s %d (%d/ %d)\n",
@@ -797,6 +804,9 @@ static void usbhsf_dma_prepare_tasklet(u
 
 	usbhsf_dma_start(pipe, fifo);
 	dma_async_issue_pending(chan);
+
+xfer_work_end:
+	usbhs_unlock(priv, flags);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/renesas_usbhs/mod_gadget.c linux-libre-3.2.84-gnu1/drivers/usb/renesas_usbhs/mod_gadget.c
--- linux-libre-3.2.83-gnu1/drivers/usb/renesas_usbhs/mod_gadget.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/renesas_usbhs/mod_gadget.c	2016-11-19 20:01:45.000000000 -0500
@@ -472,6 +472,9 @@ static int usbhsg_ep_enable(struct usb_e
 	struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 	struct usbhs_pipe *pipe;
 	int ret = -EIO;
+	unsigned long flags;
+
+	usbhs_lock(priv, flags);
 
 	/*
 	 * if it already have pipe,
@@ -480,7 +483,8 @@ static int usbhsg_ep_enable(struct usb_e
 	if (uep->pipe) {
 		usbhs_pipe_clear(uep->pipe);
 		usbhs_pipe_sequence_data0(uep->pipe);
-		return 0;
+		ret = 0;
+		goto usbhsg_ep_enable_end;
 	}
 
 	pipe = usbhs_pipe_malloc(priv,
@@ -508,6 +512,9 @@ static int usbhsg_ep_enable(struct usb_e
 		ret = 0;
 	}
 
+usbhsg_ep_enable_end:
+	usbhs_unlock(priv, flags);
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/serial/ftdi_sio.c linux-libre-3.2.84-gnu1/drivers/usb/serial/ftdi_sio.c
--- linux-libre-3.2.83-gnu1/drivers/usb/serial/ftdi_sio.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/serial/ftdi_sio.c	2016-11-19 20:01:45.000000000 -0500
@@ -672,6 +672,8 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_PALMSENS_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IVIUM_XSTAT_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -1030,6 +1032,7 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
+	{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/serial/ftdi_sio_ids.h linux-libre-3.2.84-gnu1/drivers/usb/serial/ftdi_sio_ids.h
--- linux-libre-3.2.83-gnu1/drivers/usb/serial/ftdi_sio_ids.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/serial/ftdi_sio_ids.h	2016-11-19 20:01:45.000000000 -0500
@@ -406,6 +406,12 @@
 #define FTDI_4N_GALAXY_DE_3_PID	0xF3C2
 
 /*
+ * Ivium Technologies product IDs
+ */
+#define FTDI_PALMSENS_PID	0xf440
+#define FTDI_IVIUM_XSTAT_PID	0xf441
+
+/*
  * Linx Technologies product ids
  */
 #define LINX_SDMUSBQSS_PID	0xF448	/* Linx SDM-USB-QS-S */
@@ -667,6 +673,12 @@
 #define INTREPID_NEOVI_PID	0x0701
 
 /*
+ * WICED USB UART
+ */
+#define WICED_VID		0x0A5C
+#define WICED_USB20706V2_PID	0x6422
+
+/*
  * Definitions for ID TECH (www.idt-net.com) devices
  */
 #define IDTECH_VID		0x0ACD	/* ID TECH Vendor ID */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/serial/mos7720.c linux-libre-3.2.84-gnu1/drivers/usb/serial/mos7720.c
--- linux-libre-3.2.83-gnu1/drivers/usb/serial/mos7720.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/serial/mos7720.c	2016-11-19 20:01:45.000000000 -0500
@@ -1320,7 +1320,7 @@ static int mos7720_write(struct tty_stru
 
 	if (urb->transfer_buffer == NULL) {
 		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
-					       GFP_KERNEL);
+					       GFP_ATOMIC);
 		if (urb->transfer_buffer == NULL) {
 			dev_err(&port->dev, "%s no more kernel memory...\n",
 				__func__);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/serial/mos7840.c linux-libre-3.2.84-gnu1/drivers/usb/serial/mos7840.c
--- linux-libre-3.2.83-gnu1/drivers/usb/serial/mos7840.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/serial/mos7840.c	2016-11-19 20:01:45.000000000 -0500
@@ -1524,8 +1524,8 @@ static int mos7840_write(struct tty_stru
 	}
 
 	if (urb->transfer_buffer == NULL) {
-		urb->transfer_buffer =
-		    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+					       GFP_ATOMIC);
 
 		if (urb->transfer_buffer == NULL) {
 			dev_err(&port->dev, "%s no more kernel memory...\n",
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/usb/serial/option.c linux-libre-3.2.84-gnu1/drivers/usb/serial/option.c
--- linux-libre-3.2.83-gnu1/drivers/usb/serial/option.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/usb/serial/option.c	2016-11-19 20:01:45.000000000 -0500
@@ -273,6 +273,7 @@ static void option_instat_callback(struc
 #define TELIT_PRODUCT_LE922_USBCFG3		0x1043
 #define TELIT_PRODUCT_LE920			0x1200
 #define TELIT_PRODUCT_LE910			0x1201
+#define TELIT_PRODUCT_LE910_USBCFG4		0x1206
 
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID				0x19d2
@@ -511,6 +512,12 @@ static void option_instat_callback(struc
 #define VIATELECOM_VENDOR_ID			0x15eb
 #define VIATELECOM_PRODUCT_CDS7			0x0001
 
+/* WeTelecom products */
+#define WETELECOM_VENDOR_ID			0x22de
+#define WETELECOM_PRODUCT_WMD200		0x6801
+#define WETELECOM_PRODUCT_6802			0x6802
+#define WETELECOM_PRODUCT_WMD300		0x6803
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
 		OPTION_BLACKLIST_NONE = 0,
@@ -1193,6 +1200,8 @@ static const struct usb_device_id option
 		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
 		.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
 		.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
@@ -1942,8 +1951,12 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
 	{ USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
 	{ USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD200, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) },
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/virtio/virtio_balloon.c linux-libre-3.2.84-gnu1/drivers/virtio/virtio_balloon.c
--- linux-libre-3.2.83-gnu1/drivers/virtio/virtio_balloon.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/virtio/virtio_balloon.c	2016-11-19 20:01:45.000000000 -0500
@@ -142,6 +142,8 @@ static void leak_balloon(struct virtio_b
 	/* We can only do one array worth at a time. */
 	num = min(num, ARRAY_SIZE(vb->pfns));
 
+	/* We can't release more pages than taken */
+	num = min(num, (size_t)vb->num_pages);
 	for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
 		page = list_first_entry(&vb->pages, struct page, lru);
 		list_del(&page->lru);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/drivers/xen/xenfs/xenbus.c linux-libre-3.2.84-gnu1/drivers/xen/xenfs/xenbus.c
--- linux-libre-3.2.83-gnu1/drivers/xen/xenfs/xenbus.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/drivers/xen/xenfs/xenbus.c	2016-11-19 20:01:45.000000000 -0500
@@ -310,11 +310,18 @@ static int xenbus_write_transaction(unsi
 			rc = -ENOMEM;
 			goto out;
 		}
+	} else if (msg_type == XS_TRANSACTION_END) {
+		list_for_each_entry(trans, &u->transactions, list)
+			if (trans->handle.id == u->u.msg.tx_id)
+				break;
+		if (&trans->list == &u->transactions)
+			return -ESRCH;
 	}
 
 	reply = xenbus_dev_request_and_reply(&u->u.msg);
 	if (IS_ERR(reply)) {
-		kfree(trans);
+		if (msg_type == XS_TRANSACTION_START)
+			kfree(trans);
 		rc = PTR_ERR(reply);
 		goto out;
 	}
@@ -324,12 +331,7 @@ static int xenbus_write_transaction(unsi
 
 		list_add(&trans->list, &u->transactions);
 	} else if (msg_type == XS_TRANSACTION_END) {
-		list_for_each_entry(trans, &u->transactions, list)
-			if (trans->handle.id == u->u.msg.tx_id)
-				break;
-		BUG_ON(&trans->list == &u->transactions);
 		list_del(&trans->list);
-
 		kfree(trans);
 	}
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/9p/acl.c linux-libre-3.2.84-gnu1/fs/9p/acl.c
--- linux-libre-3.2.83-gnu1/fs/9p/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/9p/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -319,32 +319,26 @@ static int v9fs_xattr_set_acl(struct den
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			retval = posix_acl_equiv_mode(acl, &mode);
-			if (retval < 0)
+			struct iattr iattr;
+
+			retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
+			if (retval)
 				goto err_out;
-			else {
-				struct iattr iattr;
-				if (retval == 0) {
-					/*
-					 * ACL can be represented
-					 * by the mode bits. So don't
-					 * update ACL.
-					 */
-					acl = NULL;
-					value = NULL;
-					size = 0;
-				}
-				/* Updte the mode bits */
-				iattr.ia_mode = ((mode & S_IALLUGO) |
-						 (inode->i_mode & ~S_IALLUGO));
-				iattr.ia_valid = ATTR_MODE;
-				/* FIXME should we update ctime ?
-				 * What is the following setxattr update the
-				 * mode ?
+			if (!acl) {
+				/*
+				 * ACL can be represented
+				 * by the mode bits. So don't
+				 * update ACL.
 				 */
-				v9fs_vfs_setattr_dotl(dentry, &iattr);
+				value = NULL;
+				size = 0;
 			}
+			iattr.ia_valid = ATTR_MODE;
+			/* FIXME should we update ctime ?
+			 * What is the following setxattr update the
+			 * mode ?
+			 */
+			v9fs_vfs_setattr_dotl(dentry, &iattr);
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/9p/vfs_inode.c linux-libre-3.2.84-gnu1/fs/9p/vfs_inode.c
--- linux-libre-3.2.83-gnu1/fs/9p/vfs_inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/9p/vfs_inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1068,7 +1068,7 @@ static int v9fs_vfs_setattr(struct dentr
 	struct p9_wstat wstat;
 
 	P9_DPRINTK(P9_DEBUG_VFS, "\n");
-	retval = inode_change_ok(dentry->d_inode, iattr);
+	retval = setattr_prepare(dentry, iattr);
 	if (retval)
 		return retval;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/9p/vfs_inode_dotl.c linux-libre-3.2.84-gnu1/fs/9p/vfs_inode_dotl.c
--- linux-libre-3.2.83-gnu1/fs/9p/vfs_inode_dotl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/9p/vfs_inode_dotl.c	2016-11-19 20:01:45.000000000 -0500
@@ -538,7 +538,7 @@ int v9fs_vfs_setattr_dotl(struct dentry
 
 	P9_DPRINTK(P9_DEBUG_VFS, "\n");
 
-	retval = inode_change_ok(dentry->d_inode, iattr);
+	retval = setattr_prepare(dentry, iattr);
 	if (retval)
 		return retval;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/adfs/inode.c linux-libre-3.2.84-gnu1/fs/adfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/adfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/adfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -298,7 +298,7 @@ adfs_notify_change(struct dentry *dentry
 	unsigned int ia_valid = attr->ia_valid;
 	int error;
 	
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 
 	/*
 	 * we can't change the UID or GID of any file -
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/affs/inode.c linux-libre-3.2.84-gnu1/fs/affs/inode.c
--- linux-libre-3.2.83-gnu1/fs/affs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/affs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -222,7 +222,7 @@ affs_notify_change(struct dentry *dentry
 
 	pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
 
-	error = inode_change_ok(inode,attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		goto out;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/attr.c linux-libre-3.2.84-gnu1/fs/attr.c
--- linux-libre-3.2.83-gnu1/fs/attr.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/attr.c	2016-11-19 20:01:45.000000000 -0500
@@ -16,19 +16,22 @@
 #include <linux/evm.h>
 
 /**
- * inode_change_ok - check if attribute changes to an inode are allowed
- * @inode:	inode to check
+ * setattr_prepare - check if attribute changes to a dentry are allowed
+ * @dentry:	dentry to check
  * @attr:	attributes to change
  *
  * Check if we are allowed to change the attributes contained in @attr
- * in the given inode.  This includes the normal unix access permission
- * checks, as well as checks for rlimits and others.
+ * in the given dentry.  This includes the normal unix access permission
+ * checks, as well as checks for rlimits and others. The function also clears
+ * SGID bit from mode if user is not allowed to set it. Also file capabilities
+ * and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
  *
  * Should be called as the first thing in ->setattr implementations,
  * possibly after taking additional locks.
  */
-int inode_change_ok(const struct inode *inode, struct iattr *attr)
+int setattr_prepare(struct dentry *dentry, struct iattr *attr)
 {
+	struct inode *inode = dentry->d_inode;
 	unsigned int ia_valid = attr->ia_valid;
 
 	/*
@@ -43,7 +46,7 @@ int inode_change_ok(const struct inode *
 
 	/* If force is set do it anyway. */
 	if (ia_valid & ATTR_FORCE)
-		return 0;
+		goto kill_priv;
 
 	/* Make sure a caller can chown. */
 	if ((ia_valid & ATTR_UID) &&
@@ -74,9 +77,19 @@ int inode_change_ok(const struct inode *
 			return -EPERM;
 	}
 
+kill_priv:
+	/* User has permission for the change */
+	if (ia_valid & ATTR_KILL_PRIV) {
+		int error;
+
+		error = security_inode_killpriv(dentry);
+		if (error)
+			return error;
+	}
+
 	return 0;
 }
-EXPORT_SYMBOL(inode_change_ok);
+EXPORT_SYMBOL(setattr_prepare);
 
 /**
  * inode_newsize_ok - may this inode be truncated to a given size
@@ -196,13 +209,11 @@ int notify_change(struct dentry * dentry
 	if (!(ia_valid & ATTR_MTIME_SET))
 		attr->ia_mtime = now;
 	if (ia_valid & ATTR_KILL_PRIV) {
-		attr->ia_valid &= ~ATTR_KILL_PRIV;
-		ia_valid &= ~ATTR_KILL_PRIV;
 		error = security_inode_need_killpriv(dentry);
-		if (error > 0)
-			error = security_inode_killpriv(dentry);
-		if (error)
+		if (error < 0)
 			return error;
+		if (error == 0)
+			ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/btrfs/acl.c linux-libre-3.2.84-gnu1/fs/btrfs/acl.c
--- linux-libre-3.2.83-gnu1/fs/btrfs/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/btrfs/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -118,8 +118,8 @@ static int btrfs_set_acl(struct btrfs_tr
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			ret = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (ret < 0)
+			ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (ret)
 				return ret;
 		}
 		ret = 0;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/btrfs/inode.c linux-libre-3.2.84-gnu1/fs/btrfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/btrfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/btrfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -3533,7 +3533,7 @@ static int btrfs_setattr(struct dentry *
 	if (btrfs_root_readonly(root))
 		return -EROFS;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/btrfs/ioctl.c linux-libre-3.2.84-gnu1/fs/btrfs/ioctl.c
--- linux-libre-3.2.83-gnu1/fs/btrfs/ioctl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/btrfs/ioctl.c	2016-11-19 20:01:45.000000000 -0500
@@ -1302,6 +1302,9 @@ static noinline int btrfs_ioctl_snap_cre
 	int namelen;
 	int ret = 0;
 
+	if (!S_ISDIR(file->f_dentry->d_inode->i_mode))
+		return -ENOTDIR;
+
 	if (root->fs_info->sb->s_flags & MS_RDONLY)
 		return -EROFS;
 
@@ -1350,6 +1353,9 @@ static noinline int btrfs_ioctl_snap_cre
 	struct btrfs_ioctl_vol_args *vol_args;
 	int ret;
 
+	if (!S_ISDIR(file->f_dentry->d_inode->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -1372,6 +1378,9 @@ static noinline int btrfs_ioctl_snap_cre
 	u64 *ptr = NULL;
 	bool readonly = false;
 
+	if (!S_ISDIR(file->f_dentry->d_inode->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -1848,6 +1857,9 @@ static noinline int btrfs_ioctl_snap_des
 	int ret;
 	int err = 0;
 
+	if (!S_ISDIR(dir->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ceph/file.c linux-libre-3.2.84-gnu1/fs/ceph/file.c
--- linux-libre-3.2.83-gnu1/fs/ceph/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ceph/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -793,17 +793,15 @@ out:
 static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
 {
 	struct inode *inode = file->f_mapping->host;
-	int ret;
+	loff_t ret;
 
 	mutex_lock(&inode->i_mutex);
 	__ceph_do_pending_vmtruncate(inode);
 
 	if (origin == SEEK_END || origin == SEEK_DATA || origin == SEEK_HOLE) {
 		ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
-		if (ret < 0) {
-			offset = ret;
+		if (ret < 0)
 			goto out;
-		}
 	}
 
 	switch (origin) {
@@ -818,7 +816,7 @@ static loff_t ceph_llseek(struct file *f
 		 * write() or lseek() might have altered it
 		 */
 		if (offset == 0) {
-			offset = file->f_pos;
+			ret = file->f_pos;
 			goto out;
 		}
 		offset += file->f_pos;
@@ -839,7 +837,7 @@ static loff_t ceph_llseek(struct file *f
 	}
 
 	if (offset < 0 || offset > inode->i_sb->s_maxbytes) {
-		offset = -EINVAL;
+		ret = -EINVAL;
 		goto out;
 	}
 
@@ -848,10 +846,11 @@ static loff_t ceph_llseek(struct file *f
 		file->f_pos = offset;
 		file->f_version = 0;
 	}
+	ret = offset;
 
 out:
 	mutex_unlock(&inode->i_mutex);
-	return offset;
+	return ret;
 }
 
 const struct file_operations ceph_file_fops = {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ceph/inode.c linux-libre-3.2.84-gnu1/fs/ceph/inode.c
--- linux-libre-3.2.83-gnu1/fs/ceph/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ceph/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1541,7 +1541,7 @@ int ceph_setattr(struct dentry *dentry,
 
 	__ceph_do_pending_vmtruncate(inode);
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err != 0)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/cifs/inode.c linux-libre-3.2.84-gnu1/fs/cifs/inode.c
--- linux-libre-3.2.83-gnu1/fs/cifs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/cifs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1948,7 +1948,7 @@ cifs_setattr_unix(struct dentry *direntr
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
 		attrs->ia_valid |= ATTR_FORCE;
 
-	rc = inode_change_ok(inode, attrs);
+	rc = setattr_prepare(direntry, attrs);
 	if (rc < 0)
 		goto out;
 
@@ -2089,7 +2089,7 @@ cifs_setattr_nounix(struct dentry *diren
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
 		attrs->ia_valid |= ATTR_FORCE;
 
-	rc = inode_change_ok(inode, attrs);
+	rc = setattr_prepare(direntry, attrs);
 	if (rc < 0) {
 		FreeXid(xid);
 		return rc;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ecryptfs/inode.c linux-libre-3.2.84-gnu1/fs/ecryptfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/ecryptfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ecryptfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1026,7 +1026,7 @@ static int ecryptfs_setattr(struct dentr
 	}
 	mutex_unlock(&crypt_stat->cs_mutex);
 
-	rc = inode_change_ok(inode, ia);
+	rc = setattr_prepare(dentry, ia);
 	if (rc)
 		goto out;
 	if (ia->ia_valid & ATTR_SIZE) {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/exofs/inode.c linux-libre-3.2.84-gnu1/fs/exofs/inode.c
--- linux-libre-3.2.83-gnu1/fs/exofs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/exofs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1018,7 +1018,7 @@ int exofs_setattr(struct dentry *dentry,
 	if (unlikely(error))
 		return error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (unlikely(error))
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext2/acl.c linux-libre-3.2.84-gnu1/fs/ext2/acl.c
--- linux-libre-3.2.83-gnu1/fs/ext2/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext2/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -194,15 +194,11 @@ ext2_set_acl(struct inode *inode, int ty
 		case ACL_TYPE_ACCESS:
 			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
 			if (acl) {
-				error = posix_acl_equiv_mode(acl, &inode->i_mode);
-				if (error < 0)
+				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+				if (error)
 					return error;
-				else {
-					inode->i_ctime = CURRENT_TIME_SEC;
-					mark_inode_dirty(inode);
-					if (error == 0)
-						acl = NULL;
-				}
+				inode->i_ctime = CURRENT_TIME_SEC;
+				mark_inode_dirty(inode);
 			}
 			break;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext2/inode.c linux-libre-3.2.84-gnu1/fs/ext2/inode.c
--- linux-libre-3.2.83-gnu1/fs/ext2/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext2/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1530,7 +1530,7 @@ int ext2_setattr(struct dentry *dentry,
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext3/acl.c linux-libre-3.2.84-gnu1/fs/ext3/acl.c
--- linux-libre-3.2.83-gnu1/fs/ext3/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext3/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -199,15 +199,11 @@ ext3_set_acl(handle_t *handle, struct in
 		case ACL_TYPE_ACCESS:
 			name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
 			if (acl) {
-				error = posix_acl_equiv_mode(acl, &inode->i_mode);
-				if (error < 0)
+				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+				if (error)
 					return error;
-				else {
-					inode->i_ctime = CURRENT_TIME_SEC;
-					ext3_mark_inode_dirty(handle, inode);
-					if (error == 0)
-						acl = NULL;
-				}
+				inode->i_ctime = CURRENT_TIME_SEC;
+				ext3_mark_inode_dirty(handle, inode);
 			}
 			break;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext3/inode.c linux-libre-3.2.84-gnu1/fs/ext3/inode.c
--- linux-libre-3.2.83-gnu1/fs/ext3/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext3/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -223,8 +223,12 @@ void ext3_evict_inode (struct inode *ino
 	 *
 	 * Note that directories do not have this problem because they don't
 	 * use page cache.
+	 *
+	 * The s_journal check handles the case when ext3_get_journal() fails
+	 * and puts the journal inode.
 	 */
 	if (inode->i_nlink && ext3_should_journal_data(inode) &&
+	    EXT3_SB(inode->i_sb)->s_journal &&
 	    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
 		tid_t commit_tid = atomic_read(&ei->i_datasync_tid);
 		journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
@@ -3271,7 +3275,7 @@ int ext3_setattr(struct dentry *dentry,
 	int error, rc = 0;
 	const unsigned int ia_valid = attr->ia_valid;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext4/acl.c linux-libre-3.2.84-gnu1/fs/ext4/acl.c
--- linux-libre-3.2.83-gnu1/fs/ext4/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext4/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -198,15 +198,11 @@ ext4_set_acl(handle_t *handle, struct in
 	case ACL_TYPE_ACCESS:
 		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
-			else {
-				inode->i_ctime = ext4_current_time(inode);
-				ext4_mark_inode_dirty(handle, inode);
-				if (error == 0)
-					acl = NULL;
-			}
+			inode->i_ctime = ext4_current_time(inode);
+			ext4_mark_inode_dirty(handle, inode);
 		}
 		break;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext4/extents.c linux-libre-3.2.84-gnu1/fs/ext4/extents.c
--- linux-libre-3.2.83-gnu1/fs/ext4/extents.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext4/extents.c	2016-11-19 20:01:45.000000000 -0500
@@ -319,9 +319,13 @@ static int ext4_valid_extent(struct inod
 	ext4_fsblk_t block = ext4_ext_pblock(ext);
 	int len = ext4_ext_get_actual_len(ext);
 	ext4_lblk_t lblock = le32_to_cpu(ext->ee_block);
-	ext4_lblk_t last = lblock + len - 1;
 
-	if (len == 0 || lblock > last)
+	/*
+	 * We allow neither:
+	 *  - zero length
+	 *  - overflow/wrap-around
+	 */
+	if (lblock + len <= lblock)
 		return 0;
 	return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
 }
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext4/inode.c linux-libre-3.2.84-gnu1/fs/ext4/inode.c
--- linux-libre-3.2.83-gnu1/fs/ext4/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext4/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -142,9 +142,9 @@ void ext4_evict_inode(struct inode *inod
 		 * Note that directories do not have this problem because they
 		 * don't use page cache.
 		 */
-		if (ext4_should_journal_data(inode) &&
-		    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
-		    inode->i_ino != EXT4_JOURNAL_INO) {
+		if (inode->i_ino != EXT4_JOURNAL_INO &&
+		    ext4_should_journal_data(inode) &&
+		    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
 			journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
 			tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;
 
@@ -4291,7 +4291,7 @@ int ext4_setattr(struct dentry *dentry,
 	int orphan = 0;
 	const unsigned int ia_valid = attr->ia_valid;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext4/mballoc.c linux-libre-3.2.84-gnu1/fs/ext4/mballoc.c
--- linux-libre-3.2.83-gnu1/fs/ext4/mballoc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext4/mballoc.c	2016-11-19 20:01:45.000000000 -0500
@@ -2824,7 +2824,7 @@ ext4_mb_mark_diskspace_used(struct ext4_
 		ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
 			   "fs metadata\n", block, block+len);
 		/* File system mounted not to panic on error
-		 * Fix the bitmap and repeat the block allocation
+		 * Fix the bitmap and return EIO
 		 * We leak some of the blocks here.
 		 */
 		ext4_lock_group(sb, ac->ac_b_ex.fe_group);
@@ -2833,7 +2833,7 @@ ext4_mb_mark_diskspace_used(struct ext4_
 		ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
 		err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
 		if (!err)
-			err = -EAGAIN;
+			err = -EIO;
 		goto out_err;
 	}
 
@@ -4401,18 +4401,7 @@ repeat:
 	}
 	if (likely(ac->ac_status == AC_STATUS_FOUND)) {
 		*errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
-		if (*errp == -EAGAIN) {
-			/*
-			 * drop the reference that we took
-			 * in ext4_mb_use_best_found
-			 */
-			ext4_mb_release_context(ac);
-			ac->ac_b_ex.fe_group = 0;
-			ac->ac_b_ex.fe_start = 0;
-			ac->ac_b_ex.fe_len = 0;
-			ac->ac_status = AC_STATUS_CONTINUE;
-			goto repeat;
-		} else if (*errp)
+		if (*errp)
 		errout:
 			ext4_discard_allocated_blocks(ac);
 		else {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ext4/super.c linux-libre-3.2.84-gnu1/fs/ext4/super.c
--- linux-libre-3.2.83-gnu1/fs/ext4/super.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ext4/super.c	2016-11-19 20:01:45.000000000 -0500
@@ -2097,6 +2097,7 @@ int ext4_group_desc_csum_verify(struct e
 
 /* Called at mount-time, super-block is locked */
 static int ext4_check_descriptors(struct super_block *sb,
+				  ext4_fsblk_t sb_block,
 				  ext4_group_t *first_not_zeroed)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -2127,6 +2128,11 @@ static int ext4_check_descriptors(struct
 			grp = i;
 
 		block_bitmap = ext4_block_bitmap(sb, gdp);
+		if (block_bitmap == sb_block) {
+			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+				 "Block bitmap for group %u overlaps "
+				 "superblock", i);
+		}
 		if (block_bitmap < first_block || block_bitmap > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 			       "Block bitmap for group %u not in group "
@@ -2134,6 +2140,11 @@ static int ext4_check_descriptors(struct
 			return 0;
 		}
 		inode_bitmap = ext4_inode_bitmap(sb, gdp);
+		if (inode_bitmap == sb_block) {
+			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+				 "Inode bitmap for group %u overlaps "
+				 "superblock", i);
+		}
 		if (inode_bitmap < first_block || inode_bitmap > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 			       "Inode bitmap for group %u not in group "
@@ -2141,6 +2152,11 @@ static int ext4_check_descriptors(struct
 			return 0;
 		}
 		inode_table = ext4_inode_table(sb, gdp);
+		if (inode_table == sb_block) {
+			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+				 "Inode table for group %u overlaps "
+				 "superblock", i);
+		}
 		if (inode_table < first_block ||
 		    inode_table + sbi->s_itb_per_group - 1 > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -2246,6 +2262,16 @@ static void ext4_orphan_cleanup(struct s
 	while (es->s_last_orphan) {
 		struct inode *inode;
 
+		/*
+		 * We may have encountered an error during cleanup; if
+		 * so, skip the rest.
+		 */
+		if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
+			jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
+			es->s_last_orphan = 0;
+			break;
+		}
+
 		inode = ext4_orphan_get(sb, le32_to_cpu(es->s_last_orphan));
 		if (IS_ERR(inode)) {
 			es->s_last_orphan = 0;
@@ -3429,6 +3455,13 @@ static int ext4_fill_super(struct super_
 		goto failed_mount;
 	}
 
+	if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) {
+		ext4_msg(sb, KERN_ERR,
+			 "Number of reserved GDT blocks insanely large: %d",
+			 le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks));
+		goto failed_mount;
+	}
+
 	if (sb->s_blocksize != blocksize) {
 		/* Validate the filesystem blocksize */
 		if (!sb_set_blocksize(sb, blocksize)) {
@@ -3657,7 +3690,7 @@ static int ext4_fill_super(struct super_
 			goto failed_mount2;
 		}
 	}
-	if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
+	if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
 		ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
 		goto failed_mount2;
 	}
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/fat/file.c linux-libre-3.2.84-gnu1/fs/fat/file.c
--- linux-libre-3.2.83-gnu1/fs/fat/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/fat/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -382,7 +382,7 @@ int fat_setattr(struct dentry *dentry, s
 			attr->ia_valid &= ~TIMES_SET_FLAGS;
 	}
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	attr->ia_valid = ia_valid;
 	if (error) {
 		if (sbi->options.quiet)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/fuse/dir.c linux-libre-3.2.84-gnu1/fs/fuse/dir.c
--- linux-libre-3.2.83-gnu1/fs/fuse/dir.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/fuse/dir.c	2016-11-19 20:01:45.000000000 -0500
@@ -1298,7 +1298,7 @@ static int fuse_do_setattr(struct dentry
 	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
 		attr->ia_valid |= ATTR_FORCE;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(entry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/generic_acl.c linux-libre-3.2.84-gnu1/fs/generic_acl.c
--- linux-libre-3.2.83-gnu1/fs/generic_acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/generic_acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -86,16 +86,17 @@ generic_acl_set(struct dentry *dentry, c
 		if (error)
 			goto failed;
 		switch (type) {
-		case ACL_TYPE_ACCESS:
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+		case ACL_TYPE_ACCESS: {
+			struct posix_acl *saved_acl = acl;
+
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (acl == NULL)
+				posix_acl_release(saved_acl);
+			if (error)
 				goto failed;
 			inode->i_ctime = CURRENT_TIME;
-			if (error == 0) {
-				posix_acl_release(acl);
-				acl = NULL;
-			}
 			break;
+		}
 		case ACL_TYPE_DEFAULT:
 			if (!S_ISDIR(inode->i_mode)) {
 				error = -EINVAL;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/gfs2/acl.c linux-libre-3.2.84-gnu1/fs/gfs2/acl.c
--- linux-libre-3.2.83-gnu1/fs/gfs2/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/gfs2/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -277,16 +277,14 @@ static int gfs2_xattr_system_set(struct
 		goto out_release;
 
 	if (type == ACL_TYPE_ACCESS) {
-		umode_t mode = inode->i_mode;
-		error = posix_acl_equiv_mode(acl, &mode);
-
-		if (error <= 0) {
-			posix_acl_release(acl);
-			acl = NULL;
+		struct posix_acl *saved_acl = acl;
+		umode_t mode;
 
-			if (error < 0)
-				return error;
-		}
+		error = posix_acl_update_mode(inode, &mode, &acl);
+		if (error || acl == NULL)
+			posix_acl_release(saved_acl);
+		if (error)
+			return error;
 
 		error = gfs2_set_mode(inode, mode);
 		if (error)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/gfs2/inode.c linux-libre-3.2.84-gnu1/fs/gfs2/inode.c
--- linux-libre-3.2.83-gnu1/fs/gfs2/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/gfs2/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -1646,7 +1646,7 @@ static int gfs2_setattr(struct dentry *d
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto out;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		goto out;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/hfs/inode.c linux-libre-3.2.84-gnu1/fs/hfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/hfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/hfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -588,7 +588,7 @@ int hfs_inode_setattr(struct dentry *den
 	struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
 	int error;
 
-	error = inode_change_ok(inode, attr); /* basic permission checks */
+	error = setattr_prepare(dentry, attr); /* basic permission checks */
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/hfsplus/inode.c linux-libre-3.2.84-gnu1/fs/hfsplus/inode.c
--- linux-libre-3.2.83-gnu1/fs/hfsplus/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/hfsplus/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -292,7 +292,7 @@ static int hfsplus_setattr(struct dentry
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/hostfs/hostfs_kern.c linux-libre-3.2.84-gnu1/fs/hostfs/hostfs_kern.c
--- linux-libre-3.2.83-gnu1/fs/hostfs/hostfs_kern.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/hostfs/hostfs_kern.c	2016-11-19 20:01:45.000000000 -0500
@@ -792,7 +792,7 @@ int hostfs_setattr(struct dentry *dentry
 
 	int fd = HOSTFS_I(inode)->fd;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
@@ -955,10 +955,11 @@ static int hostfs_fill_sb_common(struct
 
 	if (S_ISLNK(root_inode->i_mode)) {
 		char *name = follow_link(host_root_path);
-		if (IS_ERR(name))
+		if (IS_ERR(name)) {
 			err = PTR_ERR(name);
-		else
-			err = read_name(root_inode, name);
+			goto out_put;
+		}
+		err = read_name(root_inode, name);
 		kfree(name);
 		if (err)
 			goto out_put;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/hpfs/inode.c linux-libre-3.2.84-gnu1/fs/hpfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/hpfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/hpfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -268,7 +268,7 @@ int hpfs_setattr(struct dentry *dentry,
 	if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
 		goto out_unlock;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		goto out_unlock;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/hugetlbfs/inode.c linux-libre-3.2.84-gnu1/fs/hugetlbfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/hugetlbfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/hugetlbfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -422,7 +422,7 @@ static int hugetlbfs_setattr(struct dent
 
 	BUG_ON(!inode);
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/jffs2/acl.c linux-libre-3.2.84-gnu1/fs/jffs2/acl.c
--- linux-libre-3.2.83-gnu1/fs/jffs2/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/jffs2/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -227,9 +227,10 @@ static int jffs2_set_acl(struct inode *i
 	case ACL_TYPE_ACCESS:
 		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			rc = posix_acl_equiv_mode(acl, &mode);
-			if (rc < 0)
+			umode_t mode;
+
+			rc = posix_acl_update_mode(inode, &mode, &acl);
+			if (rc)
 				return rc;
 			if (inode->i_mode != mode) {
 				struct iattr attr;
@@ -241,8 +242,6 @@ static int jffs2_set_acl(struct inode *i
 				if (rc < 0)
 					return rc;
 			}
-			if (rc == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/jffs2/fs.c linux-libre-3.2.84-gnu1/fs/jffs2/fs.c
--- linux-libre-3.2.83-gnu1/fs/jffs2/fs.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/jffs2/fs.c	2016-11-19 20:01:45.000000000 -0500
@@ -186,7 +186,7 @@ int jffs2_setattr(struct dentry *dentry,
 {
 	int rc;
 
-	rc = inode_change_ok(dentry->d_inode, iattr);
+	rc = setattr_prepare(dentry, iattr);
 	if (rc)
 		return rc;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/jfs/file.c linux-libre-3.2.84-gnu1/fs/jfs/file.c
--- linux-libre-3.2.83-gnu1/fs/jfs/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/jfs/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -102,7 +102,7 @@ int jfs_setattr(struct dentry *dentry, s
 	struct inode *inode = dentry->d_inode;
 	int rc;
 
-	rc = inode_change_ok(inode, iattr);
+	rc = setattr_prepare(dentry, iattr);
 	if (rc)
 		return rc;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/jfs/xattr.c linux-libre-3.2.84-gnu1/fs/jfs/xattr.c
--- linux-libre-3.2.83-gnu1/fs/jfs/xattr.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/jfs/xattr.c	2016-11-19 20:01:45.000000000 -0500
@@ -693,9 +693,11 @@ static int can_set_system_xattr(struct i
 			return rc;
 		}
 		if (acl) {
-			rc = posix_acl_equiv_mode(acl, &inode->i_mode);
+			struct posix_acl *dummy = acl;
+
+			rc = posix_acl_update_mode(inode, &inode->i_mode, &dummy);
 			posix_acl_release(acl);
-			if (rc < 0) {
+			if (rc) {
 				printk(KERN_ERR
 				       "posix_acl_equiv_mode returned %d\n",
 				       rc);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/libfs.c linux-libre-3.2.84-gnu1/fs/libfs.c
--- linux-libre-3.2.83-gnu1/fs/libfs.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/libfs.c	2016-11-19 20:01:45.000000000 -0500
@@ -364,7 +364,7 @@ int simple_setattr(struct dentry *dentry
 
 	WARN_ON_ONCE(inode->i_op->truncate);
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/logfs/file.c linux-libre-3.2.84-gnu1/fs/logfs/file.c
--- linux-libre-3.2.83-gnu1/fs/logfs/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/logfs/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -241,7 +241,7 @@ static int logfs_setattr(struct dentry *
 	struct inode *inode = dentry->d_inode;
 	int err = 0;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/minix/file.c linux-libre-3.2.84-gnu1/fs/minix/file.c
--- linux-libre-3.2.83-gnu1/fs/minix/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/minix/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -28,7 +28,7 @@ static int minix_setattr(struct dentry *
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ncpfs/inode.c linux-libre-3.2.84-gnu1/fs/ncpfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/ncpfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ncpfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -880,7 +880,7 @@ int ncp_notify_change(struct dentry *den
 	/* ageing the dentry to force validation */
 	ncp_age_dentry(server, dentry);
 
-	result = inode_change_ok(inode, attr);
+	result = setattr_prepare(dentry, attr);
 	if (result < 0)
 		goto out;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/nfs/callback_xdr.c linux-libre-3.2.84-gnu1/fs/nfs/callback_xdr.c
--- linux-libre-3.2.83-gnu1/fs/nfs/callback_xdr.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/nfs/callback_xdr.c	2016-11-19 20:01:45.000000000 -0500
@@ -878,7 +878,7 @@ static __be32 nfs4_callback_compound(str
 	if (hdr_arg.minorversion == 0) {
 		cps.clp = nfs4_find_client_ident(hdr_arg.cb_ident);
 		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
-			return rpc_drop_reply;
+			goto out_invalidcred;
 	}
 
 	hdr_res.taglen = hdr_arg.taglen;
@@ -905,6 +905,10 @@ static __be32 nfs4_callback_compound(str
 	nfs_put_client(cps.clp);
 	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
 	return rpc_success;
+
+out_invalidcred:
+	pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
+	return rpc_autherr_badcred;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/nfs/nfs4proc.c linux-libre-3.2.84-gnu1/fs/nfs/nfs4proc.c
--- linux-libre-3.2.83-gnu1/fs/nfs/nfs4proc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/nfs/nfs4proc.c	2016-11-19 20:01:45.000000000 -0500
@@ -5360,14 +5360,21 @@ static int _nfs4_proc_create_session(str
 
 	status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
 
+	switch (status) {
+	case -NFS4ERR_STALE_CLIENTID:
+	case -NFS4ERR_DELAY:
+	case -ETIMEDOUT:
+	case -EACCES:
+	case -EAGAIN:
+		goto out;
+	};
+
+	clp->cl_seqid++;
 	if (!status)
 		/* Verify the session's negotiated channel_attrs values */
 		status = nfs4_verify_channel_attrs(&args, session);
-	if (!status) {
-		/* Increment the clientid slot sequence id */
-		clp->cl_seqid++;
-	}
 
+out:
 	return status;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/nfs/write.c linux-libre-3.2.84-gnu1/fs/nfs/write.c
--- linux-libre-3.2.83-gnu1/fs/nfs/write.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/nfs/write.c	2016-11-19 20:01:45.000000000 -0500
@@ -747,6 +747,9 @@ int nfs_updatepage(struct file *file, st
 		file->f_path.dentry->d_name.name, count,
 		(long long)(page_offset(page) + offset));
 
+	if (!count)
+		goto out;
+
 	/* If we're not using byte range locks, and we know the page
 	 * is up to date, it may be more efficient to extend the write
 	 * to cover the entire page in order to avoid fragmentation
@@ -764,7 +767,7 @@ int nfs_updatepage(struct file *file, st
 		nfs_set_pageerror(page);
 	else
 		__set_page_dirty_nobuffers(page);
-
+out:
 	dprintk("NFS:       nfs_updatepage returns %d (isize %lld)\n",
 			status, (long long)i_size_read(inode));
 	return status;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/nfsd/vfs.c linux-libre-3.2.84-gnu1/fs/nfsd/vfs.c
--- linux-libre-3.2.83-gnu1/fs/nfsd/vfs.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/nfsd/vfs.c	2016-11-19 20:01:45.000000000 -0500
@@ -301,17 +301,19 @@ commit_metadata(struct svc_fh *fhp)
  * NFS semantics and what Linux expects.
  */
 static void
-nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
+nfsd_sanitize_attrs(struct dentry *dentry, struct iattr *iap)
 {
+	struct inode *inode = dentry->d_inode;
+
 	/*
 	 * NFSv2 does not differentiate between "set-[ac]time-to-now"
 	 * which only requires access, and "set-[ac]time-to-X" which
 	 * requires ownership.
 	 * So if it looks like it might be "set both to the same time which
-	 * is close to now", and if inode_change_ok fails, then we
+	 * is close to now", and if setattr_prepare fails, then we
 	 * convert to "set to now" instead of "set to explicit time"
 	 *
-	 * We only call inode_change_ok as the last test as technically
+	 * We only call setattr_prepare as the last test as technically
 	 * it is not an interface that we should be using.
 	 */
 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
@@ -329,7 +331,7 @@ nfsd_sanitize_attrs(struct inode *inode,
 		if (delta < 0)
 			delta = -delta;
 		if (delta < MAX_TOUCH_TIME_ERROR &&
-		    inode_change_ok(inode, iap) != 0) {
+		    setattr_prepare(dentry, iap) != 0) {
 			/*
 			 * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
 			 * This will cause notify_change to set these times
@@ -437,7 +439,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str
 	if (!iap->ia_valid)
 		goto out;
 
-	nfsd_sanitize_attrs(inode, iap);
+	nfsd_sanitize_attrs(dentry, iap);
 
 	/*
 	 * The size case is special, it changes the file in addition to the
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/nilfs2/inode.c linux-libre-3.2.84-gnu1/fs/nilfs2/inode.c
--- linux-libre-3.2.83-gnu1/fs/nilfs2/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/nilfs2/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -792,7 +792,7 @@ int nilfs_setattr(struct dentry *dentry,
 	struct super_block *sb = inode->i_sb;
 	int err;
 
-	err = inode_change_ok(inode, iattr);
+	err = setattr_prepare(dentry, iattr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ntfs/inode.c linux-libre-3.2.84-gnu1/fs/ntfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/ntfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ntfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -2890,7 +2890,7 @@ int ntfs_setattr(struct dentry *dentry,
 	int err;
 	unsigned int ia_valid = attr->ia_valid;
 
-	err = inode_change_ok(vi, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		goto out;
 	/* We do not support NTFS ACLs yet. */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ocfs2/acl.c linux-libre-3.2.84-gnu1/fs/ocfs2/acl.c
--- linux-libre-3.2.83-gnu1/fs/ocfs2/acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ocfs2/acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -247,14 +247,11 @@ static int ocfs2_set_acl(handle_t *handl
 	case ACL_TYPE_ACCESS:
 		name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			ret = posix_acl_equiv_mode(acl, &mode);
-			if (ret < 0)
+			umode_t mode;
+			ret = posix_acl_update_mode(inode, &mode, &acl);
+			if (ret)
 				return ret;
 			else {
-				if (ret == 0)
-					acl = NULL;
-
 				ret = ocfs2_acl_set_mode(inode, di_bh,
 							 handle, mode);
 				if (ret)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ocfs2/dlm/dlmconvert.c linux-libre-3.2.84-gnu1/fs/ocfs2/dlm/dlmconvert.c
--- linux-libre-3.2.83-gnu1/fs/ocfs2/dlm/dlmconvert.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ocfs2/dlm/dlmconvert.c	2016-11-19 20:01:45.000000000 -0500
@@ -265,7 +265,6 @@ enum dlm_status dlmconvert_remote(struct
 				  struct dlm_lock *lock, int flags, int type)
 {
 	enum dlm_status status;
-	u8 old_owner = res->owner;
 
 	mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type,
 	     lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS);
@@ -332,7 +331,6 @@ enum dlm_status dlmconvert_remote(struct
 
 	spin_lock(&res->spinlock);
 	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
-	lock->convert_pending = 0;
 	/* if it failed, move it back to granted queue.
 	 * if master returns DLM_NORMAL and then down before sending ast,
 	 * it may have already been moved to granted queue, reset to
@@ -341,12 +339,14 @@ enum dlm_status dlmconvert_remote(struct
 		if (status != DLM_NOTQUEUED)
 			dlm_error(status);
 		dlm_revert_pending_convert(res, lock);
-	} else if ((res->state & DLM_LOCK_RES_RECOVERING) ||
-			(old_owner != res->owner)) {
-		mlog(0, "res %.*s is in recovering or has been recovered.\n",
-				res->lockname.len, res->lockname.name);
+	} else if (!lock->convert_pending) {
+		mlog(0, "%s: res %.*s, owner died and lock has been moved back "
+				"to granted list, retry convert.\n",
+				dlm->name, res->lockname.len, res->lockname.name);
 		status = DLM_RECOVERING;
 	}
+
+	lock->convert_pending = 0;
 bail:
 	spin_unlock(&res->spinlock);
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ocfs2/dlmfs/dlmfs.c linux-libre-3.2.84-gnu1/fs/ocfs2/dlmfs/dlmfs.c
--- linux-libre-3.2.83-gnu1/fs/ocfs2/dlmfs/dlmfs.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ocfs2/dlmfs/dlmfs.c	2016-11-19 20:01:45.000000000 -0500
@@ -212,7 +212,7 @@ static int dlmfs_file_setattr(struct den
 	struct inode *inode = dentry->d_inode;
 
 	attr->ia_valid &= ~ATTR_SIZE;
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ocfs2/file.c linux-libre-3.2.84-gnu1/fs/ocfs2/file.c
--- linux-libre-3.2.83-gnu1/fs/ocfs2/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ocfs2/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -1127,7 +1127,7 @@ int ocfs2_setattr(struct dentry *dentry,
 	if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
 		return 0;
 
-	status = inode_change_ok(inode, attr);
+	status = setattr_prepare(dentry, attr);
 	if (status)
 		return status;
 
@@ -1518,7 +1518,8 @@ static int ocfs2_zero_partial_clusters(s
 				       u64 start, u64 len)
 {
 	int ret = 0;
-	u64 tmpend, end = start + len;
+	u64 tmpend = 0;
+	u64 end = start + len;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	unsigned int csize = osb->s_clustersize;
 	handle_t *handle;
@@ -1550,18 +1551,31 @@ static int ocfs2_zero_partial_clusters(s
 	}
 
 	/*
-	 * We want to get the byte offset of the end of the 1st cluster.
+	 * If start is on a cluster boundary and end is somewhere in another
+	 * cluster, we have not COWed the cluster starting at start, unless
+	 * end is also within the same cluster. So, in this case, we skip this
+	 * first call to ocfs2_zero_range_for_truncate() truncate and move on
+	 * to the next one.
 	 */
-	tmpend = (u64)osb->s_clustersize + (start & ~(osb->s_clustersize - 1));
-	if (tmpend > end)
-		tmpend = end;
+	if ((start & (csize - 1)) != 0) {
+		/*
+		 * We want to get the byte offset of the end of the 1st
+		 * cluster.
+		 */
+		tmpend = (u64)osb->s_clustersize +
+			(start & ~(osb->s_clustersize - 1));
+		if (tmpend > end)
+			tmpend = end;
 
-	trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start,
-						 (unsigned long long)tmpend);
+		trace_ocfs2_zero_partial_clusters_range1(
+			(unsigned long long)start,
+			(unsigned long long)tmpend);
 
-	ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend);
-	if (ret)
-		mlog_errno(ret);
+		ret = ocfs2_zero_range_for_truncate(inode, handle, start,
+						    tmpend);
+		if (ret)
+			mlog_errno(ret);
+	}
 
 	if (tmpend < end) {
 		/*
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/omfs/file.c linux-libre-3.2.84-gnu1/fs/omfs/file.c
--- linux-libre-3.2.83-gnu1/fs/omfs/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/omfs/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -345,7 +345,7 @@ static int omfs_setattr(struct dentry *d
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/posix_acl.c linux-libre-3.2.84-gnu1/fs/posix_acl.c
--- linux-libre-3.2.83-gnu1/fs/posix_acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/posix_acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -341,6 +341,36 @@ static int posix_acl_create_masq(struct
         return not_equiv;
 }
 
+/**
+ * posix_acl_update_mode  -  update mode in set_acl
+ *
+ * Update the file mode when setting an ACL: compute the new file permission
+ * bits based on the ACL.  In addition, if the ACL is equivalent to the new
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
+ *
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
+ * or capable of CAP_FSETID (see inode_change_ok).
+ *
+ * Called from set_acl inode operations.
+ */
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
+			  struct posix_acl **acl)
+{
+	umode_t mode = inode->i_mode;
+	int error;
+
+	error = posix_acl_equiv_mode(*acl, &mode);
+	if (error < 0)
+		return error;
+	if (error == 0)
+		*acl = NULL;
+	if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+		mode &= ~S_ISGID;
+	*mode_p = mode;
+	return 0;
+}
+EXPORT_SYMBOL(posix_acl_update_mode);
+
 /*
  * Modify the ACL for the chmod syscall.
  */
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/proc/base.c linux-libre-3.2.84-gnu1/fs/proc/base.c
--- linux-libre-3.2.83-gnu1/fs/proc/base.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/proc/base.c	2016-11-19 20:01:45.000000000 -0500
@@ -558,7 +558,7 @@ int proc_setattr(struct dentry *dentry,
 	if (attr->ia_valid & ATTR_MODE)
 		return -EPERM;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/proc/generic.c linux-libre-3.2.84-gnu1/fs/proc/generic.c
--- linux-libre-3.2.83-gnu1/fs/proc/generic.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/proc/generic.c	2016-11-19 20:01:45.000000000 -0500
@@ -257,7 +257,7 @@ static int proc_notify_change(struct den
 	struct proc_dir_entry *de = PDE(inode);
 	int error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/proc/proc_sysctl.c linux-libre-3.2.84-gnu1/fs/proc/proc_sysctl.c
--- linux-libre-3.2.83-gnu1/fs/proc/proc_sysctl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/proc/proc_sysctl.c	2016-11-19 20:01:45.000000000 -0500
@@ -387,7 +387,7 @@ static int proc_sys_setattr(struct dentr
 	if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		return -EPERM;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ramfs/file-nommu.c linux-libre-3.2.84-gnu1/fs/ramfs/file-nommu.c
--- linux-libre-3.2.83-gnu1/fs/ramfs/file-nommu.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ramfs/file-nommu.c	2016-11-19 20:01:45.000000000 -0500
@@ -164,7 +164,7 @@ static int ramfs_nommu_setattr(struct de
 	int ret = 0;
 
 	/* POSIX UID/GID verification for setting inode attributes */
-	ret = inode_change_ok(inode, ia);
+	ret = setattr_prepare(dentry, ia);
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/reiserfs/inode.c linux-libre-3.2.84-gnu1/fs/reiserfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/reiserfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/reiserfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -3107,7 +3107,7 @@ int reiserfs_setattr(struct dentry *dent
 	int depth;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/reiserfs/xattr_acl.c linux-libre-3.2.84-gnu1/fs/reiserfs/xattr_acl.c
--- linux-libre-3.2.83-gnu1/fs/reiserfs/xattr_acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/reiserfs/xattr_acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -272,13 +272,9 @@ reiserfs_set_acl(struct reiserfs_transac
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
-			else {
-				if (error == 0)
-					acl = NULL;
-			}
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/seq_file.c linux-libre-3.2.84-gnu1/fs/seq_file.c
--- linux-libre-3.2.83-gnu1/fs/seq_file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/seq_file.c	2016-11-19 20:01:45.000000000 -0500
@@ -184,8 +184,10 @@ ssize_t seq_read(struct file *file, char
 		size -= n;
 		buf += n;
 		copied += n;
-		if (!m->count)
+		if (!m->count) {
+			m->from = 0;
 			m->index++;
+		}
 		if (!size)
 			goto Done;
 	}
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/sysfs/inode.c linux-libre-3.2.84-gnu1/fs/sysfs/inode.c
--- linux-libre-3.2.83-gnu1/fs/sysfs/inode.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/sysfs/inode.c	2016-11-19 20:01:45.000000000 -0500
@@ -114,7 +114,7 @@ int sysfs_setattr(struct dentry *dentry,
 		return -EINVAL;
 
 	mutex_lock(&sysfs_mutex);
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		goto out;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/sysv/file.c linux-libre-3.2.84-gnu1/fs/sysv/file.c
--- linux-libre-3.2.83-gnu1/fs/sysv/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/sysv/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -35,7 +35,7 @@ static int sysv_setattr(struct dentry *d
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ubifs/file.c linux-libre-3.2.84-gnu1/fs/ubifs/file.c
--- linux-libre-3.2.83-gnu1/fs/ubifs/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ubifs/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -1260,7 +1260,7 @@ int ubifs_setattr(struct dentry *dentry,
 
 	dbg_gen("ino %lu, mode %#x, ia_valid %#x",
 		inode->i_ino, inode->i_mode, attr->ia_valid);
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ubifs/tnc_commit.c linux-libre-3.2.84-gnu1/fs/ubifs/tnc_commit.c
--- linux-libre-3.2.83-gnu1/fs/ubifs/tnc_commit.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ubifs/tnc_commit.c	2016-11-19 20:01:45.000000000 -0500
@@ -373,7 +373,7 @@ static int layout_in_gaps(struct ubifs_i
 
 	p = c->gap_lebs;
 	do {
-		ubifs_assert(p < c->gap_lebs + sizeof(int) * c->lst.idx_lebs);
+		ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs);
 		written = layout_leb_in_gaps(c, p);
 		if (written < 0) {
 			err = written;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/udf/file.c linux-libre-3.2.84-gnu1/fs/udf/file.c
--- linux-libre-3.2.83-gnu1/fs/udf/file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/udf/file.c	2016-11-19 20:01:45.000000000 -0500
@@ -251,7 +251,7 @@ static int udf_setattr(struct dentry *de
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/ufs/truncate.c linux-libre-3.2.84-gnu1/fs/ufs/truncate.c
--- linux-libre-3.2.83-gnu1/fs/ufs/truncate.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/ufs/truncate.c	2016-11-19 20:01:45.000000000 -0500
@@ -496,7 +496,7 @@ int ufs_setattr(struct dentry *dentry, s
 	unsigned int ia_valid = attr->ia_valid;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/utimes.c linux-libre-3.2.84-gnu1/fs/utimes.c
--- linux-libre-3.2.83-gnu1/fs/utimes.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/utimes.c	2016-11-19 20:01:45.000000000 -0500
@@ -80,7 +80,7 @@ static int utimes_common(struct path *pa
 			newattrs.ia_valid |= ATTR_MTIME_SET;
 		}
 		/*
-		 * Tell inode_change_ok(), that this is an explicit time
+		 * Tell setattr_prepare(), that this is an explicit time
 		 * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
 		 * were used.
 		 */
@@ -89,7 +89,7 @@ static int utimes_common(struct path *pa
 		/*
 		 * If times is NULL (or both times are UTIME_NOW),
 		 * then we need to check permissions, because
-		 * inode_change_ok() won't do it.
+		 * setattr_prepare() won't do it.
 		 */
 		error = -EACCES;
                 if (IS_IMMUTABLE(inode))
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/xfs/xfs_acl.c linux-libre-3.2.84-gnu1/fs/xfs/xfs_acl.c
--- linux-libre-3.2.83-gnu1/fs/xfs/xfs_acl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/xfs/xfs_acl.c	2016-11-19 20:01:45.000000000 -0500
@@ -223,7 +223,7 @@ xfs_set_acl(struct inode *inode, int typ
 }
 
 static int
-xfs_set_mode(struct inode *inode, umode_t mode)
+xfs_set_mode(struct dentry *dentry, struct inode *inode, umode_t mode)
 {
 	int error = 0;
 
@@ -234,7 +234,8 @@ xfs_set_mode(struct inode *inode, umode_
 		iattr.ia_mode = mode;
 		iattr.ia_ctime = current_fs_time(inode->i_sb);
 
-		error = -xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
+		error = -xfs_setattr_nonsize(dentry, XFS_I(inode), &iattr,
+					     XFS_ATTR_NOACL);
 	}
 
 	return error;
@@ -290,7 +291,7 @@ xfs_inherit_acl(struct inode *inode, str
 	if (error > 0)
 		inherit = 1;
 
-	error = xfs_set_mode(inode, mode);
+	error = xfs_set_mode(NULL, inode, mode);
 	if (error)
 		goto out;
 
@@ -383,18 +384,15 @@ xfs_xattr_acl_set(struct dentry *dentry,
 		goto out_release;
 
 	if (type == ACL_TYPE_ACCESS) {
-		umode_t mode = inode->i_mode;
-		error = posix_acl_equiv_mode(acl, &mode);
-
-		if (error <= 0) {
-			posix_acl_release(acl);
-			acl = NULL;
-
-			if (error < 0)
-				return error;
-		}
+		struct posix_acl *saved_acl = acl;
+		umode_t mode;
 
-		error = xfs_set_mode(inode, mode);
+		error = posix_acl_update_mode(inode, &mode, &acl);
+		if (error || acl == NULL)
+			posix_acl_release(saved_acl);
+		if (error)
+			return error;
+		error = xfs_set_mode(dentry, inode, mode);
 		if (error)
 			goto out_release;
 	}
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/xfs/xfs_file.c linux-libre-3.2.84-gnu1/fs/xfs/xfs_file.c
--- linux-libre-3.2.83-gnu1/fs/xfs/xfs_file.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/xfs/xfs_file.c	2016-11-19 20:01:45.000000000 -0500
@@ -1026,7 +1026,8 @@ xfs_file_fallocate(
 	if (file->f_flags & O_DSYNC)
 		attr_flags |= XFS_ATTR_SYNC;
 
-	error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags);
+	error = -xfs_change_file_space(file->f_dentry, cmd, &bf, 0,
+				       attr_flags);
 	if (error)
 		goto out_unlock;
 
@@ -1036,7 +1037,8 @@ xfs_file_fallocate(
 
 		iattr.ia_valid = ATTR_SIZE;
 		iattr.ia_size = new_size;
-		error = -xfs_setattr_size(ip, &iattr, XFS_ATTR_NOLOCK);
+		error = -xfs_setattr_size(file->f_dentry, &iattr,
+					  XFS_ATTR_NOLOCK);
 	}
 
 out_unlock:
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/xfs/xfs_ioctl.c linux-libre-3.2.84-gnu1/fs/xfs/xfs_ioctl.c
--- linux-libre-3.2.83-gnu1/fs/xfs/xfs_ioctl.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/xfs/xfs_ioctl.c	2016-11-19 20:01:45.000000000 -0500
@@ -632,7 +632,8 @@ xfs_ioc_space(
 	if (ioflags & IO_INVIS)
 		attr_flags |= XFS_ATTR_DMI;
 
-	error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags);
+	error = xfs_change_file_space(filp->f_dentry, cmd, bf, filp->f_pos,
+				      attr_flags);
 	return -error;
 }
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/xfs/xfs_iops.c linux-libre-3.2.84-gnu1/fs/xfs/xfs_iops.c
--- linux-libre-3.2.83-gnu1/fs/xfs/xfs_iops.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/xfs/xfs_iops.c	2016-11-19 20:01:45.000000000 -0500
@@ -531,6 +531,7 @@ xfs_setattr_mode(
 
 int
 xfs_setattr_nonsize(
+	struct dentry		*dentry,
 	struct xfs_inode	*ip,
 	struct iattr		*iattr,
 	int			flags)
@@ -553,9 +554,15 @@ xfs_setattr_nonsize(
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	error = -inode_change_ok(inode, iattr);
-	if (error)
-		return XFS_ERROR(error);
+	/*
+	 * dentry can be NULL only when we're called from xfs_inherit_acl(),
+	 * in which case no permission checks are needed
+	 */
+	if (dentry) {
+		error = -setattr_prepare(dentry, iattr);
+		if (error)
+			return XFS_ERROR(error);
+	}
 
 	ASSERT((mask & ATTR_SIZE) == 0);
 
@@ -755,12 +762,13 @@ out_dqrele:
  */
 int
 xfs_setattr_size(
-	struct xfs_inode	*ip,
+	struct dentry		*dentry,
 	struct iattr		*iattr,
 	int			flags)
 {
+	struct inode		*inode = dentry->d_inode;
+	struct xfs_inode	*ip = XFS_I(inode);
 	struct xfs_mount	*mp = ip->i_mount;
-	struct inode		*inode = VFS_I(ip);
 	int			mask = iattr->ia_valid;
 	struct xfs_trans	*tp;
 	int			error;
@@ -776,7 +784,7 @@ xfs_setattr_size(
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	error = -inode_change_ok(inode, iattr);
+	error = -setattr_prepare(dentry, iattr);
 	if (error)
 		return XFS_ERROR(error);
 
@@ -802,7 +810,7 @@ xfs_setattr_size(
 		 */
 		xfs_iunlock(ip, lock_flags);
 		iattr->ia_valid &= ~ATTR_SIZE;
-		return xfs_setattr_nonsize(ip, iattr, 0);
+		return xfs_setattr_nonsize(dentry, ip, iattr, 0);
 	}
 
 	/*
@@ -950,8 +958,8 @@ xfs_vn_setattr(
 	struct iattr	*iattr)
 {
 	if (iattr->ia_valid & ATTR_SIZE)
-		return -xfs_setattr_size(XFS_I(dentry->d_inode), iattr, 0);
-	return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0);
+		return -xfs_setattr_size(dentry, iattr, 0);
+	return -xfs_setattr_nonsize(dentry, XFS_I(dentry->d_inode), iattr, 0);
 }
 
 #define XFS_FIEMAP_FLAGS	(FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/xfs/xfs_vnodeops.c linux-libre-3.2.84-gnu1/fs/xfs/xfs_vnodeops.c
--- linux-libre-3.2.83-gnu1/fs/xfs/xfs_vnodeops.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/xfs/xfs_vnodeops.c	2016-11-19 20:01:45.000000000 -0500
@@ -2234,12 +2234,13 @@ xfs_free_file_space(
  */
 int
 xfs_change_file_space(
-	xfs_inode_t	*ip,
+	struct dentry	*dentry,
 	int		cmd,
 	xfs_flock64_t	*bf,
 	xfs_off_t	offset,
 	int		attr_flags)
 {
+	xfs_inode_t	*ip = XFS_I(dentry->d_inode);
 	xfs_mount_t	*mp = ip->i_mount;
 	int		clrprealloc;
 	int		error;
@@ -2329,7 +2330,7 @@ xfs_change_file_space(
 		iattr.ia_valid = ATTR_SIZE;
 		iattr.ia_size = startoffset;
 
-		error = xfs_setattr_size(ip, &iattr, attr_flags);
+		error = xfs_setattr_size(dentry, &iattr, attr_flags);
 
 		if (error)
 			return error;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/fs/xfs/xfs_vnodeops.h linux-libre-3.2.84-gnu1/fs/xfs/xfs_vnodeops.h
--- linux-libre-3.2.83-gnu1/fs/xfs/xfs_vnodeops.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/fs/xfs/xfs_vnodeops.h	2016-11-19 20:01:45.000000000 -0500
@@ -13,8 +13,9 @@ struct xfs_inode;
 struct xfs_iomap;
 
 
-int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, int flags);
-int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap, int flags);
+int xfs_setattr_nonsize(struct dentry *dentry, struct xfs_inode *ip,
+			struct iattr *vap, int flags);
+int xfs_setattr_size(struct dentry *dentry, struct iattr *vap, int flags);
 #define	XFS_ATTR_DMI		0x01	/* invocation from a DMI function */
 #define	XFS_ATTR_NONBLOCK	0x02	/* return EAGAIN if operation would block */
 #define XFS_ATTR_NOLOCK		0x04	/* Don't grab any conflicting locks */
@@ -37,7 +38,7 @@ int xfs_readdir(struct xfs_inode	*dp, vo
 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
 		const char *target_path, mode_t mode, struct xfs_inode **ipp);
 int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
-int xfs_change_file_space(struct xfs_inode *ip, int cmd,
+int xfs_change_file_space(struct dentry *dentry, int cmd,
 		xfs_flock64_t *bf, xfs_off_t offset, int attr_flags);
 int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
 		struct xfs_inode *src_ip, struct xfs_inode *target_dp,
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/asm-generic/uaccess.h linux-libre-3.2.84-gnu1/include/asm-generic/uaccess.h
--- linux-libre-3.2.83-gnu1/include/asm-generic/uaccess.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/asm-generic/uaccess.h	2016-11-19 20:01:45.000000000 -0500
@@ -221,13 +221,17 @@ extern int __put_user_bad(void) __attrib
 	might_sleep();						\
 	access_ok(VERIFY_READ, ptr, sizeof(*ptr)) ?		\
 		__get_user(x, ptr) :				\
-		-EFAULT;					\
+		((x) = (__typeof__(*(ptr)))0,-EFAULT);		\
 })
 
 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
 {
-	size = __copy_from_user(x, ptr, size);
-	return size ? -EFAULT : size;
+	size_t n = __copy_from_user(x, ptr, size);
+	if (unlikely(n)) {
+		memset(x + (size - n), 0, n);
+		return -EFAULT;
+	}
+	return 0;
 }
 
 extern int __get_user_bad(void) __attribute__((noreturn));
@@ -243,11 +247,13 @@ extern int __get_user_bad(void) __attrib
 static inline long copy_from_user(void *to,
 		const void __user * from, unsigned long n)
 {
+	unsigned long res = n;
 	might_sleep();
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_from_user(to, from, n);
-	else
-		return n;
+	if (likely(access_ok(VERIFY_READ, from, n)))
+		res = __copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 static inline long copy_to_user(void __user *to,
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/bcma/bcma.h linux-libre-3.2.84-gnu1/include/linux/bcma/bcma.h
--- linux-libre-3.2.83-gnu1/include/linux/bcma/bcma.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/bcma/bcma.h	2016-11-19 20:01:45.000000000 -0500
@@ -124,6 +124,7 @@ struct bcma_host_ops {
 #define BCMA_CORE_DEFAULT		0xFFF
 
 #define BCMA_MAX_NR_CORES		16
+#define BCMA_CORE_SIZE			0x1000
 
 struct bcma_device {
 	struct bcma_bus *bus;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/bcma/bcma_regs.h linux-libre-3.2.84-gnu1/include/linux/bcma/bcma_regs.h
--- linux-libre-3.2.83-gnu1/include/linux/bcma/bcma_regs.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/bcma/bcma_regs.h	2016-11-19 20:01:45.000000000 -0500
@@ -35,6 +35,7 @@
 #define  BCMA_IOST_BIST_DONE		0x8000
 #define BCMA_RESET_CTL			0x0800
 #define  BCMA_RESET_CTL_RESET		0x0001
+#define BCMA_RESET_ST			0x0804
 
 /* BCMA PCI config space registers. */
 #define BCMA_PCI_PMCSR			0x44
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/can/dev.h linux-libre-3.2.84-gnu1/include/linux/can/dev.h
--- linux-libre-3.2.83-gnu1/include/linux/can/dev.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/can/dev.h	2016-11-19 20:01:45.000000000 -0500
@@ -30,6 +30,7 @@ enum can_mode {
  * CAN common private data
  */
 struct can_priv {
+	struct net_device *dev;
 	struct can_device_stats can_stats;
 
 	struct can_bittiming bittiming;
@@ -41,7 +42,7 @@ struct can_priv {
 	u32 ctrlmode_supported;
 
 	int restart_ms;
-	struct timer_list restart_timer;
+	struct delayed_work restart_work;
 
 	int (*do_set_bittiming)(struct net_device *dev);
 	int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/fs.h linux-libre-3.2.84-gnu1/include/linux/fs.h
--- linux-libre-3.2.83-gnu1/include/linux/fs.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/fs.h	2016-11-19 20:01:45.000000000 -0500
@@ -2615,7 +2615,7 @@ extern int buffer_migrate_page(struct ad
 #define buffer_migrate_page NULL
 #endif
 
-extern int inode_change_ok(const struct inode *, struct iattr *);
+extern int setattr_prepare(struct dentry *, struct iattr *);
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/i8042.h linux-libre-3.2.84-gnu1/include/linux/i8042.h
--- linux-libre-3.2.83-gnu1/include/linux/i8042.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/i8042.h	2016-11-19 20:01:45.000000000 -0500
@@ -38,7 +38,6 @@ struct serio;
 void i8042_lock_chip(void);
 void i8042_unlock_chip(void);
 int i8042_command(unsigned char *param, int command);
-bool i8042_check_port_owner(const struct serio *);
 int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
 					struct serio *serio));
 int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
@@ -59,11 +58,6 @@ static inline int i8042_command(unsigned
 	return -ENODEV;
 }
 
-static inline bool i8042_check_port_owner(const struct serio *serio)
-{
-	return false;
-}
-
 static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
 					struct serio *serio))
 {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/mroute6.h linux-libre-3.2.84-gnu1/include/linux/mroute6.h
--- linux-libre-3.2.83-gnu1/include/linux/mroute6.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/mroute6.h	2016-11-19 20:01:45.000000000 -0500
@@ -228,7 +228,7 @@ struct mfc6_cache {
 #ifdef __KERNEL__
 struct rtmsg;
 extern int ip6mr_get_route(struct net *net, struct sk_buff *skb,
-			   struct rtmsg *rtm, int nowait);
+			   struct rtmsg *rtm, int nowait, u32 portid);
 
 #ifdef CONFIG_IPV6_MROUTE
 extern struct sock *mroute6_socket(struct net *net, struct sk_buff *skb);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/mroute.h linux-libre-3.2.84-gnu1/include/linux/mroute.h
--- linux-libre-3.2.83-gnu1/include/linux/mroute.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/mroute.h	2016-11-19 20:01:45.000000000 -0500
@@ -245,7 +245,7 @@ struct mfc_cache {
 struct rtmsg;
 extern int ipmr_get_route(struct net *net, struct sk_buff *skb,
 			  __be32 saddr, __be32 daddr,
-			  struct rtmsg *rtm, int nowait);
+			  struct rtmsg *rtm, int nowait, u32 portid);
 #endif
 
 #endif
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/posix_acl.h linux-libre-3.2.84-gnu1/include/linux/posix_acl.h
--- linux-libre-3.2.83-gnu1/include/linux/posix_acl.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/posix_acl.h	2016-11-19 20:01:45.000000000 -0500
@@ -83,6 +83,7 @@ extern struct posix_acl *posix_acl_from_
 extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
 extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
 extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
 
 extern struct posix_acl *get_posix_acl(struct inode *, int);
 extern int set_posix_acl(struct inode *, int, struct posix_acl *);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/linux/serio.h linux-libre-3.2.84-gnu1/include/linux/serio.h
--- linux-libre-3.2.83-gnu1/include/linux/serio.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/linux/serio.h	2016-11-19 20:01:45.000000000 -0500
@@ -33,7 +33,8 @@ struct serio {
 
 	struct serio_device_id id;
 
-	spinlock_t lock;		/* protects critical sections from port's interrupt handler */
+	/* Protects critical sections from port's interrupt handler */
+	spinlock_t lock;
 
 	int (*write)(struct serio *, unsigned char);
 	int (*open)(struct serio *);
@@ -42,16 +43,29 @@ struct serio {
 	void (*stop)(struct serio *);
 
 	struct serio *parent;
-	struct list_head child_node;	/* Entry in parent->children list */
+	/* Entry in parent->children list */
+	struct list_head child_node;
 	struct list_head children;
-	unsigned int depth;		/* level of nesting in serio hierarchy */
+	/* Level of nesting in serio hierarchy */
+	unsigned int depth;
 
-	struct serio_driver *drv;	/* accessed from interrupt, must be protected by serio->lock and serio->sem */
-	struct mutex drv_mutex;		/* protects serio->drv so attributes can pin driver */
+	/*
+	 * serio->drv is accessed from interrupt handlers; when modifying
+	 * caller should acquire serio->drv_mutex and serio->lock.
+	 */
+	struct serio_driver *drv;
+	/* Protects serio->drv so attributes can pin current driver */
+	struct mutex drv_mutex;
 
 	struct device dev;
 
 	struct list_head node;
+
+	/*
+	 * For use by PS/2 layer when several ports share hardware and
+	 * may get indigestion when exposed to concurrent access (i8042).
+	 */
+	struct mutex *ps2_cmd_mutex;
 };
 #define to_serio_port(d)	container_of(d, struct serio, dev)
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/include/net/tcp.h linux-libre-3.2.84-gnu1/include/net/tcp.h
--- linux-libre-3.2.83-gnu1/include/net/tcp.h	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/include/net/tcp.h	2016-11-19 20:01:45.000000000 -0500
@@ -1293,6 +1293,8 @@ static inline void tcp_check_send_head(s
 {
 	if (sk->sk_send_head == skb_unlinked)
 		sk->sk_send_head = NULL;
+	if (tcp_sk(sk)->highest_sack == skb_unlinked)
+		tcp_sk(sk)->highest_sack = NULL;
 }
 
 static inline void tcp_init_send_head(struct sock *sk)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/kernel/sched.c linux-libre-3.2.84-gnu1/kernel/sched.c
--- linux-libre-3.2.83-gnu1/kernel/sched.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/kernel/sched.c	2016-11-19 20:01:45.000000000 -0500
@@ -2084,19 +2084,6 @@ EXPORT_SYMBOL_GPL(account_system_vtime);
 
 #endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 
-static inline void account_reset_rq(struct rq *rq)
-{
-#ifdef CONFIG_IRQ_TIME_ACCOUNTING
-	rq->prev_irq_time = 0;
-#endif
-#ifdef CONFIG_PARAVIRT
-	rq->prev_steal_time = 0;
-#endif
-#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
-	rq->prev_steal_time_rq = 0;
-#endif
-}
-
 #ifdef CONFIG_PARAVIRT
 static inline u64 steal_ticks(u64 steal)
 {
@@ -2846,6 +2833,28 @@ try_to_wake_up(struct task_struct *p, un
 	success = 1; /* we're going to change ->state */
 	cpu = task_cpu(p);
 
+	/*
+	 * Ensure we load p->on_rq _after_ p->state, otherwise it would
+	 * be possible to, falsely, observe p->on_rq == 0 and get stuck
+	 * in smp_cond_load_acquire() below.
+	 *
+	 * sched_ttwu_pending()                 try_to_wake_up()
+	 *   [S] p->on_rq = 1;                  [L] P->state
+	 *       UNLOCK rq->lock  -----.
+	 *                              \
+	 *				 +---   RMB
+	 * schedule()                   /
+	 *       LOCK rq->lock    -----'
+	 *       UNLOCK rq->lock
+	 *
+	 * [task p]
+	 *   [S] p->state = UNINTERRUPTIBLE     [L] p->on_rq
+	 *
+	 * Pairs with the UNLOCK+LOCK on rq->lock from the
+	 * last wakeup of our task and the schedule that got our task
+	 * current.
+	 */
+	smp_rmb();
 	if (p->on_rq && ttwu_remote(p, wake_flags))
 		goto stat;
 
@@ -6869,7 +6878,6 @@ migration_call(struct notifier_block *nf
 
 	case CPU_UP_PREPARE:
 		rq->calc_load_update = calc_load_update;
-		account_reset_rq(rq);
 		break;
 
 	case CPU_ONLINE:
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/kernel/trace/trace.c linux-libre-3.2.84-gnu1/kernel/trace/trace.c
--- linux-libre-3.2.83-gnu1/kernel/trace/trace.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/kernel/trace/trace.c	2016-11-19 20:01:45.000000000 -0500
@@ -3331,13 +3331,6 @@ tracing_read_pipe(struct file *filp, cha
 	static struct tracer *old_tracer;
 	ssize_t sret;
 
-	/* return any leftover data */
-	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
-	if (sret != -EBUSY)
-		return sret;
-
-	trace_seq_init(&iter->seq);
-
 	/* copy the tracer to avoid using a global lock all around */
 	mutex_lock(&trace_types_lock);
 	if (unlikely(old_tracer != current_trace && current_trace)) {
@@ -3352,6 +3345,14 @@ tracing_read_pipe(struct file *filp, cha
 	 * is protected.
 	 */
 	mutex_lock(&iter->mutex);
+
+	/* return any leftover data */
+	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+	if (sret != -EBUSY)
+		goto out;
+
+	trace_seq_init(&iter->seq);
+
 	if (iter->trace->read) {
 		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
 		if (sret)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/Makefile linux-libre-3.2.84-gnu1/Makefile
--- linux-libre-3.2.83-gnu1/Makefile	2016-10-21 11:05:09.000000000 -0400
+++ linux-libre-3.2.84-gnu1/Makefile	2016-11-20 23:00:21.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 83
+SUBLEVEL = 84
 EXTRAVERSION =-gnu1
 NAME = Saber-toothed Squirrel
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/mm/hugetlb.c linux-libre-3.2.84-gnu1/mm/hugetlb.c
--- linux-libre-3.2.83-gnu1/mm/hugetlb.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/mm/hugetlb.c	2016-11-19 20:01:45.000000000 -0500
@@ -1417,6 +1417,10 @@ static unsigned long set_max_huge_pages(
 		 * and reducing the surplus.
 		 */
 		spin_unlock(&hugetlb_lock);
+
+		/* yield cpu to avoid soft lockup */
+		cond_resched();
+
 		ret = alloc_fresh_huge_page(h, nodes_allowed);
 		spin_lock(&hugetlb_lock);
 		if (!ret)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/mm/ksm.c linux-libre-3.2.84-gnu1/mm/ksm.c
--- linux-libre-3.2.83-gnu1/mm/ksm.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/mm/ksm.c	2016-11-19 20:01:45.000000000 -0500
@@ -238,7 +238,8 @@ static inline struct rmap_item *alloc_rm
 {
 	struct rmap_item *rmap_item;
 
-	rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL);
+	rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL |
+						__GFP_NORETRY | __GFP_NOWARN);
 	if (rmap_item)
 		ksm_rmap_items++;
 	return rmap_item;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/mm/shmem.c linux-libre-3.2.84-gnu1/mm/shmem.c
--- linux-libre-3.2.83-gnu1/mm/shmem.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/mm/shmem.c	2016-11-19 20:01:45.000000000 -0500
@@ -562,7 +562,7 @@ static int shmem_setattr(struct dentry *
 	struct inode *inode = dentry->d_inode;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/bluetooth/l2cap_sock.c linux-libre-3.2.84-gnu1/net/bluetooth/l2cap_sock.c
--- linux-libre-3.2.83-gnu1/net/bluetooth/l2cap_sock.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/bluetooth/l2cap_sock.c	2016-11-19 20:01:45.000000000 -0500
@@ -630,7 +630,7 @@ static int l2cap_sock_setsockopt(struct
 			break;
 		}
 
-		if (get_user(opt, (u32 __user *) optval)) {
+		if (get_user(opt, (u16 __user *) optval)) {
 			err = -EFAULT;
 			break;
 		}
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/bluetooth/rfcomm/sock.c linux-libre-3.2.84-gnu1/net/bluetooth/rfcomm/sock.c
--- linux-libre-3.2.83-gnu1/net/bluetooth/rfcomm/sock.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/bluetooth/rfcomm/sock.c	2016-11-19 20:01:45.000000000 -0500
@@ -349,15 +349,19 @@ static int rfcomm_sock_create(struct net
 
 static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 {
-	struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
+	struct sockaddr_rc sa;
 	struct sock *sk = sock->sk;
-	int err = 0;
-
-	BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
+	int len, err = 0;
 
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
 
+	memset(&sa, 0, sizeof(sa));
+	len = min_t(unsigned int, sizeof(sa), addr_len);
+	memcpy(&sa, addr, len);
+
+	BT_DBG("sk %p %s", sk, batostr(&sa.rc_bdaddr));
+
 	lock_sock(sk);
 
 	if (sk->sk_state != BT_OPEN) {
@@ -372,12 +376,13 @@ static int rfcomm_sock_bind(struct socke
 
 	write_lock_bh(&rfcomm_sk_list.lock);
 
-	if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
+	if (sa.rc_channel &&
+	    __rfcomm_get_sock_by_addr(sa.rc_channel, &sa.rc_bdaddr)) {
 		err = -EADDRINUSE;
 	} else {
 		/* Save source address */
-		bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr);
-		rfcomm_pi(sk)->channel = sa->rc_channel;
+		bacpy(&bt_sk(sk)->src, &sa.rc_bdaddr);
+		rfcomm_pi(sk)->channel = sa.rc_channel;
 		sk->sk_state = BT_BOUND;
 	}
 
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/ipv4/ipmr.c linux-libre-3.2.84-gnu1/net/ipv4/ipmr.c
--- linux-libre-3.2.83-gnu1/net/ipv4/ipmr.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/ipv4/ipmr.c	2016-11-19 20:01:45.000000000 -0500
@@ -2058,7 +2058,7 @@ rtattr_failure:
 
 int ipmr_get_route(struct net *net, struct sk_buff *skb,
 		   __be32 saddr, __be32 daddr,
-		   struct rtmsg *rtm, int nowait)
+		   struct rtmsg *rtm, int nowait, u32 portid)
 {
 	struct mfc_cache *cache;
 	struct mr_table *mrt;
@@ -2098,6 +2098,7 @@ int ipmr_get_route(struct net *net, stru
 			return -ENOMEM;
 		}
 
+		NETLINK_CB(skb2).pid = portid;
 		skb_push(skb2, sizeof(struct iphdr));
 		skb_reset_network_header(skb2);
 		iph = ip_hdr(skb2);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/ipv4/route.c linux-libre-3.2.84-gnu1/net/ipv4/route.c
--- linux-libre-3.2.83-gnu1/net/ipv4/route.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/ipv4/route.c	2016-11-19 20:01:45.000000000 -0500
@@ -3077,7 +3077,8 @@ static int rt_fill_info(struct net *net,
 		    IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
 			int err = ipmr_get_route(net, skb,
 						 rt->rt_src, rt->rt_dst,
-						 r, nowait);
+						 r, nowait, pid);
+
 			if (err <= 0) {
 				if (!nowait) {
 					if (err == 0)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/ipv4/tcp_output.c linux-libre-3.2.84-gnu1/net/ipv4/tcp_output.c
--- linux-libre-3.2.83-gnu1/net/ipv4/tcp_output.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/ipv4/tcp_output.c	2016-11-19 20:01:45.000000000 -0500
@@ -220,7 +220,8 @@ void tcp_select_initial_window(int __spa
 		/* Set window scaling on max possible window
 		 * See RFC1323 for an explanation of the limit to 14
 		 */
-		space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
+		space = max_t(u32, space, sysctl_tcp_rmem[2]);
+		space = max_t(u32, space, sysctl_rmem_max);
 		space = min_t(u32, space, *window_clamp);
 		while (space > 65535 && (*rcv_wscale) < 14) {
 			space >>= 1;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/ipv6/ip6mr.c linux-libre-3.2.84-gnu1/net/ipv6/ip6mr.c
--- linux-libre-3.2.83-gnu1/net/ipv6/ip6mr.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/ipv6/ip6mr.c	2016-11-19 20:01:45.000000000 -0500
@@ -2137,8 +2137,8 @@ rtattr_failure:
 	return -EMSGSIZE;
 }
 
-int ip6mr_get_route(struct net *net,
-		    struct sk_buff *skb, struct rtmsg *rtm, int nowait)
+int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
+		    int nowait, u32 portid)
 {
 	int err;
 	struct mr6_table *mrt;
@@ -2176,6 +2176,7 @@ int ip6mr_get_route(struct net *net,
 			return -ENOMEM;
 		}
 
+		NETLINK_CB(skb2).pid = portid;
 		skb_reset_transport_header(skb2);
 
 		skb_put(skb2, sizeof(struct ipv6hdr));
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/ipv6/route.c linux-libre-3.2.84-gnu1/net/ipv6/route.c
--- linux-libre-3.2.83-gnu1/net/ipv6/route.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/ipv6/route.c	2016-11-19 20:01:45.000000000 -0500
@@ -2416,7 +2416,9 @@ static int rt6_fill_node(struct net *net
 	if (iif) {
 #ifdef CONFIG_IPV6_MROUTE
 		if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) {
-			int err = ip6mr_get_route(net, skb, rtm, nowait);
+			int err = ip6mr_get_route(net, skb, rtm, nowait,
+						  pid);
+
 			if (err <= 0) {
 				if (!nowait) {
 					if (err == 0)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/irda/af_irda.c linux-libre-3.2.84-gnu1/net/irda/af_irda.c
--- linux-libre-3.2.83-gnu1/net/irda/af_irda.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/irda/af_irda.c	2016-11-19 20:01:45.000000000 -0500
@@ -846,7 +846,7 @@ static int irda_accept(struct socket *so
 	struct sock *sk = sock->sk;
 	struct irda_sock *new, *self = irda_sk(sk);
 	struct sock *newsk;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
 	int err;
 
 	IRDA_DEBUG(2, "%s()\n", __func__);
@@ -916,7 +916,6 @@ static int irda_accept(struct socket *so
 	err = -EPERM; /* value does not seem to make sense. -arnd */
 	if (!new->tsap) {
 		IRDA_DEBUG(0, "%s(), dup failed!\n", __func__);
-		kfree_skb(skb);
 		goto out;
 	}
 
@@ -935,7 +934,6 @@ static int irda_accept(struct socket *so
 	/* Clean up the original one to keep it in listen state */
 	irttp_listen(self->tsap);
 
-	kfree_skb(skb);
 	sk->sk_ack_backlog--;
 
 	newsock->state = SS_CONNECTED;
@@ -943,6 +941,7 @@ static int irda_accept(struct socket *so
 	irda_connect_response(new);
 	err = 0;
 out:
+	kfree_skb(skb);
 	release_sock(sk);
 	return err;
 }
@@ -1040,8 +1039,11 @@ static int irda_connect(struct socket *s
 	}
 
 	/* Check if we have opened a local TSAP */
-	if (!self->tsap)
-		irda_open_tsap(self, LSAP_ANY, addr->sir_name);
+	if (!self->tsap) {
+		err = irda_open_tsap(self, LSAP_ANY, addr->sir_name);
+		if (err)
+			goto out;
+	}
 
 	/* Move to connecting socket, start sending Connect Requests */
 	sock->state = SS_CONNECTING;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/l2tp/l2tp_ppp.c linux-libre-3.2.84-gnu1/net/l2tp/l2tp_ppp.c
--- linux-libre-3.2.83-gnu1/net/l2tp/l2tp_ppp.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/l2tp/l2tp_ppp.c	2016-11-19 20:01:45.000000000 -0500
@@ -914,10 +914,8 @@ static int pppol2tp_getname(struct socke
 
 	pls = l2tp_session_priv(session);
 	tunnel = l2tp_sock_to_tunnel(pls->tunnel_sock);
-	if (tunnel == NULL) {
-		error = -EBADF;
+	if (tunnel == NULL)
 		goto end_put_sess;
-	}
 
 	inet = inet_sk(tunnel->sock);
 	if (tunnel->version == 2) {
@@ -955,12 +953,11 @@ static int pppol2tp_getname(struct socke
 	}
 
 	*usockaddr_len = len;
+	error = 0;
 
 	sock_put(pls->tunnel_sock);
 end_put_sess:
 	sock_put(sk);
-	error = 0;
-
 end:
 	return error;
 }
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/netfilter/nfnetlink_queue.c linux-libre-3.2.84-gnu1/net/netfilter/nfnetlink_queue.c
--- linux-libre-3.2.83-gnu1/net/netfilter/nfnetlink_queue.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/netfilter/nfnetlink_queue.c	2016-11-19 20:01:45.000000000 -0500
@@ -716,9 +716,6 @@ nfqnl_recv_verdict(struct sock *ctnl, st
 	unsigned int verdict;
 	struct nf_queue_entry *entry;
 
-	queue = instance_lookup(queue_num);
-	if (!queue)
-
 	queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
 	if (IS_ERR(queue))
 		return PTR_ERR(queue);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/netlabel/netlabel_kapi.c linux-libre-3.2.84-gnu1/net/netlabel/netlabel_kapi.c
--- linux-libre-3.2.83-gnu1/net/netlabel/netlabel_kapi.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/netlabel/netlabel_kapi.c	2016-11-19 20:01:45.000000000 -0500
@@ -710,7 +710,11 @@ socket_setattr_return:
  */
 void netlbl_sock_delattr(struct sock *sk)
 {
-	cipso_v4_sock_delattr(sk);
+	switch (sk->sk_family) {
+	case AF_INET:
+		cipso_v4_sock_delattr(sk);
+		break;
+	}
 }
 
 /**
@@ -889,7 +893,11 @@ req_setattr_return:
 */
 void netlbl_req_delattr(struct request_sock *req)
 {
-	cipso_v4_req_delattr(req);
+	switch (req->rsk_ops->family) {
+	case AF_INET:
+		cipso_v4_req_delattr(req);
+		break;
+	}
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/sunrpc/svc.c linux-libre-3.2.84-gnu1/net/sunrpc/svc.c
--- linux-libre-3.2.83-gnu1/net/sunrpc/svc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/sunrpc/svc.c	2016-11-19 20:01:45.000000000 -0500
@@ -1167,11 +1167,16 @@ svc_process_common(struct svc_rqst *rqst
 		*statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
 
 		/* Encode reply */
-		if (rqstp->rq_dropme) {
+		if (*statp == rpc_drop_reply || rqstp->rq_dropme) {
 			if (procp->pc_release)
 				procp->pc_release(rqstp, NULL, rqstp->rq_resp);
 			goto dropit;
 		}
+		if (*statp == rpc_autherr_badcred) {
+			if (procp->pc_release)
+				procp->pc_release(rqstp, NULL, rqstp->rq_resp);
+			goto err_bad_auth;
+		}
 		if (*statp == rpc_success &&
 		    (xdr = procp->pc_encode) &&
 		    !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/xfrm/xfrm_state.c linux-libre-3.2.84-gnu1/net/xfrm/xfrm_state.c
--- linux-libre-3.2.83-gnu1/net/xfrm/xfrm_state.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/xfrm/xfrm_state.c	2016-11-19 20:01:45.000000000 -0500
@@ -351,6 +351,7 @@ static void xfrm_state_gc_destroy(struct
 {
 	tasklet_hrtimer_cancel(&x->mtimer);
 	del_timer_sync(&x->rtimer);
+	kfree(x->aead);
 	kfree(x->aalg);
 	kfree(x->ealg);
 	kfree(x->calg);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/net/xfrm/xfrm_user.c linux-libre-3.2.84-gnu1/net/xfrm/xfrm_user.c
--- linux-libre-3.2.83-gnu1/net/xfrm/xfrm_user.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/net/xfrm/xfrm_user.c	2016-11-19 20:01:45.000000000 -0500
@@ -558,9 +558,12 @@ static struct xfrm_state *xfrm_state_con
 	if (err)
 		goto error;
 
-	if (attrs[XFRMA_SEC_CTX] &&
-	    security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX])))
-		goto error;
+	if (attrs[XFRMA_SEC_CTX]) {
+		err = security_xfrm_state_alloc(x,
+						nla_data(attrs[XFRMA_SEC_CTX]));
+		if (err)
+			goto error;
+	}
 
 	if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn,
 					       attrs[XFRMA_REPLAY_ESN_VAL])))
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/security/keys/proc.c linux-libre-3.2.84-gnu1/security/keys/proc.c
--- linux-libre-3.2.83-gnu1/security/keys/proc.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/security/keys/proc.c	2016-11-19 20:01:45.000000000 -0500
@@ -188,7 +188,7 @@ static int proc_keys_show(struct seq_fil
 	struct timespec now;
 	unsigned long timo;
 	key_ref_t key_ref, skey_ref;
-	char xbuf[12];
+	char xbuf[16];
 	int rc;
 
 	key_ref = make_key_ref(key, 0);
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/sound/core/control.c linux-libre-3.2.84-gnu1/sound/core/control.c
--- linux-libre-3.2.83-gnu1/sound/core/control.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/sound/core/control.c	2016-11-19 20:01:45.000000000 -0500
@@ -150,6 +150,8 @@ void snd_ctl_notify(struct snd_card *car
 	
 	if (snd_BUG_ON(!card || !id))
 		return;
+	if (card->shutdown)
+		return;
 	read_lock(&card->ctl_files_rwlock);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	card->mixer_oss_change_count++;
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/sound/core/rawmidi.c linux-libre-3.2.84-gnu1/sound/core/rawmidi.c
--- linux-libre-3.2.83-gnu1/sound/core/rawmidi.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/sound/core/rawmidi.c	2016-11-19 20:01:45.000000000 -0500
@@ -1609,11 +1609,13 @@ static int snd_rawmidi_dev_register(stru
 		return -EBUSY;
 	}
 	list_add_tail(&rmidi->list, &snd_rawmidi_devices);
+	mutex_unlock(&register_mutex);
 	sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
 				       rmidi->card, rmidi->device,
 				       &snd_rawmidi_f_ops, rmidi, name)) < 0) {
 		snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
+		mutex_lock(&register_mutex);
 		list_del(&rmidi->list);
 		mutex_unlock(&register_mutex);
 		return err;
@@ -1621,6 +1623,7 @@ static int snd_rawmidi_dev_register(stru
 	if (rmidi->ops && rmidi->ops->dev_register &&
 	    (err = rmidi->ops->dev_register(rmidi)) < 0) {
 		snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
+		mutex_lock(&register_mutex);
 		list_del(&rmidi->list);
 		mutex_unlock(&register_mutex);
 		return err;
@@ -1649,7 +1652,6 @@ static int snd_rawmidi_dev_register(stru
 		}
 	}
 #endif /* CONFIG_SND_OSSEMUL */
-	mutex_unlock(&register_mutex);
 	sprintf(name, "midi%d", rmidi->device);
 	entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
 	if (entry) {
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/sound/core/timer.c linux-libre-3.2.84-gnu1/sound/core/timer.c
--- linux-libre-3.2.83-gnu1/sound/core/timer.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/sound/core/timer.c	2016-11-19 20:01:45.000000000 -0500
@@ -34,6 +34,9 @@
 #include <sound/initval.h>
 #include <linux/kmod.h>
 
+/* internal flags */
+#define SNDRV_TIMER_IFLG_PAUSED		0x00010000
+
 #if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
 #define DEFAULT_TIMER_LIMIT 4
 #elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
@@ -290,8 +293,19 @@ int snd_timer_open(struct snd_timer_inst
 	}
 	timeri->slave_class = tid->dev_sclass;
 	timeri->slave_id = slave_id;
-	if (list_empty(&timer->open_list_head) && timer->hw.open)
-		timer->hw.open(timer);
+
+	if (list_empty(&timer->open_list_head) && timer->hw.open) {
+		int err = timer->hw.open(timer);
+		if (err) {
+			kfree(timeri->owner);
+			kfree(timeri);
+
+			module_put(timer->module);
+			mutex_unlock(&register_mutex);
+			return err;
+		}
+	}
+
 	list_add_tail(&timeri->open_list, &timer->open_list_head);
 	snd_timer_check_master(timeri);
 	mutex_unlock(&register_mutex);
@@ -299,8 +313,7 @@ int snd_timer_open(struct snd_timer_inst
 	return 0;
 }
 
-static int _snd_timer_stop(struct snd_timer_instance *timeri,
-			   int keep_flag, int event);
+static int _snd_timer_stop(struct snd_timer_instance *timeri, int event);
 
 /*
  * close a timer instance
@@ -342,7 +355,7 @@ int snd_timer_close(struct snd_timer_ins
 		spin_unlock_irq(&timer->lock);
 		mutex_lock(&register_mutex);
 		list_del(&timeri->open_list);
-		if (timer && list_empty(&timer->open_list_head) &&
+		if (list_empty(&timer->open_list_head) &&
 		    timer->hw.close)
 			timer->hw.close(timer);
 		/* remove slave links */
@@ -494,8 +507,7 @@ int snd_timer_start(struct snd_timer_ins
 	return result;
 }
 
-static int _snd_timer_stop(struct snd_timer_instance * timeri,
-			   int keep_flag, int event)
+static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
 {
 	struct snd_timer *timer;
 	unsigned long flags;
@@ -504,21 +516,19 @@ static int _snd_timer_stop(struct snd_ti
 		return -ENXIO;
 
 	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
-		if (!keep_flag) {
-			spin_lock_irqsave(&slave_active_lock, flags);
-			if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
-				spin_unlock_irqrestore(&slave_active_lock, flags);
-				return -EBUSY;
-			}
-			if (timeri->timer)
-				spin_lock(&timeri->timer->lock);
-			timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-			list_del_init(&timeri->ack_list);
-			list_del_init(&timeri->active_list);
-			if (timeri->timer)
-				spin_unlock(&timeri->timer->lock);
+		spin_lock_irqsave(&slave_active_lock, flags);
+		if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
 			spin_unlock_irqrestore(&slave_active_lock, flags);
+			return -EBUSY;
 		}
+		if (timeri->timer)
+			spin_lock(&timeri->timer->lock);
+		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+		list_del_init(&timeri->ack_list);
+		list_del_init(&timeri->active_list);
+		if (timeri->timer)
+			spin_unlock(&timeri->timer->lock);
+		spin_unlock_irqrestore(&slave_active_lock, flags);
 		goto __end;
 	}
 	timer = timeri->timer;
@@ -544,9 +554,11 @@ static int _snd_timer_stop(struct snd_ti
 			}
 		}
 	}
-	if (!keep_flag)
-		timeri->flags &=
-			~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
+	timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
+	if (event == SNDRV_TIMER_EVENT_STOP)
+		timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED;
+	else
+		timeri->flags |= SNDRV_TIMER_IFLG_PAUSED;
 	spin_unlock_irqrestore(&timer->lock, flags);
       __end:
 	if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@@ -565,7 +577,7 @@ int snd_timer_stop(struct snd_timer_inst
 	unsigned long flags;
 	int err;
 
-	err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
+	err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP);
 	if (err < 0)
 		return err;
 	timer = timeri->timer;
@@ -589,6 +601,10 @@ int snd_timer_continue(struct snd_timer_
 
 	if (timeri == NULL)
 		return result;
+	/* timer can continue only after pause */
+	if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
+		return -EINVAL;
+
 	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
 		return snd_timer_start_slave(timeri);
 	timer = timeri->timer;
@@ -614,7 +630,7 @@ int snd_timer_continue(struct snd_timer_
  */
 int snd_timer_pause(struct snd_timer_instance * timeri)
 {
-	return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
+	return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE);
 }
 
 /*
@@ -822,6 +838,7 @@ int snd_timer_new(struct snd_card *card,
 	timer->tmr_subdevice = tid->subdevice;
 	if (id)
 		strlcpy(timer->id, id, sizeof(timer->id));
+	timer->sticks = 1;
 	INIT_LIST_HEAD(&timer->device_list);
 	INIT_LIST_HEAD(&timer->open_list_head);
 	INIT_LIST_HEAD(&timer->active_list_head);
@@ -1792,6 +1809,9 @@ static int snd_timer_user_continue(struc
 	tu = file->private_data;
 	if (!tu->timeri)
 		return -EBADFD;
+	/* start timer instead of continue if it's not used before */
+	if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
+		return snd_timer_user_start(file);
 	tu->timeri->lost = 0;
 	return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
 }
@@ -1929,6 +1949,7 @@ 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)))
@@ -1938,6 +1959,7 @@ 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)
diff -druNp --no-dereference linux-libre-3.2.83-gnu1/virt/kvm/kvm_main.c linux-libre-3.2.84-gnu1/virt/kvm/kvm_main.c
--- linux-libre-3.2.83-gnu1/virt/kvm/kvm_main.c	2016-10-20 18:41:00.000000000 -0400
+++ linux-libre-3.2.84-gnu1/virt/kvm/kvm_main.c	2016-11-19 20:01:45.000000000 -0500
@@ -156,6 +156,7 @@ void vcpu_load(struct kvm_vcpu *vcpu)
 	kvm_arch_vcpu_load(vcpu, cpu);
 	put_cpu();
 }
+EXPORT_SYMBOL_GPL(vcpu_load);
 
 void vcpu_put(struct kvm_vcpu *vcpu)
 {
@@ -165,6 +166,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)
 	preempt_enable();
 	mutex_unlock(&vcpu->mutex);
 }
+EXPORT_SYMBOL_GPL(vcpu_put);
 
 static void ack_flush(void *_completed)
 {
