diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/arm64/kernel/hw_breakpoint.c linux-libre-3.16.78-gnu/arch/arm64/kernel/hw_breakpoint.c
--- linux-libre-3.16.77-gnu/arch/arm64/kernel/hw_breakpoint.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/arm64/kernel/hw_breakpoint.c	2019-11-22 10:57:34.000000000 -0500
@@ -501,13 +501,14 @@ int arch_validate_hwbkpt_settings(struct
 			/* Aligned */
 			break;
 		case 1:
-			/* Allow single byte watchpoint. */
-			if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
-				break;
 		case 2:
 			/* Allow halfword watchpoints and breakpoints. */
 			if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
 				break;
+		case 3:
+			/* Allow single byte watchpoint. */
+			if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
+				break;
 		default:
 			return -EINVAL;
 		}
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/sh/kernel/hw_breakpoint.c linux-libre-3.16.78-gnu/arch/sh/kernel/hw_breakpoint.c
--- linux-libre-3.16.77-gnu/arch/sh/kernel/hw_breakpoint.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/sh/kernel/hw_breakpoint.c	2019-11-22 10:57:34.000000000 -0500
@@ -160,6 +160,7 @@ int arch_bp_generic_fields(int sh_len, i
 	switch (sh_type) {
 	case SH_BREAKPOINT_READ:
 		*gen_type = HW_BREAKPOINT_R;
+		break;
 	case SH_BREAKPOINT_WRITE:
 		*gen_type = HW_BREAKPOINT_W;
 		break;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/include/asm/nospec-branch.h linux-libre-3.16.78-gnu/arch/x86/include/asm/nospec-branch.h
--- linux-libre-3.16.77-gnu/arch/x86/include/asm/nospec-branch.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/include/asm/nospec-branch.h	2019-11-22 10:57:34.000000000 -0500
@@ -151,7 +151,7 @@
 	"    	lfence;\n"					\
 	"       jmp    902b;\n"					\
 	"       .align 16\n"					\
-	"903:	addl   $4, %%esp;\n"				\
+	"903:	lea    4(%%esp), %%esp;\n"			\
 	"       pushl  %[thunk_target];\n"			\
 	"       ret;\n"						\
 	"       .align 16\n"					\
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/include/asm/ptrace.h linux-libre-3.16.78-gnu/arch/x86/include/asm/ptrace.h
--- linux-libre-3.16.77-gnu/arch/x86/include/asm/ptrace.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/include/asm/ptrace.h	2019-11-22 10:57:34.000000000 -0500
@@ -118,9 +118,9 @@ static inline int v8086_mode(struct pt_r
 #endif
 }
 
-#ifdef CONFIG_X86_64
 static inline bool user_64bit_mode(struct pt_regs *regs)
 {
+#ifdef CONFIG_X86_64
 #ifndef CONFIG_PARAVIRT
 	/*
 	 * On non-paravirt systems, this is the only long mode CPL 3
@@ -131,8 +131,12 @@ static inline bool user_64bit_mode(struc
 	/* Headers are too twisted for this to go in paravirt.h. */
 	return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
 #endif
+#else /* !CONFIG_X86_64 */
+	return false;
+#endif
 }
 
+#ifdef CONFIG_X86_64
 #define current_user_stack_pointer()	this_cpu_read(old_rsp)
 /* ia32 vs. x32 difference */
 #define compat_user_stack_pointer()	\
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/include/asm/smp.h linux-libre-3.16.78-gnu/arch/x86/include/asm/smp.h
--- linux-libre-3.16.77-gnu/arch/x86/include/asm/smp.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/include/asm/smp.h	2019-11-22 10:57:34.000000000 -0500
@@ -203,16 +203,6 @@ extern int safe_smp_processor_id(void);
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
-
-#ifndef CONFIG_X86_64
-static inline int logical_smp_processor_id(void)
-{
-	/* we don't want to mark this access volatile - bad code generation */
-	return GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
-}
-
-#endif
-
 extern int hard_smp_processor_id(void);
 
 #else /* CONFIG_X86_LOCAL_APIC */
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kernel/apic/apic.c linux-libre-3.16.78-gnu/arch/x86/kernel/apic/apic.c
--- linux-libre-3.16.77-gnu/arch/x86/kernel/apic/apic.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kernel/apic/apic.c	2019-11-22 10:57:34.000000000 -0500
@@ -1339,16 +1339,21 @@ void setup_local_APIC(void)
 	apic->init_apic_ldr();
 
 #ifdef CONFIG_X86_32
-	/*
-	 * APIC LDR is initialized.  If logical_apicid mapping was
-	 * initialized during get_smp_config(), make sure it matches the
-	 * actual value.
-	 */
-	i = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
-	WARN_ON(i != BAD_APICID && i != logical_smp_processor_id());
-	/* always use the value from LDR */
-	early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
-		logical_smp_processor_id();
+	if (apic->dest_logical) {
+		int logical_apicid, ldr_apicid;
+
+		/*
+		 * APIC LDR is initialized.  If logical_apicid mapping was
+		 * initialized during get_smp_config(), make sure it matches
+		 * the actual value.
+		 */
+		logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
+		ldr_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
+		if (logical_apicid != BAD_APICID)
+			WARN_ON(logical_apicid != ldr_apicid);
+		/* Always use the value from LDR. */
+		early_per_cpu(x86_cpu_to_logical_apicid, cpu) = ldr_apicid;
+	}
 
 	/*
 	 * Some NUMA implementations (NUMAQ) don't initialize apicid to
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kernel/apic/bigsmp_32.c linux-libre-3.16.78-gnu/arch/x86/kernel/apic/bigsmp_32.c
--- linux-libre-3.16.77-gnu/arch/x86/kernel/apic/bigsmp_32.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kernel/apic/bigsmp_32.c	2019-11-22 10:57:34.000000000 -0500
@@ -42,32 +42,12 @@ static int bigsmp_early_logical_apicid(i
 	return early_per_cpu(x86_cpu_to_apicid, cpu);
 }
 
-static inline unsigned long calculate_ldr(int cpu)
-{
-	unsigned long val, id;
-
-	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-	id = per_cpu(x86_bios_cpu_apicid, cpu);
-	val |= SET_APIC_LOGICAL_ID(id);
-
-	return val;
-}
-
 /*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
+ * bigsmp enables physical destination mode
+ * and doesn't use LDR and DFR
  */
 static void bigsmp_init_apic_ldr(void)
 {
-	unsigned long val;
-	int cpu = smp_processor_id();
-
-	apic_write(APIC_DFR, APIC_DFR_FLAT);
-	val = calculate_ldr(cpu);
-	apic_write(APIC_LDR, val);
 }
 
 static void bigsmp_setup_apic_routing(void)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kernel/cpu/bugs.c linux-libre-3.16.78-gnu/arch/x86/kernel/cpu/bugs.c
--- linux-libre-3.16.77-gnu/arch/x86/kernel/cpu/bugs.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kernel/cpu/bugs.c	2019-11-22 10:57:34.000000000 -0500
@@ -1349,12 +1349,10 @@ static ssize_t itlb_multihit_show_state(
 
 static ssize_t mds_show_state(char *buf)
 {
-#ifdef CONFIG_HYPERVISOR_GUEST
-	if (x86_hyper) {
+	if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
 		return sprintf(buf, "%s; SMT Host state unknown\n",
 			       mds_strings[mds_mitigation]);
 	}
-#endif
 
 	if (boot_cpu_has(X86_BUG_MSBDS_ONLY)) {
 		return sprintf(buf, "%s; SMT %s\n", mds_strings[mds_mitigation],
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kernel/sysfb_efi.c linux-libre-3.16.78-gnu/arch/x86/kernel/sysfb_efi.c
--- linux-libre-3.16.77-gnu/arch/x86/kernel/sysfb_efi.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kernel/sysfb_efi.c	2019-11-22 10:57:34.000000000 -0500
@@ -216,9 +216,55 @@ static const struct dmi_system_id efifb_
 	{},
 };
 
+/*
+ * Some devices have a portrait LCD but advertise a landscape resolution (and
+ * pitch). We simply swap width and height for these devices so that we can
+ * correctly deal with some of them coming with multiple resolutions.
+ */
+static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = {
+	{
+		/*
+		 * Lenovo MIIX310-10ICR, only some batches have the troublesome
+		 * 800x1280 portrait screen. Luckily the portrait version has
+		 * its own BIOS version, so we match on that.
+		 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"),
+			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1HCN44WW"),
+		},
+	},
+	{
+		/* Lenovo MIIX 320-10ICR with 800x1280 portrait screen */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
+					"Lenovo MIIX 320-10ICR"),
+		},
+	},
+	{
+		/* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
+					"Lenovo ideapad D330-10IGM"),
+		},
+	},
+	{},
+};
+
 __init void sysfb_apply_efi_quirks(void)
 {
 	if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI ||
 	    !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS))
 		dmi_check_system(efifb_dmi_system_table);
+
+	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI &&
+	    dmi_check_system(efifb_dmi_swap_width_height)) {
+		u16 temp = screen_info.lfb_width;
+
+		screen_info.lfb_width = screen_info.lfb_height;
+		screen_info.lfb_height = temp;
+		screen_info.lfb_linelength = 4 * screen_info.lfb_width;
+	}
 }
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kernel/uprobes.c linux-libre-3.16.78-gnu/arch/x86/kernel/uprobes.c
--- linux-libre-3.16.77-gnu/arch/x86/kernel/uprobes.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kernel/uprobes.c	2019-11-22 10:57:34.000000000 -0500
@@ -455,9 +455,12 @@ struct uprobe_xol_ops {
 	void	(*abort)(struct arch_uprobe *, struct pt_regs *);
 };
 
-static inline int sizeof_long(void)
+static inline int sizeof_long(struct pt_regs *regs)
 {
-	return is_ia32_task() ? 4 : 8;
+	/*
+	 * Check registers for mode as in_xxx_syscall() does not apply here.
+	 */
+	return user_64bit_mode(regs) ? 8 : 4;
 }
 
 static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
@@ -468,9 +471,9 @@ static int default_pre_xol_op(struct arc
 
 static int push_ret_address(struct pt_regs *regs, unsigned long ip)
 {
-	unsigned long new_sp = regs->sp - sizeof_long();
+	unsigned long new_sp = regs->sp - sizeof_long(regs);
 
-	if (copy_to_user((void __user *)new_sp, &ip, sizeof_long()))
+	if (copy_to_user((void __user *)new_sp, &ip, sizeof_long(regs)))
 		return -EFAULT;
 
 	regs->sp = new_sp;
@@ -503,7 +506,7 @@ static int default_post_xol_op(struct ar
 		long correction = utask->vaddr - utask->xol_vaddr;
 		regs->ip += correction;
 	} else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) {
-		regs->sp += sizeof_long(); /* Pop incorrect return address */
+		regs->sp += sizeof_long(regs); /* Pop incorrect return address */
 		if (push_ret_address(regs, utask->vaddr + auprobe->defparam.ilen))
 			return -ERESTART;
 	}
@@ -612,7 +615,7 @@ static int branch_post_xol_op(struct arc
 	 * "call" insn was executed out-of-line. Just restore ->sp and restart.
 	 * We could also restore ->ip and try to call branch_emulate_op() again.
 	 */
-	regs->sp += sizeof_long();
+	regs->sp += sizeof_long(regs);
 	return -ERESTART;
 }
 
@@ -903,7 +906,7 @@ bool arch_uprobe_skip_sstep(struct arch_
 unsigned long
 arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs)
 {
-	int rasize = sizeof_long(), nleft;
+	int rasize = sizeof_long(regs), nleft;
 	unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */
 
 	if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize))
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kvm/vmx.c linux-libre-3.16.78-gnu/arch/x86/kvm/vmx.c
--- linux-libre-3.16.77-gnu/arch/x86/kvm/vmx.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kvm/vmx.c	2019-11-22 10:57:34.000000000 -0500
@@ -6426,6 +6426,7 @@ static int handle_vmread(struct kvm_vcpu
 	unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 	u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
 	gva_t gva = 0;
+	struct x86_exception e;
 
 	if (!nested_vmx_check_permission(vcpu) ||
 	    !nested_vmx_check_vmcs12(vcpu))
@@ -6452,8 +6453,10 @@ static int handle_vmread(struct kvm_vcpu
 				vmx_instruction_info, &gva))
 			return 1;
 		/* _system ok, as nested_vmx_check_permission verified cpl=0 */
-		kvm_write_guest_virt_system(vcpu, gva, &field_value,
-					    (is_long_mode(vcpu) ? 8 : 4), NULL);
+		if (kvm_write_guest_virt_system(vcpu, gva, &field_value,
+						(is_long_mode(vcpu) ? 8 : 4),
+						&e))
+			kvm_inject_page_fault(vcpu, &e);
 	}
 
 	nested_vmx_succeed(vcpu);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/arch/x86/kvm/x86.c linux-libre-3.16.78-gnu/arch/x86/kvm/x86.c
--- linux-libre-3.16.77-gnu/arch/x86/kvm/x86.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/arch/x86/kvm/x86.c	2019-11-22 10:57:34.000000000 -0500
@@ -4329,6 +4329,13 @@ static int emulator_write_std(struct x86
 int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val,
 				unsigned int bytes, struct x86_exception *exception)
 {
+	/*
+	 * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED
+	 * is returned, but our callers are not ready for that and they blindly
+	 * call kvm_inject_page_fault.  Ensure that they at least do not leak
+	 * uninitialized kernel stack memory into cr2 and error code.
+	 */
+	memset(exception, 0, sizeof(*exception));
 	return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
 					   PFERR_WRITE_MASK, exception);
 }
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/ata/libata-zpodd.c linux-libre-3.16.78-gnu/drivers/ata/libata-zpodd.c
--- linux-libre-3.16.77-gnu/drivers/ata/libata-zpodd.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/ata/libata-zpodd.c	2019-11-22 10:57:34.000000000 -0500
@@ -55,7 +55,7 @@ static enum odd_mech_type zpodd_get_mech
 	unsigned int ret;
 	struct rm_feature_desc *desc = (void *)(buf + 8);
 	struct ata_taskfile tf;
-	static const char cdb[] = {  GPCMD_GET_CONFIGURATION,
+	static const char cdb[ATAPI_CDB_LEN] = {  GPCMD_GET_CONFIGURATION,
 			2,      /* only 1 feature descriptor requested */
 			0, 3,   /* 3, removable medium feature */
 			0, 0, 0,/* reserved */
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/char/hpet.c linux-libre-3.16.78-gnu/drivers/char/hpet.c
--- linux-libre-3.16.77-gnu/drivers/char/hpet.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/char/hpet.c	2019-11-22 10:57:34.000000000 -0500
@@ -570,8 +570,7 @@ static inline unsigned long hpet_time_di
 	unsigned long long m;
 
 	m = hpets->hp_tick_freq + (dis >> 1);
-	do_div(m, dis);
-	return (unsigned long)m;
+	return div64_ul(m, dis);
 }
 
 static int
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/hwmon/nct6775.c linux-libre-3.16.78-gnu/drivers/hwmon/nct6775.c
--- linux-libre-3.16.77-gnu/drivers/hwmon/nct6775.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/hwmon/nct6775.c	2019-11-22 10:57:34.000000000 -0500
@@ -598,7 +598,7 @@ static const u16 NCT6106_REG_TARGET[] =
 static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188 };
 static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189 };
 static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a };
