diff -druNp --no-dereference linux-libre-3.2.78-gnu1/arch/mips/kernel/traps.c linux-libre-3.2.79-gnu1/arch/mips/kernel/traps.c
--- linux-libre-3.2.78-gnu1/arch/mips/kernel/traps.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/arch/mips/kernel/traps.c	2016-03-31 20:54:38.000000000 -0400
@@ -656,14 +656,14 @@ static int simulate_sync(struct pt_regs
 
 asmlinkage void do_ov(struct pt_regs *regs)
 {
-	siginfo_t info;
+	siginfo_t info = {
+		.si_signo = SIGFPE,
+		.si_code = FPE_INTOVF,
+		.si_addr = (void __user *)regs->cp0_epc,
+	};
 
 	die_if_kernel("Integer overflow", regs);
 
-	info.si_code = FPE_INTOVF;
-	info.si_signo = SIGFPE;
-	info.si_errno = 0;
-	info.si_addr = (void __user *) regs->cp0_epc;
 	force_sig_info(SIGFPE, &info, current);
 }
 
@@ -758,7 +758,7 @@ asmlinkage void do_fpe(struct pt_regs *r
 static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
 	const char *str)
 {
-	siginfo_t info;
+	siginfo_t info = { 0 };
 	char b[40];
 
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@@ -785,7 +785,6 @@ static void do_trap_or_bp(struct pt_regs
 		else
 			info.si_code = FPE_INTOVF;
 		info.si_signo = SIGFPE;
-		info.si_errno = 0;
 		info.si_addr = (void __user *) regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/arch/s390/include/asm/mmu_context.h linux-libre-3.2.79-gnu1/arch/s390/include/asm/mmu_context.h
--- linux-libre-3.2.78-gnu1/arch/s390/include/asm/mmu_context.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/arch/s390/include/asm/mmu_context.h	2016-03-31 20:54:38.000000000 -0400
@@ -16,12 +16,11 @@
 static inline int init_new_context(struct task_struct *tsk,
 				   struct mm_struct *mm)
 {
+	spin_lock_init(&mm->context.list_lock);
+	INIT_LIST_HEAD(&mm->context.pgtable_list);
+	INIT_LIST_HEAD(&mm->context.gmap_list);
 	atomic_set(&mm->context.attach_count, 0);
 	mm->context.flush_mm = 0;
-	mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
-#ifdef CONFIG_64BIT
-	mm->context.asce_bits |= _ASCE_TYPE_REGION3;
-#endif
 	if (current->mm && current->mm->context.alloc_pgste) {
 		/*
 		 * alloc_pgste indicates, that any NEW context will be created
@@ -40,7 +39,14 @@ static inline int init_new_context(struc
 		mm->context.has_pgste = 0;
 		mm->context.alloc_pgste = 0;
 	}
-	mm->context.asce_limit = STACK_TOP_MAX;
+	if (mm->context.asce_limit == 0) {
+		/* context created by exec, set asce limit to 4TB */
+		mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
+#ifdef CONFIG_64BIT
+		mm->context.asce_bits |= _ASCE_TYPE_REGION3;
+#endif
+		mm->context.asce_limit = STACK_TOP_MAX;
+	}
 	crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
 	return 0;
 }
@@ -94,10 +100,6 @@ static inline void activate_mm(struct mm
 static inline void arch_dup_mmap(struct mm_struct *oldmm,
 				 struct mm_struct *mm)
 {
-#ifdef CONFIG_64BIT
-	if (oldmm->context.asce_limit < mm->context.asce_limit)
-		crst_table_downgrade(mm, oldmm->context.asce_limit);
-#endif
 }
 
 static inline void arch_exit_mmap(struct mm_struct *mm)
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/arch/s390/include/asm/pgalloc.h linux-libre-3.2.79-gnu1/arch/s390/include/asm/pgalloc.h
--- linux-libre-3.2.78-gnu1/arch/s390/include/asm/pgalloc.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/arch/s390/include/asm/pgalloc.h	2016-03-31 20:54:38.000000000 -0400
@@ -110,9 +110,6 @@ static inline void pud_populate(struct m
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	spin_lock_init(&mm->context.list_lock);
-	INIT_LIST_HEAD(&mm->context.pgtable_list);
-	INIT_LIST_HEAD(&mm->context.gmap_list);
 	return (pgd_t *) crst_table_alloc(mm);
 }
 #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/arch/x86/kernel/acpi/sleep.c linux-libre-3.2.79-gnu1/arch/x86/kernel/acpi/sleep.c
--- linux-libre-3.2.78-gnu1/arch/x86/kernel/acpi/sleep.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/arch/x86/kernel/acpi/sleep.c	2016-03-31 20:54:38.000000000 -0400
@@ -15,6 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 
+#include <linux/ftrace.h>
 #include "realmode/wakeup.h"
 #include "sleep.h"
 
@@ -102,7 +103,13 @@ int acpi_suspend_lowlevel(void)
        saved_magic = 0x123456789abcdef0L;
 #endif /* CONFIG_64BIT */
 
+	/*
+	 * Pause/unpause graph tracing around do_suspend_lowlevel as it has
+	 * inconsistent call/return info after it jumps to the wakeup vector.
+	 */
+	pause_graph_tracing();
 	do_suspend_lowlevel();
+	unpause_graph_tracing();
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/arch/x86/lib/copy_user_nocache_64.S linux-libre-3.2.79-gnu1/arch/x86/lib/copy_user_nocache_64.S
--- linux-libre-3.2.78-gnu1/arch/x86/lib/copy_user_nocache_64.S	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/arch/x86/lib/copy_user_nocache_64.S	2016-03-31 20:54:38.000000000 -0400
@@ -14,6 +14,7 @@
 #include <asm/current.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
+#include <asm/asm.h>
 
 	.macro ALIGN_DESTINATION
 #ifdef FIX_ALIGNMENT
@@ -36,27 +37,38 @@
 	jmp copy_user_handle_tail
 	.previous
 
-	.section __ex_table,"a"
-	.align 8
-	.quad 100b,103b
-	.quad 101b,103b
-	.previous
+	_ASM_EXTABLE(100b,103b)
+	_ASM_EXTABLE(101b,103b)
 #endif
 	.endm
 
 /*
  * copy_user_nocache - Uncached memory copy with exception handling
- * This will force destination/source out of cache for more performance.
+ * This will force destination out of cache for more performance.
+ *
+ * Note: Cached memory copy is used when destination or size is not
+ * naturally aligned. That is:
+ *  - Require 8-byte alignment when size is 8 bytes or larger.
+ *  - Require 4-byte alignment when size is 4 bytes.
  */
 ENTRY(__copy_user_nocache)
 	CFI_STARTPROC
+
+	/* If size is less than 8 bytes, go to 4-byte copy */
 	cmpl $8,%edx
-	jb 20f		/* less then 8 bytes, go to byte copy loop */
+	jb .L_4b_nocache_copy_entry
+
+	/* If destination is not 8-byte aligned, "cache" copy to align it */
 	ALIGN_DESTINATION
+
+	/* Set 4x8-byte copy count and remainder */
 	movl %edx,%ecx
 	andl $63,%edx
 	shrl $6,%ecx
-	jz 17f
+	jz .L_8b_nocache_copy_entry	/* jump if count is 0 */
+
+	/* Perform 4x8-byte nocache loop-copy */
+.L_4x8b_nocache_copy_loop:
 1:	movq (%rsi),%r8
 2:	movq 1*8(%rsi),%r9
 3:	movq 2*8(%rsi),%r10
@@ -76,62 +88,106 @@ ENTRY(__copy_user_nocache)
 	leaq 64(%rsi),%rsi
 	leaq 64(%rdi),%rdi
 	decl %ecx
-	jnz 1b
-17:	movl %edx,%ecx
+	jnz .L_4x8b_nocache_copy_loop
+
+	/* Set 8-byte copy count and remainder */
+.L_8b_nocache_copy_entry:
+	movl %edx,%ecx
 	andl $7,%edx
 	shrl $3,%ecx
-	jz 20f
-18:	movq (%rsi),%r8
-19:	movnti %r8,(%rdi)
+	jz .L_4b_nocache_copy_entry	/* jump if count is 0 */
+
+	/* Perform 8-byte nocache loop-copy */
+.L_8b_nocache_copy_loop:
+20:	movq (%rsi),%r8
+21:	movnti %r8,(%rdi)
 	leaq 8(%rsi),%rsi
 	leaq 8(%rdi),%rdi
 	decl %ecx
-	jnz 18b
-20:	andl %edx,%edx
-	jz 23f
+	jnz .L_8b_nocache_copy_loop
+
+	/* If no byte left, we're done */
+.L_4b_nocache_copy_entry:
+	andl %edx,%edx
+	jz .L_finish_copy
+
+	/* If destination is not 4-byte aligned, go to byte copy: */
+	movl %edi,%ecx
+	andl $3,%ecx
+	jnz .L_1b_cache_copy_entry
+
+	/* Set 4-byte copy count (1 or 0) and remainder */
 	movl %edx,%ecx
-21:	movb (%rsi),%al
-22:	movb %al,(%rdi)
+	andl $3,%edx
+	shrl $2,%ecx
+	jz .L_1b_cache_copy_entry	/* jump if count is 0 */
+
+	/* Perform 4-byte nocache copy: */
+30:	movl (%rsi),%r8d
+31:	movnti %r8d,(%rdi)
+	leaq 4(%rsi),%rsi
+	leaq 4(%rdi),%rdi
+
+	/* If no bytes left, we're done: */
+	andl %edx,%edx
+	jz .L_finish_copy
+
+	/* Perform byte "cache" loop-copy for the remainder */
+.L_1b_cache_copy_entry:
+	movl %edx,%ecx
+.L_1b_cache_copy_loop:
+40:	movb (%rsi),%al
+41:	movb %al,(%rdi)
 	incq %rsi
 	incq %rdi
 	decl %ecx
-	jnz 21b
-23:	xorl %eax,%eax
+	jnz .L_1b_cache_copy_loop
+
+	/* Finished copying; fence the prior stores */
+.L_finish_copy:
+	xorl %eax,%eax
 	sfence
 	ret
 
 	.section .fixup,"ax"
-30:	shll $6,%ecx
+.L_fixup_4x8b_copy:
+	shll $6,%ecx
 	addl %ecx,%edx
-	jmp 60f
-40:	lea (%rdx,%rcx,8),%rdx
-	jmp 60f
-50:	movl %ecx,%edx
-60:	sfence
+	jmp .L_fixup_handle_tail
+.L_fixup_8b_copy:
+	lea (%rdx,%rcx,8),%rdx
+	jmp .L_fixup_handle_tail
+.L_fixup_4b_copy:
+	lea (%rdx,%rcx,4),%rdx
+	jmp .L_fixup_handle_tail
+.L_fixup_1b_copy:
+	movl %ecx,%edx
+.L_fixup_handle_tail:
+	sfence
 	jmp copy_user_handle_tail
 	.previous
 
-	.section __ex_table,"a"
-	.quad 1b,30b
-	.quad 2b,30b
-	.quad 3b,30b
-	.quad 4b,30b
-	.quad 5b,30b
-	.quad 6b,30b
-	.quad 7b,30b
-	.quad 8b,30b
-	.quad 9b,30b
-	.quad 10b,30b
-	.quad 11b,30b
-	.quad 12b,30b
-	.quad 13b,30b
-	.quad 14b,30b
-	.quad 15b,30b
-	.quad 16b,30b
-	.quad 18b,40b
-	.quad 19b,40b
-	.quad 21b,50b
-	.quad 22b,50b
-	.previous
+	_ASM_EXTABLE(1b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(2b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(3b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(4b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(5b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(6b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(7b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(8b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(9b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(10b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(11b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(12b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(13b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(14b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(15b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(16b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(20b,.L_fixup_8b_copy)
+	_ASM_EXTABLE(21b,.L_fixup_8b_copy)
+	_ASM_EXTABLE(30b,.L_fixup_4b_copy)
+	_ASM_EXTABLE(31b,.L_fixup_4b_copy)
+	_ASM_EXTABLE(40b,.L_fixup_1b_copy)
+	_ASM_EXTABLE(41b,.L_fixup_1b_copy)
 	CFI_ENDPROC
 ENDPROC(__copy_user_nocache)
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/crypto/ablkcipher.c linux-libre-3.2.79-gnu1/crypto/ablkcipher.c
--- linux-libre-3.2.78-gnu1/crypto/ablkcipher.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/crypto/ablkcipher.c	2016-03-31 20:54:38.000000000 -0400
@@ -461,6 +461,7 @@ static int crypto_init_givcipher_ops(str
 	crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt;
 	crt->base = __crypto_ablkcipher_cast(tfm);
 	crt->ivsize = alg->ivsize;
+	crt->has_setkey = alg->max_keysize;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/crypto/algif_skcipher.c linux-libre-3.2.79-gnu1/crypto/algif_skcipher.c
--- linux-libre-3.2.78-gnu1/crypto/algif_skcipher.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/crypto/algif_skcipher.c	2016-03-31 20:54:38.000000000 -0400
@@ -249,11 +249,8 @@ static int skcipher_sendmsg(struct kiocb
 {
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
-	struct sock *psk = ask->parent;
-	struct alg_sock *pask = alg_sk(psk);
 	struct skcipher_ctx *ctx = ask->private;
-	struct ablkcipher_tfm *skc = pask->private;
-	struct crypto_ablkcipher *tfm = skc->base;
+	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
 	unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
 	struct skcipher_sg_list *sgl;
 	struct af_alg_control con = {};
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/crypto/blkcipher.c linux-libre-3.2.79-gnu1/crypto/blkcipher.c
--- linux-libre-3.2.78-gnu1/crypto/blkcipher.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/crypto/blkcipher.c	2016-03-31 20:54:38.000000000 -0400
@@ -458,6 +458,7 @@ static int crypto_init_blkcipher_ops_asy
 	}
 	crt->base = __crypto_ablkcipher_cast(tfm);
 	crt->ivsize = alg->ivsize;
+	crt->has_setkey = alg->max_keysize;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/ata/ahci.c linux-libre-3.2.79-gnu1/drivers/ata/ahci.c
--- linux-libre-3.2.78-gnu1/drivers/ata/ahci.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/ata/ahci.c	2016-03-31 20:54:38.000000000 -0400
@@ -377,15 +377,21 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/ata/libata-scsi.c linux-libre-3.2.79-gnu1/drivers/ata/libata-scsi.c
--- linux-libre-3.2.78-gnu1/drivers/ata/libata-scsi.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/ata/libata-scsi.c	2016-03-31 20:54:38.000000000 -0400
@@ -672,19 +672,18 @@ static int ata_ioc32(struct ata_port *ap
 int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
 		     int cmd, void __user *arg)
 {
-	int val = -EINVAL, rc = -EINVAL;
+	unsigned long val;
+	int rc = -EINVAL;
 	unsigned long flags;
 
 	switch (cmd) {
-	case ATA_IOC_GET_IO32:
+	case HDIO_GET_32BIT:
 		spin_lock_irqsave(ap->lock, flags);
 		val = ata_ioc32(ap);
 		spin_unlock_irqrestore(ap->lock, flags);
-		if (copy_to_user(arg, &val, 1))
-			return -EFAULT;
-		return 0;
+		return put_user(val, (unsigned long __user *)arg);
 
-	case ATA_IOC_SET_IO32:
+	case HDIO_SET_32BIT:
 		val = (unsigned long) arg;
 		rc = 0;
 		spin_lock_irqsave(ap->lock, flags);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/gpu/drm/i915/intel_i2c.c linux-libre-3.2.79-gnu1/drivers/gpu/drm/i915/intel_i2c.c
--- linux-libre-3.2.78-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2016-03-31 20:54:38.000000000 -0400
@@ -410,7 +410,7 @@ int intel_setup_gmbus(struct drm_device
 	return 0;
 
 err:
-	while (--i) {
+	while (i--) {
 		struct intel_gmbus *bus = &dev_priv->gmbus[i];
 		i2c_del_adapter(&bus->adapter);
 	}
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/gpu/drm/radeon/radeon_device.c linux-libre-3.2.79-gnu1/drivers/gpu/drm/radeon/radeon_device.c
--- linux-libre-3.2.78-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2016-03-31 20:54:38.000000000 -0400
@@ -960,7 +960,6 @@ int radeon_resume_kms(struct drm_device
 	}
 
 	drm_kms_helper_poll_enable(dev);
-	drm_helper_hpd_irq_event(dev);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/hid/usbhid/hid-core.c linux-libre-3.2.79-gnu1/drivers/hid/usbhid/hid-core.c
--- linux-libre-3.2.78-gnu1/drivers/hid/usbhid/hid-core.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/hid/usbhid/hid-core.c	2016-03-31 20:54:38.000000000 -0400
@@ -448,8 +448,6 @@ static void hid_ctrl(struct urb *urb)
 	struct usbhid_device *usbhid = hid->driver_data;
 	int unplug = 0, status = urb->status;
 
-	spin_lock(&usbhid->lock);
-
 	switch (status) {
 	case 0:			/* success */
 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
@@ -469,6 +467,8 @@ static void hid_ctrl(struct urb *urb)
 		hid_warn(urb->dev, "ctrl urb status %d received\n", status);
 	}
 
+	spin_lock(&usbhid->lock);
+
 	if (unplug)
 		usbhid->ctrltail = usbhid->ctrlhead;
 	else
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/infiniband/core/sa_query.c linux-libre-3.2.79-gnu1/drivers/infiniband/core/sa_query.c
--- linux-libre-3.2.78-gnu1/drivers/infiniband/core/sa_query.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/infiniband/core/sa_query.c	2016-03-31 20:54:38.000000000 -0400
@@ -508,7 +508,7 @@ int ib_init_ah_from_path(struct ib_devic
 
 	force_grh = rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_ETHERNET;
 
-	if (rec->hop_limit > 1 || force_grh) {
+	if (rec->hop_limit > 0 || force_grh) {
 		ah_attr->ah_flags = IB_AH_GRH;
 		ah_attr->grh.dgid = rec->dgid;
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/input/tablet/aiptek.c linux-libre-3.2.79-gnu1/drivers/input/tablet/aiptek.c
--- linux-libre-3.2.78-gnu1/drivers/input/tablet/aiptek.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/input/tablet/aiptek.c	2016-03-31 20:54:38.000000000 -0400
@@ -1810,6 +1810,14 @@ aiptek_probe(struct usb_interface *intf,
 	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
 	input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
 
+	/* Verify that a device really has an endpoint */
+	if (intf->altsetting[0].desc.bNumEndpoints < 1) {
+		dev_err(&intf->dev,
+			"interface has %d endpoints, but must have minimum 1\n",
+			intf->altsetting[0].desc.bNumEndpoints);
+		err = -EINVAL;
+		goto fail3;
+	}
 	endpoint = &intf->altsetting[0].endpoint[0].desc;
 
 	/* Go set up our URB, which is called when the tablet receives
@@ -1852,6 +1860,7 @@ aiptek_probe(struct usb_interface *intf,
 	if (i == ARRAY_SIZE(speeds)) {
 		dev_info(&intf->dev,
 			 "Aiptek tried all speeds, no sane response\n");
+		err = -EINVAL;
 		goto fail2;
 	}
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/iommu/dmar.c linux-libre-3.2.79-gnu1/drivers/iommu/dmar.c
--- linux-libre-3.2.78-gnu1/drivers/iommu/dmar.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/iommu/dmar.c	2016-03-31 20:54:38.000000000 -0400
@@ -923,7 +923,7 @@ void dmar_disable_qi(struct intel_iommu
 
 	raw_spin_lock_irqsave(&iommu->register_lock, flags);
 
-	sts =  dmar_readq(iommu->reg + DMAR_GSTS_REG);
+	sts =  readl(iommu->reg + DMAR_GSTS_REG);
 	if (!(sts & DMA_GSTS_QIES))
 		goto end;
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/iommu/intr_remapping.c linux-libre-3.2.79-gnu1/drivers/iommu/intr_remapping.c
--- linux-libre-3.2.78-gnu1/drivers/iommu/intr_remapping.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/iommu/intr_remapping.c	2016-03-31 20:54:38.000000000 -0400
@@ -496,7 +496,7 @@ static void iommu_disable_intr_remapping
 
 	raw_spin_lock_irqsave(&iommu->register_lock, flags);
 
-	sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+	sts = readl(iommu->reg + DMAR_GSTS_REG);
 	if (!(sts & DMA_GSTS_IRES))
 		goto end;
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/mtd/ubi/upd.c linux-libre-3.2.79-gnu1/drivers/mtd/ubi/upd.c
--- linux-libre-3.2.78-gnu1/drivers/mtd/ubi/upd.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/mtd/ubi/upd.c	2016-03-31 20:54:38.000000000 -0400
@@ -197,7 +197,7 @@ int ubi_start_leb_change(struct ubi_devi
 	vol->ch_lnum = req->lnum;
 	vol->ch_dtype = req->dtype;
 
-	vol->upd_buf = vmalloc(req->bytes);
+	vol->upd_buf = vmalloc(ALIGN((int)req->bytes, ubi->min_io_size));
 	if (!vol->upd_buf)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/net/can/usb/ems_usb.c linux-libre-3.2.79-gnu1/drivers/net/can/usb/ems_usb.c
--- linux-libre-3.2.78-gnu1/drivers/net/can/usb/ems_usb.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/net/can/usb/ems_usb.c	2016-03-31 20:54:38.000000000 -0400
@@ -118,6 +118,9 @@ MODULE_LICENSE("GPL v2");
  */
 #define EMS_USB_ARM7_CLOCK 8000000
 
+#define CPC_TX_QUEUE_TRIGGER_LOW	25
+#define CPC_TX_QUEUE_TRIGGER_HIGH	35
+
 /*
  * CAN-Message representation in a CPC_MSG. Message object type is
  * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
@@ -280,6 +283,11 @@ static void ems_usb_read_interrupt_callb
 	switch (urb->status) {
 	case 0:
 		dev->free_slots = dev->intr_in_buffer[1];
+		if(dev->free_slots > CPC_TX_QUEUE_TRIGGER_HIGH){
+			if (netif_queue_stopped(netdev)){
+				netif_wake_queue(netdev);
+			}
+		}
 		break;
 
 	case -ECONNRESET: /* unlink */
@@ -535,8 +543,6 @@ static void ems_usb_write_bulk_callback(
 	/* Release context */
 	context->echo_index = MAX_TX_URBS;
 
-	if (netif_queue_stopped(netdev))
-		netif_wake_queue(netdev);
 }
 
 /*
@@ -596,7 +602,7 @@ static int ems_usb_start(struct ems_usb
 	int err, i;
 
 	dev->intr_in_buffer[0] = 0;
-	dev->free_slots = 15; /* initial size */
+	dev->free_slots = 50; /* initial size */
 
 	for (i = 0; i < MAX_RX_URBS; i++) {
 		struct urb *urb = NULL;
@@ -858,7 +864,7 @@ static netdev_tx_t ems_usb_start_xmit(st
 
 		/* Slow down tx path */
 		if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
-		    dev->free_slots < 5) {
+		    dev->free_slots < CPC_TX_QUEUE_TRIGGER_LOW) {
 			netif_stop_queue(netdev);
 		}
 	}
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/net/ethernet/mellanox/mlx4/en_port.c linux-libre-3.2.79-gnu1/drivers/net/ethernet/mellanox/mlx4/en_port.c
--- linux-libre-3.2.78-gnu1/drivers/net/ethernet/mellanox/mlx4/en_port.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/net/ethernet/mellanox/mlx4/en_port.c	2016-03-31 20:54:38.000000000 -0400
@@ -248,11 +248,11 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_e
 			   be64_to_cpu(mlx4_en_stats->MCAST_novlan);
 	stats->collisions = 0;
 	stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
-	stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+	stats->rx_over_errors = 0;
 	stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
 	stats->rx_frame_errors = 0;
 	stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
-	stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+	stats->rx_missed_errors = 0;
 	stats->tx_aborted_errors = 0;
 	stats->tx_carrier_errors = 0;
 	stats->tx_fifo_errors = 0;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/pci/xen-pcifront.c linux-libre-3.2.79-gnu1/drivers/pci/xen-pcifront.c
--- linux-libre-3.2.78-gnu1/drivers/pci/xen-pcifront.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/pci/xen-pcifront.c	2016-03-31 20:54:38.000000000 -0400
@@ -50,7 +50,7 @@ struct pcifront_device {
 };
 
 struct pcifront_sd {
-	int domain;
+	struct pci_sysdata sd;
 	struct pcifront_device *pdev;
 };
 
@@ -64,7 +64,9 @@ static inline void pcifront_init_sd(stru
 				    unsigned int domain, unsigned int bus,
 				    struct pcifront_device *pdev)
 {
-	sd->domain = domain;
+	/* Because we do not expose that information via XenBus. */
+	sd->sd.node = first_online_node;
+	sd->sd.domain = domain;
 	sd->pdev = pdev;
 }
 
@@ -461,8 +463,8 @@ static int __devinit pcifront_scan_root(
 	dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
 		 domain, bus);
 
-	bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
-	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+	bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
+	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 	if (!bus_entry || !sd) {
 		err = -ENOMEM;
 		goto err_out;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/s390/block/dasd_alias.c linux-libre-3.2.79-gnu1/drivers/s390/block/dasd_alias.c
--- linux-libre-3.2.78-gnu1/drivers/s390/block/dasd_alias.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/s390/block/dasd_alias.c	2016-03-31 20:54:38.000000000 -0400
@@ -326,8 +326,10 @@ void dasd_alias_disconnect_device_from_l
 		spin_unlock_irqrestore(&lcu->lock, flags);
 		cancel_work_sync(&lcu->suc_data.worker);
 		spin_lock_irqsave(&lcu->lock, flags);
-		if (device == lcu->suc_data.device)
+		if (device == lcu->suc_data.device) {
+			dasd_put_device(device);
 			lcu->suc_data.device = NULL;
+		}
 	}
 	was_pending = 0;
 	if (device == lcu->ruac_data.device) {
@@ -335,8 +337,10 @@ void dasd_alias_disconnect_device_from_l
 		was_pending = 1;
 		cancel_delayed_work_sync(&lcu->ruac_data.dwork);
 		spin_lock_irqsave(&lcu->lock, flags);
-		if (device == lcu->ruac_data.device)
+		if (device == lcu->ruac_data.device) {
+			dasd_put_device(device);
 			lcu->ruac_data.device = NULL;
+		}
 	}
 	private->lcu = NULL;
 	spin_unlock_irqrestore(&lcu->lock, flags);
@@ -586,8 +590,10 @@ static void lcu_update_work(struct work_
 	if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
 		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 			    " alias data in lcu (rc = %d), retry later", rc);
-		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
+		if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
+			dasd_put_device(device);
 	} else {
+		dasd_put_device(device);
 		lcu->ruac_data.device = NULL;
 		lcu->flags &= ~UPDATE_PENDING;
 	}
@@ -630,8 +636,10 @@ static int _schedule_lcu_update(struct a
 	 */
 	if (!usedev)
 		return -EINVAL;
+	dasd_get_device(usedev);
 	lcu->ruac_data.device = usedev;
-	schedule_delayed_work(&lcu->ruac_data.dwork, 0);
+	if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
+		dasd_put_device(usedev);
 	return 0;
 }
 
@@ -749,7 +757,7 @@ static int reset_summary_unit_check(stru
 	ASCEBC((char *) &cqr->magic, 4);
 	ccw = cqr->cpaddr;
 	ccw->cmd_code = DASD_ECKD_CCW_RSCK;
-	ccw->flags = 0 ;
+	ccw->flags = CCW_FLAG_SLI;
 	ccw->count = 16;
 	ccw->cda = (__u32)(addr_t) cqr->data;
 	((char *)cqr->data)[0] = reason;
@@ -953,6 +961,7 @@ static void summary_unit_check_handling_
 	/* 3. read new alias configuration */
 	_schedule_lcu_update(lcu, device);
 	lcu->suc_data.device = NULL;
+	dasd_put_device(device);
 	spin_unlock_irqrestore(&lcu->lock, flags);
 }
 
@@ -1012,6 +1021,8 @@ void dasd_alias_handle_summary_unit_chec
 	}
 	lcu->suc_data.reason = reason;
 	lcu->suc_data.device = device;
+	dasd_get_device(device);
 	spin_unlock(&lcu->lock);
-	schedule_work(&lcu->suc_data.worker);
+	if (!schedule_work(&lcu->suc_data.worker))
+		dasd_put_device(device);
 };
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/scsi/ipr.c linux-libre-3.2.79-gnu1/drivers/scsi/ipr.c
--- linux-libre-3.2.78-gnu1/drivers/scsi/ipr.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/scsi/ipr.c	2016-03-31 20:54:38.000000000 -0400
@@ -3736,13 +3736,17 @@ static ssize_t ipr_store_update_fw(struc
 	struct ipr_sglist *sglist;
 	char fname[100];
 	char *src;
-	int len, result, dnld_size;
+	char *endline;
+	int result, dnld_size;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
-	len = snprintf(fname, 99, "%s", buf);
-	fname[len-1] = '\0';
+	snprintf(fname, sizeof(fname), "%s", buf);
+
+	endline = strchr(fname, '\n');
+	if (endline)
+		*endline = '\0';
 
 	if(request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
 		dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/usb/dwc3/core.h linux-libre-3.2.79-gnu1/drivers/usb/dwc3/core.h
--- linux-libre-3.2.78-gnu1/drivers/usb/dwc3/core.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/usb/dwc3/core.h	2016-03-31 20:54:38.000000000 -0400
@@ -610,7 +610,6 @@ struct dwc3 {
 	unsigned		ep0_status_pending:1;
 	unsigned		ep0_bounced:1;
 	unsigned		ep0_expect_in:1;
-	unsigned		start_config_issued:1;
 
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_state	ep0state;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/usb/dwc3/ep0.c linux-libre-3.2.79-gnu1/drivers/usb/dwc3/ep0.c
--- linux-libre-3.2.78-gnu1/drivers/usb/dwc3/ep0.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/usb/dwc3/ep0.c	2016-03-31 20:54:38.000000000 -0400
@@ -449,7 +449,6 @@ static int dwc3_ep0_set_config(struct dw
 	u32 cfg;
 	int ret;
 
-	dwc->start_config_issued = false;
 	cfg = le16_to_cpu(ctrl->wValue);
 
 	switch (dwc->dev_state) {
@@ -498,10 +497,6 @@ static int dwc3_ep0_std_request(struct d
 		dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");
 		ret = dwc3_ep0_set_config(dwc, ctrl);
 		break;
-	case USB_REQ_SET_INTERFACE:
-		dev_vdbg(dwc->dev ,"USB_REQ_SET_INTERFACE");
-		dwc->start_config_issued = false;
-		/* Fall through */
 	default:
 		dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
 		ret = dwc3_ep0_delegate_req(dwc, ctrl);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/usb/dwc3/gadget.c linux-libre-3.2.79-gnu1/drivers/usb/dwc3/gadget.c
--- linux-libre-3.2.78-gnu1/drivers/usb/dwc3/gadget.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/usb/dwc3/gadget.c	2016-03-31 20:54:38.000000000 -0400
@@ -229,24 +229,66 @@ static void dwc3_free_trb_pool(struct dw
 	dep->trb_pool_dma = 0;
 }
 
+static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep);
+
+/**
+ * dwc3_gadget_start_config - Configure EP resources
+ * @dwc: pointer to our controller context structure
+ * @dep: endpoint that is being enabled
+ *
+ * The assignment of transfer resources cannot perfectly follow the
+ * data book due to the fact that the controller driver does not have
+ * all knowledge of the configuration in advance. It is given this
+ * information piecemeal by the composite gadget framework after every
+ * SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook
+ * programming model in this scenario can cause errors. For two
+ * reasons:
+ *
+ * 1) The databook says to do DEPSTARTCFG for every SET_CONFIGURATION
+ * and SET_INTERFACE (8.1.5). This is incorrect in the scenario of
+ * multiple interfaces.
+ *
+ * 2) The databook does not mention doing more DEPXFERCFG for new
+ * endpoint on alt setting (8.1.6).
+ *
+ * The following simplified method is used instead:
+ *
+ * All hardware endpoints can be assigned a transfer resource and this
+ * setting will stay persistent until either a core reset or
+ * hibernation. So whenever we do a DEPSTARTCFG(0) we can go ahead and
+ * do DEPXFERCFG for every hardware endpoint as well. We are
+ * guaranteed that there are as many transfer resources as endpoints.
+ *
+ * This function is called for each endpoint when it is being enabled
+ * but is triggered only when called for EP0-out, which always happens
+ * first, and which should only happen in one of the above conditions.
+ */
 static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
 	struct dwc3_gadget_ep_cmd_params params;
 	u32			cmd;
+	int			i;
+	int			ret;
+
+	if (dep->number)
+		return 0;
 
 	memset(&params, 0x00, sizeof(params));
+	cmd = DWC3_DEPCMD_DEPSTARTCFG;
 
-	if (dep->number != 1) {
-		cmd = DWC3_DEPCMD_DEPSTARTCFG;
-		/* XferRscIdx == 0 for ep0 and 2 for the remaining */
-		if (dep->number > 1) {
-			if (dwc->start_config_issued)
-				return 0;
-			dwc->start_config_issued = true;
-			cmd |= DWC3_DEPCMD_PARAM(2);
-		}
+	ret = dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
+	if (ret)
+		return ret;
 
-		return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
+	for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
+		struct dwc3_ep *dep = dwc->eps[i];
+
+		if (!dep)
+			continue;
+
+		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -340,10 +382,6 @@ static int __dwc3_gadget_ep_enable(struc
 		struct dwc3_trb_hw	*trb_link_hw;
 		struct dwc3_trb		trb_link;
 
-		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
-		if (ret)
-			return ret;
-
 		dep->desc = desc;
 		dep->type = usb_endpoint_type(desc);
 		dep->flags |= DWC3_EP_ENABLED;
@@ -1185,8 +1223,6 @@ static int dwc3_gadget_start(struct usb_
 	reg |= DWC3_DCFG_SUPERSPEED;
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
-	dwc->start_config_issued = false;
-
 	/* Start with SuperSpeed Default */
 	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 
@@ -1640,7 +1676,6 @@ static void dwc3_gadget_disconnect_inter
 
 	dwc3_stop_active_transfers(dwc);
 	dwc3_disconnect_gadget(dwc);
-	dwc->start_config_issued = false;
 
 	dwc->gadget.speed = USB_SPEED_UNKNOWN;
 }
@@ -1692,7 +1727,6 @@ static void dwc3_gadget_reset_interrupt(
 
 	dwc3_stop_active_transfers(dwc);
 	dwc3_clear_stall_all_ep(dwc);
-	dwc->start_config_issued = false;
 
 	/* Reset device address to zero */
 	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/usb/serial/cp210x.c linux-libre-3.2.79-gnu1/drivers/usb/serial/cp210x.c
--- linux-libre-3.2.78-gnu1/drivers/usb/serial/cp210x.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/usb/serial/cp210x.c	2016-03-31 20:54:38.000000000 -0400
@@ -168,6 +168,9 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
 	{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+	{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
+	{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
+	{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
 	{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
 	{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
 	{ USB_DEVICE(0x1BA4, 0x0002) },	/* Silicon Labs 358x factory default */
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/usb/serial/option.c linux-libre-3.2.79-gnu1/drivers/usb/serial/option.c
--- linux-libre-3.2.78-gnu1/drivers/usb/serial/option.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/usb/serial/option.c	2016-03-31 20:54:38.000000000 -0400
@@ -316,6 +316,7 @@ static void option_instat_callback(struc
 #define TOSHIBA_PRODUCT_G450			0x0d45
 
 #define ALINK_VENDOR_ID				0x1e0e
+#define SIMCOM_PRODUCT_SIM7100E			0x9001 /* Yes, ALINK_VENDOR_ID */
 #define ALINK_PRODUCT_PH300			0x9100
 #define ALINK_PRODUCT_3GU			0x9200
 
@@ -613,6 +614,10 @@ static const struct option_blacklist_inf
 	.reserved = BIT(3) | BIT(4),
 };
 
+static const struct option_blacklist_info simcom_sim7100e_blacklist = {
+	.reserved = BIT(5) | BIT(6),
+};
+
 static const struct option_blacklist_info telit_le910_blacklist = {
 	.sendsetup = BIT(0),
 	.reserved = BIT(1) | BIT(2),
@@ -1128,9 +1133,13 @@ static const struct usb_device_id option
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */
+	  .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
+	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
+	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
@@ -1644,6 +1653,8 @@ static const struct usb_device_id option
 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
 	{ USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
+	  .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist },
 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
 	  .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
 	},
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/drivers/xen/xen-pciback/pciback_ops.c linux-libre-3.2.79-gnu1/drivers/xen/xen-pciback/pciback_ops.c
--- linux-libre-3.2.78-gnu1/drivers/xen/xen-pciback/pciback_ops.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/drivers/xen/xen-pciback/pciback_ops.c	2016-03-31 20:54:38.000000000 -0400
@@ -225,8 +225,9 @@ int xen_pcibk_enable_msix(struct xen_pci
 	/*
 	 * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
 	 * to access the BARs where the MSI-X entries reside.
+	 * But VF devices are unique in which the PF needs to be checked.
 	 */
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	pci_read_config_word(pci_physfn(dev), PCI_COMMAND, &cmd);
 	if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
 		return -ENXIO;
 
@@ -330,6 +331,9 @@ void xen_pcibk_do_op(struct work_struct
 	struct xen_pcibk_dev_data *dev_data = NULL;
 	struct xen_pci_op *op = &pdev->op;
 	int test_intx = 0;
+#ifdef CONFIG_PCI_MSI
+	unsigned int nr = 0;
+#endif
 
 	*op = pdev->sh_info->op;
 	barrier();
@@ -358,6 +362,7 @@ void xen_pcibk_do_op(struct work_struct
 			op->err = xen_pcibk_disable_msi(pdev, dev, op);
 			break;
 		case XEN_PCI_OP_enable_msix:
+			nr = op->value;
 			op->err = xen_pcibk_enable_msix(pdev, dev, op);
 			break;
 		case XEN_PCI_OP_disable_msix:
@@ -380,7 +385,7 @@ void xen_pcibk_do_op(struct work_struct
 	if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
 		unsigned int i;
 
-		for (i = 0; i < op->value; i++)
+		for (i = 0; i < nr; i++)
 			pdev->sh_info->op.msix_entries[i].vector =
 				op->msix_entries[i].vector;
 	}
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/cifs/cifsencrypt.c linux-libre-3.2.79-gnu1/fs/cifs/cifsencrypt.c
--- linux-libre-3.2.78-gnu1/fs/cifs/cifsencrypt.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/cifs/cifsencrypt.c	2016-03-31 20:54:38.000000000 -0400
@@ -616,7 +616,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
 
 	ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
 	if (!ses->auth_key.response) {
-		rc = ENOMEM;
+		rc = -ENOMEM;
 		ses->auth_key.len = 0;
 		cERROR(1, "%s: Can't allocate auth blob", __func__);
 		goto setup_ntlmv2_rsp_ret;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/ext4/inode.c linux-libre-3.2.79-gnu1/fs/ext4/inode.c
--- linux-libre-3.2.78-gnu1/fs/ext4/inode.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/ext4/inode.c	2016-03-31 20:54:38.000000000 -0400
@@ -595,6 +595,34 @@ int ext4_map_blocks(handle_t *handle, st
 	return retval;
 }
 
+/*
+ * Update EXT4_MAP_FLAGS in bh->b_state. For buffer heads attached to pages
+ * we have to be careful as someone else may be manipulating b_state as well.
+ */
+static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
+{
+	unsigned long old_state;
+	unsigned long new_state;
+
+	flags &= EXT4_MAP_FLAGS;
+
+	/* Dummy buffer_head? Set non-atomically. */
+	if (!bh->b_page) {
+		bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | flags;
+		return;
+	}
+	/*
+	 * Someone else may be modifying b_state. Be careful! This is ugly but
+	 * once we get rid of using bh as a container for mapping information
+	 * to pass to / from get_block functions, this can go away.
+	 */
+	do {
+		old_state = ACCESS_ONCE(bh->b_state);
+		new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
+	} while (unlikely(
+		 cmpxchg(&bh->b_state, old_state, new_state) != old_state));
+}
+
 /* Maximum number of blocks we map for direct IO at once. */
 #define DIO_MAX_BLOCKS 4096
 
@@ -625,7 +653,7 @@ static int _ext4_get_block(struct inode
 	ret = ext4_map_blocks(handle, inode, &map, flags);
 	if (ret > 0) {
 		map_bh(bh, inode->i_sb, map.m_pblk);
-		bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
+		ext4_update_bh_state(bh, map.m_flags);
 		bh->b_size = inode->i_sb->s_blocksize * map.m_len;
 		ret = 0;
 	}
@@ -1787,7 +1815,7 @@ static int ext4_da_get_block_prep(struct
 		return ret;
 
 	map_bh(bh, inode->i_sb, map.m_pblk);
-	bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
+	ext4_update_bh_state(bh, map.m_flags);
 
 	if (buffer_unwritten(bh)) {
 		/* A delayed write to unwritten bh should be marked
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/hpfs/namei.c linux-libre-3.2.79-gnu1/fs/hpfs/namei.c
--- linux-libre-3.2.78-gnu1/fs/hpfs/namei.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/hpfs/namei.c	2016-03-31 20:54:38.000000000 -0400
@@ -362,12 +362,11 @@ static int hpfs_unlink(struct inode *dir
 	struct inode *inode = dentry->d_inode;
 	dnode_secno dno;
 	int r;
-	int rep = 0;
 	int err;
 
 	hpfs_lock(dir->i_sb);
 	hpfs_adjust_length(name, &len);
-again:
+
 	err = -ENOENT;
 	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
 	if (!de)
@@ -387,33 +386,9 @@ again:
 		hpfs_error(dir->i_sb, "there was error when removing dirent");
 		err = -EFSERROR;
 		break;
-	case 2:		/* no space for deleting, try to truncate file */
-
+	case 2:		/* no space for deleting */
 		err = -ENOSPC;
-		if (rep++)
-			break;
-
-		dentry_unhash(dentry);
-		if (!d_unhashed(dentry)) {
-			hpfs_unlock(dir->i_sb);
-			return -ENOSPC;
-		}
-		if (generic_permission(inode, MAY_WRITE) ||
-		    !S_ISREG(inode->i_mode) ||
-		    get_write_access(inode)) {
-			d_rehash(dentry);
-		} else {
-			struct iattr newattrs;
-			/*printk("HPFS: truncating file before delete.\n");*/
-			newattrs.ia_size = 0;
-			newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-			err = notify_change(dentry, &newattrs);
-			put_write_access(inode);
-			if (!err)
-				goto again;
-		}
-		hpfs_unlock(dir->i_sb);
-		return -ENOSPC;
+		break;
 	default:
 		drop_nlink(inode);
 		err = 0;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/jffs2/build.c linux-libre-3.2.79-gnu1/fs/jffs2/build.c
--- linux-libre-3.2.78-gnu1/fs/jffs2/build.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/jffs2/build.c	2016-03-31 20:54:38.000000000 -0400
@@ -47,7 +47,8 @@ next_inode(int *i, struct jffs2_inode_ca
 
 
 static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
-				    struct jffs2_inode_cache *ic)
+				    struct jffs2_inode_cache *ic,
+				    int *dir_hardlinks)
 {
 	struct jffs2_full_dirent *fd;
 
@@ -66,19 +67,21 @@ static void jffs2_build_inode_pass1(stru
 			dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
 				  fd->name, fd->ino, ic->ino);
 			jffs2_mark_node_obsolete(c, fd->raw);
+			/* Clear the ic/raw union so it doesn't cause problems later. */
+			fd->ic = NULL;
 			continue;
 		}
 
+		/* From this point, fd->raw is no longer used so we can set fd->ic */
+		fd->ic = child_ic;
+		child_ic->pino_nlink++;
+		/* If we appear (at this stage) to have hard-linked directories,
+		 * set a flag to trigger a scan later */
 		if (fd->type == DT_DIR) {
-			if (child_ic->pino_nlink) {
-				JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
-					    fd->name, fd->ino, ic->ino);
-				/* TODO: What do we do about it? */
-			} else {
-				child_ic->pino_nlink = ic->ino;
-			}
-		} else
-			child_ic->pino_nlink++;
+			child_ic->flags |= INO_FLAGS_IS_DIR;
+			if (child_ic->pino_nlink > 1)
+				*dir_hardlinks = 1;
+		}
 
 		dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
 		/* Can't free scan_dents so far. We might need them in pass 2 */
@@ -92,8 +95,7 @@ static void jffs2_build_inode_pass1(stru
 */
 static int jffs2_build_filesystem(struct jffs2_sb_info *c)
 {
-	int ret;
-	int i;
+	int ret, i, dir_hardlinks = 0;
 	struct jffs2_inode_cache *ic;
 	struct jffs2_full_dirent *fd;
 	struct jffs2_full_dirent *dead_fds = NULL;
@@ -117,7 +119,7 @@ static int jffs2_build_filesystem(struct
 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
 	for_each_inode(i, c, ic) {
 		if (ic->scan_dents) {
-			jffs2_build_inode_pass1(c, ic);
+			jffs2_build_inode_pass1(c, ic, &dir_hardlinks);
 			cond_resched();
 		}
 	}
@@ -153,6 +155,20 @@ static int jffs2_build_filesystem(struct
 	}
 
 	dbg_fsbuild("pass 2a complete\n");
+
+	if (dir_hardlinks) {
+		/* If we detected directory hardlinks earlier, *hopefully*
+		 * they are gone now because some of the links were from
+		 * dead directories which still had some old dirents lying
+		 * around and not yet garbage-collected, but which have
+		 * been discarded above. So clear the pino_nlink field
+		 * in each directory, so that the final scan below can
+		 * print appropriate warnings. */
+		for_each_inode(i, c, ic) {
+			if (ic->flags & INO_FLAGS_IS_DIR)
+				ic->pino_nlink = 0;
+		}
+	}
 	dbg_fsbuild("freeing temporary data structures\n");
 
 	/* Finally, we can scan again and free the dirent structs */
@@ -160,6 +176,33 @@ static int jffs2_build_filesystem(struct
 		while(ic->scan_dents) {
 			fd = ic->scan_dents;
 			ic->scan_dents = fd->next;
+			/* We do use the pino_nlink field to count nlink of
+			 * directories during fs build, so set it to the
+			 * parent ino# now. Now that there's hopefully only
+			 * one. */
+			if (fd->type == DT_DIR) {
+				if (!fd->ic) {
+					/* We'll have complained about it and marked the coresponding
+					   raw node obsolete already. Just skip it. */
+					continue;
+				}
+
+				/* We *have* to have set this in jffs2_build_inode_pass1() */
+				BUG_ON(!(fd->ic->flags & INO_FLAGS_IS_DIR));
+
+				/* We clear ic->pino_nlink ∀ directories' ic *only* if dir_hardlinks
+				 * is set. Otherwise, we know this should never trigger anyway, so
+				 * we don't do the check. And ic->pino_nlink still contains the nlink
+				 * value (which is 1). */
+				if (dir_hardlinks && fd->ic->pino_nlink) {
+					JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u is also hard linked from dir ino #%u\n",
+						    fd->name, fd->ino, ic->ino, fd->ic->pino_nlink);
+					/* Should we unlink it from its previous parent? */
+				}
+
+				/* For directories, ic->pino_nlink holds that parent inode # */
+				fd->ic->pino_nlink = ic->ino;
+			}
 			jffs2_free_full_dirent(fd);
 		}
 		ic->scan_dents = NULL;
@@ -238,11 +281,7 @@ static void jffs2_build_remove_unlinked_
 
 			/* Reduce nlink of the child. If it's now zero, stick it on the
 			   dead_fds list to be cleaned up later. Else just free the fd */
-
-			if (fd->type == DT_DIR)
-				child_ic->pino_nlink = 0;
-			else
-				child_ic->pino_nlink--;
+			child_ic->pino_nlink--;
 
 			if (!child_ic->pino_nlink) {
 				dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n",
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/jffs2/file.c linux-libre-3.2.79-gnu1/fs/jffs2/file.c
--- linux-libre-3.2.78-gnu1/fs/jffs2/file.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/jffs2/file.c	2016-03-31 20:54:38.000000000 -0400
@@ -135,39 +135,33 @@ static int jffs2_write_begin(struct file
 	struct page *pg;
 	struct inode *inode = mapping->host;
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-	struct jffs2_raw_inode ri;
-	uint32_t alloc_len = 0;
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	uint32_t pageofs = index << PAGE_CACHE_SHIFT;
 	int ret = 0;
 
-	D1(printk(KERN_DEBUG "%s()\n", __func__));
-
-	if (pageofs > inode->i_size) {
-		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-		if (ret)
-			return ret;
-	}
-
-	mutex_lock(&f->sem);
 	pg = grab_cache_page_write_begin(mapping, index, flags);
-	if (!pg) {
-		if (alloc_len)
-			jffs2_complete_reservation(c);
-		mutex_unlock(&f->sem);
+	if (!pg)
 		return -ENOMEM;
-	}
 	*pagep = pg;
 
-	if (alloc_len) {
+	D1(printk(KERN_DEBUG "%s()\n", __func__));
+
+	if (pageofs > inode->i_size) {
 		/* Make new hole frag from old EOF to new page */
+		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+		struct jffs2_raw_inode ri;
 		struct jffs2_full_dnode *fn;
+		uint32_t alloc_len;
 
 		D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
 			  (unsigned int)inode->i_size, pageofs));
 
+		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+		if (ret)
+			goto out_page;
+
+		mutex_lock(&f->sem);
 		memset(&ri, 0, sizeof(ri));
 
 		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -194,6 +188,7 @@ static int jffs2_write_begin(struct file
 		if (IS_ERR(fn)) {
 			ret = PTR_ERR(fn);
 			jffs2_complete_reservation(c);
+			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -207,10 +202,12 @@ static int jffs2_write_begin(struct file
 			jffs2_mark_node_obsolete(c, fn->raw);
 			jffs2_free_full_dnode(fn);
 			jffs2_complete_reservation(c);
+			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		jffs2_complete_reservation(c);
 		inode->i_size = pageofs;
+		mutex_unlock(&f->sem);
 	}
 
 	/*
@@ -219,18 +216,18 @@ static int jffs2_write_begin(struct file
 	 * case of a short-copy.
 	 */
 	if (!PageUptodate(pg)) {
+		mutex_lock(&f->sem);
 		ret = jffs2_do_readpage_nolock(inode, pg);
+		mutex_unlock(&f->sem);
 		if (ret)
 			goto out_page;
 	}
-	mutex_unlock(&f->sem);
 	D1(printk(KERN_DEBUG "end write_begin(). pg->flags %lx\n", pg->flags));
 	return ret;
 
 out_page:
 	unlock_page(pg);
 	page_cache_release(pg);
-	mutex_unlock(&f->sem);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/jffs2/gc.c linux-libre-3.2.79-gnu1/fs/jffs2/gc.c
--- linux-libre-3.2.78-gnu1/fs/jffs2/gc.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/jffs2/gc.c	2016-03-31 20:54:38.000000000 -0400
@@ -1246,14 +1246,17 @@ static int jffs2_garbage_collect_dnode(s
 		BUG_ON(start > orig_start);
 	}
 
-	/* First, use readpage() to read the appropriate page into the page cache */
-	/* Q: What happens if we actually try to GC the _same_ page for which commit_write()
-	 *    triggered garbage collection in the first place?
-	 * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the
-	 *    page OK. We'll actually write it out again in commit_write, which is a little
-	 *    suboptimal, but at least we're correct.
-	 */
+	/* The rules state that we must obtain the page lock *before* f->sem, so
+	 * drop f->sem temporarily. Since we also hold c->alloc_sem, nothing's
+	 * actually going to *change* so we're safe; we only allow reading.
+	 *
+	 * It is important to note that jffs2_write_begin() will ensure that its
+	 * page is marked Uptodate before allocating space. That means that if we
+	 * end up here trying to GC the *same* page that jffs2_write_begin() is
+	 * trying to write out, read_cache_page() will not deadlock. */
+	mutex_unlock(&f->sem);
 	pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
+	mutex_lock(&f->sem);
 
 	if (IS_ERR(pg_ptr)) {
 		printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg_ptr));
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/jffs2/nodelist.h linux-libre-3.2.79-gnu1/fs/jffs2/nodelist.h
--- linux-libre-3.2.78-gnu1/fs/jffs2/nodelist.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/jffs2/nodelist.h	2016-03-31 20:54:38.000000000 -0400
@@ -194,6 +194,7 @@ struct jffs2_inode_cache {
 #define INO_STATE_CLEARING	6	/* In clear_inode() */
 
 #define INO_FLAGS_XATTR_CHECKED	0x01	/* has no duplicate xattr_ref */
+#define INO_FLAGS_IS_DIR	0x02	/* is a directory */
 
 #define RAWNODE_CLASS_INODE_CACHE	0
 #define RAWNODE_CLASS_XATTR_DATUM	1
@@ -249,7 +250,10 @@ struct jffs2_readinode_info
 
 struct jffs2_full_dirent
 {
-	struct jffs2_raw_node_ref *raw;
+	union {
+		struct jffs2_raw_node_ref *raw;
+		struct jffs2_inode_cache *ic; /* Just during part of build */
+	};
 	struct jffs2_full_dirent *next;
 	uint32_t version;
 	uint32_t ino; /* == zero for unlink */
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/fs/jffs2/README.Locking linux-libre-3.2.79-gnu1/fs/jffs2/README.Locking
--- linux-libre-3.2.78-gnu1/fs/jffs2/README.Locking	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/fs/jffs2/README.Locking	2016-03-31 20:54:38.000000000 -0400
@@ -2,10 +2,6 @@
 	JFFS2 LOCKING DOCUMENTATION
 	---------------------------
 
-At least theoretically, JFFS2 does not require the Big Kernel Lock
-(BKL), which was always helpfully obtained for it by Linux 2.4 VFS
-code. It has its own locking, as described below.
-
 This document attempts to describe the existing locking rules for
 JFFS2. It is not expected to remain perfectly up to date, but ought to
 be fairly close.
@@ -69,6 +65,7 @@ Ordering constraints:
 	   any f->sem held.
 	2. Never attempt to lock two file mutexes in one thread.
 	   No ordering rules have been made for doing so.
+	3. Never lock a page cache page with f->sem held.
 
 
 	erase_completion_lock spinlock
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/ata.h linux-libre-3.2.79-gnu1/include/linux/ata.h
--- linux-libre-3.2.78-gnu1/include/linux/ata.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/ata.h	2016-03-31 20:54:38.000000000 -0400
@@ -464,8 +464,8 @@ enum ata_tf_protocols {
 };
 
 enum ata_ioctls {
-	ATA_IOC_GET_IO32	= 0x309,
-	ATA_IOC_SET_IO32	= 0x324,
+	ATA_IOC_GET_IO32	= 0x309, /* HDIO_GET_32BIT */
+	ATA_IOC_SET_IO32	= 0x324, /* HDIO_SET_32BIT */
 };
 
 /* core structures */
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/compiler.h linux-libre-3.2.79-gnu1/include/linux/compiler.h
--- linux-libre-3.2.78-gnu1/include/linux/compiler.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/compiler.h	2016-03-31 20:54:38.000000000 -0400
@@ -125,7 +125,7 @@ void ftrace_likely_update(struct ftrace_
  */
 #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
 #define __trace_if(cond) \
-	if (__builtin_constant_p((cond)) ? !!(cond) :			\
+	if (__builtin_constant_p(!!(cond)) ? !!(cond) :			\
 	({								\
 		int ______r;						\
 		static struct ftrace_branch_data			\
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/libata.h linux-libre-3.2.79-gnu1/include/linux/libata.h
--- linux-libre-3.2.78-gnu1/include/linux/libata.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/libata.h	2016-03-31 20:54:38.000000000 -0400
@@ -662,7 +662,7 @@ struct ata_device {
 	union {
 		u16		id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 		u32		gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
-	};
+	} ____cacheline_aligned;
 
 	/* error history */
 	int			spdn_cnt;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/nfs_fs.h linux-libre-3.2.79-gnu1/include/linux/nfs_fs.h
--- linux-libre-3.2.78-gnu1/include/linux/nfs_fs.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/nfs_fs.h	2016-03-31 20:54:38.000000000 -0400
@@ -588,9 +588,7 @@ static inline void nfs3_forget_cached_ac
 
 static inline loff_t nfs_size_to_loff_t(__u64 size)
 {
-	if (size > (__u64) OFFSET_MAX - 1)
-		return OFFSET_MAX - 1;
-	return (loff_t) size;
+	return min_t(u64, size, OFFSET_MAX);
 }
 
 static inline ino_t
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/poison.h linux-libre-3.2.79-gnu1/include/linux/poison.h
--- linux-libre-3.2.78-gnu1/include/linux/poison.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/poison.h	2016-03-31 20:54:38.000000000 -0400
@@ -19,8 +19,8 @@
  * under normal circumstances, used to verify that nobody uses
  * non-initialized list entries.
  */
-#define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)
-#define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)
+#define LIST_POISON1  ((void *) 0x100 + POISON_POINTER_DELTA)
+#define LIST_POISON2  ((void *) 0x200 + POISON_POINTER_DELTA)
 
 /********** include/linux/timer.h **********/
 /*
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/skbuff.h linux-libre-3.2.79-gnu1/include/linux/skbuff.h
--- linux-libre-3.2.78-gnu1/include/linux/skbuff.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/skbuff.h	2016-03-31 20:54:38.000000000 -0400
@@ -1377,6 +1377,30 @@ static inline void skb_reserve(struct sk
 	skb->tail += len;
 }
 
+/**
+ *	skb_tailroom_reserve - adjust reserved_tailroom
+ *	@skb: buffer to alter
+ *	@mtu: maximum amount of headlen permitted
+ *	@needed_tailroom: minimum amount of reserved_tailroom
+ *
+ *	Set reserved_tailroom so that headlen can be as large as possible but
+ *	not larger than mtu and tailroom cannot be smaller than
+ *	needed_tailroom.
+ *	The required headroom should already have been reserved before using
+ *	this function.
+ */
+static inline void skb_tailroom_reserve(struct sk_buff *skb, unsigned int mtu,
+					unsigned int needed_tailroom)
+{
+	SKB_LINEAR_ASSERT(skb);
+	if (mtu < skb_tailroom(skb) - needed_tailroom)
+		/* use at most mtu */
+		skb->reserved_tailroom = skb_tailroom(skb) - mtu;
+	else
+		/* use up to all available space */
+		skb->reserved_tailroom = needed_tailroom;
+}
+
 static inline void skb_reset_mac_len(struct sk_buff *skb)
 {
 	skb->mac_len = skb->network_header - skb->mac_header;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/linux/tracepoint.h linux-libre-3.2.79-gnu1/include/linux/tracepoint.h
--- linux-libre-3.2.78-gnu1/include/linux/tracepoint.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/linux/tracepoint.h	2016-03-31 20:54:38.000000000 -0400
@@ -14,8 +14,10 @@
  * See the file COPYING for more details.
  */
 
+#include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/cpumask.h>
 #include <linux/rcupdate.h>
 #include <linux/jump_label.h>
 
@@ -126,6 +128,9 @@ static inline void tracepoint_synchroniz
 		void *it_func;						\
 		void *__data;						\
 									\
+		if (!cpu_online(raw_smp_processor_id()))		\
+			return;						\
+									\
 		if (!(cond))						\
 			return;						\
 		rcu_read_lock_sched_notrace();				\
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/include/net/iw_handler.h linux-libre-3.2.79-gnu1/include/net/iw_handler.h
--- linux-libre-3.2.78-gnu1/include/net/iw_handler.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/include/net/iw_handler.h	2016-03-31 20:54:38.000000000 -0400
@@ -442,6 +442,12 @@ extern void wireless_send_event(struct n
 				unsigned int		cmd,
 				union iwreq_data *	wrqu,
 				const char *		extra);
+#ifdef CONFIG_WEXT_CORE
+/* flush all previous wext events - if work is done from netdev notifiers */
+void wireless_nlevent_flush(void);
+#else
+static inline void wireless_nlevent_flush(void) {}
+#endif
 
 /* We may need a function to send a stream of events to user space.
  * More on that later... */
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/kernel/resource.c linux-libre-3.2.79-gnu1/kernel/resource.c
--- linux-libre-3.2.78-gnu1/kernel/resource.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/kernel/resource.c	2016-03-31 20:54:38.000000000 -0400
@@ -886,9 +886,10 @@ struct resource * __request_region(struc
 		if (!conflict)
 			break;
 		if (conflict != parent) {
-			parent = conflict;
-			if (!(conflict->flags & IORESOURCE_BUSY))
+			if (!(conflict->flags & IORESOURCE_BUSY)) {
+				parent = conflict;
 				continue;
+			}
 		}
 		if (conflict->flags & flags & IORESOURCE_MUXED) {
 			add_wait_queue(&muxed_resource_wait, &wait);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/Makefile linux-libre-3.2.79-gnu1/Makefile
--- linux-libre-3.2.78-gnu1/Makefile	2016-02-28 20:53:54.000000000 -0500
+++ linux-libre-3.2.79-gnu1/Makefile	2016-04-01 15:19:20.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 78
+SUBLEVEL = 79
 EXTRAVERSION =-gnu1
 NAME = Saber-toothed Squirrel
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/mm/memory.c linux-libre-3.2.79-gnu1/mm/memory.c
--- linux-libre-3.2.78-gnu1/mm/memory.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/mm/memory.c	2016-03-31 20:54:38.000000000 -0400
@@ -3583,8 +3583,18 @@ retry:
 	 */
 	if (unlikely(pmd_none(*pmd)) && __pte_alloc(mm, vma, pmd, address))
 		return VM_FAULT_OOM;
-	/* if an huge pmd materialized from under us just retry later */
-	if (unlikely(pmd_trans_huge(*pmd)))
+	/*
+	 * If a huge pmd materialized under us just retry later.  Use
+	 * pmd_trans_unstable() instead of pmd_trans_huge() to ensure the pmd
+	 * didn't become pmd_trans_huge under us and then back to pmd_none, as
+	 * a result of MADV_DONTNEED running immediately after a huge pmd fault
+	 * in a different thread of this mm, in turn leading to a misleading
+	 * pmd_trans_huge() retval.  All we have to ensure is that it is a
+	 * regular pmd that we can walk with pte_offset_map() and we can do that
+	 * through an atomic read in C, which is what pmd_trans_unstable()
+	 * provides.
+	 */
+	if (unlikely(pmd_trans_unstable(pmd)))
 		return 0;
 	/*
 	 * A regular pmd is established and it can't morph into a huge pmd
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/ipv4/igmp.c linux-libre-3.2.79-gnu1/net/ipv4/igmp.c
--- linux-libre-3.2.78-gnu1/net/ipv4/igmp.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/ipv4/igmp.c	2016-03-31 20:54:38.000000000 -0400
@@ -327,9 +327,8 @@ static struct sk_buff *igmpv3_newpack(st
 	skb_dst_set(skb, &rt->dst);
 	skb->dev = dev;
 
-	skb->reserved_tailroom = skb_end_offset(skb) -
-				 min(mtu, skb_end_offset(skb));
 	skb_reserve(skb, hlen);
+	skb_tailroom_reserve(skb, mtu, tlen);
 
 	skb_reset_network_header(skb);
 	pip = ip_hdr(skb);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/ipv6/mcast.c linux-libre-3.2.79-gnu1/net/ipv6/mcast.c
--- linux-libre-3.2.78-gnu1/net/ipv6/mcast.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/ipv6/mcast.c	2016-03-31 20:54:38.000000000 -0400
@@ -1359,9 +1359,8 @@ static struct sk_buff *mld_newpack(struc
 	if (!skb)
 		return NULL;
 
-	skb->reserved_tailroom = skb_end_offset(skb) -
-				 min(mtu, skb_end_offset(skb));
 	skb_reserve(skb, hlen);
+	skb_tailroom_reserve(skb, mtu, tlen);
 
 	if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
 		/* <draft-ietf-magma-mld-source-05.txt>:
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/mac80211/agg-rx.c linux-libre-3.2.79-gnu1/net/mac80211/agg-rx.c
--- linux-libre-3.2.78-gnu1/net/mac80211/agg-rx.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/mac80211/agg-rx.c	2016-03-31 20:54:38.000000000 -0400
@@ -280,7 +280,7 @@ void ieee80211_process_addba_request(str
 	}
 
 	/* prepare A-MPDU MLME for Rx aggregation */
-	tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
+	tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL);
 	if (!tid_agg_rx)
 		goto end;
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/mac80211/rc80211_minstrel_ht.c linux-libre-3.2.79-gnu1/net/mac80211/rc80211_minstrel_ht.c
--- linux-libre-3.2.78-gnu1/net/mac80211/rc80211_minstrel_ht.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/mac80211/rc80211_minstrel_ht.c	2016-03-31 20:54:38.000000000 -0400
@@ -376,7 +376,7 @@ minstrel_aggr_check(struct minstrel_priv
 	if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
 		return;
 
-	ieee80211_start_tx_ba_session(pubsta, tid, 5000);
+	ieee80211_start_tx_ba_session(pubsta, tid, 0);
 }
 
 static void
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/sunrpc/cache.c linux-libre-3.2.79-gnu1/net/sunrpc/cache.c
--- linux-libre-3.2.78-gnu1/net/sunrpc/cache.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/sunrpc/cache.c	2016-03-31 20:54:38.000000000 -0400
@@ -1211,7 +1211,7 @@ int qword_get(char **bpp, char *dest, in
 	if (bp[0] == '\\' && bp[1] == 'x') {
 		/* HEX STRING */
 		bp += 2;
-		while (len < bufsize) {
+		while (len < bufsize - 1) {
 			int h, l;
 
 			h = hex_to_bin(bp[0]);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/unix/af_unix.c linux-libre-3.2.79-gnu1/net/unix/af_unix.c
--- linux-libre-3.2.78-gnu1/net/unix/af_unix.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/unix/af_unix.c	2016-03-31 20:54:38.000000000 -0400
@@ -1694,7 +1694,12 @@ restart_locked:
 			goto out_unlock;
 	}
 
-	if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+	/* other == sk && unix_peer(other) != sk if
+	 * - unix_peer(sk) == NULL, destination address bound to sk
+	 * - unix_peer(sk) == sk by time of get but disconnected before lock
+	 */
+	if (other != sk &&
+	    unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
 		if (timeo) {
 			timeo = unix_wait_for_peer(other, timeo);
 
@@ -2059,13 +2064,15 @@ static int unix_stream_recvmsg(struct ki
 	int err = 0;
 	long timeo;
 
-	err = -EINVAL;
-	if (sk->sk_state != TCP_ESTABLISHED)
+	if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
+		err = -EINVAL;
 		goto out;
+	}
 
-	err = -EOPNOTSUPP;
-	if (flags&MSG_OOB)
+	if (unlikely(flags & MSG_OOB)) {
+		err = -EOPNOTSUPP;
 		goto out;
+	}
 
 	target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
 	timeo = sock_rcvtimeo(sk, noblock);
@@ -2107,9 +2114,11 @@ static int unix_stream_recvmsg(struct ki
 				goto unlock;
 
 			unix_state_unlock(sk);
-			err = -EAGAIN;
-			if (!timeo)
+			if (!timeo) {
+				err = -EAGAIN;
 				break;
+			}
+
 			mutex_unlock(&u->readlock);
 
 			timeo = unix_stream_data_wait(sk, timeo);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/wireless/core.c linux-libre-3.2.79-gnu1/net/wireless/core.c
--- linux-libre-3.2.78-gnu1/net/wireless/core.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/wireless/core.c	2016-03-31 20:54:38.000000000 -0400
@@ -985,8 +985,12 @@ static int cfg80211_netdev_notifier_call
 		if (ret)
 			return notifier_from_errno(ret);
 		break;
+	default:
+		return NOTIFY_DONE;
 	}
 
+	wireless_nlevent_flush();
+
 	return NOTIFY_DONE;
 }
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/net/wireless/wext-core.c linux-libre-3.2.79-gnu1/net/wireless/wext-core.c
--- linux-libre-3.2.78-gnu1/net/wireless/wext-core.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/net/wireless/wext-core.c	2016-03-31 20:54:38.000000000 -0400
@@ -342,6 +342,40 @@ static const int compat_event_type_size[
 
 /* IW event code */
 
+void wireless_nlevent_flush(void)
+{
+	struct sk_buff *skb;
+	struct net *net;
+
+	ASSERT_RTNL();
+
+	for_each_net(net) {
+		while ((skb = skb_dequeue(&net->wext_nlevents)))
+			rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
+				    GFP_KERNEL);
+	}
+}
+EXPORT_SYMBOL_GPL(wireless_nlevent_flush);
+
+static int wext_netdev_notifier_call(struct notifier_block *nb,
+				     unsigned long state, void *ptr)
+{
+	/*
+	 * When a netdev changes state in any way, flush all pending messages
+	 * to avoid them going out in a strange order, e.g. RTM_NEWLINK after
+	 * RTM_DELLINK, or with IFF_UP after without IFF_UP during dev_close()
+	 * or similar - all of which could otherwise happen due to delays from
+	 * schedule_work().
+	 */
+	wireless_nlevent_flush();
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block wext_netdev_notifier = {
+	.notifier_call = wext_netdev_notifier_call,
+};
+
 static int __net_init wext_pernet_init(struct net *net)
 {
 	skb_queue_head_init(&net->wext_nlevents);
@@ -360,7 +394,12 @@ static struct pernet_operations wext_per
 
 static int __init wireless_nlevent_init(void)
 {
-	return register_pernet_subsys(&wext_pernet_ops);
+	int err = register_pernet_subsys(&wext_pernet_ops);
+
+	if (err)
+		return err;
+
+	return register_netdevice_notifier(&wext_netdev_notifier);
 }
 
 subsys_initcall(wireless_nlevent_init);
@@ -368,17 +407,8 @@ subsys_initcall(wireless_nlevent_init);
 /* Process events generated by the wireless layer or the driver. */
 static void wireless_nlevent_process(struct work_struct *work)
 {
-	struct sk_buff *skb;
-	struct net *net;
-
 	rtnl_lock();
-
-	for_each_net(net) {
-		while ((skb = skb_dequeue(&net->wext_nlevents)))
-			rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
-				    GFP_KERNEL);
-	}
-
+	wireless_nlevent_flush();
 	rtnl_unlock();
 }
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/core/seq/oss/seq_oss.c linux-libre-3.2.79-gnu1/sound/core/seq/oss/seq_oss.c
--- linux-libre-3.2.78-gnu1/sound/core/seq/oss/seq_oss.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/core/seq/oss/seq_oss.c	2016-03-31 20:54:38.000000000 -0400
@@ -150,8 +150,6 @@ odev_release(struct inode *inode, struct
 	if ((dp = file->private_data) == NULL)
 		return 0;
 
-	snd_seq_oss_drain_write(dp);
-
 	mutex_lock(&register_mutex);
 	snd_seq_oss_release(dp);
 	mutex_unlock(&register_mutex);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/core/seq/oss/seq_oss_device.h linux-libre-3.2.79-gnu1/sound/core/seq/oss/seq_oss_device.h
--- linux-libre-3.2.78-gnu1/sound/core/seq/oss/seq_oss_device.h	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/core/seq/oss/seq_oss_device.h	2016-03-31 20:54:38.000000000 -0400
@@ -131,7 +131,6 @@ int snd_seq_oss_write(struct seq_oss_dev
 unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
 
 void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
-void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
 
 /* */
 void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/core/seq/oss/seq_oss_init.c linux-libre-3.2.79-gnu1/sound/core/seq/oss/seq_oss_init.c
--- linux-libre-3.2.78-gnu1/sound/core/seq/oss/seq_oss_init.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/core/seq/oss/seq_oss_init.c	2016-03-31 20:54:38.000000000 -0400
@@ -447,23 +447,6 @@ snd_seq_oss_release(struct seq_oss_devin
 
 
 /*
- * Wait until the queue is empty (if we don't have nonblock)
- */
-void
-snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
-{
-	if (! dp->timer->running)
-		return;
-	if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
-	    dp->writeq) {
-		debug_printk(("syncing..\n"));
-		while (snd_seq_oss_writeq_sync(dp->writeq))
-			;
-	}
-}
-
-
-/*
  * reset sequencer devices
  */
 void
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/core/seq/seq_memory.c linux-libre-3.2.79-gnu1/sound/core/seq/seq_memory.c
--- linux-libre-3.2.78-gnu1/sound/core/seq/seq_memory.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/core/seq/seq_memory.c	2016-03-31 20:54:38.000000000 -0400
@@ -383,17 +383,22 @@ int snd_seq_pool_init(struct snd_seq_poo
 
 	if (snd_BUG_ON(!pool))
 		return -EINVAL;
-	if (pool->ptr)			/* should be atomic? */
-		return 0;
 
-	pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
-	if (pool->ptr == NULL) {
+	cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
+	if (!cellptr) {
 		snd_printd("seq: malloc for sequencer events failed\n");
 		return -ENOMEM;
 	}
 
 	/* add new cells to the free cell list */
 	spin_lock_irqsave(&pool->lock, flags);
+	if (pool->ptr) {
+		spin_unlock_irqrestore(&pool->lock, flags);
+		vfree(cellptr);
+		return 0;
+	}
+
+	pool->ptr = cellptr;
 	pool->free = NULL;
 
 	for (cell = 0; cell < pool->size; cell++) {
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/core/seq/seq_ports.c linux-libre-3.2.79-gnu1/sound/core/seq/seq_ports.c
--- linux-libre-3.2.78-gnu1/sound/core/seq/seq_ports.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/core/seq/seq_ports.c	2016-03-31 20:54:38.000000000 -0400
@@ -540,19 +540,22 @@ static void delete_and_unsubscribe_port(
 					bool is_src, bool ack)
 {
 	struct snd_seq_port_subs_info *grp;
+	struct list_head *list;
+	bool empty;
 
 	grp = is_src ? &port->c_src : &port->c_dest;
+	list = is_src ? &subs->src_list : &subs->dest_list;
 	down_write(&grp->list_mutex);
 	write_lock_irq(&grp->list_lock);
-	if (is_src)
-		list_del(&subs->src_list);
-	else
-		list_del(&subs->dest_list);
+	empty = list_empty(list);
+	if (!empty)
+		list_del_init(list);
 	grp->exclusive = 0;
 	write_unlock_irq(&grp->list_lock);
 	up_write(&grp->list_mutex);
 
-	unsubscribe_port(client, port, grp, &subs->info, ack);
+	if (!empty)
+		unsubscribe_port(client, port, grp, &subs->info, ack);
 }
 
 /* connect two ports */
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/core/timer_compat.c linux-libre-3.2.79-gnu1/sound/core/timer_compat.c
--- linux-libre-3.2.78-gnu1/sound/core/timer_compat.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/core/timer_compat.c	2016-03-31 20:54:38.000000000 -0400
@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(
 					struct snd_timer_status32 __user *_status)
 {
 	struct snd_timer_user *tu;
-	struct snd_timer_status status;
+	struct snd_timer_status32 status;
 	
 	tu = file->private_data;
 	if (snd_BUG_ON(!tu->timeri))
 		return -ENXIO;
 	memset(&status, 0, sizeof(status));
-	status.tstamp = tu->tstamp;
+	status.tstamp.tv_sec = tu->tstamp.tv_sec;
+	status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
 	status.resolution = snd_timer_resolution(tu->timeri);
 	status.lost = tu->timeri->lost;
 	status.overrun = tu->overrun;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/pci/rme9652/hdsp.c linux-libre-3.2.79-gnu1/sound/pci/rme9652/hdsp.c
--- linux-libre-3.2.78-gnu1/sound/pci/rme9652/hdsp.c	2016-02-28 21:10:44.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/pci/rme9652/hdsp.c	2016-04-01 15:32:43.000000000 -0400
@@ -3159,7 +3159,7 @@ static int snd_hdsp_get_dds_offset(struc
 {
 	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
+	ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp);
 	return 0;
 }
 
@@ -3171,7 +3171,7 @@ static int snd_hdsp_put_dds_offset(struc
 
 	if (!snd_hdsp_use_is_exclusive(hdsp))
 		return -EBUSY;
-	val = ucontrol->value.enumerated.item[0];
+	val = ucontrol->value.integer.value[0];
 	spin_lock_irq(&hdsp->lock);
 	if (val != hdsp_dds_offset(hdsp))
 		change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/pci/rme9652/hdspm.c linux-libre-3.2.79-gnu1/sound/pci/rme9652/hdspm.c
--- linux-libre-3.2.78-gnu1/sound/pci/rme9652/hdspm.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/pci/rme9652/hdspm.c	2016-03-31 20:54:38.000000000 -0400
@@ -4386,7 +4386,7 @@ static int snd_hdspm_get_tco_word_term(s
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.enumerated.item[0] = hdspm->tco->term;
+	ucontrol->value.integer.value[0] = hdspm->tco->term;
 
 	return 0;
 }
@@ -4397,8 +4397,8 @@ static int snd_hdspm_put_tco_word_term(s
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
-	if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
-		hdspm->tco->term = ucontrol->value.enumerated.item[0];
+	if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
+		hdspm->tco->term = ucontrol->value.integer.value[0];
 
 		hdspm_tco_write(hdspm);
 
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/soc/codecs/wm8958-dsp2.c linux-libre-3.2.79-gnu1/sound/soc/codecs/wm8958-dsp2.c
--- linux-libre-3.2.78-gnu1/sound/soc/codecs/wm8958-dsp2.c	2016-02-28 21:11:10.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/soc/codecs/wm8958-dsp2.c	2016-04-01 15:33:34.000000000 -0400
@@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct sn
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_pdata *pdata = wm8994->pdata;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
@@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct sn
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_pdata *pdata = wm8994->pdata;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
@@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struc
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_pdata *pdata = wm8994->pdata;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
@@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_pdata *pdata = wm8994->pdata;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/sound/soc/codecs/wm8994.c linux-libre-3.2.79-gnu1/sound/soc/codecs/wm8994.c
--- linux-libre-3.2.78-gnu1/sound/soc/codecs/wm8994.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/sound/soc/codecs/wm8994.c	2016-03-31 20:54:38.000000000 -0400
@@ -386,7 +386,7 @@ static int wm8994_put_drc_enum(struct sn
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_pdata *pdata = wm8994->pdata;
 	int drc = wm8994_get_drc(kcontrol->id.name);
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 
 	if (drc < 0)
 		return drc;
@@ -489,7 +489,7 @@ static int wm8994_put_retune_mobile_enum
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_pdata *pdata = wm8994->pdata;
 	int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 
 	if (block < 0)
 		return block;
diff -druNp --no-dereference linux-libre-3.2.78-gnu1/virt/kvm/async_pf.c linux-libre-3.2.79-gnu1/virt/kvm/async_pf.c
--- linux-libre-3.2.78-gnu1/virt/kvm/async_pf.c	2016-02-27 09:28:50.000000000 -0500
+++ linux-libre-3.2.79-gnu1/virt/kvm/async_pf.c	2016-03-31 20:54:38.000000000 -0400
@@ -159,7 +159,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *
 	 * do alloc nowait since if we are going to sleep anyway we
 	 * may as well sleep faulting in page
 	 */
-	work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT);
+	work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT | __GFP_NOWARN);
 	if (!work)
 		return 0;
 