-static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x17c };
+static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x18b };
 static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c };
 static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d };
 
@@ -3339,6 +3339,7 @@ static int nct6775_probe(struct platform
 		data->REG_FAN_TIME[0] = NCT6106_REG_FAN_STOP_TIME;
 		data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
 		data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
+		data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H;
 		data->REG_PWM[0] = NCT6106_REG_PWM;
 		data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
 		data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/md/dm-table.c linux-libre-3.16.78-gnu/drivers/md/dm-table.c
--- linux-libre-3.16.77-gnu/drivers/md/dm-table.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/md/dm-table.c	2019-11-22 10:57:34.000000000 -0500
@@ -1158,7 +1158,7 @@ void dm_table_event(struct dm_table *t)
 }
 EXPORT_SYMBOL(dm_table_event);
 
-sector_t dm_table_get_size(struct dm_table *t)
+inline sector_t dm_table_get_size(struct dm_table *t)
 {
 	return t->num_targets ? (t->highs[t->num_targets - 1] + 1) : 0;
 }
@@ -1183,6 +1183,9 @@ struct dm_target *dm_table_find_target(s
 	unsigned int l, n = 0, k = 0;
 	sector_t *node;
 
+	if (unlikely(sector >= dm_table_get_size(t)))
+		return &t->targets[t->num_targets];
+
 	for (l = 0; l < t->depth; l++) {
 		n = get_child(n, k);
 		node = get_node(t, l, n);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/md/persistent-data/dm-btree.c linux-libre-3.16.78-gnu/drivers/md/persistent-data/dm-btree.c
--- linux-libre-3.16.77-gnu/drivers/md/persistent-data/dm-btree.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/md/persistent-data/dm-btree.c	2019-11-22 10:57:34.000000000 -0500
@@ -533,39 +533,40 @@ static int btree_split_beneath(struct sh
 
 	new_parent = shadow_current(s);
 
+	pn = dm_block_data(new_parent);
+	size = le32_to_cpu(pn->header.flags) & INTERNAL_NODE ?
+		sizeof(__le64) : s->info->value_type.size;
+
+	/* create & init the left block */
 	r = new_block(s->info, &left);
 	if (r < 0)
 		return r;
 
+	ln = dm_block_data(left);
+	nr_left = le32_to_cpu(pn->header.nr_entries) / 2;
+
+	ln->header.flags = pn->header.flags;
+	ln->header.nr_entries = cpu_to_le32(nr_left);
+	ln->header.max_entries = pn->header.max_entries;
+	ln->header.value_size = pn->header.value_size;
+	memcpy(ln->keys, pn->keys, nr_left * sizeof(pn->keys[0]));
+	memcpy(value_ptr(ln, 0), value_ptr(pn, 0), nr_left * size);
+
+	/* create & init the right block */
 	r = new_block(s->info, &right);
 	if (r < 0) {
 		unlock_block(s->info, left);
 		return r;
 	}
 
-	pn = dm_block_data(new_parent);
-	ln = dm_block_data(left);
 	rn = dm_block_data(right);
-
-	nr_left = le32_to_cpu(pn->header.nr_entries) / 2;
 	nr_right = le32_to_cpu(pn->header.nr_entries) - nr_left;
 
-	ln->header.flags = pn->header.flags;
-	ln->header.nr_entries = cpu_to_le32(nr_left);
-	ln->header.max_entries = pn->header.max_entries;
-	ln->header.value_size = pn->header.value_size;
-
 	rn->header.flags = pn->header.flags;
 	rn->header.nr_entries = cpu_to_le32(nr_right);
 	rn->header.max_entries = pn->header.max_entries;
 	rn->header.value_size = pn->header.value_size;
-
-	memcpy(ln->keys, pn->keys, nr_left * sizeof(pn->keys[0]));
 	memcpy(rn->keys, pn->keys + nr_left, nr_right * sizeof(pn->keys[0]));
-
-	size = le32_to_cpu(pn->header.flags) & INTERNAL_NODE ?
-		sizeof(__le64) : s->info->value_type.size;
-	memcpy(value_ptr(ln, 0), value_ptr(pn, 0), nr_left * size);
 	memcpy(value_ptr(rn, 0), value_ptr(pn, nr_left),
 	       nr_right * size);
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/md/persistent-data/dm-space-map-metadata.c linux-libre-3.16.78-gnu/drivers/md/persistent-data/dm-space-map-metadata.c
--- linux-libre-3.16.77-gnu/drivers/md/persistent-data/dm-space-map-metadata.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/md/persistent-data/dm-space-map-metadata.c	2019-11-22 10:57:34.000000000 -0500
@@ -248,7 +248,7 @@ static int out(struct sm_metadata *smm)
 	}
 
 	if (smm->recursion_count == 1)
-		apply_bops(smm);
+		r = apply_bops(smm);
 
 	smm->recursion_count--;
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/md/raid5.c linux-libre-3.16.78-gnu/drivers/md/raid5.c
--- linux-libre-3.16.77-gnu/drivers/md/raid5.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/md/raid5.c	2019-11-22 10:57:34.000000000 -0500
@@ -3385,7 +3385,7 @@ static void handle_parity_checks6(struct
 		/* now write out any block on a failed drive,
 		 * or P or Q if they were recomputed
 		 */
-		BUG_ON(s->uptodate < disks - 1); /* We don't need Q to recover */
+		dev = NULL;
 		if (s->failed == 2) {
 			dev = &sh->dev[s->failed_num[1]];
 			s->locked++;
@@ -3410,6 +3410,14 @@ static void handle_parity_checks6(struct
 			set_bit(R5_LOCKED, &dev->flags);
 			set_bit(R5_Wantwrite, &dev->flags);
 		}
+		if (WARN_ONCE(dev && !test_bit(R5_UPTODATE, &dev->flags),
+			      "%s: disk%td not up to date\n",
+			      mdname(conf->mddev),
+			      dev - (struct r5dev *) &sh->dev)) {
+			clear_bit(R5_LOCKED, &dev->flags);
+			clear_bit(R5_Wantwrite, &dev->flags);
+			s->locked--;
+		}
 		clear_bit(STRIPE_DEGRADED, &sh->state);
 
 		set_bit(STRIPE_INSYNC, &sh->state);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/misc/vmw_vmci/vmci_doorbell.c linux-libre-3.16.78-gnu/drivers/misc/vmw_vmci/vmci_doorbell.c
--- linux-libre-3.16.77-gnu/drivers/misc/vmw_vmci/vmci_doorbell.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/misc/vmw_vmci/vmci_doorbell.c	2019-11-22 10:57:34.000000000 -0500
@@ -318,7 +318,8 @@ int vmci_dbell_host_context_notify(u32 s
 
 	entry = container_of(resource, struct dbell_entry, resource);
 	if (entry->run_delayed) {
-		schedule_work(&entry->work);
+		if (!schedule_work(&entry->work))
+			vmci_resource_put(resource);
 	} else {
 		entry->notify_cb(entry->client_data);
 		vmci_resource_put(resource);
@@ -366,7 +367,8 @@ static void dbell_fire_entries(u32 notif
 		    atomic_read(&dbell->active) == 1) {
 			if (dbell->run_delayed) {
 				vmci_resource_get(&dbell->resource);
-				schedule_work(&dbell->work);
+				if (!schedule_work(&dbell->work))
+					vmci_resource_put(&dbell->resource);
 			} else {
 				dbell->notify_cb(dbell->client_data);
 			}
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/mmc/card/queue.c linux-libre-3.16.78-gnu/drivers/mmc/card/queue.c
--- linux-libre-3.16.77-gnu/drivers/mmc/card/queue.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/mmc/card/queue.c	2019-11-22 10:57:34.000000000 -0500
@@ -16,6 +16,7 @@
 #include <linux/kthread.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/backing-dev.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -204,6 +205,10 @@ int mmc_init_queue(struct mmc_queue *mq,
 	if (!mq->queue)
 		return -ENOMEM;
 
+	if (mmc_host_is_spi(host) && host->use_spi_crc)
+		mq->queue->backing_dev_info.capabilities |=
+			BDI_CAP_STABLE_WRITES;
+
 	mq->mqrq_cur = mqrq_cur;
 	mq->mqrq_prev = mqrq_prev;
 	mq->queue->queuedata = mq;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/mmc/core/sd.c linux-libre-3.16.78-gnu/drivers/mmc/core/sd.c
--- linux-libre-3.16.77-gnu/drivers/mmc/core/sd.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/mmc/core/sd.c	2019-11-22 10:57:34.000000000 -0500
@@ -1242,6 +1242,12 @@ int mmc_attach_sd(struct mmc_host *host)
 			goto err;
 	}
 
+	/*
+	 * Some SD cards claims an out of spec VDD voltage range. Let's treat
+	 * these bits as being in-valid and especially also bit7.
+	 */
+	ocr &= ~0x7FFF;
+
 	rocr = mmc_select_voltage(host, ocr);
 
 	/*
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c linux-libre-3.16.78-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c
--- linux-libre-3.16.77-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c	2019-11-22 10:57:34.000000000 -0500
@@ -572,16 +572,16 @@ static int peak_usb_ndo_stop(struct net_
 	dev->state &= ~PCAN_USB_STATE_STARTED;
 	netif_stop_queue(netdev);
 
+	close_candev(netdev);
+
+	dev->can.state = CAN_STATE_STOPPED;
+
 	/* unlink all pending urbs and free used memory */
 	peak_usb_unlink_all_urbs(dev);
 
 	if (dev->adapter->dev_stop)
 		dev->adapter->dev_stop(dev);
 
-	close_candev(netdev);
-
-	dev->can.state = CAN_STATE_STOPPED;
-
 	/* can set bus off now */
 	if (dev->adapter->dev_set_bus) {
 		int err = dev->adapter->dev_set_bus(dev, 0);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/net/can/usb/peak_usb/pcan_usb_pro.c linux-libre-3.16.78-gnu/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
--- linux-libre-3.16.77-gnu/drivers/net/can/usb/peak_usb/pcan_usb_pro.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/net/can/usb/peak_usb/pcan_usb_pro.c	2019-11-22 10:57:34.000000000 -0500
@@ -508,7 +508,7 @@ static int pcan_usb_pro_drv_loaded(struc
 	u8 *buffer;
 	int err;
 
-	buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
+	buffer = kzalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-libre-3.16.78-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
--- linux-libre-3.16.77-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2019-11-14 21:43:32.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2019-11-23 14:11:09.000000000 -0500
@@ -1914,7 +1914,7 @@ u16 bnx2x_select_queue(struct net_device
 	}
 
 	/* select a non-FCoE queue */
-	return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
+	return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp));
 }
 
 void bnx2x_set_num_queues(struct bnx2x *bp)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/net/ethernet/seeq/sgiseeq.c linux-libre-3.16.78-gnu/drivers/net/ethernet/seeq/sgiseeq.c
--- linux-libre-3.16.77-gnu/drivers/net/ethernet/seeq/sgiseeq.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/net/ethernet/seeq/sgiseeq.c	2019-11-22 10:57:34.000000000 -0500
@@ -792,15 +792,16 @@ static int sgiseeq_probe(struct platform
 		printk(KERN_ERR "Sgiseeq: Cannot register net device, "
 		       "aborting.\n");
 		err = -ENODEV;
-		goto err_out_free_page;
+		goto err_out_free_attrs;
 	}
 
 	printk(KERN_INFO "%s: %s %pM\n", dev->name, sgiseeqstr, dev->dev_addr);
 
 	return 0;
 
-err_out_free_page:
-	free_page((unsigned long) sp->srings);
+err_out_free_attrs:
+	dma_free_attrs(&pdev->dev, sizeof(*sp->srings), sp->srings,
+		       sp->srings_dma, DMA_ATTR_NON_CONSISTENT);
 err_out_free_dev:
 	free_netdev(dev);
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/net/ethernet/toshiba/tc35815.c linux-libre-3.16.78-gnu/drivers/net/ethernet/toshiba/tc35815.c
--- linux-libre-3.16.77-gnu/drivers/net/ethernet/toshiba/tc35815.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/net/ethernet/toshiba/tc35815.c	2019-11-22 10:57:34.000000000 -0500
@@ -1528,7 +1528,7 @@ tc35815_rx(struct net_device *dev, int l
 			pci_unmap_single(lp->pci_dev,
 					 lp->rx_skbs[cur_bd].skb_dma,
 					 RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
-			if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN)
+			if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN != 0)
 				memmove(skb->data, skb->data - NET_IP_ALIGN,
 					pkt_len);
 			data = skb_put(skb, pkt_len);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/net/tun.c linux-libre-3.16.78-gnu/drivers/net/tun.c
--- linux-libre-3.16.77-gnu/drivers/net/tun.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/net/tun.c	2019-11-22 10:57:34.000000000 -0500
@@ -528,7 +528,8 @@ static void tun_detach_all(struct net_de
 		module_put(THIS_MODULE);
 }
 
-static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter)
+static int tun_attach(struct tun_struct *tun, struct file *file,
+		      bool skip_filter, bool publish_tun)
 {
 	struct tun_file *tfile = file->private_data;
 	int err;
@@ -561,7 +562,8 @@ static int tun_attach(struct tun_struct
 	}
 	tfile->queue_index = tun->numqueues;
 	tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
-	rcu_assign_pointer(tfile->tun, tun);
+	if (publish_tun)
+		rcu_assign_pointer(tfile->tun, tun);
 	rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
 	tun->numqueues++;
 
@@ -1599,7 +1601,8 @@ static int tun_set_iff(struct net *net,
 		if (err < 0)
 			return err;
 
-		err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER);
+		err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER,
+				 true);
 		if (err < 0)
 			return err;
 
@@ -1678,13 +1681,17 @@ static int tun_set_iff(struct net *net,
 				       NETIF_F_HW_VLAN_STAG_TX);
 
 		INIT_LIST_HEAD(&tun->disabled);
-		err = tun_attach(tun, file, false);
+		err = tun_attach(tun, file, false, false);
 		if (err < 0)
 			goto err_free_flow;
 
 		err = register_netdevice(tun->dev);
 		if (err < 0)
 			goto err_detach;
+		/* free_netdev() won't check refcnt, to aovid race
+		 * with dev_put() we need publish tun after registration.
+		 */
+		rcu_assign_pointer(tfile->tun, tun);
 
 		if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
 		    device_create_file(&tun->dev->dev, &dev_attr_owner) ||
@@ -1848,7 +1855,7 @@ static int tun_set_queue(struct file *fi
 		ret = security_tun_dev_attach_queue(tun->security);
 		if (ret < 0)
 			goto unlock;
-		ret = tun_attach(tun, file, false);
+		ret = tun_attach(tun, file, false, true);
 	} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
 		tun = rtnl_dereference(tfile->tun);
 		if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/pci/host/pci-tegra.c linux-libre-3.16.78-gnu/drivers/pci/host/pci-tegra.c
--- linux-libre-3.16.77-gnu/drivers/pci/host/pci-tegra.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/pci/host/pci-tegra.c	2019-11-22 10:57:34.000000000 -0500
@@ -615,12 +615,15 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NV
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class);
 
-/* Tegra PCIE requires relaxed ordering */
+/* Tegra20 and Tegra30 PCIE requires relaxed ordering */
 static void tegra_pcie_relax_enable(struct pci_dev *dev)
 {
 	pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_relax_enable);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
 
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/s390/block/dasd_alias.c linux-libre-3.16.78-gnu/drivers/s390/block/dasd_alias.c
--- linux-libre-3.16.77-gnu/drivers/s390/block/dasd_alias.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/s390/block/dasd_alias.c	2019-11-22 10:57:34.000000000 -0500
@@ -396,6 +396,20 @@ suborder_not_supported(struct dasd_ccw_r
 	char msg_format;
 	char msg_no;
 
+	/*
+	 * intrc values ENODEV, ENOLINK and EPERM
+	 * will be optained from sleep_on to indicate that no
+	 * IO operation can be started
+	 */
+	if (cqr->intrc == -ENODEV)
+		return 1;
+
+	if (cqr->intrc == -ENOLINK)
+		return 1;
+
+	if (cqr->intrc == -EPERM)
+		return 1;
+
 	sense = dasd_get_sense(&cqr->irb);
 	if (!sense)
 		return 0;
@@ -460,12 +474,8 @@ static int read_unit_address_configurati
 	lcu->flags &= ~NEED_UAC_UPDATE;
 	spin_unlock_irqrestore(&lcu->lock, flags);
 
-	do {
-		rc = dasd_sleep_on(cqr);
-		if (rc && suborder_not_supported(cqr))
-			return -EOPNOTSUPP;
-	} while (rc && (cqr->retries > 0));
-	if (rc) {
+	rc = dasd_sleep_on(cqr);
+	if (rc && !suborder_not_supported(cqr)) {
 		spin_lock_irqsave(&lcu->lock, flags);
 		lcu->flags |= NEED_UAC_UPDATE;
 		spin_unlock_irqrestore(&lcu->lock, flags);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/staging/comedi/drivers/dt3000.c linux-libre-3.16.78-gnu/drivers/staging/comedi/drivers/dt3000.c
--- linux-libre-3.16.77-gnu/drivers/staging/comedi/drivers/dt3000.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/staging/comedi/drivers/dt3000.c	2019-11-22 10:57:34.000000000 -0500
@@ -379,9 +379,9 @@ static irqreturn_t dt3k_interrupt(int ir
 static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
 			    unsigned int round_mode)
 {
-	int divider, base, prescale;
+	unsigned int divider, base, prescale;
 
-	/* This function needs improvment */
+	/* This function needs improvement */
 	/* Don't know if divider==0 works. */
 
 	for (prescale = 0; prescale < 16; prescale++) {
@@ -395,7 +395,7 @@ static int dt3k_ns_to_timer(unsigned int
 			divider = (*nanosec) / base;
 			break;
 		case TRIG_ROUND_UP:
-			divider = (*nanosec) / base;
+			divider = DIV_ROUND_UP(*nanosec, base);
 			break;
 		}
 		if (divider < 65536) {
@@ -405,7 +405,7 @@ static int dt3k_ns_to_timer(unsigned int
 	}
 
 	prescale = 15;
-	base = timer_base * (1 << prescale);
+	base = timer_base * (prescale + 1);
 	divider = 65535;
 	*nanosec = divider * base;
 	return (prescale << 16) | (divider);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/tty/tty_ldsem.c linux-libre-3.16.78-gnu/drivers/tty/tty_ldsem.c
--- linux-libre-3.16.77-gnu/drivers/tty/tty_ldsem.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/tty/tty_ldsem.c	2019-11-22 10:57:34.000000000 -0500
@@ -137,8 +137,7 @@ static void __ldsem_wake_readers(struct
 
 	list_for_each_entry_safe(waiter, next, &sem->read_wait, list) {
 		tsk = waiter->task;
-		smp_mb();
-		waiter->task = NULL;
+		smp_store_release(&waiter->task, NULL);
 		wake_up_process(tsk);
 		put_task_struct(tsk);
 	}
@@ -234,7 +233,7 @@ down_read_failed(struct ld_semaphore *se
 	for (;;) {
 		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 
-		if (!waiter.task)
+		if (!smp_load_acquire(&waiter.task))
 			break;
 		if (!timeout)
 			break;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/class/cdc-acm.c linux-libre-3.16.78-gnu/drivers/usb/class/cdc-acm.c
--- linux-libre-3.16.77-gnu/drivers/usb/class/cdc-acm.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/class/cdc-acm.c	2019-11-22 10:57:34.000000000 -0500
@@ -1371,13 +1371,6 @@ made_compressed_probe:
 		goto alloc_fail;
 	}
 
-	minor = acm_alloc_minor(acm);
-	if (minor == ACM_TTY_MINORS) {
-		dev_err(&intf->dev, "no more free acm devices\n");
-		kfree(acm);
-		return -ENODEV;
-	}
-
 	ctrlsize = usb_endpoint_maxp(epctrl);
 	readsize = usb_endpoint_maxp(epread) *
 				(quirks == SINGLE_RX_URB ? 1 : 2);
@@ -1385,6 +1378,16 @@ made_compressed_probe:
 	acm->writesize = usb_endpoint_maxp(epwrite) * 20;
 	acm->control = control_interface;
 	acm->data = data_interface;
+
+	usb_get_intf(acm->control); /* undone in destruct() */
+
+	minor = acm_alloc_minor(acm);
+	if (minor < 0) {
+		dev_err(&intf->dev, "no more free acm devices\n");
+		kfree(acm);
+		return -ENODEV;
+	}
+
 	acm->minor = minor;
 	acm->dev = usb_dev;
 	acm->ctrl_caps = ac_management_function;
@@ -1540,7 +1543,6 @@ skip_countries:
 	usb_driver_claim_interface(&acm_driver, data_interface, acm);
 	usb_set_intfdata(data_interface, acm);
 
-	usb_get_intf(control_interface);
 	tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
 			&control_interface->dev);
 	if (IS_ERR(tty_dev)) {
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/class/cdc-wdm.c linux-libre-3.16.78-gnu/drivers/usb/class/cdc-wdm.c
--- linux-libre-3.16.77-gnu/drivers/usb/class/cdc-wdm.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/class/cdc-wdm.c	2019-11-22 10:57:34.000000000 -0500
@@ -576,10 +576,20 @@ static int wdm_flush(struct file *file,
 {
 	struct wdm_device *desc = file->private_data;
 
-	wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
+	wait_event(desc->wait,
+			/*
+			 * needs both flags. We cannot do with one
+			 * because resetting it would cause a race
+			 * with write() yet we need to signal
+			 * a disconnect
+			 */
+			!test_bit(WDM_IN_USE, &desc->flags) ||
+			test_bit(WDM_DISCONNECTING, &desc->flags));
 
 	/* cannot dereference desc->intf if WDM_DISCONNECTING */
-	if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags))
+	if (test_bit(WDM_DISCONNECTING, &desc->flags))
+		return -ENODEV;
+	if (desc->werr < 0)
 		dev_err(&desc->intf->dev, "Error in flush path: %d\n",
 			desc->werr);
 
@@ -967,8 +977,6 @@ static void wdm_disconnect(struct usb_in
 	spin_lock_irqsave(&desc->iuspin, flags);
 	set_bit(WDM_DISCONNECTING, &desc->flags);
 	set_bit(WDM_READ, &desc->flags);
-	/* to terminate pending flushes */
-	clear_bit(WDM_IN_USE, &desc->flags);
 	spin_unlock_irqrestore(&desc->iuspin, flags);
 	wake_up_all(&desc->wait);
 	mutex_lock(&desc->rlock);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/core/file.c linux-libre-3.16.78-gnu/drivers/usb/core/file.c
--- linux-libre-3.16.77-gnu/drivers/usb/core/file.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/core/file.c	2019-11-22 10:57:34.000000000 -0500
@@ -191,9 +191,10 @@ int usb_register_dev(struct usb_interfac
 		intf->minor = minor;
 		break;
 	}
-	up_write(&minor_rwsem);
-	if (intf->minor < 0)
+	if (intf->minor < 0) {
+		up_write(&minor_rwsem);
 		return -EXFULL;
+	}
 
 	/* create a usb class device for this usb interface */
 	snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
@@ -206,12 +207,11 @@ int usb_register_dev(struct usb_interfac
 				      MKDEV(USB_MAJOR, minor), class_driver,
 				      "%s", temp);
 	if (IS_ERR(intf->usb_dev)) {
-		down_write(&minor_rwsem);
 		usb_minors[minor] = NULL;
 		intf->minor = -1;
-		up_write(&minor_rwsem);
 		retval = PTR_ERR(intf->usb_dev);
 	}
+	up_write(&minor_rwsem);
 	return retval;
 }
 EXPORT_SYMBOL_GPL(usb_register_dev);
@@ -237,12 +237,12 @@ void usb_deregister_dev(struct usb_inter
 		return;
 
 	dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);
+	device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
 
 	down_write(&minor_rwsem);
 	usb_minors[intf->minor] = NULL;
 	up_write(&minor_rwsem);
 
-	device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
 	intf->usb_dev = NULL;
 	intf->minor = -1;
 	destroy_usb_class();
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/host/hwa-hc.c linux-libre-3.16.78-gnu/drivers/usb/host/hwa-hc.c
--- linux-libre-3.16.77-gnu/drivers/usb/host/hwa-hc.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/host/hwa-hc.c	2019-11-22 10:57:34.000000000 -0500
@@ -173,7 +173,7 @@ out:
 	return result;
 
 error_set_cluster_id:
-	wusb_cluster_id_put(wusbhc->cluster_id);
+	wusb_cluster_id_put(addr);
 error_cluster_id_get:
 	goto out;
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/host/ohci-hcd.c linux-libre-3.16.78-gnu/drivers/usb/host/ohci-hcd.c
--- linux-libre-3.16.77-gnu/drivers/usb/host/ohci-hcd.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/host/ohci-hcd.c	2019-11-22 10:57:34.000000000 -0500
@@ -392,8 +392,7 @@ static void ohci_usb_reset (struct ohci_
  * other cases where the next software may expect clean state from the
  * "firmware".  this is bus-neutral, unlike shutdown() methods.
  */
-static void
-ohci_shutdown (struct usb_hcd *hcd)
+static void _ohci_shutdown(struct usb_hcd *hcd)
 {
 	struct ohci_hcd *ohci;
 
@@ -408,6 +407,16 @@ ohci_shutdown (struct usb_hcd *hcd)
 	ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
 }
 
+static void ohci_shutdown(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ohci->lock, flags);
+	_ohci_shutdown(hcd);
+	spin_unlock_irqrestore(&ohci->lock, flags);
+}
+
 static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
 {
 	return (hc32_to_cpu(ohci, ed->hwINFO) & ED_IN) != 0
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/host/pci-quirks.c linux-libre-3.16.78-gnu/drivers/usb/host/pci-quirks.c
--- linux-libre-3.16.77-gnu/drivers/usb/host/pci-quirks.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/host/pci-quirks.c	2019-11-22 10:57:34.000000000 -0500
@@ -188,7 +188,7 @@ int usb_amd_find_chipset_info(void)
 {
 	unsigned long flags;
 	struct amd_chipset_info info;
-	int ret;
+	int need_pll_quirk = 0;
 
 	spin_lock_irqsave(&amd_lock, flags);
 
@@ -202,21 +202,28 @@ int usb_amd_find_chipset_info(void)
 	spin_unlock_irqrestore(&amd_lock, flags);
 
 	if (!amd_chipset_sb_type_init(&info)) {
-		ret = 0;
 		goto commit;
 	}
 
-	/* Below chipset generations needn't enable AMD PLL quirk */
-	if (info.sb_type.gen == AMD_CHIPSET_UNKNOWN ||
-			info.sb_type.gen == AMD_CHIPSET_SB600 ||
-			info.sb_type.gen == AMD_CHIPSET_YANGTZE ||
-			(info.sb_type.gen == AMD_CHIPSET_SB700 &&
-			info.sb_type.rev > 0x3b)) {
+	switch (info.sb_type.gen) {
+	case AMD_CHIPSET_SB700:
+		need_pll_quirk = info.sb_type.rev <= 0x3B;
+		break;
+	case AMD_CHIPSET_SB800:
+	case AMD_CHIPSET_HUDSON2:
+	case AMD_CHIPSET_BOLTON:
+		need_pll_quirk = 1;
+		break;
+	default:
+		need_pll_quirk = 0;
+		break;
+	}
+
+	if (!need_pll_quirk) {
 		if (info.smbus_dev) {
 			pci_dev_put(info.smbus_dev);
 			info.smbus_dev = NULL;
 		}
-		ret = 0;
 		goto commit;
 	}
 
@@ -235,7 +242,7 @@ int usb_amd_find_chipset_info(void)
 		}
 	}
 
-	ret = info.probe_result = 1;
+	need_pll_quirk = info.probe_result = 1;
 	printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n");
 
 commit:
@@ -246,7 +253,7 @@ commit:
 
 		/* Mark that we where here */
 		amd_chipset.probe_count++;
-		ret = amd_chipset.probe_result;
+		need_pll_quirk = amd_chipset.probe_result;
 
 		spin_unlock_irqrestore(&amd_lock, flags);
 
@@ -262,7 +269,7 @@ commit:
 		spin_unlock_irqrestore(&amd_lock, flags);
 	}
 
-	return ret;
+	return need_pll_quirk;
 }
 EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info);
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/misc/yurex.c linux-libre-3.16.78-gnu/drivers/usb/misc/yurex.c
--- linux-libre-3.16.77-gnu/drivers/usb/misc/yurex.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/misc/yurex.c	2019-11-22 10:57:34.000000000 -0500
@@ -96,7 +96,6 @@ static void yurex_delete(struct kref *kr
 
 	dev_dbg(&dev->interface->dev, "%s\n", __func__);
 
-	usb_put_dev(dev->udev);
 	if (dev->cntl_urb) {
 		usb_kill_urb(dev->cntl_urb);
 		kfree(dev->cntl_req);
@@ -112,6 +111,7 @@ static void yurex_delete(struct kref *kr
 				dev->int_buffer, dev->urb->transfer_dma);
 		usb_free_urb(dev->urb);
 	}
+	usb_put_dev(dev->udev);
 	kfree(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/serial/option.c linux-libre-3.16.78-gnu/drivers/usb/serial/option.c
--- linux-libre-3.16.77-gnu/drivers/usb/serial/option.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/serial/option.c	2019-11-22 10:57:34.000000000 -0500
@@ -1109,6 +1109,11 @@ static const struct usb_device_id option
 	{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) },
 	{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7C) },
 
+	/* Motorola devices */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2a70, 0xff, 0xff, 0xff) },	/* mdm6600 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2e0a, 0xff, 0xff, 0xff) },	/* mdm9600 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x4281, 0x0a, 0x00, 0xfc) },	/* mdm ram dl */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x900e, 0xff, 0xff, 0xff) },	/* mdm qc dl */
 
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
@@ -1672,6 +1677,7 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff),  /* Telewell TW-LTE 4G v2 */
 		.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
 	{ USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) },	/* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0x00, 0x00) }, /* ZTE MF871A */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) },
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/storage/realtek_cr.c linux-libre-3.16.78-gnu/drivers/usb/storage/realtek_cr.c
--- linux-libre-3.16.77-gnu/drivers/usb/storage/realtek_cr.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/storage/realtek_cr.c	2019-11-22 10:57:34.000000000 -0500
@@ -47,7 +47,7 @@ MODULE_VERSION("1.03");
 
 static int auto_delink_en = 1;
 module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(auto_delink_en, "enable auto delink");
+MODULE_PARM_DESC(auto_delink_en, "auto delink mode (0=firmware, 1=software [default])");
 
 #ifdef CONFIG_REALTEK_AUTOPM
 static int ss_en = 1;
@@ -1001,12 +1001,15 @@ static int init_realtek_cr(struct us_dat
 			goto INIT_FAIL;
 	}
 
-	if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) ||
-	    CHECK_FW_VER(chip, 0x5901))
-		SET_AUTO_DELINK(chip);
-	if (STATUS_LEN(chip) == 16) {
-		if (SUPPORT_AUTO_DELINK(chip))
+	if (CHECK_PID(chip, 0x0138) || CHECK_PID(chip, 0x0158) ||
+	    CHECK_PID(chip, 0x0159)) {
+		if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) ||
+				CHECK_FW_VER(chip, 0x5901))
 			SET_AUTO_DELINK(chip);
+		if (STATUS_LEN(chip) == 16) {
+			if (SUPPORT_AUTO_DELINK(chip))
+				SET_AUTO_DELINK(chip);
+		}
 	}
 #ifdef CONFIG_REALTEK_AUTOPM
 	if (ss_en)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/usb/storage/unusual_devs.h linux-libre-3.16.78-gnu/drivers/usb/storage/unusual_devs.h
--- linux-libre-3.16.77-gnu/drivers/usb/storage/unusual_devs.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/usb/storage/unusual_devs.h	2019-11-22 10:57:34.000000000 -0500
@@ -1987,7 +1987,7 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x
 		US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Michael Büsch <m@bues.ch> */
-UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
+UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0117,
 		"JMicron",
 		"USB to ATA/ATAPI Bridge",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/vhost/test.c linux-libre-3.16.78-gnu/drivers/vhost/test.c
--- linux-libre-3.16.77-gnu/drivers/vhost/test.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/vhost/test.c	2019-11-22 10:57:34.000000000 -0500
@@ -23,6 +23,12 @@
  * Using this limit prevents one virtqueue from starving others. */
 #define VHOST_TEST_WEIGHT 0x80000
 
+/* Max number of packets transferred before requeueing the job.
+ * Using this limit prevents one virtqueue from starving others with
+ * pkts.
+ */
+#define VHOST_TEST_PKT_WEIGHT 256
+
 enum {
 	VHOST_TEST_VQ = 0,
 	VHOST_TEST_VQ_MAX = 1,
@@ -81,10 +87,8 @@ static void handle_vq(struct vhost_test
 		}
 		vhost_add_used_and_signal(&n->dev, vq, head, 0);
 		total_len += len;
-		if (unlikely(total_len >= VHOST_TEST_WEIGHT)) {
-			vhost_poll_queue(&vq->poll);
+		if (unlikely(vhost_exceeds_weight(vq, 0, total_len)))
 			break;
-		}
 	}
 
 	mutex_unlock(&vq->mutex);
@@ -116,7 +120,8 @@ static int vhost_test_open(struct inode
 	dev = &n->dev;
 	vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
 	n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
-	vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
+	vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX,
+		       VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT);
 
 	f->private_data = n;
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/drivers/xen/swiotlb-xen.c linux-libre-3.16.78-gnu/drivers/xen/swiotlb-xen.c
--- linux-libre-3.16.77-gnu/drivers/xen/swiotlb-xen.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/drivers/xen/swiotlb-xen.c	2019-11-22 10:57:34.000000000 -0500
@@ -372,8 +372,8 @@ xen_swiotlb_free_coherent(struct device
 	/* Convert the size to actually allocated. */
 	size = 1UL << (order + PAGE_SHIFT);
 
-	if (((dev_addr + size - 1 <= dma_mask)) ||
-	    range_straddles_page_boundary(phys, size))
+	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
+		     range_straddles_page_boundary(phys, size)))
 		xen_destroy_contiguous_region(phys, order);
 
 	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/btrfs/volumes.c linux-libre-3.16.78-gnu/fs/btrfs/volumes.c
--- linux-libre-3.16.77-gnu/fs/btrfs/volumes.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/btrfs/volumes.c	2019-11-22 10:57:34.000000000 -0500
@@ -27,6 +27,7 @@
 #include <linux/kthread.h>
 #include <linux/raid/pq.h>
 #include <linux/semaphore.h>
+#include <linux/sizes.h>
 #include <asm/div64.h>
 #include "ctree.h"
 #include "extent_map.h"
@@ -4270,21 +4271,18 @@ static int __btrfs_alloc_chunk(struct bt
 	/*
 	 * Use the number of data stripes to figure out how big this chunk
 	 * is really going to be in terms of logical address space,
-	 * and compare that answer with the max chunk size
+	 * and compare that answer with the max chunk size. If it's higher,
+	 * we try to reduce stripe_size.
 	 */
 	if (stripe_size * data_stripes > max_chunk_size) {
-		u64 mask = (1ULL << 24) - 1;
-		stripe_size = max_chunk_size;
-		do_div(stripe_size, data_stripes);
-
-		/* bump the answer up to a 16MB boundary */
-		stripe_size = (stripe_size + mask) & ~mask;
-
-		/* but don't go higher than the limits we found
-		 * while searching for free extents
+		/*
+		 * Reduce stripe_size, round it up to a 16MB boundary again and
+		 * then use it, unless it ends up being even bigger than the
+		 * previous value we had already.
 		 */
-		if (stripe_size > devices_info[ndevs-1].max_avail)
-			stripe_size = devices_info[ndevs-1].max_avail;
+		stripe_size = min(round_up(div_u64(max_chunk_size,
+						   data_stripes), SZ_16M),
+				  stripe_size);
 	}
 
 	/* align to BTRFS_STRIPE_LEN */
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/cifs/file.c linux-libre-3.16.78-gnu/fs/cifs/file.c
--- linux-libre-3.16.77-gnu/fs/cifs/file.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/cifs/file.c	2019-11-22 10:57:34.000000000 -0500
@@ -398,10 +398,11 @@ void _cifsFileInfo_put(struct cifsFileIn
 	bool oplock_break_cancelled;
 
 	spin_lock(&tcon->open_file_lock);
-
+	spin_lock(&cifsi->open_file_lock);
 	spin_lock(&cifs_file->file_info_lock);
 	if (--cifs_file->count > 0) {
 		spin_unlock(&cifs_file->file_info_lock);
+		spin_unlock(&cifsi->open_file_lock);
 		spin_unlock(&tcon->open_file_lock);
 		return;
 	}
@@ -414,9 +415,7 @@ void _cifsFileInfo_put(struct cifsFileIn
 	cifs_add_pending_open_locked(&fid, cifs_file->tlink, &open);
 
 	/* remove it from the lists */
-	spin_lock(&cifsi->open_file_lock);
 	list_del(&cifs_file->flist);
-	spin_unlock(&cifsi->open_file_lock);
 	list_del(&cifs_file->tlist);
 
 	if (list_empty(&cifsi->openFileList)) {
@@ -432,6 +431,7 @@ void _cifsFileInfo_put(struct cifsFileIn
 		cifs_set_oplock_level(cifsi, 0);
 	}
 
+	spin_unlock(&cifsi->open_file_lock);
 	spin_unlock(&tcon->open_file_lock);
 
 	oplock_break_cancelled = wait_oplock_handler ?
@@ -1756,13 +1756,12 @@ struct cifsFileInfo *find_readable_file(
 {
 	struct cifsFileInfo *open_file = NULL;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
-	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 
 	/* only filter by fsuid on multiuser mounts */
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
 		fsuid_only = false;
 
-	spin_lock(&tcon->open_file_lock);
+	spin_lock(&cifs_inode->open_file_lock);
 	/* we could simply get the first_list_entry since write-only entries
 	   are always at the end of the list but since the first entry might
 	   have a close pending, we go through the whole list */
@@ -1774,7 +1773,7 @@ struct cifsFileInfo *find_readable_file(
 				/* found a good file */
 				/* lock it so it will not be closed on us */
 				cifsFileInfo_get(open_file);
-				spin_unlock(&tcon->open_file_lock);
+				spin_unlock(&cifs_inode->open_file_lock);
 				return open_file;
 			} /* else might as well continue, and look for
 			     another, or simply have the caller reopen it
@@ -1782,7 +1781,7 @@ struct cifsFileInfo *find_readable_file(
 		} else /* write only file */
 			break; /* write only files are last so must be done */
 	}
-	spin_unlock(&tcon->open_file_lock);
+	spin_unlock(&cifs_inode->open_file_lock);
 	return NULL;
 }
 
@@ -1791,7 +1790,6 @@ struct cifsFileInfo *find_writable_file(
 {
 	struct cifsFileInfo *open_file, *inv_file = NULL;
 	struct cifs_sb_info *cifs_sb;
-	struct cifs_tcon *tcon;
 	bool any_available = false;
 	int rc;
 	unsigned int refind = 0;
@@ -1807,16 +1805,15 @@ struct cifsFileInfo *find_writable_file(
 	}
 
 	cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
-	tcon = cifs_sb_master_tcon(cifs_sb);
 
 	/* only filter by fsuid on multiuser mounts */
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
 		fsuid_only = false;
 
-	spin_lock(&tcon->open_file_lock);
+	spin_lock(&cifs_inode->open_file_lock);
 refind_writable:
 	if (refind > MAX_REOPEN_ATT) {
-		spin_unlock(&tcon->open_file_lock);
+		spin_unlock(&cifs_inode->open_file_lock);
 		return NULL;
 	}
 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
@@ -1828,7 +1825,7 @@ refind_writable:
 			if (!open_file->invalidHandle) {
 				/* found a good writable file */
 				cifsFileInfo_get(open_file);
-				spin_unlock(&tcon->open_file_lock);
+				spin_unlock(&cifs_inode->open_file_lock);
 				return open_file;
 			} else {
 				if (!inv_file)
@@ -1847,7 +1844,7 @@ refind_writable:
 		cifsFileInfo_get(inv_file);
 	}
 
-	spin_unlock(&tcon->open_file_lock);
+	spin_unlock(&cifs_inode->open_file_lock);
 
 	if (inv_file) {
 		rc = cifs_reopen_file(inv_file, false);
@@ -1861,7 +1858,7 @@ refind_writable:
 			cifsFileInfo_put(inv_file);
 			++refind;
 			inv_file = NULL;
-			spin_lock(&tcon->open_file_lock);
+			spin_lock(&cifs_inode->open_file_lock);
 			goto refind_writable;
 		}
 	}
@@ -3508,17 +3505,15 @@ static int cifs_readpage(struct file *fi
 static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
 {
 	struct cifsFileInfo *open_file;
-	struct cifs_tcon *tcon =
-		cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb));
 
-	spin_lock(&tcon->open_file_lock);
+	spin_lock(&cifs_inode->open_file_lock);
 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
 		if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
-			spin_unlock(&tcon->open_file_lock);
+			spin_unlock(&cifs_inode->open_file_lock);
 			return 1;
 		}
 	}
-	spin_unlock(&tcon->open_file_lock);
+	spin_unlock(&cifs_inode->open_file_lock);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/cifs/smb2pdu.c linux-libre-3.16.78-gnu/fs/cifs/smb2pdu.c
--- linux-libre-3.16.77-gnu/fs/cifs/smb2pdu.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/cifs/smb2pdu.c	2019-11-22 10:57:34.000000000 -0500
@@ -171,7 +171,7 @@ smb2_reconnect(__le16 smb2_command, stru
 	if (tcon == NULL)
 		return 0;
 
-	if (smb2_command == SMB2_TREE_CONNECT)
+	if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)
 		return 0;
 
 	if (tcon->tidStatus == CifsExiting) {
@@ -646,7 +646,12 @@ ssetup_ntlmssp_authenticate:
 	else
 		req->SecurityMode = 0;
 
+#ifdef CONFIG_CIFS_DFS_UPCALL
+	req->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS);
+#else
 	req->Capabilities = 0;
+#endif /* DFS_UPCALL */
+
 	req->Channel = 0; /* MBZ */
 
 	iov[0].iov_base = (char *)req;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/exec.c linux-libre-3.16.78-gnu/fs/exec.c
--- linux-libre-3.16.77-gnu/fs/exec.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/exec.c	2019-11-22 10:57:34.000000000 -0500
@@ -1589,7 +1589,7 @@ static int do_execve_common(struct filen
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
 	acct_update_integrals(current);
-	task_numa_free(current);
+	task_numa_free(current, false);
 	free_bprm(bprm);
 	putname(filename);
 	if (displaced)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/nfs/nfs4client.c linux-libre-3.16.78-gnu/fs/nfs/nfs4client.c
--- linux-libre-3.16.77-gnu/fs/nfs/nfs4client.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/nfs/nfs4client.c	2019-11-22 10:57:34.000000000 -0500
@@ -682,9 +682,12 @@ int nfs41_walk_client_list(struct nfs_cl
 
 static void nfs4_destroy_server(struct nfs_server *server)
 {
+	LIST_HEAD(freeme);
+
 	nfs_server_return_all_delegations(server);
 	unset_pnfs_layoutdriver(server);
-	nfs4_purge_state_owners(server);
+	nfs4_purge_state_owners(server, &freeme);
+	nfs4_free_state_owners(&freeme);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/nfs/nfs4_fs.h linux-libre-3.16.78-gnu/fs/nfs/nfs4_fs.h
--- linux-libre-3.16.77-gnu/fs/nfs/nfs4_fs.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/nfs/nfs4_fs.h	2019-11-22 10:57:34.000000000 -0500
@@ -419,7 +419,8 @@ static inline void nfs4_schedule_session
 
 extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *, gfp_t);
 extern void nfs4_put_state_owner(struct nfs4_state_owner *);
-extern void nfs4_purge_state_owners(struct nfs_server *);
+extern void nfs4_purge_state_owners(struct nfs_server *, struct list_head *);
+extern void nfs4_free_state_owners(struct list_head *head);
 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
 extern void nfs4_put_open_state(struct nfs4_state *);
 extern void nfs4_close_state(struct nfs4_state *, fmode_t);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/fs/nfs/nfs4state.c linux-libre-3.16.78-gnu/fs/nfs/nfs4state.c
--- linux-libre-3.16.77-gnu/fs/nfs/nfs4state.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/fs/nfs/nfs4state.c	2019-11-22 10:57:34.000000000 -0500
@@ -598,24 +598,39 @@ void nfs4_put_state_owner(struct nfs4_st
 /**
  * nfs4_purge_state_owners - Release all cached state owners
  * @server: nfs_server with cached state owners to release
+ * @head: resulting list of state owners
  *
  * Called at umount time.  Remaining state owners will be on
  * the LRU with ref count of zero.
+ * Note that the state owners are not freed, but are added
+ * to the list @head, which can later be used as an argument
+ * to nfs4_free_state_owners.
  */
-void nfs4_purge_state_owners(struct nfs_server *server)
+void nfs4_purge_state_owners(struct nfs_server *server, struct list_head *head)
 {
 	struct nfs_client *clp = server->nfs_client;
 	struct nfs4_state_owner *sp, *tmp;
-	LIST_HEAD(doomed);
 
 	spin_lock(&clp->cl_lock);
 	list_for_each_entry_safe(sp, tmp, &server->state_owners_lru, so_lru) {
-		list_move(&sp->so_lru, &doomed);
+		list_move(&sp->so_lru, head);
 		nfs4_remove_state_owner_locked(sp);
 	}
 	spin_unlock(&clp->cl_lock);
+}
 
-	list_for_each_entry_safe(sp, tmp, &doomed, so_lru) {
+/**
+ * nfs4_purge_state_owners - Release all cached state owners
+ * @head: resulting list of state owners
+ *
+ * Frees a list of state owners that was generated by
+ * nfs4_purge_state_owners
+ */
+void nfs4_free_state_owners(struct list_head *head)
+{
+	struct nfs4_state_owner *sp, *tmp;
+
+	list_for_each_entry_safe(sp, tmp, head, so_lru) {
 		list_del(&sp->so_lru);
 		nfs4_free_state_owner(sp);
 	}
@@ -1719,12 +1734,13 @@ static int nfs4_do_reclaim(struct nfs_cl
 	struct nfs4_state_owner *sp;
 	struct nfs_server *server;
 	struct rb_node *pos;
+	LIST_HEAD(freeme);
 	int status = 0;
 
 restart:
 	rcu_read_lock();
 	list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
-		nfs4_purge_state_owners(server);
+		nfs4_purge_state_owners(server, &freeme);
 		spin_lock(&clp->cl_lock);
 		for (pos = rb_first(&server->state_owners);
 		     pos != NULL;
@@ -1752,6 +1768,7 @@ restart:
 		spin_unlock(&clp->cl_lock);
 	}
 	rcu_read_unlock();
+	nfs4_free_state_owners(&freeme);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/include/asm-generic/getorder.h linux-libre-3.16.78-gnu/include/asm-generic/getorder.h
--- linux-libre-3.16.77-gnu/include/asm-generic/getorder.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/include/asm-generic/getorder.h	2019-11-22 10:57:34.000000000 -0500
@@ -6,24 +6,6 @@
 #include <linux/compiler.h>
 #include <linux/log2.h>
 
-/*
- * Runtime evaluation of get_order()
- */
-static inline __attribute_const__
-int __get_order(unsigned long size)
-{
-	int order;
-
-	size--;
-	size >>= PAGE_SHIFT;
-#if BITS_PER_LONG == 32
-	order = fls(size);
-#else
-	order = fls64(size);
-#endif
-	return order;
-}
-
 /**
  * get_order - Determine the allocation order of a memory size
  * @size: The size for which to get the order
@@ -42,19 +24,27 @@ int __get_order(unsigned long size)
  * to hold an object of the specified size.
  *
  * The result is undefined if the size is 0.
- *
- * This function may be used to initialise variables with compile time
- * evaluations of constants.
  */
-#define get_order(n)						\
-(								\
-	__builtin_constant_p(n) ? (				\
-		((n) == 0UL) ? BITS_PER_LONG - PAGE_SHIFT :	\
-		(((n) < (1UL << PAGE_SHIFT)) ? 0 :		\
-		 ilog2((n) - 1) - PAGE_SHIFT + 1)		\
-	) :							\
-	__get_order(n)						\
-)
+static inline __attribute_const__ int get_order(unsigned long size)
+{
+	if (__builtin_constant_p(size)) {
+		if (!size)
+			return BITS_PER_LONG - PAGE_SHIFT;
+
+		if (size < (1UL << PAGE_SHIFT))
+			return 0;
+
+		return ilog2((size) - 1) - PAGE_SHIFT + 1;
+	}
+
+	size--;
+	size >>= PAGE_SHIFT;
+#if BITS_PER_LONG == 32
+	return fls(size);
+#else
+	return fls64(size);
+#endif
+}
 
 #endif	/* __ASSEMBLY__ */
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/include/linux/sched.h linux-libre-3.16.78-gnu/include/linux/sched.h
--- linux-libre-3.16.77-gnu/include/linux/sched.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/include/linux/sched.h	2019-11-22 10:57:34.000000000 -0500
@@ -1671,7 +1671,7 @@ struct task_struct {
 extern void task_numa_fault(int last_node, int node, int pages, int flags);
 extern pid_t task_numa_group_id(struct task_struct *p);
 extern void set_numabalancing_state(bool enabled);
-extern void task_numa_free(struct task_struct *p);
+extern void task_numa_free(struct task_struct *p, bool final);
 extern bool should_numa_migrate_memory(struct task_struct *p, struct page *page,
 					int src_nid, int dst_cpu);
 #else
@@ -1686,7 +1686,7 @@ static inline pid_t task_numa_group_id(s
 static inline void set_numabalancing_state(bool enabled)
 {
 }
-static inline void task_numa_free(struct task_struct *p)
+static inline void task_numa_free(struct task_struct *p, bool final)
 {
 }
 static inline bool should_numa_migrate_memory(struct task_struct *p,
diff -druNp --no-dereference linux-libre-3.16.77-gnu/include/sound/compress_driver.h linux-libre-3.16.78-gnu/include/sound/compress_driver.h
--- linux-libre-3.16.77-gnu/include/sound/compress_driver.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/include/sound/compress_driver.h	2019-11-22 10:57:34.000000000 -0500
@@ -176,10 +176,7 @@ static inline void snd_compr_drain_notif
 	if (snd_BUG_ON(!stream))
 		return;
 
-	if (stream->direction == SND_COMPRESS_PLAYBACK)
-		stream->runtime->state = SNDRV_PCM_STATE_SETUP;
-	else
-		stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
+	stream->runtime->state = SNDRV_PCM_STATE_SETUP;
 
 	wake_up(&stream->runtime->sleep);
 }
diff -druNp --no-dereference linux-libre-3.16.77-gnu/kernel/fork.c linux-libre-3.16.78-gnu/kernel/fork.c
--- linux-libre-3.16.77-gnu/kernel/fork.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/kernel/fork.c	2019-11-22 10:57:34.000000000 -0500
@@ -242,7 +242,7 @@ void __put_task_struct(struct task_struc
 	WARN_ON(atomic_read(&tsk->usage));
 	WARN_ON(tsk == current);
 
-	task_numa_free(tsk);
+	task_numa_free(tsk, true);
 	security_task_free(tsk);
 	exit_creds(tsk);
 	delayacct_tsk_free(tsk);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/kernel/irq/resend.c linux-libre-3.16.78-gnu/kernel/irq/resend.c
--- linux-libre-3.16.77-gnu/kernel/irq/resend.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/kernel/irq/resend.c	2019-11-22 10:57:34.000000000 -0500
@@ -37,6 +37,8 @@ static void resend_irqs(unsigned long ar
 		irq = find_first_bit(irqs_resend, nr_irqs);
 		clear_bit(irq, irqs_resend);
 		desc = irq_to_desc(irq);
+		if (!desc)
+			continue;
 		local_irq_disable();
 		desc->handle_irq(irq, desc);
 		local_irq_enable();
diff -druNp --no-dereference linux-libre-3.16.77-gnu/kernel/sched/fair.c linux-libre-3.16.78-gnu/kernel/sched/fair.c
--- linux-libre-3.16.77-gnu/kernel/sched/fair.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/kernel/sched/fair.c	2019-11-22 10:57:34.000000000 -0500
@@ -1747,13 +1747,23 @@ no_join:
 	return;
 }
 
-void task_numa_free(struct task_struct *p)
+/*
+ * Get rid of NUMA staticstics associated with a task (either current or dead).
+ * If @final is set, the task is dead and has reached refcount zero, so we can
+ * safely free all relevant data structures. Otherwise, there might be
+ * concurrent reads from places like load balancing and procfs, and we should
+ * reset the data back to default state without freeing ->numa_faults.
+ */
+void task_numa_free(struct task_struct *p, bool final)
 {
 	struct numa_group *grp = p->numa_group;
-	void *numa_faults = p->numa_faults_memory;
+	unsigned long *numa_faults = p->numa_faults_memory;
 	unsigned long flags;
 	int i;
 
+	if (!numa_faults)
+		return;
+
 	if (grp) {
 		spin_lock_irqsave(&grp->lock, flags);
 		for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
@@ -1767,11 +1777,17 @@ void task_numa_free(struct task_struct *
 		put_numa_group(grp);
 	}
 
-	p->numa_faults_memory = NULL;
-	p->numa_faults_buffer_memory = NULL;
-	p->numa_faults_cpu= NULL;
-	p->numa_faults_buffer_cpu = NULL;
-	kfree(numa_faults);
+	if (final) {
+		p->numa_faults_memory = NULL;
+		p->numa_faults_buffer_memory = NULL;
+		p->numa_faults_cpu = NULL;
+		p->numa_faults_buffer_cpu = NULL;
+		kfree(numa_faults);
+	} else {
+		p->total_numa_faults = 0;
+		for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
+			numa_faults[i] = 0;
+	}
 }
 
 /*
@@ -3255,6 +3271,8 @@ static void __account_cfs_rq_runtime(str
 	if (likely(cfs_rq->runtime_remaining > 0))
 		return;
 
+	if (cfs_rq->throttled)
+		return;
 	/*
 	 * if we're unable to extend our runtime we resched so that the active
 	 * hierarchy can be throttled
@@ -3434,6 +3452,11 @@ static u64 distribute_cfs_runtime(struct
 		if (!cfs_rq_throttled(cfs_rq))
 			goto next;
 
+		/* By the above check, this should never be true */
+#ifdef CONFIG_SCHED_DEBUG
+		WARN_ON_ONCE(cfs_rq->runtime_remaining > 0);
+#endif
+
 		runtime = -cfs_rq->runtime_remaining + 1;
 		if (runtime > remaining)
 			runtime = remaining;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/kernel/time/alarmtimer.c linux-libre-3.16.78-gnu/kernel/time/alarmtimer.c
--- linux-libre-3.16.77-gnu/kernel/time/alarmtimer.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/kernel/time/alarmtimer.c	2019-11-22 10:57:34.000000000 -0500
@@ -533,7 +533,7 @@ static int alarm_timer_create(struct k_i
 	struct alarm_base *base;
 
 	if (!alarmtimer_get_rtcdev())
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	if (!capable(CAP_WAKE_ALARM))
 		return -EPERM;
@@ -576,7 +576,7 @@ static void alarm_timer_get(struct k_iti
 static int alarm_timer_del(struct k_itimer *timr)
 {
 	if (!rtcdev)
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
 		return TIMER_RETRY;
@@ -600,7 +600,7 @@ static int alarm_timer_set(struct k_itim
 	ktime_t exp;
 
 	if (!rtcdev)
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	if (flags & ~TIMER_ABSTIME)
 		return -EINVAL;
@@ -761,7 +761,7 @@ static int alarm_timer_nsleep(const cloc
 	struct restart_block *restart;
 
 	if (!alarmtimer_get_rtcdev())
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	if (flags & ~TIMER_ABSTIME)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/Makefile linux-libre-3.16.78-gnu/Makefile
--- linux-libre-3.16.77-gnu/Makefile	2019-11-14 21:37:06.000000000 -0500
+++ linux-libre-3.16.78-gnu/Makefile	2019-11-23 14:04:44.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 16
-SUBLEVEL = 77
+SUBLEVEL = 78
 EXTRAVERSION =-gnu
 NAME = Museum of Fishiegoodies
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/batman-adv/bat_iv_ogm.c linux-libre-3.16.78-gnu/net/batman-adv/bat_iv_ogm.c
--- linux-libre-3.16.77-gnu/net/batman-adv/bat_iv_ogm.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/batman-adv/bat_iv_ogm.c	2019-11-22 10:57:34.000000000 -0500
@@ -395,13 +395,19 @@ static uint8_t batadv_hop_penalty(uint8_
 }
 
 /* is there another aggregated packet here? */
-static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
-				     __be16 tvlv_len)
+static bool
+batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
+			  const struct batadv_ogm_packet *ogm_packet)
 {
 	int next_buff_pos = 0;
 
-	next_buff_pos += buff_pos + BATADV_OGM_HLEN;
-	next_buff_pos += ntohs(tvlv_len);
+	/* check if there is enough space for the header */
+	next_buff_pos += buff_pos + sizeof(*ogm_packet);
+	if (next_buff_pos > packet_len)
+		return false;
+
+	/* check if there is enough space for the optional TVLV */
+	next_buff_pos += ntohs(ogm_packet->tvlv_len);
 
 	return (next_buff_pos <= packet_len) &&
 	       (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
@@ -429,7 +435,7 @@ static void batadv_iv_ogm_send_to_if(str
 
 	/* adjust all flags and log packets */
 	while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
-					 batadv_ogm_packet->tvlv_len)) {
+					 batadv_ogm_packet)) {
 		/* we might have aggregated direct link packets with an
 		 * ordinary base packet
 		 */
@@ -1745,7 +1751,7 @@ static int batadv_iv_ogm_receive(struct
 
 	/* unpack the aggregated packets and process them one by one */
 	while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
-					 ogm_packet->tvlv_len)) {
+					 ogm_packet)) {
 		batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
 
 		ogm_offset += BATADV_OGM_HLEN;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/bridge/br_multicast.c linux-libre-3.16.78-gnu/net/bridge/br_multicast.c
--- linux-libre-3.16.77-gnu/net/bridge/br_multicast.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/bridge/br_multicast.c	2019-11-22 10:57:34.000000000 -0500
@@ -1471,6 +1471,9 @@ br_multicast_leave_group(struct net_brid
 			if (p->port != port)
 				continue;
 
+			if (p->state & MDB_PERMANENT)
+				break;
+
 			rcu_assign_pointer(*pp, p->next);
 			hlist_del_init(&p->mglist);
 			del_timer(&p->timer);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/core/dev.c linux-libre-3.16.78-gnu/net/core/dev.c
--- linux-libre-3.16.77-gnu/net/core/dev.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/core/dev.c	2019-11-22 10:57:34.000000000 -0500
@@ -6278,6 +6278,8 @@ int register_netdevice(struct net_device
 	ret = notifier_to_errno(ret);
 	if (ret) {
 		rollback_registered(dev);
+		rcu_barrier();
+
 		dev->reg_state = NETREG_UNREGISTERED;
 	}
 	/*
@@ -7207,6 +7209,8 @@ static void __net_exit default_device_ex
 
 		/* Push remaining network devices to init_net */
 		snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
+		if (__dev_get_by_name(&init_net, fb_name))
+			snprintf(fb_name, IFNAMSIZ, "dev%%d");
 		err = dev_change_net_namespace(dev, &init_net, fb_name);
 		if (err) {
 			pr_emerg("%s: failed to move %s to init_net: %d\n",
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/ipv4/tcp_input.c linux-libre-3.16.78-gnu/net/ipv4/tcp_input.c
--- linux-libre-3.16.77-gnu/net/ipv4/tcp_input.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/ipv4/tcp_input.c	2019-11-22 10:57:34.000000000 -0500
@@ -214,7 +214,7 @@ static inline void TCP_ECN_accept_cwr(st
 
 static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp)
 {
-	tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
+	tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
 }
 
 static inline void TCP_ECN_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/ipv6/mcast.c linux-libre-3.16.78-gnu/net/ipv6/mcast.c
--- linux-libre-3.16.77-gnu/net/ipv6/mcast.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/ipv6/mcast.c	2019-11-22 10:57:34.000000000 -0500
@@ -807,12 +807,13 @@ static void mld_del_delrec(struct inet6_
 		im->idev = pmc->idev;
 		im->mca_crcount = idev->mc_qrv;
 		if (im->mca_sfmode == MCAST_INCLUDE) {
-			im->mca_tomb = pmc->mca_tomb;
-			im->mca_sources = pmc->mca_sources;
+			swap(im->mca_tomb, pmc->mca_tomb);
+			swap(im->mca_sources, pmc->mca_sources);
 			for (psf = im->mca_sources; psf; psf = psf->sf_next)
 				psf->sf_crcount = im->mca_crcount;
 		}
 		in6_dev_put(pmc->idev);
+		ip6_mc_clear_src(pmc);
 		kfree(pmc);
 	}
 	spin_unlock_bh(&im->mca_lock);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/ipv6/ping.c linux-libre-3.16.78-gnu/net/ipv6/ping.c
--- linux-libre-3.16.77-gnu/net/ipv6/ping.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/ipv6/ping.c	2019-11-22 10:57:34.000000000 -0500
@@ -230,7 +230,7 @@ static int __net_init ping_v6_proc_init_
 	return ping_proc_register(net, &ping_v6_seq_afinfo);
 }
 
-static void __net_init ping_v6_proc_exit_net(struct net *net)
+static void __net_exit ping_v6_proc_exit_net(struct net *net)
 {
 	return ping_proc_unregister(net, &ping_v6_seq_afinfo);
 }
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/netfilter/nf_conntrack_core.c linux-libre-3.16.78-gnu/net/netfilter/nf_conntrack_core.c
--- linux-libre-3.16.77-gnu/net/netfilter/nf_conntrack_core.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/netfilter/nf_conntrack_core.c	2019-11-22 10:57:34.000000000 -0500
@@ -240,13 +240,12 @@ EXPORT_SYMBOL_GPL(nf_ct_invert_tuple);
  * table location, we assume id gets exposed to userspace.
  *
  * Following nf_conn items do not change throughout lifetime
- * of the nf_conn after it has been committed to main hash table:
+ * of the nf_conn:
  *
  * 1. nf_conn address
- * 2. nf_conn->ext address
- * 3. nf_conn->master address (normally NULL)
- * 4. tuple
- * 5. the associated net namespace
+ * 2. nf_conn->master address (normally NULL)
+ * 3. the associated net namespace
+ * 4. the original direction tuple
  */
 u32 nf_ct_get_id(const struct nf_conn *ct)
 {
@@ -256,9 +255,10 @@ u32 nf_ct_get_id(const struct nf_conn *c
 	net_get_random_once(&ct_id_seed, sizeof(ct_id_seed));
 
 	a = (unsigned long)ct;
-	b = (unsigned long)ct->master ^ net_hash_mix(nf_ct_net(ct));
-	c = (unsigned long)ct->ext;
-	d = (unsigned long)siphash(&ct->tuplehash, sizeof(ct->tuplehash),
+	b = (unsigned long)ct->master;
+	c = (unsigned long)nf_ct_net(ct);
+	d = (unsigned long)siphash(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+				   sizeof(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple),
 				   &ct_id_seed);
 #ifdef CONFIG_64BIT
 	return siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &ct_id_seed);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/packet/af_packet.c linux-libre-3.16.78-gnu/net/packet/af_packet.c
--- linux-libre-3.16.77-gnu/net/packet/af_packet.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/packet/af_packet.c	2019-11-22 10:57:34.000000000 -0500
@@ -2286,6 +2286,13 @@ static int tpacket_snd(struct packet_soc
 
 	mutex_lock(&po->pg_vec_lock);
 
+	/* packet_sendmsg() check on tx_ring.pg_vec was lockless,
+	 * we need to confirm it under protection of pg_vec_lock.
+	 */
+	if (unlikely(!po->tx_ring.pg_vec)) {
+		err = -EBUSY;
+		goto out;
+	}
 	if (likely(saddr == NULL)) {
 		dev	= packet_cached_dev_get(po);
 		proto	= po->num;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/sched/sch_codel.c linux-libre-3.16.78-gnu/net/sched/sch_codel.c
--- linux-libre-3.16.77-gnu/net/sched/sch_codel.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/sched/sch_codel.c	2019-11-22 10:57:34.000000000 -0500
@@ -68,7 +68,8 @@ static struct sk_buff *dequeue(struct co
 {
 	struct sk_buff *skb = __skb_dequeue(&sch->q);
 
-	prefetch(&skb->end); /* we'll need skb_shinfo() */
+	if (skb)
+		prefetch(&skb->end); /* we'll need skb_shinfo() */
 	return skb;
 }
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/sched/sch_hhf.c linux-libre-3.16.78-gnu/net/sched/sch_hhf.c
--- linux-libre-3.16.77-gnu/net/sched/sch_hhf.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/sched/sch_hhf.c	2019-11-22 10:57:34.000000000 -0500
@@ -560,7 +560,7 @@ static int hhf_change(struct Qdisc *sch,
 		new_hhf_non_hh_weight = nla_get_u32(tb[TCA_HHF_NON_HH_WEIGHT]);
 
 	non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight;
-	if (non_hh_quantum > INT_MAX)
+	if (non_hh_quantum == 0 || non_hh_quantum > INT_MAX)
 		return -EINVAL;
 
 	sch_tree_lock(sch);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/sctp/protocol.c linux-libre-3.16.78-gnu/net/sctp/protocol.c
--- linux-libre-3.16.77-gnu/net/sctp/protocol.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/sctp/protocol.c	2019-11-22 10:57:34.000000000 -0500
@@ -1314,7 +1314,7 @@ static int __net_init sctp_ctrlsock_init
 	return status;
 }
 
-static void __net_init sctp_ctrlsock_exit(struct net *net)
+static void __net_exit sctp_ctrlsock_exit(struct net *net)
 {
 	/* Free the control endpoint.  */
 	inet_ctl_sock_destroy(net->sctp.ctl_sock);
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/sctp/sm_sideeffect.c linux-libre-3.16.78-gnu/net/sctp/sm_sideeffect.c
--- linux-libre-3.16.77-gnu/net/sctp/sm_sideeffect.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/sctp/sm_sideeffect.c	2019-11-22 10:57:34.000000000 -0500
@@ -504,8 +504,8 @@ static void sctp_do_8_2_transport_strike
 	 * see SCTP Quick Failover Draft, section 5.1
 	 */
 	if ((transport->state == SCTP_ACTIVE) &&
-	   (asoc->pf_retrans < transport->pathmaxrxt) &&
-	   (transport->error_count > asoc->pf_retrans)) {
+	   (transport->error_count < transport->pathmaxrxt) &&
+	   (transport->error_count > transport->pf_retrans)) {
 
 		sctp_assoc_control_transport(asoc, transport,
 					     SCTP_TRANSPORT_PF,
diff -druNp --no-dereference linux-libre-3.16.77-gnu/net/wireless/reg.c linux-libre-3.16.78-gnu/net/wireless/reg.c
--- linux-libre-3.16.77-gnu/net/wireless/reg.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/net/wireless/reg.c	2019-11-22 10:57:34.000000000 -0500
@@ -1913,7 +1913,7 @@ static void reg_process_pending_hints(vo
 
 	/* When last_request->processed becomes true this will be rescheduled */
 	if (lr && !lr->processed) {
-		reg_process_hint(lr);
+		pr_debug("Pending regulatory request, waiting for it to be processed...\n");
 		return;
 	}
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/security/keys/request_key_auth.c linux-libre-3.16.78-gnu/security/keys/request_key_auth.c
--- linux-libre-3.16.77-gnu/security/keys/request_key_auth.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/security/keys/request_key_auth.c	2019-11-22 10:57:34.000000000 -0500
@@ -58,6 +58,9 @@ static void request_key_auth_describe(co
 {
 	struct request_key_auth *rka = key->payload.data;
 
+	if (!rka)
+		return;
+
 	seq_puts(m, "key:");
 	seq_puts(m, key->description);
 	if (key_is_instantiated(key))
@@ -75,6 +78,9 @@ static long request_key_auth_read(const
 	size_t datalen;
 	long ret;
 
+	if (!rka)
+		return -EKEYREVOKED;
+
 	datalen = rka->callout_len;
 	ret = datalen;
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/security/selinux/ss/policydb.c linux-libre-3.16.78-gnu/security/selinux/ss/policydb.c
--- linux-libre-3.16.77-gnu/security/selinux/ss/policydb.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/security/selinux/ss/policydb.c	2019-11-22 10:57:34.000000000 -0500
@@ -261,6 +261,8 @@ static int rangetr_cmp(struct hashtab *h
 	return v;
 }
 
+static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap);
+
 /*
  * Initialize a policy database structure.
  */
@@ -304,8 +306,10 @@ static int policydb_init(struct policydb
 out:
 	hashtab_destroy(p->filename_trans);
 	hashtab_destroy(p->range_tr);
-	for (i = 0; i < SYM_NUM; i++)
+	for (i = 0; i < SYM_NUM; i++) {
+		hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
 		hashtab_destroy(p->symtab[i].table);
+	}
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/core/compress_offload.c linux-libre-3.16.78-gnu/sound/core/compress_offload.c
--- linux-libre-3.16.77-gnu/sound/core/compress_offload.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/core/compress_offload.c	2019-11-22 10:57:34.000000000 -0500
@@ -549,10 +549,7 @@ snd_compr_set_params(struct snd_compr_st
 		stream->metadata_set = false;
 		stream->next_track = false;
 
-		if (stream->direction == SND_COMPRESS_PLAYBACK)
-			stream->runtime->state = SNDRV_PCM_STATE_SETUP;
-		else
-			stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
+		stream->runtime->state = SNDRV_PCM_STATE_SETUP;
 	} else {
 		return -EPERM;
 	}
@@ -668,8 +665,17 @@ static int snd_compr_start(struct snd_co
 {
 	int retval;
 
-	if (stream->runtime->state != SNDRV_PCM_STATE_PREPARED)
+	switch (stream->runtime->state) {
+	case SNDRV_PCM_STATE_SETUP:
+		if (stream->direction != SND_COMPRESS_CAPTURE)
+			return -EPERM;
+		break;
+	case SNDRV_PCM_STATE_PREPARED:
+		break;
+	default:
 		return -EPERM;
+	}
+
 	retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START);
 	if (!retval)
 		stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/core/seq/seq_clientmgr.c linux-libre-3.16.78-gnu/sound/core/seq/seq_clientmgr.c
--- linux-libre-3.16.77-gnu/sound/core/seq/seq_clientmgr.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/core/seq/seq_clientmgr.c	2019-11-22 10:57:34.000000000 -0500
@@ -1911,8 +1911,7 @@ static int snd_seq_ioctl_get_client_pool
 	if (cptr->type == USER_CLIENT) {
 		info.input_pool = cptr->data.user.fifo_pool_size;
 		info.input_free = info.input_pool;
-		if (cptr->data.user.fifo)
-			info.input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);
+		info.input_free = snd_seq_fifo_unused_cells(cptr->data.user.fifo);
 	} else {
 		info.input_pool = 0;
 		info.input_free = 0;
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/core/seq/seq_fifo.c linux-libre-3.16.78-gnu/sound/core/seq/seq_fifo.c
--- linux-libre-3.16.77-gnu/sound/core/seq/seq_fifo.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/core/seq/seq_fifo.c	2019-11-22 10:57:34.000000000 -0500
@@ -278,3 +278,20 @@ int snd_seq_fifo_resize(struct snd_seq_f
 
 	return 0;
 }
+
+/* get the number of unused cells safely */
+int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f)
+{
+	unsigned long flags;
+	int cells;
+
+	if (!f)
+		return 0;
+
+	snd_use_lock_use(&f->use_lock);
+	spin_lock_irqsave(&f->lock, flags);
+	cells = snd_seq_unused_cells(f->pool);
+	spin_unlock_irqrestore(&f->lock, flags);
+	snd_use_lock_free(&f->use_lock);
+	return cells;
+}
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/core/seq/seq_fifo.h linux-libre-3.16.78-gnu/sound/core/seq/seq_fifo.h
--- linux-libre-3.16.77-gnu/sound/core/seq/seq_fifo.h	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/core/seq/seq_fifo.h	2019-11-22 10:57:34.000000000 -0500
@@ -68,5 +68,7 @@ int snd_seq_fifo_poll_wait(struct snd_se
 /* resize pool in fifo */
 int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize);
 
+/* get the number of unused cells safely */
+int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f);
 
 #endif
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/firewire/packets-buffer.c linux-libre-3.16.78-gnu/sound/firewire/packets-buffer.c
--- linux-libre-3.16.77-gnu/sound/firewire/packets-buffer.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/firewire/packets-buffer.c	2019-11-22 10:57:34.000000000 -0500
@@ -37,7 +37,7 @@ int iso_packets_buffer_init(struct iso_p
 	packets_per_page = PAGE_SIZE / packet_size;
 	if (WARN_ON(!packets_per_page)) {
 		err = -EINVAL;
-		goto error;
+		goto err_packets;
 	}
 	pages = DIV_ROUND_UP(count, packets_per_page);
 
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/pci/hda/hda_auto_parser.c linux-libre-3.16.78-gnu/sound/pci/hda/hda_auto_parser.c
--- linux-libre-3.16.77-gnu/sound/pci/hda/hda_auto_parser.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/pci/hda/hda_auto_parser.c	2019-11-22 10:57:34.000000000 -0500
@@ -787,6 +787,8 @@ static void apply_fixup(struct hda_codec
 	while (id >= 0) {
 		const struct hda_fixup *fix = codec->fixup_list + id;
 
+		if (++depth > 10)
+			break;
 		if (fix->chained_before)
 			apply_fixup(codec, fix->chain_id, action, depth + 1);
 
@@ -826,8 +828,6 @@ static void apply_fixup(struct hda_codec
 		}
 		if (!fix->chained || fix->chained_before)
 			break;
-		if (++depth > 10)
-			break;
 		id = fix->chain_id;
 	}
 }
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/pci/hda/hda_generic.c linux-libre-3.16.78-gnu/sound/pci/hda/hda_generic.c
--- linux-libre-3.16.77-gnu/sound/pci/hda/hda_generic.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/pci/hda/hda_generic.c	2019-11-22 10:57:34.000000000 -0500
@@ -5431,7 +5431,7 @@ int snd_hda_parse_generic_codec(struct h
 
 	err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0);
 	if (err < 0)
-		return err;
+		goto error;
 
 	err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-3.16.77-gnu/sound/sound_core.c linux-libre-3.16.78-gnu/sound/sound_core.c
--- linux-libre-3.16.77-gnu/sound/sound_core.c	2019-11-14 19:56:57.000000000 -0500
+++ linux-libre-3.16.78-gnu/sound/sound_core.c	2019-11-22 10:57:34.000000000 -0500
@@ -287,7 +287,8 @@ retry:
 				goto retry;
 			}
 			spin_unlock(&sound_loader_lock);
-			return -EBUSY;
+			r = -EBUSY;
+			goto fail;
 		}
 	}
 
