diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/alpha/kernel/console.c linux-libre-4.9.90-gnu/arch/alpha/kernel/console.c
--- linux-libre-4.9.89-gnu/arch/alpha/kernel/console.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/alpha/kernel/console.c	2018-03-24 06:00:27.000000000 -0400
@@ -20,6 +20,7 @@
 struct pci_controller *pci_vga_hose;
 static struct resource alpha_vga = {
 	.name	= "alpha-vga+",
+	.flags	= IORESOURCE_IO,
 	.start	= 0x3C0,
 	.end	= 0x3DF
 };
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/arm/boot/dts/aspeed-ast2500-evb.dts linux-libre-4.9.90-gnu/arch/arm/boot/dts/aspeed-ast2500-evb.dts
--- linux-libre-4.9.89-gnu/arch/arm/boot/dts/aspeed-ast2500-evb.dts	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/arm/boot/dts/aspeed-ast2500-evb.dts	2018-03-24 06:00:27.000000000 -0400
@@ -15,7 +15,7 @@
 		bootargs = "console=ttyS4,115200 earlyprintk";
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 };
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/arm/kernel/ftrace.c linux-libre-4.9.90-gnu/arch/arm/kernel/ftrace.c
--- linux-libre-4.9.89-gnu/arch/arm/kernel/ftrace.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/arm/kernel/ftrace.c	2018-03-24 06:00:27.000000000 -0400
@@ -29,11 +29,6 @@
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-#ifdef CONFIG_OLD_MCOUNT
-#define OLD_MCOUNT_ADDR	((unsigned long) mcount)
-#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
-
-#define	OLD_NOP		0xe1a00000	/* mov r0, r0 */
 
 static int __ftrace_modify_code(void *data)
 {
@@ -51,6 +46,12 @@ void arch_ftrace_update_code(int command
 	stop_machine(__ftrace_modify_code, &command, NULL);
 }
 
+#ifdef CONFIG_OLD_MCOUNT
+#define OLD_MCOUNT_ADDR	((unsigned long) mcount)
+#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
+
+#define	OLD_NOP		0xe1a00000	/* mov r0, r0 */
+
 static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
 {
 	return rec->arch.old_mcount ? OLD_NOP : NOP;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c linux-libre-4.9.90-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c
--- linux-libre-4.9.89-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c	2018-03-24 06:00:27.000000000 -0400
@@ -524,7 +524,7 @@ static struct clockdomain pcie_7xx_clkdm
 	.dep_bit	  = DRA7XX_PCIE_STATDEP_SHIFT,
 	.wkdep_srcs	  = pcie_wkup_sleep_deps,
 	.sleepdep_srcs	  = pcie_wkup_sleep_deps,
-	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.flags		  = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain atl_7xx_clkdm = {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/ia64/kernel/module.c linux-libre-4.9.90-gnu/arch/ia64/kernel/module.c
--- linux-libre-4.9.89-gnu/arch/ia64/kernel/module.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/ia64/kernel/module.c	2018-03-24 06:00:27.000000000 -0400
@@ -153,7 +153,7 @@ slot (const struct insn *insn)
 static int
 apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
 {
-	if (slot(insn) != 2) {
+	if (slot(insn) != 1 && slot(insn) != 2) {
 		printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
 		       mod->name, slot(insn));
 		return 0;
@@ -165,7 +165,7 @@ apply_imm64 (struct module *mod, struct
 static int
 apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
 {
-	if (slot(insn) != 2) {
+	if (slot(insn) != 1 && slot(insn) != 2) {
 		printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
 		       mod->name, slot(insn));
 		return 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/powerpc/include/asm/cputable.h linux-libre-4.9.90-gnu/arch/powerpc/include/asm/cputable.h
--- linux-libre-4.9.89-gnu/arch/powerpc/include/asm/cputable.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/powerpc/include/asm/cputable.h	2018-03-24 06:00:27.000000000 -0400
@@ -474,7 +474,8 @@ enum {
 	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
 	    CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300)
-#define CPU_FTRS_POWER9_DD1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1)
+#define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
+			     (~CPU_FTR_SAO))
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c linux-libre-4.9.90-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c
--- linux-libre-4.9.89-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c	2018-03-24 06:00:27.000000000 -0400
@@ -177,12 +177,15 @@ map_again:
 	ret = mmu_hash_ops.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
 				       hpsize, hpsize, MMU_SEGSIZE_256M);
 
-	if (ret < 0) {
+	if (ret == -1) {
 		/* If we couldn't map a primary PTE, try a secondary */
 		hash = ~hash;
 		vflags ^= HPTE_V_SECONDARY;
 		attempt++;
 		goto map_again;
+	} else if (ret < 0) {
+		r = -EIO;
+		goto out_unlock;
 	} else {
 		trace_kvm_book3s_64_mmu_map(rflags, hpteg,
 					    vpn, hpaddr, orig_pte);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/powerpc/kvm/book3s_pr.c linux-libre-4.9.90-gnu/arch/powerpc/kvm/book3s_pr.c
--- linux-libre-4.9.89-gnu/arch/powerpc/kvm/book3s_pr.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/powerpc/kvm/book3s_pr.c	2018-03-24 06:00:27.000000000 -0400
@@ -627,7 +627,11 @@ int kvmppc_handle_pagefault(struct kvm_r
 			kvmppc_mmu_unmap_page(vcpu, &pte);
 		}
 		/* The guest's PTE is not mapped yet. Map on the host */
-		kvmppc_mmu_map_page(vcpu, &pte, iswrite);
+		if (kvmppc_mmu_map_page(vcpu, &pte, iswrite) == -EIO) {
+			/* Exit KVM if mapping failed */
+			run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+			return RESUME_HOST;
+		}
 		if (data)
 			vcpu->stat.sp_storage++;
 		else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/x86/boot/compressed/kaslr.c linux-libre-4.9.90-gnu/arch/x86/boot/compressed/kaslr.c
--- linux-libre-4.9.89-gnu/arch/x86/boot/compressed/kaslr.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/x86/boot/compressed/kaslr.c	2018-03-24 06:00:27.000000000 -0400
@@ -460,10 +460,17 @@ void choose_random_location(unsigned lon
 			add_identity_map(random_addr, output_size);
 			*output = random_addr;
 		}
+
+		/*
+		 * This loads the identity mapping page table.
+		 * This should only be done if a new physical address
+		 * is found for the kernel, otherwise we should keep
+		 * the old page table to make it be like the "nokaslr"
+		 * case.
+		 */
+		finalize_identity_maps();
 	}
 
-	/* This actually loads the identity pagetable on x86_64. */
-	finalize_identity_maps();
 
 	/* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */
 	if (IS_ENABLED(CONFIG_X86_64))
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/x86/kernel/i8259.c linux-libre-4.9.90-gnu/arch/x86/kernel/i8259.c
--- linux-libre-4.9.89-gnu/arch/x86/kernel/i8259.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/x86/kernel/i8259.c	2018-03-24 06:00:27.000000000 -0400
@@ -418,6 +418,7 @@ struct legacy_pic default_legacy_pic = {
 };
 
 struct legacy_pic *legacy_pic = &default_legacy_pic;
+EXPORT_SYMBOL(legacy_pic);
 
 static int __init i8259A_init_ops(void)
 {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/x86/kernel/smp.c linux-libre-4.9.90-gnu/arch/x86/kernel/smp.c
--- linux-libre-4.9.89-gnu/arch/x86/kernel/smp.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/x86/kernel/smp.c	2018-03-24 06:00:27.000000000 -0400
@@ -33,6 +33,7 @@
 #include <asm/mce.h>
 #include <asm/trace/irq_vectors.h>
 #include <asm/kexec.h>
+#include <asm/virtext.h>
 
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
@@ -162,6 +163,7 @@ static int smp_stop_nmi_callback(unsigne
 	if (raw_smp_processor_id() == atomic_read(&stopping_cpu))
 		return NMI_HANDLED;
 
+	cpu_emergency_vmxoff();
 	stop_this_cpu(NULL);
 
 	return NMI_HANDLED;
@@ -174,6 +176,7 @@ static int smp_stop_nmi_callback(unsigne
 asmlinkage __visible void smp_reboot_interrupt(void)
 {
 	ipi_entering_ack_irq();
+	cpu_emergency_vmxoff();
 	stop_this_cpu(NULL);
 	irq_exit();
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/arch/x86/xen/smp.c linux-libre-4.9.90-gnu/arch/x86/xen/smp.c
--- linux-libre-4.9.89-gnu/arch/x86/xen/smp.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/arch/x86/xen/smp.c	2018-03-24 06:00:27.000000000 -0400
@@ -299,35 +299,46 @@ static void __init xen_filter_cpu_maps(v
 
 }
 
-static void __init xen_smp_prepare_boot_cpu(void)
+static void __init xen_pv_smp_prepare_boot_cpu(void)
 {
 	BUG_ON(smp_processor_id() != 0);
 	native_smp_prepare_boot_cpu();
 
-	if (xen_pv_domain()) {
-		if (!xen_feature(XENFEAT_writable_page_tables))
-			/* We've switched to the "real" per-cpu gdt, so make
-			 * sure the old memory can be recycled. */
-			make_lowmem_page_readwrite(xen_initial_gdt);
+	if (!xen_feature(XENFEAT_writable_page_tables))
+		/* We've switched to the "real" per-cpu gdt, so make
+		 * sure the old memory can be recycled. */
+		make_lowmem_page_readwrite(xen_initial_gdt);
 
 #ifdef CONFIG_X86_32
-		/*
-		 * Xen starts us with XEN_FLAT_RING1_DS, but linux code
-		 * expects __USER_DS
-		 */
-		loadsegment(ds, __USER_DS);
-		loadsegment(es, __USER_DS);
+	/*
+	 * Xen starts us with XEN_FLAT_RING1_DS, but linux code
+	 * expects __USER_DS
+	 */
+	loadsegment(ds, __USER_DS);
+	loadsegment(es, __USER_DS);
 #endif
 
-		xen_filter_cpu_maps();
-		xen_setup_vcpu_info_placement();
-	}
+	xen_filter_cpu_maps();
+	xen_setup_vcpu_info_placement();
+
+	/*
+	 * The alternative logic (which patches the unlock/lock) runs before
+	 * the smp bootup up code is activated. Hence we need to set this up
+	 * the core kernel is being patched. Otherwise we will have only
+	 * modules patched but not core code.
+	 */
+	xen_init_spinlocks();
+}
+
+static void __init xen_hvm_smp_prepare_boot_cpu(void)
+{
+	BUG_ON(smp_processor_id() != 0);
+	native_smp_prepare_boot_cpu();
 
 	/*
 	 * Setup vcpu_info for boot CPU.
 	 */
-	if (xen_hvm_domain())
-		xen_vcpu_setup(0);
+	xen_vcpu_setup(0);
 
 	/*
 	 * The alternative logic (which patches the unlock/lock) runs before
@@ -733,7 +744,7 @@ static irqreturn_t xen_irq_work_interrup
 }
 
 static const struct smp_ops xen_smp_ops __initconst = {
-	.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
+	.smp_prepare_boot_cpu = xen_pv_smp_prepare_boot_cpu,
 	.smp_prepare_cpus = xen_smp_prepare_cpus,
 	.smp_cpus_done = xen_smp_cpus_done,
 
@@ -772,5 +783,5 @@ void __init xen_hvm_smp_init(void)
 	smp_ops.cpu_die = xen_cpu_die;
 	smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi;
 	smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi;
-	smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu;
+	smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/block/blk-mq.c linux-libre-4.9.90-gnu/block/blk-mq.c
--- linux-libre-4.9.89-gnu/block/blk-mq.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/block/blk-mq.c	2018-03-24 06:00:27.000000000 -0400
@@ -2014,15 +2014,15 @@ struct request_queue *blk_mq_init_alloca
 
 	blk_mq_init_cpu_queues(q, set->nr_hw_queues);
 
-	get_online_cpus();
 	mutex_lock(&all_q_mutex);
+	get_online_cpus();
 
 	list_add_tail(&q->all_q_node, &all_q_list);
 	blk_mq_add_queue_tag_set(set, q);
 	blk_mq_map_swqueue(q, cpu_online_mask);
 
-	mutex_unlock(&all_q_mutex);
 	put_online_cpus();
+	mutex_unlock(&all_q_mutex);
 
 	return q;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt linux-libre-4.9.90-gnu/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt
--- linux-libre-4.9.89-gnu/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-Toppoly TD028TTEC1 Panel
-========================
-
-Required properties:
-- compatible: "toppoly,td028ttec1"
-
-Optional properties:
-- label: a symbolic name for the panel
-
-Required nodes:
-- Video port for DPI input
-
-Example
--------
-
-lcd-panel: td028ttec1@0 {
-	compatible = "toppoly,td028ttec1";
-	reg = <0>;
-	spi-max-frequency = <100000>;
-	spi-cpol;
-	spi-cpha;
-
-	label = "lcd";
-	port {
-		lcd_in: endpoint {
-			remote-endpoint = <&dpi_out>;
-		};
-	};
-};
-
diff -druNp --no-dereference linux-libre-4.9.89-gnu/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt linux-libre-4.9.90-gnu/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
--- linux-libre-4.9.89-gnu/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9.90-gnu/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt	2018-03-24 06:00:27.000000000 -0400
@@ -0,0 +1,30 @@
+Toppoly TD028TTEC1 Panel
+========================
+
+Required properties:
+- compatible: "tpo,td028ttec1"
+
+Optional properties:
+- label: a symbolic name for the panel
+
+Required nodes:
+- Video port for DPI input
+
+Example
+-------
+
+lcd-panel: td028ttec1@0 {
+	compatible = "tpo,td028ttec1";
+	reg = <0>;
+	spi-max-frequency = <100000>;
+	spi-cpol;
+	spi-cpha;
+
+	label = "lcd";
+	port {
+		lcd_in: endpoint {
+			remote-endpoint = <&dpi_out>;
+		};
+	};
+};
+
diff -druNp --no-dereference linux-libre-4.9.89-gnu/Documentation/devicetree/bindings/mfd/axp20x.txt linux-libre-4.9.90-gnu/Documentation/devicetree/bindings/mfd/axp20x.txt
--- linux-libre-4.9.89-gnu/Documentation/devicetree/bindings/mfd/axp20x.txt	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/Documentation/devicetree/bindings/mfd/axp20x.txt	2018-03-24 06:00:27.000000000 -0400
@@ -28,6 +28,9 @@ Optional properties:
 		  regulator to drive the OTG VBus, rather then as an input pin
 		  which signals whether the board is driving OTG VBus or not.
 
+- x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is
+			wired for master mode. The default is slave mode.
+
 - <input>-supply: a phandle to the regulator supply node. May be omitted if
 		  inputs are unregulated, such as using the IPSOUT output
 		  from the PMIC.
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/acpi/pmic/intel_pmic_xpower.c linux-libre-4.9.90-gnu/drivers/acpi/pmic/intel_pmic_xpower.c
--- linux-libre-4.9.89-gnu/drivers/acpi/pmic/intel_pmic_xpower.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/acpi/pmic/intel_pmic_xpower.c	2018-03-24 06:00:27.000000000 -0400
@@ -28,97 +28,97 @@ static struct pmic_table power_table[] =
 		.address = 0x00,
 		.reg = 0x13,
 		.bit = 0x05,
-	},
+	}, /* ALD1 */
 	{
 		.address = 0x04,
 		.reg = 0x13,
 		.bit = 0x06,
-	},
+	}, /* ALD2 */
 	{
 		.address = 0x08,
 		.reg = 0x13,
 		.bit = 0x07,
-	},
+	}, /* ALD3 */
 	{
 		.address = 0x0c,
 		.reg = 0x12,
 		.bit = 0x03,
-	},
+	}, /* DLD1 */
 	{
 		.address = 0x10,
 		.reg = 0x12,
 		.bit = 0x04,
-	},
+	}, /* DLD2 */
 	{
 		.address = 0x14,
 		.reg = 0x12,
 		.bit = 0x05,
-	},
+	}, /* DLD3 */
 	{
 		.address = 0x18,
 		.reg = 0x12,
 		.bit = 0x06,
-	},
+	}, /* DLD4 */
 	{
 		.address = 0x1c,
 		.reg = 0x12,
 		.bit = 0x00,
-	},
+	}, /* ELD1 */
 	{
 		.address = 0x20,
 		.reg = 0x12,
 		.bit = 0x01,
-	},
+	}, /* ELD2 */
 	{
 		.address = 0x24,
 		.reg = 0x12,
 		.bit = 0x02,
-	},
+	}, /* ELD3 */
 	{
 		.address = 0x28,
 		.reg = 0x13,
 		.bit = 0x02,
-	},
+	}, /* FLD1 */
 	{
 		.address = 0x2c,
 		.reg = 0x13,
 		.bit = 0x03,
-	},
+	}, /* FLD2 */
 	{
 		.address = 0x30,
 		.reg = 0x13,
 		.bit = 0x04,
-	},
+	}, /* FLD3 */
 	{
-		.address = 0x38,
+		.address = 0x34,
 		.reg = 0x10,
 		.bit = 0x03,
-	},
+	}, /* BUC1 */
 	{
-		.address = 0x3c,
+		.address = 0x38,
 		.reg = 0x10,
 		.bit = 0x06,
-	},
+	}, /* BUC2 */
 	{
-		.address = 0x40,
+		.address = 0x3c,
 		.reg = 0x10,
 		.bit = 0x05,
-	},
+	}, /* BUC3 */
 	{
-		.address = 0x44,
+		.address = 0x40,
 		.reg = 0x10,
 		.bit = 0x04,
-	},
+	}, /* BUC4 */
 	{
-		.address = 0x48,
+		.address = 0x44,
 		.reg = 0x10,
 		.bit = 0x01,
-	},
+	}, /* BUC5 */
 	{
-		.address = 0x4c,
+		.address = 0x48,
 		.reg = 0x10,
 		.bit = 0x00
-	},
+	}, /* BUC6 */
 };
 
 /* TMP0 - TMP5 are the same, all from GPADC */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/acpi/power.c linux-libre-4.9.90-gnu/drivers/acpi/power.c
--- linux-libre-4.9.89-gnu/drivers/acpi/power.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/acpi/power.c	2018-03-24 06:00:27.000000000 -0400
@@ -864,6 +864,16 @@ void acpi_resume_power_resources(void)
 
 		mutex_unlock(&resource->resource_lock);
 	}
+
+	mutex_unlock(&power_resource_list_lock);
+}
+
+void acpi_turn_off_unused_power_resources(void)
+{
+	struct acpi_power_resource *resource;
+
+	mutex_lock(&power_resource_list_lock);
+
 	list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
 		int result, state;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/acpi/processor_driver.c linux-libre-4.9.90-gnu/drivers/acpi/processor_driver.c
--- linux-libre-4.9.89-gnu/drivers/acpi/processor_driver.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/acpi/processor_driver.c	2018-03-24 06:00:27.000000000 -0400
@@ -251,6 +251,9 @@ static int __acpi_processor_start(struct
 	if (ACPI_SUCCESS(status))
 		return 0;
 
+	result = -ENODEV;
+	acpi_pss_perf_exit(pr, device);
+
 err_power_exit:
 	acpi_processor_power_exit(pr);
 	return result;
@@ -259,11 +262,16 @@ err_power_exit:
 static int acpi_processor_start(struct device *dev)
 {
 	struct acpi_device *device = ACPI_COMPANION(dev);
+	int ret;
 
 	if (!device)
 		return -ENODEV;
 
-	return __acpi_processor_start(device);
+	/* Protect against concurrent CPU hotplug operations */
+	get_online_cpus();
+	ret = __acpi_processor_start(device);
+	put_online_cpus();
+	return ret;
 }
 
 static int acpi_processor_stop(struct device *dev)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/acpi/processor_throttling.c linux-libre-4.9.90-gnu/drivers/acpi/processor_throttling.c
--- linux-libre-4.9.89-gnu/drivers/acpi/processor_throttling.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/acpi/processor_throttling.c	2018-03-24 06:00:27.000000000 -0400
@@ -62,8 +62,8 @@ struct acpi_processor_throttling_arg {
 #define THROTTLING_POSTCHANGE      (2)
 
 static int acpi_processor_get_throttling(struct acpi_processor *pr);
-int acpi_processor_set_throttling(struct acpi_processor *pr,
-						int state, bool force);
+static int __acpi_processor_set_throttling(struct acpi_processor *pr,
+					   int state, bool force, bool direct);
 
 static int acpi_processor_update_tsd_coord(void)
 {
@@ -891,7 +891,8 @@ static int acpi_processor_get_throttling
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				"Invalid throttling state, reset\n"));
 			state = 0;
-			ret = acpi_processor_set_throttling(pr, state, true);
+			ret = __acpi_processor_set_throttling(pr, state, true,
+							      true);
 			if (ret)
 				return ret;
 		}
@@ -901,36 +902,31 @@ static int acpi_processor_get_throttling
 	return 0;
 }
 
-static int acpi_processor_get_throttling(struct acpi_processor *pr)
+static long __acpi_processor_get_throttling(void *data)
 {
-	cpumask_var_t saved_mask;
-	int ret;
+	struct acpi_processor *pr = data;
 
+	return pr->throttling.acpi_processor_get_throttling(pr);
+}
+
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
+{
 	if (!pr)
 		return -EINVAL;
 
 	if (!pr->flags.throttling)
 		return -ENODEV;
 
-	if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
-		return -ENOMEM;
-
 	/*
-	 * Migrate task to the cpu pointed by pr.
+	 * This is either called from the CPU hotplug callback of
+	 * processor_driver or via the ACPI probe function. In the latter
+	 * case the CPU is not guaranteed to be online. Both call sites are
+	 * protected against CPU hotplug.
 	 */
-	cpumask_copy(saved_mask, &current->cpus_allowed);
-	/* FIXME: use work_on_cpu() */
-	if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
-		/* Can't migrate to the target pr->id CPU. Exit */
-		free_cpumask_var(saved_mask);
+	if (!cpu_online(pr->id))
 		return -ENODEV;
-	}
-	ret = pr->throttling.acpi_processor_get_throttling(pr);
-	/* restore the previous state */
-	set_cpus_allowed_ptr(current, saved_mask);
-	free_cpumask_var(saved_mask);
 
-	return ret;
+	return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr);
 }
 
 static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
@@ -1080,8 +1076,15 @@ static long acpi_processor_throttling_fn
 			arg->target_state, arg->force);
 }
 
-int acpi_processor_set_throttling(struct acpi_processor *pr,
-						int state, bool force)
+static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct)
+{
+	if (direct)
+		return fn(arg);
+	return work_on_cpu(cpu, fn, arg);
+}
+
+static int __acpi_processor_set_throttling(struct acpi_processor *pr,
+					   int state, bool force, bool direct)
 {
 	int ret = 0;
 	unsigned int i;
@@ -1130,7 +1133,8 @@ int acpi_processor_set_throttling(struct
 		arg.pr = pr;
 		arg.target_state = state;
 		arg.force = force;
-		ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg);
+		ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, &arg,
+				  direct);
 	} else {
 		/*
 		 * When the T-state coordination is SW_ALL or HW_ALL,
@@ -1163,8 +1167,8 @@ int acpi_processor_set_throttling(struct
 			arg.pr = match_pr;
 			arg.target_state = state;
 			arg.force = force;
-			ret = work_on_cpu(pr->id, acpi_processor_throttling_fn,
-				&arg);
+			ret = call_on_cpu(pr->id, acpi_processor_throttling_fn,
+					  &arg, direct);
 		}
 	}
 	/*
@@ -1182,6 +1186,12 @@ int acpi_processor_set_throttling(struct
 	return ret;
 }
 
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state,
+				  bool force)
+{
+	return __acpi_processor_set_throttling(pr, state, force, false);
+}
+
 int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 {
 	int result = 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/acpi/sleep.c linux-libre-4.9.90-gnu/drivers/acpi/sleep.c
--- linux-libre-4.9.89-gnu/drivers/acpi/sleep.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/acpi/sleep.c	2018-03-24 06:00:27.000000000 -0400
@@ -474,6 +474,7 @@ static void acpi_pm_start(u32 acpi_state
  */
 static void acpi_pm_end(void)
 {
+	acpi_turn_off_unused_power_resources();
 	acpi_scan_lock_release();
 	/*
 	 * This is necessary in case acpi_pm_finish() is not called during a
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/acpi/sleep.h linux-libre-4.9.90-gnu/drivers/acpi/sleep.h
--- linux-libre-4.9.89-gnu/drivers/acpi/sleep.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/acpi/sleep.h	2018-03-24 06:00:27.000000000 -0400
@@ -6,6 +6,7 @@ extern struct list_head acpi_wakeup_devi
 extern struct mutex acpi_device_lock;
 
 extern void acpi_resume_power_resources(void);
+extern void acpi_turn_off_unused_power_resources(void);
 
 static inline acpi_status acpi_set_waking_vector(u32 wakeup_address)
 {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/block/mtip32xx/mtip32xx.c linux-libre-4.9.90-gnu/drivers/block/mtip32xx/mtip32xx.c
--- linux-libre-4.9.89-gnu/drivers/block/mtip32xx/mtip32xx.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/block/mtip32xx/mtip32xx.c	2018-03-24 06:00:27.000000000 -0400
@@ -169,6 +169,25 @@ static bool mtip_check_surprise_removal(
 	return false; /* device present */
 }
 
+/* we have to use runtime tag to setup command header */
+static void mtip_init_cmd_header(struct request *rq)
+{
+	struct driver_data *dd = rq->q->queuedata;
+	struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
+	u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
+
+	/* Point the command headers at the command tables. */
+	cmd->command_header = dd->port->command_list +
+				(sizeof(struct mtip_cmd_hdr) * rq->tag);
+	cmd->command_header_dma = dd->port->command_list_dma +
+				(sizeof(struct mtip_cmd_hdr) * rq->tag);
+
+	if (host_cap_64)
+		cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16);
+
+	cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF);
+}
+
 static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd)
 {
 	struct request *rq;
@@ -180,6 +199,9 @@ static struct mtip_cmd *mtip_get_int_com
 	if (IS_ERR(rq))
 		return NULL;
 
+	/* Internal cmd isn't submitted via .queue_rq */
+	mtip_init_cmd_header(rq);
+
 	return blk_mq_rq_to_pdu(rq);
 }
 
@@ -3811,6 +3833,8 @@ static int mtip_queue_rq(struct blk_mq_h
 	struct request *rq = bd->rq;
 	int ret;
 
+	mtip_init_cmd_header(rq);
+
 	if (unlikely(mtip_check_unal_depth(hctx, rq)))
 		return BLK_MQ_RQ_QUEUE_BUSY;
 
@@ -3842,7 +3866,6 @@ static int mtip_init_cmd(void *data, str
 {
 	struct driver_data *dd = data;
 	struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
-	u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
 
 	/*
 	 * For flush requests, request_idx starts at the end of the
@@ -3859,17 +3882,6 @@ static int mtip_init_cmd(void *data, str
 
 	memset(cmd->command, 0, CMD_DMA_ALLOC_SZ);
 
-	/* Point the command headers at the command tables. */
-	cmd->command_header = dd->port->command_list +
-				(sizeof(struct mtip_cmd_hdr) * request_idx);
-	cmd->command_header_dma = dd->port->command_list_dma +
-				(sizeof(struct mtip_cmd_hdr) * request_idx);
-
-	if (host_cap_64)
-		cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16);
-
-	cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF);
-
 	sg_init_table(cmd->sg, MTIP_MAX_SG);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/bluetooth/btqcomsmd.c linux-libre-4.9.90-gnu/drivers/bluetooth/btqcomsmd.c
--- linux-libre-4.9.89-gnu/drivers/bluetooth/btqcomsmd.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/bluetooth/btqcomsmd.c	2018-03-24 06:00:27.000000000 -0400
@@ -85,7 +85,8 @@ static int btqcomsmd_send(struct hci_dev
 		break;
 	}
 
-	kfree_skb(skb);
+	if (!ret)
+		kfree_skb(skb);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/bluetooth/hci_ldisc.c linux-libre-4.9.90-gnu/drivers/bluetooth/hci_ldisc.c
--- linux-libre-4.9.89-gnu/drivers/bluetooth/hci_ldisc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/bluetooth/hci_ldisc.c	2018-03-24 06:00:27.000000000 -0400
@@ -113,16 +113,21 @@ static inline struct sk_buff *hci_uart_d
 {
 	struct sk_buff *skb = hu->tx_skb;
 
-	if (!skb)
-		skb = hu->proto->dequeue(hu);
-	else
+	if (!skb) {
+		if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
+			skb = hu->proto->dequeue(hu);
+	} else {
 		hu->tx_skb = NULL;
+	}
 
 	return skb;
 }
 
 int hci_uart_tx_wakeup(struct hci_uart *hu)
 {
+	if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
+		return 0;
+
 	if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
 		set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
 		return 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/bluetooth/hci_qca.c linux-libre-4.9.90-gnu/drivers/bluetooth/hci_qca.c
--- linux-libre-4.9.89-gnu/drivers/bluetooth/hci_qca.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/bluetooth/hci_qca.c	2018-03-24 06:00:27.000000000 -0400
@@ -936,6 +936,9 @@ static int qca_setup(struct hci_uart *hu
 	if (!ret) {
 		set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags);
 		qca_debugfs_init(hdev);
+	} else if (ret == -ENOENT) {
+		/* No patch/nvm-config found, run with original fw/config */
+		ret = 0;
 	}
 
 	/* Setup bdaddr */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/char/ipmi/ipmi_watchdog.c linux-libre-4.9.90-gnu/drivers/char/ipmi/ipmi_watchdog.c
--- linux-libre-4.9.89-gnu/drivers/char/ipmi/ipmi_watchdog.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/char/ipmi/ipmi_watchdog.c	2018-03-24 06:00:27.000000000 -0400
@@ -515,7 +515,7 @@ static void panic_halt_ipmi_heartbeat(vo
 	msg.cmd = IPMI_WDOG_RESET_TIMER;
 	msg.data = NULL;
 	msg.data_len = 0;
-	atomic_add(2, &panic_done_count);
+	atomic_add(1, &panic_done_count);
 	rv = ipmi_request_supply_msgs(watchdog_user,
 				      (struct ipmi_addr *) &addr,
 				      0,
@@ -525,7 +525,7 @@ static void panic_halt_ipmi_heartbeat(vo
 				      &panic_halt_heartbeat_recv_msg,
 				      1);
 	if (rv)
-		atomic_sub(2, &panic_done_count);
+		atomic_sub(1, &panic_done_count);
 }
 
 static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -549,12 +549,12 @@ static void panic_halt_ipmi_set_timeout(
 	/* Wait for the messages to be free. */
 	while (atomic_read(&panic_done_count) != 0)
 		ipmi_poll_interface(watchdog_user);
-	atomic_add(2, &panic_done_count);
+	atomic_add(1, &panic_done_count);
 	rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
 				&panic_halt_recv_msg,
 				&send_heartbeat_now);
 	if (rv) {
-		atomic_sub(2, &panic_done_count);
+		atomic_sub(1, &panic_done_count);
 		printk(KERN_WARNING PFX
 		       "Unable to extend the watchdog timeout.");
 	} else {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/char/tpm/tpm2-cmd.c linux-libre-4.9.90-gnu/drivers/char/tpm/tpm2-cmd.c
--- linux-libre-4.9.89-gnu/drivers/char/tpm/tpm2-cmd.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/char/tpm/tpm2-cmd.c	2018-03-24 06:00:27.000000000 -0400
@@ -668,6 +668,11 @@ static int tpm2_unseal_cmd(struct tpm_ch
 	if (!rc) {
 		data_len = be16_to_cpup(
 			(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
+		if (data_len < MIN_KEY_SIZE ||  data_len > MAX_KEY_SIZE + 1) {
+			rc = -EFAULT;
+			goto out;
+		}
+
 		data = &buf.data[TPM_HEADER_SIZE + 6];
 
 		memcpy(payload->key, data, data_len - 1);
@@ -675,6 +680,7 @@ static int tpm2_unseal_cmd(struct tpm_ch
 		payload->migratable = data[data_len - 1];
 	}
 
+out:
 	tpm_buf_destroy(&buf);
 	return rc;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/char/tpm/tpm-interface.c linux-libre-4.9.90-gnu/drivers/char/tpm/tpm-interface.c
--- linux-libre-4.9.89-gnu/drivers/char/tpm/tpm-interface.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/char/tpm/tpm-interface.c	2018-03-24 06:00:27.000000000 -0400
@@ -1078,6 +1078,11 @@ int tpm_get_random(u32 chip_num, u8 *out
 			break;
 
 		recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
+		if (recd > num_bytes) {
+			total = -EFAULT;
+			break;
+		}
+
 		memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
 
 		dest += recd;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/clk/bcm/clk-ns2.c linux-libre-4.9.90-gnu/drivers/clk/bcm/clk-ns2.c
--- linux-libre-4.9.89-gnu/drivers/clk/bcm/clk-ns2.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/clk/bcm/clk-ns2.c	2018-03-24 06:00:27.000000000 -0400
@@ -103,7 +103,7 @@ CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm
 
 static const struct iproc_pll_ctrl genpll_sw = {
 	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
-	.aon = AON_VAL(0x0, 2, 9, 8),
+	.aon = AON_VAL(0x0, 1, 11, 10),
 	.reset = RESET_VAL(0x4, 2, 1),
 	.dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
 	.ndiv_int = REG_VAL(0x8, 4, 10),
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/clk/clk-axi-clkgen.c linux-libre-4.9.90-gnu/drivers/clk/clk-axi-clkgen.c
--- linux-libre-4.9.89-gnu/drivers/clk/clk-axi-clkgen.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/clk/clk-axi-clkgen.c	2018-03-24 06:00:27.000000000 -0400
@@ -40,6 +40,10 @@
 #define MMCM_REG_FILTER1	0x4e
 #define MMCM_REG_FILTER2	0x4f
 
+#define MMCM_CLKOUT_NOCOUNT	BIT(6)
+
+#define MMCM_CLK_DIV_NOCOUNT	BIT(12)
+
 struct axi_clkgen {
 	void __iomem *base;
 	struct clk_hw clk_hw;
@@ -315,12 +319,27 @@ static unsigned long axi_clkgen_recalc_r
 	unsigned int reg;
 	unsigned long long tmp;
 
-	axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
-	dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+	axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, &reg);
+	if (reg & MMCM_CLKOUT_NOCOUNT) {
+		dout = 1;
+	} else {
+		axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
+		dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+	}
+
 	axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &reg);
-	d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
-	axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
-	m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+	if (reg & MMCM_CLK_DIV_NOCOUNT)
+		d = 1;
+	else
+		d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+
+	axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, &reg);
+	if (reg & MMCM_CLKOUT_NOCOUNT) {
+		m = 1;
+	} else {
+		axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
+		m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+	}
 
 	if (d == 0 || dout == 0)
 		return 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/clk/clk.c linux-libre-4.9.90-gnu/drivers/clk/clk.c
--- linux-libre-4.9.89-gnu/drivers/clk/clk.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/clk/clk.c	2018-03-24 06:00:27.000000000 -0400
@@ -2438,6 +2438,21 @@ static int __clk_core_init(struct clk_co
 	core->rate = core->req_rate = rate;
 
 	/*
+	 * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
+	 * don't get accidentally disabled when walking the orphan tree and
+	 * reparenting clocks
+	 */
+	if (core->flags & CLK_IS_CRITICAL) {
+		unsigned long flags;
+
+		clk_core_prepare(core);
+
+		flags = clk_enable_lock();
+		clk_core_enable(core);
+		clk_enable_unlock(flags);
+	}
+
+	/*
 	 * walk the list of orphan clocks and reparent any that newly finds a
 	 * parent.
 	 */
@@ -2445,10 +2460,13 @@ static int __clk_core_init(struct clk_co
 		struct clk_core *parent = __clk_init_parent(orphan);
 
 		/*
-		 * we could call __clk_set_parent, but that would result in a
-		 * redundant call to the .set_rate op, if it exists
+		 * We need to use __clk_set_parent_before() and _after() to
+		 * to properly migrate any prepare/enable count of the orphan
+		 * clock. This is important for CLK_IS_CRITICAL clocks, which
+		 * are enabled during init but might not have a parent yet.
 		 */
 		if (parent) {
+			/* update the clk tree topology */
 			__clk_set_parent_before(orphan, parent);
 			__clk_set_parent_after(orphan, parent, NULL);
 			__clk_recalc_accuracies(orphan);
@@ -2467,16 +2485,6 @@ static int __clk_core_init(struct clk_co
 	if (core->ops->init)
 		core->ops->init(core->hw);
 
-	if (core->flags & CLK_IS_CRITICAL) {
-		unsigned long flags;
-
-		clk_core_prepare(core);
-
-		flags = clk_enable_lock();
-		clk_core_enable(core);
-		clk_enable_unlock(flags);
-	}
-
 	kref_init(&core->ref);
 out:
 	clk_prepare_unlock();
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/clk/clk-si5351.c linux-libre-4.9.90-gnu/drivers/clk/clk-si5351.c
--- linux-libre-4.9.89-gnu/drivers/clk/clk-si5351.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/clk/clk-si5351.c	2018-03-24 06:00:27.000000000 -0400
@@ -72,7 +72,7 @@ static const char * const si5351_input_n
 	"xtal", "clkin"
 };
 static const char * const si5351_pll_names[] = {
-	"plla", "pllb", "vxco"
+	"si5351_plla", "si5351_pllb", "si5351_vxco"
 };
 static const char * const si5351_msynth_names[] = {
 	"ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/cpufreq/sh-cpufreq.c linux-libre-4.9.90-gnu/drivers/cpufreq/sh-cpufreq.c
--- linux-libre-4.9.89-gnu/drivers/cpufreq/sh-cpufreq.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/cpufreq/sh-cpufreq.c	2018-03-24 06:00:27.000000000 -0400
@@ -30,54 +30,63 @@
 
 static DEFINE_PER_CPU(struct clk, sh_cpuclk);
 
+struct cpufreq_target {
+	struct cpufreq_policy	*policy;
+	unsigned int		freq;
+};
+
 static unsigned int sh_cpufreq_get(unsigned int cpu)
 {
 	return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000;
 }
 
-/*
- * Here we notify other drivers of the proposed change and the final change.
- */
-static int sh_cpufreq_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
+static long __sh_cpufreq_target(void *arg)
 {
-	unsigned int cpu = policy->cpu;
+	struct cpufreq_target *target = arg;
+	struct cpufreq_policy *policy = target->policy;
+	int cpu = policy->cpu;
 	struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu);
-	cpumask_t cpus_allowed;
 	struct cpufreq_freqs freqs;
 	struct device *dev;
 	long freq;
 
-	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
-	BUG_ON(smp_processor_id() != cpu);
+	if (smp_processor_id() != cpu)
+		return -ENODEV;
 
 	dev = get_cpu_device(cpu);
 
 	/* Convert target_freq from kHz to Hz */
-	freq = clk_round_rate(cpuclk, target_freq * 1000);
+	freq = clk_round_rate(cpuclk, target->freq * 1000);
 
 	if (freq < (policy->min * 1000) || freq > (policy->max * 1000))
 		return -EINVAL;
 
-	dev_dbg(dev, "requested frequency %u Hz\n", target_freq * 1000);
+	dev_dbg(dev, "requested frequency %u Hz\n", target->freq * 1000);
 
 	freqs.old	= sh_cpufreq_get(cpu);
 	freqs.new	= (freq + 500) / 1000;
 	freqs.flags	= 0;
 
-	cpufreq_freq_transition_begin(policy, &freqs);
-	set_cpus_allowed_ptr(current, &cpus_allowed);
+	cpufreq_freq_transition_begin(target->policy, &freqs);
 	clk_set_rate(cpuclk, freq);
-	cpufreq_freq_transition_end(policy, &freqs, 0);
+	cpufreq_freq_transition_end(target->policy, &freqs, 0);
 
 	dev_dbg(dev, "set frequency %lu Hz\n", freq);
-
 	return 0;
 }
 
+/*
+ * Here we notify other drivers of the proposed change and the final change.
+ */
+static int sh_cpufreq_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
+{
+	struct cpufreq_target data = { .policy = policy, .freq = target_freq };
+
+	return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data);
+}
+
 static int sh_cpufreq_verify(struct cpufreq_policy *policy)
 {
 	struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/dma/ti-dma-crossbar.c linux-libre-4.9.90-gnu/drivers/dma/ti-dma-crossbar.c
--- linux-libre-4.9.89-gnu/drivers/dma/ti-dma-crossbar.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/dma/ti-dma-crossbar.c	2018-03-24 06:00:27.000000000 -0400
@@ -54,7 +54,15 @@ struct ti_am335x_xbar_map {
 
 static inline void ti_am335x_xbar_write(void __iomem *iomem, int event, u8 val)
 {
-	writeb_relaxed(val, iomem + event);
+	/*
+	 * TPCC_EVT_MUX_60_63 register layout is different than the
+	 * rest, in the sense, that event 63 is mapped to lowest byte
+	 * and event 60 is mapped to highest, handle it separately.
+	 */
+	if (event >= 60 && event <= 63)
+		writeb_relaxed(val, iomem + (63 - event % 4));
+	else
+		writeb_relaxed(val, iomem + event);
 }
 
 static void ti_am335x_xbar_free(struct device *dev, void *route_data)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/dma/xilinx/zynqmp_dma.c linux-libre-4.9.90-gnu/drivers/dma/xilinx/zynqmp_dma.c
--- linux-libre-4.9.89-gnu/drivers/dma/xilinx/zynqmp_dma.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/dma/xilinx/zynqmp_dma.c	2018-03-24 06:00:27.000000000 -0400
@@ -933,7 +933,8 @@ static void zynqmp_dma_chan_remove(struc
 	if (!chan)
 		return;
 
-	devm_free_irq(chan->zdev->dev, chan->irq, chan);
+	if (chan->irq)
+		devm_free_irq(chan->zdev->dev, chan->irq, chan);
 	tasklet_kill(&chan->tasklet);
 	list_del(&chan->common.device_node);
 	clk_disable_unprepare(chan->clk_apb);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpio/gpio-wcove.c linux-libre-4.9.90-gnu/drivers/gpio/gpio-wcove.c
--- linux-libre-4.9.89-gnu/drivers/gpio/gpio-wcove.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpio/gpio-wcove.c	2018-03-24 06:00:27.000000000 -0400
@@ -51,6 +51,8 @@
 #define GROUP1_NR_IRQS		6
 #define IRQ_MASK_BASE		0x4e19
 #define IRQ_STATUS_BASE		0x4e0b
+#define GPIO_IRQ0_MASK		GENMASK(6, 0)
+#define GPIO_IRQ1_MASK		GENMASK(5, 0)
 #define UPDATE_IRQ_TYPE		BIT(0)
 #define UPDATE_IRQ_MASK		BIT(1)
 
@@ -310,7 +312,7 @@ static irqreturn_t wcove_gpio_irq_handle
 		return IRQ_NONE;
 	}
 
-	pending = p[0] | (p[1] << 8);
+	pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
 	if (!pending)
 		return IRQ_NONE;
 
@@ -318,7 +320,7 @@ static irqreturn_t wcove_gpio_irq_handle
 	while (pending) {
 		/* One iteration is for all pending bits */
 		for_each_set_bit(gpio, (const unsigned long *)&pending,
-						 GROUP0_NR_IRQS) {
+						 WCOVE_GPIO_NUM) {
 			offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0;
 			mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) :
 								BIT(gpio);
@@ -334,7 +336,7 @@ static irqreturn_t wcove_gpio_irq_handle
 			break;
 		}
 
-		pending = p[0] | (p[1] << 8);
+		pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
 	}
 
 	return IRQ_HANDLED;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-libre-4.9.90-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
--- linux-libre-4.9.89-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2018-03-22 15:56:03.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2018-03-25 14:18:51.000000000 -0400
@@ -2237,7 +2237,7 @@ int amdgpu_gpu_reset(struct amdgpu_devic
 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 		struct amdgpu_ring *ring = adev->rings[i];
 
-		if (!ring)
+		if (!ring || !ring->sched.thread)
 			continue;
 		kthread_park(ring->sched.thread);
 		amd_sched_hw_job_reset(&ring->sched);
@@ -2326,7 +2326,8 @@ retry:
 		}
 		for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 			struct amdgpu_ring *ring = adev->rings[i];
-			if (!ring)
+
+			if (!ring || !ring->sched.thread)
 				continue;
 
 			amd_sched_job_recovery(&ring->sched);
@@ -2335,7 +2336,7 @@ retry:
 	} else {
 		dev_err(adev->dev, "asic resume failed (%d).\n", r);
 		for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
-			if (adev->rings[i]) {
+			if (adev->rings[i] && adev->rings[i]->sched.thread) {
 				kthread_unpark(adev->rings[i]->sched.thread);
 			}
 		}
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpu/drm/msm/msm_gem.c linux-libre-4.9.90-gnu/drivers/gpu/drm/msm/msm_gem.c
--- linux-libre-4.9.89-gnu/drivers/gpu/drm/msm/msm_gem.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpu/drm/msm/msm_gem.c	2018-03-24 06:00:27.000000000 -0400
@@ -91,14 +91,17 @@ static struct page **get_pages(struct dr
 			return p;
 		}
 
+		msm_obj->pages = p;
+
 		msm_obj->sgt = drm_prime_pages_to_sg(p, npages);
 		if (IS_ERR(msm_obj->sgt)) {
+			void *ptr = ERR_CAST(msm_obj->sgt);
+
 			dev_err(dev->dev, "failed to allocate sgt\n");
-			return ERR_CAST(msm_obj->sgt);
+			msm_obj->sgt = NULL;
+			return ptr;
 		}
 
-		msm_obj->pages = p;
-
 		/* For non-cached buffers, ensure the new pages are clean
 		 * because display controller, GPU, etc. are not coherent:
 		 */
@@ -121,7 +124,10 @@ static void put_pages(struct drm_gem_obj
 		if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
 			dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
 					msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
-		sg_free_table(msm_obj->sgt);
+
+		if (msm_obj->sgt)
+			sg_free_table(msm_obj->sgt);
+
 		kfree(msm_obj->sgt);
 
 		if (use_pages(obj))
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpu/drm/nouveau/nouveau_display.c linux-libre-4.9.90-gnu/drivers/gpu/drm/nouveau/nouveau_display.c
--- linux-libre-4.9.89-gnu/drivers/gpu/drm/nouveau/nouveau_display.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpu/drm/nouveau/nouveau_display.c	2018-03-24 06:00:27.000000000 -0400
@@ -106,7 +106,7 @@ nouveau_display_scanoutpos_head(struct d
 	};
 	struct nouveau_display *disp = nouveau_display(crtc->dev);
 	struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
-	int ret, retry = 1;
+	int ret, retry = 20;
 
 	do {
 		ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args));
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c linux-libre-4.9.90-gnu/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
--- linux-libre-4.9.89-gnu/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c	2018-03-24 06:00:27.000000000 -0400
@@ -456,6 +456,8 @@ static int td028ttec1_panel_remove(struc
 }
 
 static const struct of_device_id td028ttec1_of_match[] = {
+	{ .compatible = "omapdss,tpo,td028ttec1", },
+	/* keep to not break older DTB */
 	{ .compatible = "omapdss,toppoly,td028ttec1", },
 	{},
 };
@@ -475,6 +477,7 @@ static struct spi_driver td028ttec1_spi_
 
 module_spi_driver(td028ttec1_spi_driver);
 
+MODULE_ALIAS("spi:tpo,td028ttec1");
 MODULE_ALIAS("spi:toppoly,td028ttec1");
 MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
 MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c linux-libre-4.9.90-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
--- linux-libre-4.9.89-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c	2018-03-24 06:00:27.000000000 -0400
@@ -298,7 +298,12 @@ static int dmm_txn_commit(struct dmm_txn
 				msecs_to_jiffies(100))) {
 			dev_err(dmm->dev, "timed out waiting for done\n");
 			ret = -ETIMEDOUT;
+			goto cleanup;
 		}
+
+		/* Check the engine status before continue */
+		ret = wait_status(engine, DMM_PATSTATUS_READY |
+				  DMM_PATSTATUS_VALID | DMM_PATSTATUS_DONE);
 	}
 
 cleanup:
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h linux-libre-4.9.90-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h
--- linux-libre-4.9.89-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h	2018-03-24 06:00:27.000000000 -0400
@@ -124,7 +124,7 @@ static inline void tilcdc_write64(struct
 	struct tilcdc_drm_private *priv = dev->dev_private;
 	volatile void __iomem *addr = priv->mmio + reg;
 
-#ifdef iowrite64
+#if defined(iowrite64) && !defined(iowrite64_is_nonatomic)
 	iowrite64(data, addr);
 #else
 	__iowmb();
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/hsi/clients/ssi_protocol.c linux-libre-4.9.90-gnu/drivers/hsi/clients/ssi_protocol.c
--- linux-libre-4.9.89-gnu/drivers/hsi/clients/ssi_protocol.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/hsi/clients/ssi_protocol.c	2018-03-24 06:00:27.000000000 -0400
@@ -989,7 +989,7 @@ static int ssip_pn_xmit(struct sk_buff *
 		goto drop;
 	/* Pad to 32-bits - FIXME: Revisit*/
 	if ((skb->len & 3) && skb_pad(skb, 4 - (skb->len & 3)))
-		goto drop;
+		goto inc_dropped;
 
 	/*
 	 * Modem sends Phonet messages over SSI with its own endianess...
@@ -1041,8 +1041,9 @@ static int ssip_pn_xmit(struct sk_buff *
 drop2:
 	hsi_free_msg(msg);
 drop:
-	dev->stats.tx_dropped++;
 	dev_kfree_skb(skb);
+inc_dropped:
+	dev->stats.tx_dropped++;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/hwtracing/coresight/coresight-tpiu.c linux-libre-4.9.90-gnu/drivers/hwtracing/coresight/coresight-tpiu.c
--- linux-libre-4.9.89-gnu/drivers/hwtracing/coresight/coresight-tpiu.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/hwtracing/coresight/coresight-tpiu.c	2018-03-24 06:00:27.000000000 -0400
@@ -46,8 +46,11 @@
 #define TPIU_ITATBCTR0		0xef8
 
 /** register definition **/
+/* FFSR - 0x300 */
+#define FFSR_FT_STOPPED		BIT(1)
 /* FFCR - 0x304 */
 #define FFCR_FON_MAN		BIT(6)
+#define FFCR_STOP_FI		BIT(12)
 
 /**
  * @base:	memory mapped base address for this component.
@@ -85,10 +88,14 @@ static void tpiu_disable_hw(struct tpiu_
 {
 	CS_UNLOCK(drvdata->base);
 
-	/* Clear formatter controle reg. */
-	writel_relaxed(0x0, drvdata->base + TPIU_FFCR);
+	/* Clear formatter and stop on flush */
+	writel_relaxed(FFCR_STOP_FI, drvdata->base + TPIU_FFCR);
 	/* Generate manual flush */
-	writel_relaxed(FFCR_FON_MAN, drvdata->base + TPIU_FFCR);
+	writel_relaxed(FFCR_STOP_FI | FFCR_FON_MAN, drvdata->base + TPIU_FFCR);
+	/* Wait for flush to complete */
+	coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN, 0);
+	/* Wait for formatter to stop */
+	coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED, 1);
 
 	CS_LOCK(drvdata->base);
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/i2c/busses/i2c-scmi.c linux-libre-4.9.90-gnu/drivers/i2c/busses/i2c-scmi.c
--- linux-libre-4.9.89-gnu/drivers/i2c/busses/i2c-scmi.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/i2c/busses/i2c-scmi.c	2018-03-24 06:00:27.000000000 -0400
@@ -18,6 +18,9 @@
 #define ACPI_SMBUS_HC_CLASS		"smbus"
 #define ACPI_SMBUS_HC_DEVICE_NAME	"cmi"
 
+/* SMBUS HID definition as supported by Microsoft Windows */
+#define ACPI_SMBUS_MS_HID		"SMB0001"
+
 ACPI_MODULE_NAME("smbus_cmi");
 
 struct smbus_methods_t {
@@ -51,6 +54,7 @@ static const struct smbus_methods_t ibm_
 static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
 	{"SMBUS01", (kernel_ulong_t)&smbus_methods},
 	{ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
+	{ACPI_SMBUS_MS_HID, (kernel_ulong_t)&smbus_methods},
 	{"", 0}
 };
 MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/iio/accel/st_accel_core.c linux-libre-4.9.90-gnu/drivers/iio/accel/st_accel_core.c
--- linux-libre-4.9.89-gnu/drivers/iio/accel/st_accel_core.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/iio/accel/st_accel_core.c	2018-03-24 06:00:27.000000000 -0400
@@ -827,6 +827,8 @@ static const struct iio_trigger_ops st_a
 int st_accel_common_probe(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *adata = iio_priv(indio_dev);
+	struct st_sensors_platform_data *pdata =
+		(struct st_sensors_platform_data *)adata->dev->platform_data;
 	int irq = adata->get_irq_data_ready(indio_dev);
 	int err;
 
@@ -853,9 +855,8 @@ int st_accel_common_probe(struct iio_dev
 					&adata->sensor_settings->fs.fs_avl[0];
 	adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
 
-	if (!adata->dev->platform_data)
-		adata->dev->platform_data =
-			(struct st_sensors_platform_data *)&default_accel_pdata;
+	if (!pdata)
+		pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
 
 	err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c linux-libre-4.9.90-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
--- linux-libre-4.9.89-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/iio/common/hid-sensors/hid-sensor-attributes.c	2018-03-24 06:00:27.000000000 -0400
@@ -215,7 +215,7 @@ int hid_sensor_write_samp_freq_value(str
 	ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id,
 				     st->poll.index, sizeof(value), &value);
 	if (ret < 0 || value < 0)
-		ret = -EINVAL;
+		return -EINVAL;
 
 	ret = sensor_hub_get_feature(st->hsdev,
 				     st->poll.report_id,
@@ -265,7 +265,7 @@ int hid_sensor_write_raw_hyst_value(stru
 				     st->sensitivity.index, sizeof(value),
 				     &value);
 	if (ret < 0 || value < 0)
-		ret = -EINVAL;
+		return -EINVAL;
 
 	ret = sensor_hub_get_feature(st->hsdev,
 				     st->sensitivity.report_id,
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/iio/pressure/st_pressure_core.c linux-libre-4.9.90-gnu/drivers/iio/pressure/st_pressure_core.c
--- linux-libre-4.9.89-gnu/drivers/iio/pressure/st_pressure_core.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/iio/pressure/st_pressure_core.c	2018-03-24 06:00:27.000000000 -0400
@@ -638,6 +638,8 @@ static const struct iio_trigger_ops st_p
 int st_press_common_probe(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *press_data = iio_priv(indio_dev);
+	struct st_sensors_platform_data *pdata =
+		(struct st_sensors_platform_data *)press_data->dev->platform_data;
 	int irq = press_data->get_irq_data_ready(indio_dev);
 	int err;
 
@@ -673,10 +675,8 @@ int st_press_common_probe(struct iio_dev
 	press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
 
 	/* Some devices don't support a data ready pin. */
-	if (!press_data->dev->platform_data &&
-				press_data->sensor_settings->drdy_irq.addr)
-		press_data->dev->platform_data =
-			(struct st_sensors_platform_data *)&default_press_pdata;
+	if (!pdata && press_data->sensor_settings->drdy_irq.addr)
+		pdata =	(struct st_sensors_platform_data *)&default_press_pdata;
 
 	err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/core/cma.c linux-libre-4.9.90-gnu/drivers/infiniband/core/cma.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/core/cma.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/core/cma.c	2018-03-24 06:00:27.000000000 -0400
@@ -4039,6 +4039,9 @@ int rdma_join_multicast(struct rdma_cm_i
 	struct cma_multicast *mc;
 	int ret;
 
+	if (!id->device)
+		return -EINVAL;
+
 	id_priv = container_of(id, struct rdma_id_private, id);
 	if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) &&
 	    !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED))
@@ -4336,7 +4339,7 @@ static int cma_get_id_stats(struct sk_bu
 					  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR))
 				goto out;
 			if (ibnl_put_attr(skb, nlh,
-					  rdma_addr_size(cma_src_addr(id_priv)),
+					  rdma_addr_size(cma_dst_addr(id_priv)),
 					  cma_dst_addr(id_priv),
 					  RDMA_NL_RDMA_CM_ATTR_DST_ADDR))
 				goto out;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/core/iwpm_util.c linux-libre-4.9.90-gnu/drivers/infiniband/core/iwpm_util.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/core/iwpm_util.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/core/iwpm_util.c	2018-03-24 06:00:27.000000000 -0400
@@ -664,6 +664,7 @@ int iwpm_send_mapinfo(u8 nl_client, int
 	}
 	skb_num++;
 	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
+	ret = -EINVAL;
 	for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
 		hlist_for_each_entry(map_info, &iwpm_hash_bucket[i],
 				     hlist_node) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/core/ucma.c linux-libre-4.9.90-gnu/drivers/infiniband/core/ucma.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/core/ucma.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/core/ucma.c	2018-03-24 06:00:27.000000000 -0400
@@ -1330,7 +1330,7 @@ static ssize_t ucma_process_join(struct
 		return -ENOSPC;
 
 	addr = (struct sockaddr *) &cmd->addr;
-	if (!cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
+	if (cmd->addr_size != rdma_addr_size(addr))
 		return -EINVAL;
 
 	if (cmd->join_flags == RDMA_MC_JOIN_FLAG_FULLMEMBER)
@@ -1398,6 +1398,9 @@ static ssize_t ucma_join_ip_multicast(st
 	join_cmd.uid = cmd.uid;
 	join_cmd.id = cmd.id;
 	join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+	if (!join_cmd.addr_size)
+		return -EINVAL;
+
 	join_cmd.join_flags = RDMA_MC_JOIN_FLAG_FULLMEMBER;
 	memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
 
@@ -1413,6 +1416,9 @@ static ssize_t ucma_join_multicast(struc
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	if (!rdma_addr_size((struct sockaddr *)&cmd.addr))
+		return -EINVAL;
+
 	return ucma_process_join(file, &cmd, out_len);
 }
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/core/umem.c linux-libre-4.9.90-gnu/drivers/infiniband/core/umem.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/core/umem.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/core/umem.c	2018-03-24 06:00:27.000000000 -0400
@@ -357,7 +357,7 @@ int ib_umem_copy_from(void *dst, struct
 		return -EINVAL;
 	}
 
-	ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length,
+	ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->npages, dst, length,
 				 offset + ib_umem_offset(umem));
 
 	if (ret < 0)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/core/uverbs_cmd.c linux-libre-4.9.90-gnu/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/core/uverbs_cmd.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/core/uverbs_cmd.c	2018-03-24 06:00:27.000000000 -0400
@@ -2491,9 +2491,13 @@ ssize_t ib_uverbs_destroy_qp(struct ib_u
 
 static void *alloc_wr(size_t wr_size, __u32 num_sge)
 {
+	if (num_sge >= (U32_MAX - ALIGN(wr_size, sizeof (struct ib_sge))) /
+		       sizeof (struct ib_sge))
+		return NULL;
+
 	return kmalloc(ALIGN(wr_size, sizeof (struct ib_sge)) +
 			 num_sge * sizeof (struct ib_sge), GFP_KERNEL);
-};
+}
 
 ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
 			    struct ib_device *ib_dev,
@@ -2719,6 +2723,13 @@ static struct ib_recv_wr *ib_uverbs_unma
 			ret = -EINVAL;
 			goto err;
 		}
+
+		if (user_wr->num_sge >=
+		    (U32_MAX - ALIGN(sizeof *next, sizeof (struct ib_sge))) /
+		    sizeof (struct ib_sge)) {
+			ret = -EINVAL;
+			goto err;
+		}
 
 		next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
 			       user_wr->num_sge * sizeof (struct ib_sge),
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/hfi1/chip.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/hfi1/chip.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/hfi1/chip.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/hfi1/chip.c	2018-03-24 06:00:27.000000000 -0400
@@ -6379,18 +6379,17 @@ static void lcb_shutdown(struct hfi1_dev
  *
  * The expectation is that the caller of this routine would have taken
  * care of properly transitioning the link into the correct state.
+ * NOTE: the caller needs to acquire the dd->dc8051_lock lock
+ *       before calling this function.
  */
-static void dc_shutdown(struct hfi1_devdata *dd)
+static void _dc_shutdown(struct hfi1_devdata *dd)
 {
-	unsigned long flags;
+	lockdep_assert_held(&dd->dc8051_lock);
 
-	spin_lock_irqsave(&dd->dc8051_lock, flags);
-	if (dd->dc_shutdown) {
-		spin_unlock_irqrestore(&dd->dc8051_lock, flags);
+	if (dd->dc_shutdown)
 		return;
-	}
+
 	dd->dc_shutdown = 1;
-	spin_unlock_irqrestore(&dd->dc8051_lock, flags);
 	/* Shutdown the LCB */
 	lcb_shutdown(dd, 1);
 	/*
@@ -6401,35 +6400,45 @@ static void dc_shutdown(struct hfi1_devd
 	write_csr(dd, DC_DC8051_CFG_RST, 0x1);
 }
 
+static void dc_shutdown(struct hfi1_devdata *dd)
+{
+	mutex_lock(&dd->dc8051_lock);
+	_dc_shutdown(dd);
+	mutex_unlock(&dd->dc8051_lock);
+}
+
 /*
  * Calling this after the DC has been brought out of reset should not
  * do any damage.
+ * NOTE: the caller needs to acquire the dd->dc8051_lock lock
+ *       before calling this function.
  */
-static void dc_start(struct hfi1_devdata *dd)
+static void _dc_start(struct hfi1_devdata *dd)
 {
-	unsigned long flags;
-	int ret;
+	lockdep_assert_held(&dd->dc8051_lock);
 
-	spin_lock_irqsave(&dd->dc8051_lock, flags);
 	if (!dd->dc_shutdown)
-		goto done;
-	spin_unlock_irqrestore(&dd->dc8051_lock, flags);
+		return;
+
 	/* Take the 8051 out of reset */
 	write_csr(dd, DC_DC8051_CFG_RST, 0ull);
 	/* Wait until 8051 is ready */
-	ret = wait_fm_ready(dd, TIMEOUT_8051_START);
-	if (ret) {
+	if (wait_fm_ready(dd, TIMEOUT_8051_START))
 		dd_dev_err(dd, "%s: timeout starting 8051 firmware\n",
 			   __func__);
-	}
+
 	/* Take away reset for LCB and RX FPE (set in lcb_shutdown). */
 	write_csr(dd, DCC_CFG_RESET, 0x10);
 	/* lcb_shutdown() with abort=1 does not restore these */
 	write_csr(dd, DC_LCB_ERR_EN, dd->lcb_err_en);
-	spin_lock_irqsave(&dd->dc8051_lock, flags);
 	dd->dc_shutdown = 0;
-done:
-	spin_unlock_irqrestore(&dd->dc8051_lock, flags);
+}
+
+static void dc_start(struct hfi1_devdata *dd)
+{
+	mutex_lock(&dd->dc8051_lock);
+	_dc_start(dd);
+	mutex_unlock(&dd->dc8051_lock);
 }
 
 /*
@@ -8418,16 +8427,11 @@ static int do_8051_command(
 {
 	u64 reg, completed;
 	int return_code;
-	unsigned long flags;
 	unsigned long timeout;
 
 	hfi1_cdbg(DC8051, "type %d, data 0x%012llx", type, in_data);
 
-	/*
-	 * Alternative to holding the lock for a long time:
-	 * - keep busy wait - have other users bounce off
-	 */
-	spin_lock_irqsave(&dd->dc8051_lock, flags);
+	mutex_lock(&dd->dc8051_lock);
 
 	/* We can't send any commands to the 8051 if it's in reset */
 	if (dd->dc_shutdown) {
@@ -8453,10 +8457,8 @@ static int do_8051_command(
 			return_code = -ENXIO;
 			goto fail;
 		}
-		spin_unlock_irqrestore(&dd->dc8051_lock, flags);
-		dc_shutdown(dd);
-		dc_start(dd);
-		spin_lock_irqsave(&dd->dc8051_lock, flags);
+		_dc_shutdown(dd);
+		_dc_start(dd);
 	}
 
 	/*
@@ -8534,8 +8536,7 @@ static int do_8051_command(
 	write_csr(dd, DC_DC8051_CFG_HOST_CMD_0, 0);
 
 fail:
-	spin_unlock_irqrestore(&dd->dc8051_lock, flags);
-
+	mutex_unlock(&dd->dc8051_lock);
 	return return_code;
 }
 
@@ -11849,6 +11850,10 @@ static void free_cntrs(struct hfi1_devda
 	dd->scntrs = NULL;
 	kfree(dd->cntrnames);
 	dd->cntrnames = NULL;
+	if (dd->update_cntr_wq) {
+		destroy_workqueue(dd->update_cntr_wq);
+		dd->update_cntr_wq = NULL;
+	}
 }
 
 static u64 read_dev_port_cntr(struct hfi1_devdata *dd, struct cntr_entry *entry,
@@ -12004,7 +12009,7 @@ u64 write_port_cntr(struct hfi1_pportdat
 	return write_dev_port_cntr(ppd->dd, entry, sval, ppd, vl, data);
 }
 
-static void update_synth_timer(unsigned long opaque)
+static void do_update_synth_timer(struct work_struct *work)
 {
 	u64 cur_tx;
 	u64 cur_rx;
@@ -12013,8 +12018,8 @@ static void update_synth_timer(unsigned
 	int i, j, vl;
 	struct hfi1_pportdata *ppd;
 	struct cntr_entry *entry;
-
-	struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque;
+	struct hfi1_devdata *dd = container_of(work, struct hfi1_devdata,
+					       update_cntr_work);
 
 	/*
 	 * Rather than keep beating on the CSRs pick a minimal set that we can
@@ -12097,7 +12102,13 @@ static void update_synth_timer(unsigned
 	} else {
 		hfi1_cdbg(CNTR, "[%d] No update necessary", dd->unit);
 	}
+}
 
+static void update_synth_timer(unsigned long opaque)
+{
+	struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque;
+
+	queue_work(dd->update_cntr_wq, &dd->update_cntr_work);
 	mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME);
 }
 
@@ -12333,6 +12344,13 @@ static int init_cntrs(struct hfi1_devdat
 	if (init_cpu_counters(dd))
 		goto bail;
 
+	dd->update_cntr_wq = alloc_ordered_workqueue("hfi1_update_cntr_%d",
+						     WQ_MEM_RECLAIM, dd->unit);
+	if (!dd->update_cntr_wq)
+		goto bail;
+
+	INIT_WORK(&dd->update_cntr_work, do_update_synth_timer);
+
 	mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME);
 	return 0;
 bail:
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/hfi1/hfi.h linux-libre-4.9.90-gnu/drivers/infiniband/hw/hfi1/hfi.h
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/hfi1/hfi.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/hfi1/hfi.h	2018-03-24 06:00:27.000000000 -0400
@@ -475,7 +475,7 @@ struct rvt_sge_state;
 #define HFI1_PART_ENFORCE_OUT	0x2
 
 /* how often we check for synthetic counter wrap around */
-#define SYNTH_CNT_TIME 2
+#define SYNTH_CNT_TIME 3
 
 /* Counter flags */
 #define CNTR_NORMAL		0x0 /* Normal counters, just read register */
@@ -929,8 +929,9 @@ struct hfi1_devdata {
 	spinlock_t rcvctrl_lock; /* protect changes to RcvCtrl */
 	/* around rcd and (user ctxts) ctxt_cnt use (intr vs free) */
 	spinlock_t uctxt_lock; /* rcd and user context changes */
-	/* exclusive access to 8051 */
-	spinlock_t dc8051_lock;
+	struct mutex dc8051_lock; /* exclusive access to 8051 */
+	struct workqueue_struct *update_cntr_wq;
+	struct work_struct update_cntr_work;
 	/* exclusive access to 8051 memory */
 	spinlock_t dc8051_memlock;
 	int dc8051_timed_out;	/* remember if the 8051 timed out */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/hfi1/init.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/hfi1/init.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/hfi1/init.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/hfi1/init.c	2018-03-24 06:00:27.000000000 -0400
@@ -1078,11 +1078,11 @@ struct hfi1_devdata *hfi1_alloc_devdata(
 	spin_lock_init(&dd->uctxt_lock);
 	spin_lock_init(&dd->hfi1_diag_trans_lock);
 	spin_lock_init(&dd->sc_init_lock);
-	spin_lock_init(&dd->dc8051_lock);
 	spin_lock_init(&dd->dc8051_memlock);
 	seqlock_init(&dd->sc2vl_lock);
 	spin_lock_init(&dd->sde_map_lock);
 	spin_lock_init(&dd->pio_map_lock);
+	mutex_init(&dd->dc8051_lock);
 	init_waitqueue_head(&dd->event_queue);
 
 	dd->int_counter = alloc_percpu(u64);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx4/main.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx4/main.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx4/main.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx4/main.c	2018-03-24 06:00:27.000000000 -0400
@@ -1168,7 +1168,7 @@ static void mlx4_ib_disassociate_ucontex
 	/* need to protect from a race on closing the vma as part of
 	 * mlx4_ib_vma_close().
 	 */
-	down_read(&owning_mm->mmap_sem);
+	down_write(&owning_mm->mmap_sem);
 	for (i = 0; i < HW_BAR_COUNT; i++) {
 		vma = context->hw_bar_info[i].vma;
 		if (!vma)
@@ -1182,11 +1182,13 @@ static void mlx4_ib_disassociate_ucontex
 			BUG_ON(1);
 		}
 
+		context->hw_bar_info[i].vma->vm_flags &=
+			~(VM_SHARED | VM_MAYSHARE);
 		/* context going to be destroyed, should not access ops any more */
 		context->hw_bar_info[i].vma->vm_ops = NULL;
 	}
 
-	up_read(&owning_mm->mmap_sem);
+	up_write(&owning_mm->mmap_sem);
 	mmput(owning_mm);
 	put_task_struct(owning_process);
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/cq.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/cq.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/cq.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/cq.c	2018-03-24 06:00:27.000000000 -0400
@@ -172,6 +172,8 @@ static void handle_responder(struct ib_w
 	struct mlx5_ib_srq *srq;
 	struct mlx5_ib_wq *wq;
 	u16 wqe_ctr;
+	u8  roce_packet_type;
+	bool vlan_present;
 	u8 g;
 
 	if (qp->ibqp.srq || qp->ibqp.xrcd) {
@@ -223,7 +225,6 @@ static void handle_responder(struct ib_w
 		break;
 	}
 	wc->slid	   = be16_to_cpu(cqe->slid);
-	wc->sl		   = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
 	wc->src_qp	   = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;
 	wc->dlid_path_bits = cqe->ml_path;
 	g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;
@@ -237,10 +238,22 @@ static void handle_responder(struct ib_w
 		wc->pkey_index = 0;
 	}
 
-	if (ll != IB_LINK_LAYER_ETHERNET)
+	if (ll != IB_LINK_LAYER_ETHERNET) {
+		wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
 		return;
+	}
 
-	switch (wc->sl & 0x3) {
+	vlan_present = cqe->l4_l3_hdr_type & 0x1;
+	roce_packet_type   = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;
+	if (vlan_present) {
+		wc->vlan_id = (be16_to_cpu(cqe->vlan_info)) & 0xfff;
+		wc->sl = (be16_to_cpu(cqe->vlan_info) >> 13) & 0x7;
+		wc->wc_flags |= IB_WC_WITH_VLAN;
+	} else {
+		wc->sl = 0;
+	}
+
+	switch (roce_packet_type) {
 	case MLX5_CQE_ROCE_L3_HEADER_TYPE_GRH:
 		wc->network_hdr_type = RDMA_NETWORK_IB;
 		break;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/main.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/main.c	2018-03-24 06:00:27.000000000 -0400
@@ -1313,7 +1313,7 @@ static void mlx5_ib_disassociate_ucontex
 	/* need to protect from a race on closing the vma as part of
 	 * mlx5_ib_vma_close.
 	 */
-	down_read(&owning_mm->mmap_sem);
+	down_write(&owning_mm->mmap_sem);
 	list_for_each_entry_safe(vma_private, n, &context->vma_private_list,
 				 list) {
 		vma = vma_private->vma;
@@ -1323,11 +1323,12 @@ static void mlx5_ib_disassociate_ucontex
 		/* context going to be destroyed, should
 		 * not access ops any more.
 		 */
+		vma->vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
 		vma->vm_ops = NULL;
 		list_del(&vma_private->list);
 		kfree(vma_private);
 	}
-	up_read(&owning_mm->mmap_sem);
+	up_write(&owning_mm->mmap_sem);
 	mmput(owning_mm);
 	put_task_struct(owning_process);
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/qp.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/qp.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/qp.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/qp.c	2018-03-24 06:00:27.000000000 -0400
@@ -1130,7 +1130,7 @@ static void destroy_raw_packet_qp_sq(str
 	ib_umem_release(sq->ubuffer.umem);
 }
 
-static int get_rq_pas_size(void *qpc)
+static size_t get_rq_pas_size(void *qpc)
 {
 	u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12;
 	u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride);
@@ -1146,7 +1146,8 @@ static int get_rq_pas_size(void *qpc)
 }
 
 static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
-				   struct mlx5_ib_rq *rq, void *qpin)
+				   struct mlx5_ib_rq *rq, void *qpin,
+				   size_t qpinlen)
 {
 	struct mlx5_ib_qp *mqp = rq->base.container_mibqp;
 	__be64 *pas;
@@ -1155,9 +1156,12 @@ static int create_raw_packet_qp_rq(struc
 	void *rqc;
 	void *wq;
 	void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
-	int inlen;
+	size_t rq_pas_size = get_rq_pas_size(qpc);
+	size_t inlen;
 	int err;
-	u32 rq_pas_size = get_rq_pas_size(qpc);
+
+	if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas))
+		return -EINVAL;
 
 	inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size;
 	in = mlx5_vzalloc(inlen);
@@ -1235,7 +1239,7 @@ static void destroy_raw_packet_qp_tir(st
 }
 
 static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
-				u32 *in,
+				u32 *in, size_t inlen,
 				struct ib_pd *pd)
 {
 	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
@@ -1262,7 +1266,7 @@ static int create_raw_packet_qp(struct m
 	if (qp->rq.wqe_cnt) {
 		rq->base.container_mibqp = qp;
 
-		err = create_raw_packet_qp_rq(dev, rq, in);
+		err = create_raw_packet_qp_rq(dev, rq, in, inlen);
 		if (err)
 			goto err_destroy_sq;
 
@@ -1753,10 +1757,15 @@ static int create_qp_common(struct mlx5_
 		qp->flags |= MLX5_IB_QP_LSO;
 	}
 
+	if (inlen < 0) {
+		err = -EINVAL;
+		goto err;
+	}
+
 	if (init_attr->qp_type == IB_QPT_RAW_PACKET) {
 		qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
 		raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
-		err = create_raw_packet_qp(dev, qp, in, pd);
+		err = create_raw_packet_qp(dev, qp, in, inlen, pd);
 	} else {
 		err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
 	}
@@ -1796,6 +1805,7 @@ err_create:
 	else if (qp->create_type == MLX5_QP_KERNEL)
 		destroy_qp_kernel(dev, qp);
 
+err:
 	kvfree(in);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/srq.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/srq.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/mlx5/srq.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/mlx5/srq.c	2018-03-24 06:00:27.000000000 -0400
@@ -243,8 +243,8 @@ struct ib_srq *mlx5_ib_create_srq(struct
 {
 	struct mlx5_ib_dev *dev = to_mdev(pd->device);
 	struct mlx5_ib_srq *srq;
-	int desc_size;
-	int buf_size;
+	size_t desc_size;
+	size_t buf_size;
 	int err;
 	struct mlx5_srq_attr in = {0};
 	__u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
@@ -268,15 +268,18 @@ struct ib_srq *mlx5_ib_create_srq(struct
 
 	desc_size = sizeof(struct mlx5_wqe_srq_next_seg) +
 		    srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg);
+	if (desc_size == 0 || srq->msrq.max_gs > desc_size)
+		return ERR_PTR(-EINVAL);
 	desc_size = roundup_pow_of_two(desc_size);
-	desc_size = max_t(int, 32, desc_size);
+	desc_size = max_t(size_t, 32, desc_size);
+	if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg))
+		return ERR_PTR(-EINVAL);
 	srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) /
 		sizeof(struct mlx5_wqe_data_seg);
 	srq->msrq.wqe_shift = ilog2(desc_size);
 	buf_size = srq->msrq.max * desc_size;
-	mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n",
-		    desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs,
-		    srq->msrq.max_avail_gather);
+	if (buf_size < desc_size)
+		return ERR_PTR(-EINVAL);
 	in.type = init_attr->srq_type;
 
 	if (pd->uobject)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c linux-libre-4.9.90-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c	2018-03-24 06:00:27.000000000 -0400
@@ -836,7 +836,7 @@ void ocrdma_add_port_stats(struct ocrdma
 
 	dev->reset_stats.type = OCRDMA_RESET_STATS;
 	dev->reset_stats.dev = dev;
-	if (!debugfs_create_file("reset_stats", S_IRUSR, dev->dir,
+	if (!debugfs_create_file("reset_stats", 0200, dev->dir,
 				&dev->reset_stats, &ocrdma_dbg_ops))
 		goto err;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/sw/rdmavt/ah.c linux-libre-4.9.90-gnu/drivers/infiniband/sw/rdmavt/ah.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/sw/rdmavt/ah.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/sw/rdmavt/ah.c	2018-03-24 06:00:27.000000000 -0400
@@ -119,7 +119,7 @@ struct ib_ah *rvt_create_ah(struct ib_pd
 
 	spin_lock_irqsave(&dev->n_ahs_lock, flags);
 	if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
-		spin_unlock(&dev->n_ahs_lock);
+		spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
 		kfree(ah);
 		return ERR_PTR(-ENOMEM);
 	}
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/sw/rxe/rxe_resp.c linux-libre-4.9.90-gnu/drivers/infiniband/sw/rxe/rxe_resp.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/sw/rxe/rxe_resp.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/sw/rxe/rxe_resp.c	2018-03-24 06:00:27.000000000 -0400
@@ -471,8 +471,6 @@ static enum resp_states check_rkey(struc
 				state = RESPST_ERR_LENGTH;
 				goto err;
 			}
-
-			qp->resp.resid = mtu;
 		} else {
 			if (pktlen != resid) {
 				state = RESPST_ERR_LENGTH;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-4.9.90-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2018-03-24 06:00:27.000000000 -0400
@@ -974,6 +974,19 @@ static inline int update_parent_pkey(str
 		 */
 		priv->dev->broadcast[8] = priv->pkey >> 8;
 		priv->dev->broadcast[9] = priv->pkey & 0xff;
+
+		/*
+		 * Update the broadcast address in the priv->broadcast object,
+		 * in case it already exists, otherwise no one will do that.
+		 */
+		if (priv->broadcast) {
+			spin_lock_irq(&priv->lock);
+			memcpy(priv->broadcast->mcmember.mgid.raw,
+			       priv->dev->broadcast + 4,
+			sizeof(union ib_gid));
+			spin_unlock_irq(&priv->lock);
+		}
+
 		return 0;
 	}
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-libre-4.9.90-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c	2018-03-24 06:00:27.000000000 -0400
@@ -799,6 +799,22 @@ static void path_rec_completion(int stat
 	spin_lock_irqsave(&priv->lock, flags);
 
 	if (!IS_ERR_OR_NULL(ah)) {
+		/*
+		 * pathrec.dgid is used as the database key from the LLADDR,
+		 * it must remain unchanged even if the SA returns a different
+		 * GID to use in the AH.
+		 */
+		if (memcmp(pathrec->dgid.raw, path->pathrec.dgid.raw,
+			   sizeof(union ib_gid))) {
+			ipoib_dbg(
+				priv,
+				"%s got PathRec for gid %pI6 while asked for %pI6\n",
+				dev->name, pathrec->dgid.raw,
+				path->pathrec.dgid.raw);
+			memcpy(pathrec->dgid.raw, path->pathrec.dgid.raw,
+			       sizeof(union ib_gid));
+		}
+
 		path->pathrec = *pathrec;
 
 		old_ah   = path->ah;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/ulp/ipoib/ipoib_multicast.c linux-libre-4.9.90-gnu/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2018-03-24 06:00:27.000000000 -0400
@@ -487,6 +487,9 @@ static int ipoib_mcast_join(struct net_d
 	    !test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
 		return -EINVAL;
 
+	init_completion(&mcast->done);
+	set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+
 	ipoib_dbg_mcast(priv, "joining MGID %pI6\n", mcast->mcmember.mgid.raw);
 
 	rec.mgid     = mcast->mcmember.mgid;
@@ -645,8 +648,6 @@ void ipoib_mcast_join_task(struct work_s
 			if (mcast->backoff == 1 ||
 			    time_after_eq(jiffies, mcast->delay_until)) {
 				/* Found the next unjoined group */
-				init_completion(&mcast->done);
-				set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
 				if (ipoib_mcast_join(dev, mcast)) {
 					spin_unlock_irq(&priv->lock);
 					return;
@@ -666,11 +667,9 @@ out:
 		queue_delayed_work(priv->wq, &priv->mcast_task,
 				   delay_until - jiffies);
 	}
-	if (mcast) {
-		init_completion(&mcast->done);
-		set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+	if (mcast)
 		ipoib_mcast_join(dev, mcast);
-	}
+
 	spin_unlock_irq(&priv->lock);
 }
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/ulp/isert/ib_isert.c linux-libre-4.9.90-gnu/drivers/infiniband/ulp/isert/ib_isert.c
--- linux-libre-4.9.89-gnu/drivers/infiniband/ulp/isert/ib_isert.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/ulp/isert/ib_isert.c	2018-03-24 06:00:27.000000000 -0400
@@ -2098,6 +2098,9 @@ isert_rdma_rw_ctx_post(struct isert_cmd
 	u32 rkey, offset;
 	int ret;
 
+	if (cmd->ctx_init_done)
+		goto rdma_ctx_post;
+
 	if (dir == DMA_FROM_DEVICE) {
 		addr = cmd->write_va;
 		rkey = cmd->write_stag;
@@ -2125,11 +2128,15 @@ isert_rdma_rw_ctx_post(struct isert_cmd
 				se_cmd->t_data_sg, se_cmd->t_data_nents,
 				offset, addr, rkey, dir);
 	}
+
 	if (ret < 0) {
 		isert_err("Cmd: %p failed to prepare RDMA res\n", cmd);
 		return ret;
 	}
 
+	cmd->ctx_init_done = true;
+
+rdma_ctx_post:
 	ret = rdma_rw_ctx_post(&cmd->rw, conn->qp, port_num, cqe, chain_wr);
 	if (ret < 0)
 		isert_err("Cmd: %p failed to post RDMA res\n", cmd);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/infiniband/ulp/isert/ib_isert.h linux-libre-4.9.90-gnu/drivers/infiniband/ulp/isert/ib_isert.h
--- linux-libre-4.9.89-gnu/drivers/infiniband/ulp/isert/ib_isert.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/infiniband/ulp/isert/ib_isert.h	2018-03-24 06:00:27.000000000 -0400
@@ -124,6 +124,7 @@ struct isert_cmd {
 	struct rdma_rw_ctx	rw;
 	struct work_struct	comp_work;
 	struct scatterlist	sg;
+	bool			ctx_init_done;
 };
 
 static inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/input/misc/twl4030-pwrbutton.c linux-libre-4.9.90-gnu/drivers/input/misc/twl4030-pwrbutton.c
--- linux-libre-4.9.89-gnu/drivers/input/misc/twl4030-pwrbutton.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/input/misc/twl4030-pwrbutton.c	2018-03-24 06:00:27.000000000 -0400
@@ -70,7 +70,7 @@ static int twl4030_pwrbutton_probe(struc
 	pwr->phys = "twl4030_pwrbutton/input0";
 	pwr->dev.parent = &pdev->dev;
 
-	err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq,
+	err = devm_request_threaded_irq(&pdev->dev, irq, NULL, powerbutton_irq,
 			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
 			IRQF_ONESHOT,
 			"twl4030_pwrbutton", pwr);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/input/touchscreen/ar1021_i2c.c linux-libre-4.9.90-gnu/drivers/input/touchscreen/ar1021_i2c.c
--- linux-libre-4.9.89-gnu/drivers/input/touchscreen/ar1021_i2c.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/input/touchscreen/ar1021_i2c.c	2018-03-24 06:00:27.000000000 -0400
@@ -152,7 +152,7 @@ static int __maybe_unused ar1021_i2c_res
 static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume);
 
 static const struct i2c_device_id ar1021_i2c_id[] = {
-	{ "MICROCHIP_AR1021_I2C", 0 },
+	{ "ar1021", 0 },
 	{ },
 };
 MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/iommu/intel-svm.c linux-libre-4.9.90-gnu/drivers/iommu/intel-svm.c
--- linux-libre-4.9.89-gnu/drivers/iommu/intel-svm.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/iommu/intel-svm.c	2018-03-24 06:00:27.000000000 -0400
@@ -127,6 +127,7 @@ int intel_svm_enable_prq(struct intel_io
 		pr_err("IOMMU: %s: Failed to request IRQ for page request queue\n",
 		       iommu->name);
 		dmar_free_hwirq(irq);
+		iommu->pr_irq = 0;
 		goto err;
 	}
 	dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
@@ -142,9 +143,11 @@ int intel_svm_finish_prq(struct intel_io
 	dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
 	dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL);
 
-	free_irq(iommu->pr_irq, iommu);
-	dmar_free_hwirq(iommu->pr_irq);
-	iommu->pr_irq = 0;
+	if (iommu->pr_irq) {
+		free_irq(iommu->pr_irq, iommu);
+		dmar_free_hwirq(iommu->pr_irq);
+		iommu->pr_irq = 0;
+	}
 
 	free_pages((unsigned long)iommu->prq, PRQ_ORDER);
 	iommu->prq = NULL;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/iommu/omap-iommu.c linux-libre-4.9.90-gnu/drivers/iommu/omap-iommu.c
--- linux-libre-4.9.89-gnu/drivers/iommu/omap-iommu.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/iommu/omap-iommu.c	2018-03-24 06:00:27.000000000 -0400
@@ -1299,6 +1299,7 @@ static int __init omap_iommu_init(void)
 	const unsigned long flags = SLAB_HWCACHE_ALIGN;
 	size_t align = 1 << 10; /* L2 pagetable alignement */
 	struct device_node *np;
+	int ret;
 
 	np = of_find_matching_node(NULL, omap_iommu_of_match);
 	if (!np)
@@ -1312,11 +1313,25 @@ static int __init omap_iommu_init(void)
 		return -ENOMEM;
 	iopte_cachep = p;
 
-	bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
-
 	omap_iommu_debugfs_init();
 
-	return platform_driver_register(&omap_iommu_driver);
+	ret = platform_driver_register(&omap_iommu_driver);
+	if (ret) {
+		pr_err("%s: failed to register driver\n", __func__);
+		goto fail_driver;
+	}
+
+	ret = bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
+	if (ret)
+		goto fail_bus;
+
+	return 0;
+
+fail_bus:
+	platform_driver_unregister(&omap_iommu_driver);
+fail_driver:
+	kmem_cache_destroy(iopte_cachep);
+	return ret;
 }
 subsys_initcall(omap_iommu_init);
 /* must be ready before omap3isp is probed */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/irqchip/irq-mips-gic.c linux-libre-4.9.90-gnu/drivers/irqchip/irq-mips-gic.c
--- linux-libre-4.9.89-gnu/drivers/irqchip/irq-mips-gic.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/irqchip/irq-mips-gic.c	2018-03-24 06:00:27.000000000 -0400
@@ -55,6 +55,7 @@ static unsigned int gic_cpu_pin;
 static unsigned int timer_cpu_pin;
 static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
+DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
 static void __gic_irq_dispatch(void);
 
@@ -746,17 +747,17 @@ static int gic_irq_domain_alloc(struct i
 
 		return gic_setup_dev_chip(d, virq, spec->hwirq);
 	} else {
-		base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs);
+		base_hwirq = find_first_bit(ipi_available, gic_shared_intrs);
 		if (base_hwirq == gic_shared_intrs) {
 			return -ENOMEM;
 		}
 
 		/* check that we have enough space */
 		for (i = base_hwirq; i < nr_irqs; i++) {
-			if (!test_bit(i, ipi_resrv))
+			if (!test_bit(i, ipi_available))
 				return -EBUSY;
 		}
-		bitmap_clear(ipi_resrv, base_hwirq, nr_irqs);
+		bitmap_clear(ipi_available, base_hwirq, nr_irqs);
 
 		/* map the hwirq for each cpu consecutively */
 		i = 0;
@@ -787,7 +788,7 @@ static int gic_irq_domain_alloc(struct i
 
 	return 0;
 error:
-	bitmap_set(ipi_resrv, base_hwirq, nr_irqs);
+	bitmap_set(ipi_available, base_hwirq, nr_irqs);
 	return ret;
 }
 
@@ -802,7 +803,7 @@ void gic_irq_domain_free(struct irq_doma
 		return;
 
 	base_hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(data));
-	bitmap_set(ipi_resrv, base_hwirq, nr_irqs);
+	bitmap_set(ipi_available, base_hwirq, nr_irqs);
 }
 
 int gic_irq_domain_match(struct irq_domain *d, struct device_node *node,
@@ -1066,6 +1067,7 @@ static void __init __gic_init(unsigned l
 			   2 * gic_vpes);
 	}
 
+	bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
 	gic_basic_init();
 }
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/leds/led-core.c linux-libre-4.9.90-gnu/drivers/leds/led-core.c
--- linux-libre-4.9.89-gnu/drivers/leds/led-core.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/leds/led-core.c	2018-03-24 06:00:27.000000000 -0400
@@ -186,8 +186,9 @@ void led_blink_set(struct led_classdev *
 		   unsigned long *delay_on,
 		   unsigned long *delay_off)
 {
-	led_stop_software_blink(led_cdev);
+	del_timer_sync(&led_cdev->blink_timer);
 
+	led_cdev->flags &= ~LED_BLINK_SW;
 	led_cdev->flags &= ~LED_BLINK_ONESHOT;
 	led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/md/raid10.c linux-libre-4.9.90-gnu/drivers/md/raid10.c
--- linux-libre-4.9.89-gnu/drivers/md/raid10.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/md/raid10.c	2018-03-24 06:00:27.000000000 -0400
@@ -2704,6 +2704,11 @@ static void handle_write_completed(struc
 			list_add(&r10_bio->retry_list, &conf->bio_end_io_list);
 			conf->nr_queued++;
 			spin_unlock_irq(&conf->device_lock);
+			/*
+			 * In case freeze_array() is waiting for condition
+			 * nr_pending == nr_queued + extra to be true.
+			 */
+			wake_up(&conf->wait_barrier);
 			md_wakeup_thread(conf->mddev->thread);
 		} else {
 			if (test_bit(R10BIO_WriteError,
@@ -4084,6 +4089,7 @@ static int raid10_start_reshape(struct m
 				diff = 0;
 			if (first || diff < min_offset_diff)
 				min_offset_diff = diff;
+			first = 0;
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/media/dvb-core/dvb_ca_en50221.c linux-libre-4.9.90-gnu/drivers/media/dvb-core/dvb_ca_en50221.c
--- linux-libre-4.9.89-gnu/drivers/media/dvb-core/dvb_ca_en50221.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/media/dvb-core/dvb_ca_en50221.c	2018-03-24 06:00:27.000000000 -0400
@@ -779,6 +779,29 @@ static int dvb_ca_en50221_write_data(str
 		goto exit;
 	}
 
+	/*
+	 * It may need some time for the CAM to settle down, or there might
+	 * be a race condition between the CAM, writing HC and our last
+	 * check for DA. This happens, if the CAM asserts DA, just after
+	 * checking DA before we are setting HC. In this case it might be
+	 * a bug in the CAM to keep the FR bit, the lower layer/HW
+	 * communication requires a longer timeout or the CAM needs more
+	 * time internally. But this happens in reality!
+	 * We need to read the status from the HW again and do the same
+	 * we did for the previous check for DA
+	 */
+	status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
+	if (status < 0)
+		goto exit;
+
+	if (status & (STATUSREG_DA | STATUSREG_RE)) {
+		if (status & STATUSREG_DA)
+			dvb_ca_en50221_thread_wakeup(ca);
+
+		status = -EAGAIN;
+		goto exit;
+	}
+
 	/* send the amount of data */
 	if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
 		goto exit;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/media/dvb-frontends/si2168.c linux-libre-4.9.90-gnu/drivers/media/dvb-frontends/si2168.c
--- linux-libre-4.9.89-gnu/drivers/media/dvb-frontends/si2168.c	2018-03-22 16:02:57.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/media/dvb-frontends/si2168.c	2018-03-25 14:24:04.000000000 -0400
@@ -14,6 +14,8 @@
  *    GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
+
 #include "si2168_priv.h"
 
 static const struct dvb_frontend_ops si2168_ops;
@@ -378,6 +380,7 @@ static int si2168_init(struct dvb_fronte
 		if (ret)
 			goto err;
 
+		udelay(100);
 		memcpy(cmd.args, "\x85", 1);
 		cmd.wlen = 1;
 		cmd.rlen = 1;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/media/pci/bt8xx/bt878.c linux-libre-4.9.90-gnu/drivers/media/pci/bt8xx/bt878.c
--- linux-libre-4.9.89-gnu/drivers/media/pci/bt8xx/bt878.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/media/pci/bt8xx/bt878.c	2018-03-24 06:00:27.000000000 -0400
@@ -422,8 +422,7 @@ static int bt878_probe(struct pci_dev *d
 	       bt878_num);
 	if (bt878_num >= BT878_MAX) {
 		printk(KERN_ERR "bt878: Too many devices inserted\n");
-		result = -ENOMEM;
-		goto fail0;
+		return -ENOMEM;
 	}
 	if (pci_enable_device(dev))
 		return -EIO;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c linux-libre-4.9.90-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
--- linux-libre-4.9.89-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c	2018-03-22 16:03:34.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c	2018-03-25 14:29:08.000000000 -0400
@@ -83,7 +83,7 @@ static void c8sectpfe_timer_interrupt(un
 static void channel_swdemux_tsklet(unsigned long data)
 {
 	struct channel_info *channel = (struct channel_info *)data;
-	struct c8sectpfei *fei = channel->fei;
+	struct c8sectpfei *fei;
 	unsigned long wp, rp;
 	int pos, num_packets, n, size;
 	u8 *buf;
@@ -91,6 +91,8 @@ static void channel_swdemux_tsklet(unsig
 	if (unlikely(!channel || !channel->irec))
 		return;
 
+	fei = channel->fei;
+
 	wp = readl(channel->irec + DMA_PRDS_BUSWP_TP(0));
 	rp = readl(channel->irec + DMA_PRDS_BUSRP_TP(0));
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/mfd/palmas.c linux-libre-4.9.90-gnu/drivers/mfd/palmas.c
--- linux-libre-4.9.89-gnu/drivers/mfd/palmas.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/mfd/palmas.c	2018-03-24 06:00:27.000000000 -0400
@@ -430,6 +430,20 @@ static void palmas_power_off(void)
 {
 	unsigned int addr;
 	int ret, slave;
+	struct device_node *np = palmas_dev->dev->of_node;
+
+	if (of_property_read_bool(np, "ti,palmas-override-powerhold")) {
+		addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
+					  PALMAS_PRIMARY_SECONDARY_PAD2);
+		slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
+
+		ret = regmap_update_bits(palmas_dev->regmap[slave], addr,
+				PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK, 0);
+		if (ret)
+			dev_err(palmas_dev->dev,
+				"Unable to write PRIMARY_SECONDARY_PAD2 %d\n",
+				ret);
+	}
 
 	if (!palmas_dev)
 		return;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/mmc/core/core.c linux-libre-4.9.90-gnu/drivers/mmc/core/core.c
--- linux-libre-4.9.89-gnu/drivers/mmc/core/core.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/mmc/core/core.c	2018-03-24 06:00:27.000000000 -0400
@@ -2974,6 +2974,14 @@ static int mmc_pm_notify(struct notifier
 		if (!err)
 			break;
 
+		if (!mmc_card_is_removable(host)) {
+			dev_warn(mmc_dev(host),
+				 "pre_suspend failed for non-removable host: "
+				 "%d\n", err);
+			/* Avoid removing non-removable hosts */
+			break;
+		}
+
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
 		host->bus_ops->remove(host);
 		mmc_claim_host(host);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/mmc/host/omap_hsmmc.c linux-libre-4.9.90-gnu/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-4.9.89-gnu/drivers/mmc/host/omap_hsmmc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/mmc/host/omap_hsmmc.c	2018-03-24 06:00:27.000000000 -0400
@@ -1762,8 +1762,8 @@ static int omap_hsmmc_configure_wake_irq
 	 */
 	if (host->pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) {
 		struct pinctrl *p = devm_pinctrl_get(host->dev);
-		if (!p) {
-			ret = -ENODEV;
+		if (IS_ERR(p)) {
+			ret = PTR_ERR(p);
 			goto err_free_irq;
 		}
 		if (IS_ERR(pinctrl_lookup_state(p, PINCTRL_STATE_DEFAULT))) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/mmc/host/sdhci-of-esdhc.c linux-libre-4.9.90-gnu/drivers/mmc/host/sdhci-of-esdhc.c
--- linux-libre-4.9.89-gnu/drivers/mmc/host/sdhci-of-esdhc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/mmc/host/sdhci-of-esdhc.c	2018-03-24 06:00:27.000000000 -0400
@@ -432,6 +432,20 @@ static void esdhc_of_set_clock(struct sd
 	if (esdhc->vendor_ver < VENDOR_V_23)
 		pre_div = 2;
 
+	/*
+	 * Limit SD clock to 167MHz for ls1046a according to its datasheet
+	 */
+	if (clock > 167000000 &&
+	    of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
+		clock = 167000000;
+
+	/*
+	 * Limit SD clock to 125MHz for ls1012a according to its datasheet
+	 */
+	if (clock > 125000000 &&
+	    of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
+		clock = 125000000;
+
 	/* Workaround to reduce the clock frequency for p1010 esdhc */
 	if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
 		if (clock > 20000000)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/bonding/bond_main.c linux-libre-4.9.90-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-4.9.89-gnu/drivers/net/bonding/bond_main.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/bonding/bond_main.c	2018-03-24 06:00:27.000000000 -0400
@@ -2067,6 +2067,7 @@ static int bond_miimon_inspect(struct bo
 					    (bond->params.downdelay - slave->delay) *
 					    bond->params.miimon,
 					    slave->dev->name);
+				commit++;
 				continue;
 			}
 
@@ -2104,7 +2105,7 @@ static int bond_miimon_inspect(struct bo
 					    (bond->params.updelay - slave->delay) *
 					    bond->params.miimon,
 					    slave->dev->name);
-
+				commit++;
 				continue;
 			}
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-libre-4.9.90-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2018-03-22 16:07:56.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2018-03-25 14:32:20.000000000 -0400
@@ -2026,6 +2026,7 @@ static void bnx2x_set_rx_buf_size(struct
 				  ETH_OVREHEAD +
 				  mtu +
 				  BNX2X_FW_RX_ALIGN_END;
+		fp->rx_buf_size = SKB_DATA_ALIGN(fp->rx_buf_size);
 		/* Note : rx_buf_size doesn't take into account NET_SKB_PAD */
 		if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE)
 			fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/freescale/ucc_geth.c linux-libre-4.9.90-gnu/drivers/net/ethernet/freescale/ucc_geth.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/freescale/ucc_geth.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/freescale/ucc_geth.c	2018-03-24 06:00:27.000000000 -0400
@@ -2594,11 +2594,10 @@ static int ucc_geth_startup(struct ucc_g
 		} else if (ugeth->ug_info->uf_info.bd_mem_part ==
 			   MEM_PART_MURAM) {
 			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
-				 (u32) immrbar_virt_to_phys(ugeth->
-							    p_tx_bd_ring[i]));
+				 (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i]));
 			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
 				 last_bd_completed_address,
-				 (u32) immrbar_virt_to_phys(endOfRing));
+				 (u32)qe_muram_dma(endOfRing));
 		}
 	}
 
@@ -2844,8 +2843,7 @@ static int ucc_geth_startup(struct ucc_g
 		} else if (ugeth->ug_info->uf_info.bd_mem_part ==
 			   MEM_PART_MURAM) {
 			out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
-				 (u32) immrbar_virt_to_phys(ugeth->
-							    p_rx_bd_ring[i]));
+				 (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i]));
 		}
 		/* rest of fields handled by QE */
 	}
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c	2018-03-24 06:00:27.000000000 -0400
@@ -671,7 +671,7 @@ static void hns_gmac_get_strings(u32 str
 
 static int hns_gmac_get_sset_count(int stringset)
 {
-	if (stringset == ETH_SS_STATS)
+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
 		return ARRAY_SIZE(g_gmac_stats_string);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c	2018-03-24 06:00:27.000000000 -0400
@@ -422,7 +422,7 @@ void hns_ppe_update_stats(struct hns_ppe
 
 int hns_ppe_get_sset_count(int stringset)
 {
-	if (stringset == ETH_SS_STATS)
+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
 		return ETH_PPE_STATIC_NUM;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c	2018-03-24 06:00:27.000000000 -0400
@@ -798,7 +798,7 @@ void hns_rcb_get_stats(struct hnae_queue
  */
 int hns_rcb_get_ring_sset_count(int stringset)
 {
-	if (stringset == ETH_SS_STATS)
+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
 		return HNS_RING_STATIC_REG_NUM;
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c	2018-03-24 06:00:27.000000000 -0400
@@ -776,7 +776,7 @@ static void hns_xgmac_get_strings(u32 st
  */
 static int hns_xgmac_get_sset_count(int stringset)
 {
-	if (stringset == ETH_SS_STATS)
+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
 		return ARRAY_SIZE(g_xgmac_stats_string);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/ibm/ibmvnic.c linux-libre-4.9.90-gnu/drivers/net/ethernet/ibm/ibmvnic.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/ibm/ibmvnic.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/ibm/ibmvnic.c	2018-03-24 06:00:27.000000000 -0400
@@ -511,6 +511,23 @@ alloc_napi_failed:
 	return -ENOMEM;
 }
 
+static void disable_sub_crqs(struct ibmvnic_adapter *adapter)
+{
+	int i;
+
+	if (adapter->tx_scrq) {
+		for (i = 0; i < adapter->req_tx_queues; i++)
+			if (adapter->tx_scrq[i])
+				disable_irq(adapter->tx_scrq[i]->irq);
+	}
+
+	if (adapter->rx_scrq) {
+		for (i = 0; i < adapter->req_rx_queues; i++)
+			if (adapter->rx_scrq[i])
+				disable_irq(adapter->rx_scrq[i]->irq);
+	}
+}
+
 static int ibmvnic_close(struct net_device *netdev)
 {
 	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -519,6 +536,7 @@ static int ibmvnic_close(struct net_devi
 	int i;
 
 	adapter->closing = true;
+	disable_sub_crqs(adapter);
 
 	for (i = 0; i < adapter->req_rx_queues; i++)
 		napi_disable(&adapter->napi[i]);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/intel/e1000e/netdev.c linux-libre-4.9.90-gnu/drivers/net/ethernet/intel/e1000e/netdev.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2018-03-24 06:00:27.000000000 -0400
@@ -3528,6 +3528,12 @@ s32 e1000e_get_base_timinca(struct e1000
 
 	switch (hw->mac.type) {
 	case e1000_pch2lan:
+		/* Stable 96MHz frequency */
+		incperiod = INCPERIOD_96MHz;
+		incvalue = INCVALUE_96MHz;
+		shift = INCVALUE_SHIFT_96MHz;
+		adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz;
+		break;
 	case e1000_pch_lpt:
 		if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
 			/* Stable 96MHz frequency */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/intel/ixgbevf/ethtool.c linux-libre-4.9.90-gnu/drivers/net/ethernet/intel/ixgbevf/ethtool.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/intel/ixgbevf/ethtool.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/intel/ixgbevf/ethtool.c	2018-03-24 06:00:27.000000000 -0400
@@ -80,7 +80,7 @@ static struct ixgbe_stats ixgbevf_gstrin
 #define IXGBEVF_QUEUE_STATS_LEN ( \
 	(((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \
 	 ((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \
-	 (sizeof(struct ixgbe_stats) / sizeof(u64)))
+	 (sizeof(struct ixgbevf_stats) / sizeof(u64)))
 #define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats)
 
 #define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/qlogic/qed/qed_vf.c linux-libre-4.9.90-gnu/drivers/net/ethernet/qlogic/qed/qed_vf.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/qlogic/qed/qed_vf.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/qlogic/qed/qed_vf.c	2018-03-24 06:00:27.000000000 -0400
@@ -204,7 +204,7 @@ static int qed_vf_pf_acquire(struct qed_
 		/* send acquire request */
 		rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
 		if (rc)
-			return rc;
+			goto exit;
 
 		/* copy acquire response from buffer to p_hwfn */
 		memcpy(&p_iov->acquire_resp, resp, sizeof(p_iov->acquire_resp));
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c linux-libre-4.9.90-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
--- linux-libre-4.9.89-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c	2018-03-24 06:00:27.000000000 -0400
@@ -128,6 +128,8 @@ static int qlcnic_sriov_virtid_fn(struct
 		return 0;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+	if (!pos)
+		return 0;
 	pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
 	pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/hyperv/netvsc.c linux-libre-4.9.90-gnu/drivers/net/hyperv/netvsc.c
--- linux-libre-4.9.89-gnu/drivers/net/hyperv/netvsc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/hyperv/netvsc.c	2018-03-24 06:00:27.000000000 -0400
@@ -151,6 +151,13 @@ static void netvsc_destroy_buf(struct hv
 				       sizeof(struct nvsp_message),
 				       (unsigned long)revoke_packet,
 				       VM_PKT_DATA_INBAND, 0);
+		/* If the failure is because the channel is rescinded;
+		 * ignore the failure since we cannot send on a rescinded
+		 * channel. This would allow us to properly cleanup
+		 * even when the channel is rescinded.
+		 */
+		if (device->channel->rescind)
+			ret = 0;
 		/*
 		 * If we failed here, we might as well return and
 		 * have a leak rather than continue and a bugchk
@@ -211,6 +218,15 @@ static void netvsc_destroy_buf(struct hv
 				       sizeof(struct nvsp_message),
 				       (unsigned long)revoke_packet,
 				       VM_PKT_DATA_INBAND, 0);
+
+		/* If the failure is because the channel is rescinded;
+		 * ignore the failure since we cannot send on a rescinded
+		 * channel. This would allow us to properly cleanup
+		 * even when the channel is rescinded.
+		 */
+		if (device->channel->rescind)
+			ret = 0;
+
 		/* If we failed here, we might as well return and
 		 * have a leak rather than continue and a bugchk
 		 */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/usb/qmi_wwan.c linux-libre-4.9.90-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-4.9.89-gnu/drivers/net/usb/qmi_wwan.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/usb/qmi_wwan.c	2018-03-24 06:00:27.000000000 -0400
@@ -531,7 +531,7 @@ err:
 
 static const struct driver_info	qmi_wwan_info = {
 	.description	= "WWAN/QMI device",
-	.flags		= FLAG_WWAN,
+	.flags		= FLAG_WWAN | FLAG_SEND_ZLP,
 	.bind		= qmi_wwan_bind,
 	.unbind		= qmi_wwan_unbind,
 	.manage_power	= qmi_wwan_manage_power,
@@ -540,7 +540,7 @@ static const struct driver_info	qmi_wwan
 
 static const struct driver_info	qmi_wwan_info_quirk_dtr = {
 	.description	= "WWAN/QMI device",
-	.flags		= FLAG_WWAN,
+	.flags		= FLAG_WWAN | FLAG_SEND_ZLP,
 	.bind		= qmi_wwan_bind,
 	.unbind		= qmi_wwan_unbind,
 	.manage_power	= qmi_wwan_manage_power,
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/vxlan.c linux-libre-4.9.90-gnu/drivers/net/vxlan.c
--- linux-libre-4.9.89-gnu/drivers/net/vxlan.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/vxlan.c	2018-03-24 06:00:27.000000000 -0400
@@ -2816,17 +2816,21 @@ static int __vxlan_sock_add(struct vxlan
 
 static int vxlan_sock_add(struct vxlan_dev *vxlan)
 {
-	bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
 	bool metadata = vxlan->flags & VXLAN_F_COLLECT_METADATA;
+	bool ipv6 = vxlan->flags & VXLAN_F_IPV6 || metadata;
+	bool ipv4 = !ipv6 || metadata;
 	int ret = 0;
 
 	RCU_INIT_POINTER(vxlan->vn4_sock, NULL);
 #if IS_ENABLED(CONFIG_IPV6)
 	RCU_INIT_POINTER(vxlan->vn6_sock, NULL);
-	if (ipv6 || metadata)
+	if (ipv6) {
 		ret = __vxlan_sock_add(vxlan, true);
+		if (ret < 0 && ret != -EAFNOSUPPORT)
+			ipv4 = false;
+	}
 #endif
-	if (!ret && (!ipv6 || metadata))
+	if (ipv4)
 		ret = __vxlan_sock_add(vxlan, false);
 	if (ret < 0)
 		vxlan_sock_release(vxlan);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wan/pc300too.c linux-libre-4.9.90-gnu/drivers/net/wan/pc300too.c
--- linux-libre-4.9.89-gnu/drivers/net/wan/pc300too.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wan/pc300too.c	2018-03-24 06:00:27.000000000 -0400
@@ -347,6 +347,7 @@ static int pc300_pci_init_one(struct pci
 	    card->rambase == NULL) {
 		pr_err("ioremap() failed\n");
 		pc300_pci_remove_one(pdev);
+		return -ENOMEM;
 	}
 
 	/* PLX PCI 9050 workaround for local configuration register read bug */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/ath/ath10k/debug.c linux-libre-4.9.90-gnu/drivers/net/wireless/ath/ath10k/debug.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/ath/ath10k/debug.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/ath/ath10k/debug.c	2018-03-24 06:00:27.000000000 -0400
@@ -624,17 +624,21 @@ static ssize_t ath10k_write_simulate_fw_
 					      size_t count, loff_t *ppos)
 {
 	struct ath10k *ar = file->private_data;
-	char buf[32];
+	char buf[32] = {0};
+	ssize_t rc;
 	int ret;
 
-	simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+	/* filter partial writes and invalid commands */
+	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
+		return -EINVAL;
 
-	/* make sure that buf is null terminated */
-	buf[sizeof(buf) - 1] = 0;
+	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+	if (rc < 0)
+		return rc;
 
 	/* drop the possible '\n' from the end */
-	if (buf[count - 1] == '\n')
-		buf[count - 1] = 0;
+	if (buf[*ppos - 1] == '\n')
+		buf[*ppos - 1] = '\0';
 
 	mutex_lock(&ar->conf_mutex);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/ath/ath10k/mac.c linux-libre-4.9.90-gnu/drivers/net/wireless/ath/ath10k/mac.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/ath/ath10k/mac.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/ath/ath10k/mac.c	2018-03-24 06:00:27.000000000 -0400
@@ -2505,7 +2505,7 @@ static void ath10k_peer_assoc_h_qos(stru
 		}
 		break;
 	case WMI_VDEV_TYPE_STA:
-		if (vif->bss_conf.qos)
+		if (sta->wme)
 			arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
 		break;
 	case WMI_VDEV_TYPE_IBSS:
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/ath/regd.c linux-libre-4.9.90-gnu/drivers/net/wireless/ath/regd.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/ath/regd.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/ath/regd.c	2018-03-24 06:00:27.000000000 -0400
@@ -254,8 +254,12 @@ bool ath_is_49ghz_allowed(u16 regdomain)
 EXPORT_SYMBOL(ath_is_49ghz_allowed);
 
 /* Frequency is one where radar detection is required */
-static bool ath_is_radar_freq(u16 center_freq)
+static bool ath_is_radar_freq(u16 center_freq,
+			      struct ath_regulatory *reg)
+
 {
+	if (reg->country_code == CTRY_INDIA)
+		return (center_freq >= 5500 && center_freq <= 5700);
 	return (center_freq >= 5260 && center_freq <= 5700);
 }
 
@@ -306,7 +310,7 @@ __ath_reg_apply_beaconing_flags(struct w
 				enum nl80211_reg_initiator initiator,
 				struct ieee80211_channel *ch)
 {
-	if (ath_is_radar_freq(ch->center_freq) ||
+	if (ath_is_radar_freq(ch->center_freq, reg) ||
 	    (ch->flags & IEEE80211_CHAN_RADAR))
 		return;
 
@@ -395,8 +399,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip
 	}
 }
 
-/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
-static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
+/* Always apply Radar/DFS rules on freq range 5500 MHz - 5700 MHz */
+static void ath_reg_apply_radar_flags(struct wiphy *wiphy,
+				      struct ath_regulatory *reg)
 {
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_channel *ch;
@@ -409,7 +414,7 @@ static void ath_reg_apply_radar_flags(st
 
 	for (i = 0; i < sband->n_channels; i++) {
 		ch = &sband->channels[i];
-		if (!ath_is_radar_freq(ch->center_freq))
+		if (!ath_is_radar_freq(ch->center_freq, reg))
 			continue;
 		/* We always enable radar detection/DFS on this
 		 * frequency range. Additionally we also apply on
@@ -505,7 +510,7 @@ void ath_reg_notifier_apply(struct wiphy
 	struct ath_common *common = container_of(reg, struct ath_common,
 						 regulatory);
 	/* We always apply this */
-	ath_reg_apply_radar_flags(wiphy);
+	ath_reg_apply_radar_flags(wiphy, reg);
 
 	/*
 	 * This would happen when we have sent a custom regulatory request
@@ -653,7 +658,7 @@ ath_regd_init_wiphy(struct ath_regulator
 	}
 
 	wiphy_apply_custom_regulatory(wiphy, regd);
-	ath_reg_apply_radar_flags(wiphy);
+	ath_reg_apply_radar_flags(wiphy, reg);
 	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/intel/iwlwifi/iwl-a000.c linux-libre-4.9.90-gnu/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/intel/iwlwifi/iwl-a000.c	2018-03-22 16:13:13.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/intel/iwlwifi/iwl-a000.c	2018-03-25 14:36:54.000000000 -0400
@@ -65,12 +65,12 @@
 #define IWL_A000_TX_POWER_VERSION	0xffff /* meaningless */
 
 /* Memory offsets and lengths */
-#define IWL_A000_DCCM_OFFSET		0x800000
-#define IWL_A000_DCCM_LEN		0x18000
+#define IWL_A000_DCCM_OFFSET		0x800000 /* LMAC1 */
+#define IWL_A000_DCCM_LEN		0x10000 /* LMAC1 */
 #define IWL_A000_DCCM2_OFFSET		0x880000
 #define IWL_A000_DCCM2_LEN		0x8000
 #define IWL_A000_SMEM_OFFSET		0x400000
-#define IWL_A000_SMEM_LEN		0x68000
+#define IWL_A000_SMEM_LEN		0xD0000
 
 #define IWL_A000_FW_PRE "/*(DEBLOBBED)*/"
 #define IWL_A000_MODULE_FIRMWARE(api) \
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c linux-libre-4.9.90-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c	2018-03-24 06:00:27.000000000 -0400
@@ -76,8 +76,8 @@ void iwl_notification_wait_init(struct i
 }
 IWL_EXPORT_SYMBOL(iwl_notification_wait_init);
 
-void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
-				  struct iwl_rx_packet *pkt)
+bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait,
+			   struct iwl_rx_packet *pkt)
 {
 	bool triggered = false;
 
@@ -118,13 +118,11 @@ void iwl_notification_wait_notify(struct
 			}
 		}
 		spin_unlock(&notif_wait->notif_wait_lock);
-
 	}
 
-	if (triggered)
-		wake_up_all(&notif_wait->notif_waitq);
+	return triggered;
 }
-IWL_EXPORT_SYMBOL(iwl_notification_wait_notify);
+IWL_EXPORT_SYMBOL(iwl_notification_wait);
 
 void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
 {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h linux-libre-4.9.90-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h
--- linux-libre-4.9.89-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h	2018-03-24 06:00:27.000000000 -0400
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,6 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,10 +90,10 @@ struct iwl_notif_wait_data {
  *
  * This structure is not used directly, to wait for a
  * notification declare it on the stack, and call
- * iwlagn_init_notification_wait() with appropriate
+ * iwl_init_notification_wait() with appropriate
  * parameters. Then do whatever will cause the ucode
  * to notify the driver, and to wait for that then
- * call iwlagn_wait_notification().
+ * call iwl_wait_notification().
  *
  * Each notification is one-shot. If at some point we
  * need to support multi-shot notifications (which
@@ -114,10 +115,24 @@ struct iwl_notification_wait {
 
 /* caller functions */
 void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);
-void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
-				  struct iwl_rx_packet *pkt);
+bool iwl_notification_wait(struct iwl_notif_wait_data *notif_data,
+			   struct iwl_rx_packet *pkt);
 void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);
 
+static inline void
+iwl_notification_notify(struct iwl_notif_wait_data *notif_data)
+{
+	wake_up_all(&notif_data->notif_waitq);
+}
+
+static inline void
+iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
+			     struct iwl_rx_packet *pkt)
+{
+	if (iwl_notification_wait(notif_data, pkt))
+		iwl_notification_notify(notif_data);
+}
+
 /* user functions */
 void __acquires(wait_entry)
 iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/marvell/libertas/if_spi.c linux-libre-4.9.90-gnu/drivers/net/wireless/marvell/libertas/if_spi.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/marvell/libertas/if_spi.c	2018-03-22 16:13:32.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/marvell/libertas/if_spi.c	2018-03-25 14:44:13.000000000 -0400
@@ -1173,6 +1173,10 @@ static int if_spi_probe(struct spi_devic
 
 	/* Initialize interrupt handling stuff. */
 	card->workqueue = alloc_workqueue("libertas_spi", WQ_MEM_RECLAIM, 0);
+	if (!card->workqueue) {
+		err = -ENOMEM;
+		goto remove_card;
+	}
 	INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
 	INIT_WORK(&card->resume_work, if_spi_resume_worker);
 
@@ -1201,6 +1205,7 @@ release_irq:
 	free_irq(spi->irq, card);
 terminate_workqueue:
 	destroy_workqueue(card->workqueue);
+remove_card:
 	lbs_remove_card(priv); /* will call free_netdev */
 free_card:
 	free_if_spi_card(card);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/marvell/mwifiex/main.c linux-libre-4.9.90-gnu/drivers/net/wireless/marvell/mwifiex/main.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/marvell/mwifiex/main.c	2018-03-22 16:13:57.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/marvell/mwifiex/main.c	2018-03-25 14:47:46.000000000 -0400
@@ -146,7 +146,6 @@ static int mwifiex_unregister(struct mwi
 
 	kfree(adapter->regd);
 
-	vfree(adapter->chan_stats);
 	kfree(adapter);
 	return 0;
 }
@@ -636,6 +635,7 @@ static void mwifiex_fw_dpc(const struct
 	goto done;
 
 err_add_intf:
+	vfree(adapter->chan_stats);
 	wiphy_unregister(adapter->wiphy);
 	wiphy_free(adapter->wiphy);
 err_init_fw:
@@ -1429,6 +1429,7 @@ mwifiex_shutdown_sw(struct mwifiex_adapt
 			mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
 		rtnl_unlock();
 	}
+	vfree(adapter->chan_stats);
 
 	up(sem);
 exit_sem_err:
@@ -1729,6 +1730,7 @@ int mwifiex_remove_card(struct mwifiex_a
 			mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
 		rtnl_unlock();
 	}
+	vfree(adapter->chan_stats);
 
 	wiphy_unregister(adapter->wiphy);
 	wiphy_free(adapter->wiphy);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/mediatek/mt7601u/mcu.c linux-libre-4.9.90-gnu/drivers/net/wireless/mediatek/mt7601u/mcu.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/mediatek/mt7601u/mcu.c	2018-03-22 16:13:42.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/mediatek/mt7601u/mcu.c	2018-03-25 14:47:34.000000000 -0400
@@ -66,8 +66,10 @@ mt7601u_mcu_msg_alloc(struct mt7601u_dev
 	WARN_ON(len % 4); /* if length is not divisible by 4 we need to pad */
 
 	skb = alloc_skb(len + MT_DMA_HDR_LEN + 4, GFP_KERNEL);
-	skb_reserve(skb, MT_DMA_HDR_LEN);
-	memcpy(skb_put(skb, len), data, len);
+	if (skb) {
+		skb_reserve(skb, MT_DMA_HDR_LEN);
+		memcpy(skb_put(skb, len), data, len);
+	}
 
 	return skb;
 }
@@ -170,6 +172,8 @@ static int mt7601u_mcu_function_select(s
 	};
 
 	skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg));
+	if (!skb)
+		return -ENOMEM;
 	return mt7601u_mcu_msg_send(dev, skb, CMD_FUN_SET_OP, func == 5);
 }
 
@@ -205,6 +209,8 @@ mt7601u_mcu_calibrate(struct mt7601u_dev
 	};
 
 	skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg));
+	if (!skb)
+		return -ENOMEM;
 	return mt7601u_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP, true);
 }
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c linux-libre-4.9.90-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c	2018-03-24 06:00:27.000000000 -0400
@@ -1572,7 +1572,14 @@ int rtl_pci_reset_trx_ring(struct ieee80
 				dev_kfree_skb_irq(skb);
 				ring->idx = (ring->idx + 1) % ring->entries;
 			}
+
+			if (rtlpriv->use_new_trx_flow) {
+				rtlpci->tx_ring[i].cur_tx_rp = 0;
+				rtlpci->tx_ring[i].cur_tx_wp = 0;
+			}
+
 			ring->idx = 0;
+			ring->entries = rtlpci->txringcount[i];
 		}
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/net/wireless/rndis_wlan.c linux-libre-4.9.90-gnu/drivers/net/wireless/rndis_wlan.c
--- linux-libre-4.9.89-gnu/drivers/net/wireless/rndis_wlan.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/net/wireless/rndis_wlan.c	2018-03-24 06:00:27.000000000 -0400
@@ -3427,6 +3427,10 @@ static int rndis_wlan_bind(struct usbnet
 
 	/* because rndis_command() sleeps we need to use workqueue */
 	priv->workqueue = create_singlethread_workqueue("rndis_wlan");
+	if (!priv->workqueue) {
+		wiphy_free(wiphy);
+		return -ENOMEM;
+	}
 	INIT_WORK(&priv->work, rndis_wlan_worker);
 	INIT_DELAYED_WORK(&priv->dev_poller_work, rndis_device_poller);
 	INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/pinctrl/core.c linux-libre-4.9.90-gnu/drivers/pinctrl/core.c
--- linux-libre-4.9.89-gnu/drivers/pinctrl/core.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/pinctrl/core.c	2018-03-24 06:00:27.000000000 -0400
@@ -992,19 +992,16 @@ struct pinctrl_state *pinctrl_lookup_sta
 EXPORT_SYMBOL_GPL(pinctrl_lookup_state);
 
 /**
- * pinctrl_select_state() - select/activate/program a pinctrl state to HW
+ * pinctrl_commit_state() - select/activate/program a pinctrl state to HW
  * @p: the pinctrl handle for the device that requests configuration
  * @state: the state handle to select/activate/program
  */
-int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
+static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
 {
 	struct pinctrl_setting *setting, *setting2;
 	struct pinctrl_state *old_state = p->state;
 	int ret;
 
-	if (p->state == state)
-		return 0;
-
 	if (p->state) {
 		/*
 		 * For each pinmux setting in the old state, forget SW's record
@@ -1068,6 +1065,19 @@ unapply_new_state:
 
 	return ret;
 }
+
+/**
+ * pinctrl_select_state() - select/activate/program a pinctrl state to HW
+ * @p: the pinctrl handle for the device that requests configuration
+ * @state: the state handle to select/activate/program
+ */
+int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
+{
+	if (p->state == state)
+		return 0;
+
+	return pinctrl_commit_state(p, state);
+}
 EXPORT_SYMBOL_GPL(pinctrl_select_state);
 
 static void devm_pinctrl_release(struct device *dev, void *res)
@@ -1236,7 +1246,7 @@ void pinctrl_unregister_map(struct pinct
 int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
 {
 	if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
-		return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
+		return pinctrl_commit_state(pctldev->p, pctldev->hog_sleep);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
@@ -1248,7 +1258,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
 int pinctrl_force_default(struct pinctrl_dev *pctldev)
 {
 	if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
-		return pinctrl_select_state(pctldev->p, pctldev->hog_default);
+		return pinctrl_commit_state(pctldev->p, pctldev->hog_default);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pinctrl_force_default);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/pinctrl/pinctrl-rockchip.c linux-libre-4.9.90-gnu/drivers/pinctrl/pinctrl-rockchip.c
--- linux-libre-4.9.89-gnu/drivers/pinctrl/pinctrl-rockchip.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/pinctrl/pinctrl-rockchip.c	2018-03-24 06:00:27.000000000 -0400
@@ -1278,8 +1278,16 @@ static int rockchip_gpio_get_direction(s
 {
 	struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
 	u32 data;
+	int ret;
 
+	ret = clk_enable(bank->clk);
+	if (ret < 0) {
+		dev_err(bank->drvdata->dev,
+			"failed to enable clock for bank %s\n", bank->name);
+		return ret;
+	}
 	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+	clk_disable(bank->clk);
 
 	return !(data & BIT(offset));
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/platform/chrome/cros_ec_proto.c linux-libre-4.9.90-gnu/drivers/platform/chrome/cros_ec_proto.c
--- linux-libre-4.9.89-gnu/drivers/platform/chrome/cros_ec_proto.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/platform/chrome/cros_ec_proto.c	2018-03-24 06:00:27.000000000 -0400
@@ -60,12 +60,14 @@ static int send_command(struct cros_ec_d
 			struct cros_ec_command *msg)
 {
 	int ret;
+	int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
 
 	if (ec_dev->proto_version > 2)
-		ret = ec_dev->pkt_xfer(ec_dev, msg);
+		xfer_fxn = ec_dev->pkt_xfer;
 	else
-		ret = ec_dev->cmd_xfer(ec_dev, msg);
+		xfer_fxn = ec_dev->cmd_xfer;
 
+	ret = (*xfer_fxn)(ec_dev, msg);
 	if (msg->result == EC_RES_IN_PROGRESS) {
 		int i;
 		struct cros_ec_command *status_msg;
@@ -88,7 +90,7 @@ static int send_command(struct cros_ec_d
 		for (i = 0; i < EC_COMMAND_RETRIES; i++) {
 			usleep_range(10000, 11000);
 
-			ret = ec_dev->cmd_xfer(ec_dev, status_msg);
+			ret = (*xfer_fxn)(ec_dev, status_msg);
 			if (ret < 0)
 				break;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/platform/chrome/cros_ec_sysfs.c linux-libre-4.9.90-gnu/drivers/platform/chrome/cros_ec_sysfs.c
--- linux-libre-4.9.89-gnu/drivers/platform/chrome/cros_ec_sysfs.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/platform/chrome/cros_ec_sysfs.c	2018-03-24 06:00:27.000000000 -0400
@@ -187,7 +187,7 @@ static ssize_t show_ec_version(struct de
 		count += scnprintf(buf + count, PAGE_SIZE - count,
 				   "Build info:    EC error %d\n", msg->result);
 	else {
-		msg->data[sizeof(msg->data) - 1] = '\0';
+		msg->data[EC_HOST_PARAM_SIZE - 1] = '\0';
 		count += scnprintf(buf + count, PAGE_SIZE - count,
 				   "Build info:    %s\n", msg->data);
 	}
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/platform/x86/asus-nb-wmi.c linux-libre-4.9.90-gnu/drivers/platform/x86/asus-nb-wmi.c
--- linux-libre-4.9.89-gnu/drivers/platform/x86/asus-nb-wmi.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/platform/x86/asus-nb-wmi.c	2018-03-24 06:00:27.000000000 -0400
@@ -120,6 +120,10 @@ static struct quirk_entry quirk_asus_x55
 	.xusb2pr = 0x01D9,
 };
 
+static struct quirk_entry quirk_asus_ux330uak = {
+	.wmi_force_als_set = true,
+};
+
 static int dmi_matched(const struct dmi_system_id *dmi)
 {
 	quirks = dmi->driver_data;
@@ -152,6 +156,15 @@ static const struct dmi_system_id asus_q
 	},
 	{
 		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X302UA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"),
+		},
+		.driver_data = &quirk_asus_wapf4,
+	},
+	{
+		.callback = dmi_matched,
 		.ident = "ASUSTeK COMPUTER INC. X401U",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
@@ -413,6 +426,15 @@ static const struct dmi_system_id asus_q
 	},
 	{
 		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. UX330UAK",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"),
+		},
+		.driver_data = &quirk_asus_ux330uak,
+	},
+	{
+		.callback = dmi_matched,
 		.ident = "ASUSTeK COMPUTER INC. X550LB",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/platform/x86/asus-wmi.c linux-libre-4.9.90-gnu/drivers/platform/x86/asus-wmi.c
--- linux-libre-4.9.89-gnu/drivers/platform/x86/asus-wmi.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/platform/x86/asus-wmi.c	2018-03-24 06:00:27.000000000 -0400
@@ -1109,6 +1109,15 @@ static void asus_wmi_set_xusb2pr(struct
 }
 
 /*
+ * Some devices dont support or have borcken get_als method
+ * but still support set method.
+ */
+static void asus_wmi_set_als(void)
+{
+	asus_wmi_set_devstate(ASUS_WMI_DEVID_ALS_ENABLE, 1, NULL);
+}
+
+/*
  * Hwmon device
  */
 static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
@@ -2120,6 +2129,9 @@ static int asus_wmi_add(struct platform_
 			goto fail_rfkill;
 	}
 
+	if (asus->driver->quirks->wmi_force_als_set)
+		asus_wmi_set_als();
+
 	/* Some Asus desktop boards export an acpi-video backlight interface,
 	   stop this from showing up */
 	chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/platform/x86/asus-wmi.h linux-libre-4.9.90-gnu/drivers/platform/x86/asus-wmi.h
--- linux-libre-4.9.89-gnu/drivers/platform/x86/asus-wmi.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/platform/x86/asus-wmi.h	2018-03-24 06:00:27.000000000 -0400
@@ -45,6 +45,7 @@ struct quirk_entry {
 	bool store_backlight_power;
 	bool wmi_backlight_power;
 	bool wmi_backlight_native;
+	bool wmi_force_als_set;
 	int wapf;
 	/*
 	 * For machines with AMD graphic chips, it will send out WMI event
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/platform/x86/intel-vbtn.c linux-libre-4.9.90-gnu/drivers/platform/x86/intel-vbtn.c
--- linux-libre-4.9.89-gnu/drivers/platform/x86/intel-vbtn.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/platform/x86/intel-vbtn.c	2018-03-24 06:00:27.000000000 -0400
@@ -37,6 +37,10 @@ static const struct acpi_device_id intel
 static const struct key_entry intel_vbtn_keymap[] = {
 	{ KE_IGNORE, 0xC0, { KEY_POWER } },	/* power key press */
 	{ KE_KEY, 0xC1, { KEY_POWER } },	/* power key release */
+	{ KE_KEY, 0xC4, { KEY_VOLUMEUP } },		/* volume-up key press */
+	{ KE_IGNORE, 0xC5, { KEY_VOLUMEUP } },		/* volume-up key release */
+	{ KE_KEY, 0xC6, { KEY_VOLUMEDOWN } },		/* volume-down key press */
+	{ KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } },	/* volume-down key release */
 	{ KE_END },
 };
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/power/supply/bq24190_charger.c linux-libre-4.9.90-gnu/drivers/power/supply/bq24190_charger.c
--- linux-libre-4.9.89-gnu/drivers/power/supply/bq24190_charger.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/power/supply/bq24190_charger.c	2018-03-24 06:00:27.000000000 -0400
@@ -506,6 +506,9 @@ static int bq24190_register_reset(struct
 	int ret, limit = 100;
 	u8 v;
 
+	if (device_property_read_bool(bdi->dev, "disable-reset"))
+		return 0;
+
 	/* Reset the registers */
 	ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 			BQ24190_REG_POC_RESET_MASK,
@@ -1184,8 +1187,13 @@ static irqreturn_t bq24190_irq_handler_t
 		}
 	} while (f_reg && ++i < 2);
 
+	/* ignore over/under voltage fault after disconnect */
+	if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
+	    !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
+		f_reg = 0;
+
 	if (f_reg != bdi->f_reg) {
-		dev_info(bdi->dev,
+		dev_warn(bdi->dev,
 			"Fault: boost %d, charge %d, battery %d, ntc %d\n",
 			!!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
 			!!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/power/supply/isp1704_charger.c linux-libre-4.9.90-gnu/drivers/power/supply/isp1704_charger.c
--- linux-libre-4.9.89-gnu/drivers/power/supply/isp1704_charger.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/power/supply/isp1704_charger.c	2018-03-24 06:00:27.000000000 -0400
@@ -418,6 +418,10 @@ static int isp1704_charger_probe(struct
 
 		pdata = devm_kzalloc(&pdev->dev,
 			sizeof(struct isp1704_charger_data), GFP_KERNEL);
+		if (!pdata) {
+			ret = -ENOMEM;
+			goto fail0;
+		}
 		pdata->enable_gpio = gpio;
 
 		dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/power/supply/pda_power.c linux-libre-4.9.90-gnu/drivers/power/supply/pda_power.c
--- linux-libre-4.9.89-gnu/drivers/power/supply/pda_power.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/power/supply/pda_power.c	2018-03-24 06:00:27.000000000 -0400
@@ -30,9 +30,9 @@ static inline unsigned int get_irq_flags
 static struct device *dev;
 static struct pda_power_pdata *pdata;
 static struct resource *ac_irq, *usb_irq;
-static struct timer_list charger_timer;
-static struct timer_list supply_timer;
-static struct timer_list polling_timer;
+static struct delayed_work charger_work;
+static struct delayed_work polling_work;
+static struct delayed_work supply_work;
 static int polling;
 static struct power_supply *pda_psy_ac, *pda_psy_usb;
 
@@ -140,7 +140,7 @@ static void update_charger(void)
 	}
 }
 
-static void supply_timer_func(unsigned long unused)
+static void supply_work_func(struct work_struct *work)
 {
 	if (ac_status == PDA_PSY_TO_CHANGE) {
 		ac_status = new_ac_status;
@@ -161,11 +161,12 @@ static void psy_changed(void)
 	 * Okay, charger set. Now wait a bit before notifying supplicants,
 	 * charge power should stabilize.
 	 */
-	mod_timer(&supply_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_charger));
+	cancel_delayed_work(&supply_work);
+	schedule_delayed_work(&supply_work,
+			      msecs_to_jiffies(pdata->wait_for_charger));
 }
 
-static void charger_timer_func(unsigned long unused)
+static void charger_work_func(struct work_struct *work)
 {
 	update_status();
 	psy_changed();
@@ -184,13 +185,14 @@ static irqreturn_t power_changed_isr(int
 	 * Wait a bit before reading ac/usb line status and setting charger,
 	 * because ac/usb status readings may lag from irq.
 	 */
-	mod_timer(&charger_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_status));
+	cancel_delayed_work(&charger_work);
+	schedule_delayed_work(&charger_work,
+			      msecs_to_jiffies(pdata->wait_for_status));
 
 	return IRQ_HANDLED;
 }
 
-static void polling_timer_func(unsigned long unused)
+static void polling_work_func(struct work_struct *work)
 {
 	int changed = 0;
 
@@ -211,8 +213,9 @@ static void polling_timer_func(unsigned
 	if (changed)
 		psy_changed();
 
-	mod_timer(&polling_timer,
-		  jiffies + msecs_to_jiffies(pdata->polling_interval));
+	cancel_delayed_work(&polling_work);
+	schedule_delayed_work(&polling_work,
+			      msecs_to_jiffies(pdata->polling_interval));
 }
 
 #if IS_ENABLED(CONFIG_USB_PHY)
@@ -250,8 +253,9 @@ static int otg_handle_notification(struc
 	 * Wait a bit before reading ac/usb line status and setting charger,
 	 * because ac/usb status readings may lag from irq.
 	 */
-	mod_timer(&charger_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_status));
+	cancel_delayed_work(&charger_work);
+	schedule_delayed_work(&charger_work,
+			      msecs_to_jiffies(pdata->wait_for_status));
 
 	return NOTIFY_OK;
 }
@@ -300,8 +304,8 @@ static int pda_power_probe(struct platfo
 	if (!pdata->ac_max_uA)
 		pdata->ac_max_uA = 500000;
 
-	setup_timer(&charger_timer, charger_timer_func, 0);
-	setup_timer(&supply_timer, supply_timer_func, 0);
+	INIT_DELAYED_WORK(&charger_work, charger_work_func);
+	INIT_DELAYED_WORK(&supply_work, supply_work_func);
 
 	ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
 	usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
@@ -385,9 +389,10 @@ static int pda_power_probe(struct platfo
 
 	if (polling) {
 		dev_dbg(dev, "will poll for status\n");
-		setup_timer(&polling_timer, polling_timer_func, 0);
-		mod_timer(&polling_timer,
-			  jiffies + msecs_to_jiffies(pdata->polling_interval));
+		INIT_DELAYED_WORK(&polling_work, polling_work_func);
+		cancel_delayed_work(&polling_work);
+		schedule_delayed_work(&polling_work,
+				      msecs_to_jiffies(pdata->polling_interval));
 	}
 
 	if (ac_irq || usb_irq)
@@ -433,9 +438,9 @@ static int pda_power_remove(struct platf
 		free_irq(ac_irq->start, pda_psy_ac);
 
 	if (polling)
-		del_timer_sync(&polling_timer);
-	del_timer_sync(&charger_timer);
-	del_timer_sync(&supply_timer);
+		cancel_delayed_work_sync(&polling_work);
+	cancel_delayed_work_sync(&charger_work);
+	cancel_delayed_work_sync(&supply_work);
 
 	if (pdata->is_usb_online)
 		power_supply_unregister(pda_psy_usb);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/ptp/ptp_clock.c linux-libre-4.9.90-gnu/drivers/ptp/ptp_clock.c
--- linux-libre-4.9.89-gnu/drivers/ptp/ptp_clock.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/ptp/ptp_clock.c	2018-03-24 06:00:27.000000000 -0400
@@ -97,30 +97,26 @@ static s32 scaled_ppm_to_ppb(long ppm)
 
 /* posix clock implementation */
 
-static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp)
+static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp)
 {
 	tp->tv_sec = 0;
 	tp->tv_nsec = 1;
 	return 0;
 }
 
-static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp)
+static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp)
 {
 	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
-	struct timespec64 ts = timespec_to_timespec64(*tp);
 
-	return  ptp->info->settime64(ptp->info, &ts);
+	return  ptp->info->settime64(ptp->info, tp);
 }
 
-static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp)
+static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp)
 {
 	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
-	struct timespec64 ts;
 	int err;
 
-	err = ptp->info->gettime64(ptp->info, &ts);
-	if (!err)
-		*tp = timespec64_to_timespec(ts);
+	err = ptp->info->gettime64(ptp->info, tp);
 	return err;
 }
 
@@ -133,7 +129,7 @@ static int ptp_clock_adjtime(struct posi
 	ops = ptp->info;
 
 	if (tx->modes & ADJ_SETOFFSET) {
-		struct timespec ts;
+		struct timespec64 ts;
 		ktime_t kt;
 		s64 delta;
 
@@ -146,7 +142,7 @@ static int ptp_clock_adjtime(struct posi
 		if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
 			return -EINVAL;
 
-		kt = timespec_to_ktime(ts);
+		kt = timespec64_to_ktime(ts);
 		delta = ktime_to_ns(kt);
 		err = ops->adjtime(ops, delta);
 	} else if (tx->modes & ADJ_FREQUENCY) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/regulator/anatop-regulator.c linux-libre-4.9.90-gnu/drivers/regulator/anatop-regulator.c
--- linux-libre-4.9.89-gnu/drivers/regulator/anatop-regulator.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/regulator/anatop-regulator.c	2018-03-24 06:00:27.000000000 -0400
@@ -296,6 +296,11 @@ static int anatop_regulator_probe(struct
 		if (!sreg->sel && !strcmp(sreg->name, "vddpu"))
 			sreg->sel = 22;
 
+		/* set the default voltage of the pcie phy to be 1.100v */
+		if (!sreg->sel && rdesc->name &&
+		    !strcmp(rdesc->name, "vddpcie"))
+			sreg->sel = 0x10;
+
 		if (!sreg->bypass && !sreg->sel) {
 			dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
 			return -EINVAL;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/rtc/rtc-cmos.c linux-libre-4.9.90-gnu/drivers/rtc/rtc-cmos.c
--- linux-libre-4.9.89-gnu/drivers/rtc/rtc-cmos.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/rtc/rtc-cmos.c	2018-03-24 06:00:27.000000000 -0400
@@ -41,6 +41,9 @@
 #include <linux/pm.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#ifdef CONFIG_X86
+#include <asm/i8259.h>
+#endif
 
 /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
 #include <linux/mc146818rtc.h>
@@ -1117,17 +1120,23 @@ static int cmos_pnp_probe(struct pnp_dev
 {
 	cmos_wake_setup(&pnp->dev);
 
-	if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0))
+	if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+		unsigned int irq = 0;
+#ifdef CONFIG_X86
 		/* Some machines contain a PNP entry for the RTC, but
 		 * don't define the IRQ. It should always be safe to
-		 * hardcode it in these cases
+		 * hardcode it on systems with a legacy PIC.
 		 */
+		if (nr_legacy_irqs())
+			irq = 8;
+#endif
 		return cmos_do_probe(&pnp->dev,
-				pnp_get_resource(pnp, IORESOURCE_IO, 0), 8);
-	else
+				pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+	} else {
 		return cmos_do_probe(&pnp->dev,
 				pnp_get_resource(pnp, IORESOURCE_IO, 0),
 				pnp_irq(pnp, 0));
+	}
 }
 
 static void cmos_pnp_remove(struct pnp_dev *pnp)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/rtc/rtc-ds1374.c linux-libre-4.9.90-gnu/drivers/rtc/rtc-ds1374.c
--- linux-libre-4.9.89-gnu/drivers/rtc/rtc-ds1374.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/rtc/rtc-ds1374.c	2018-03-24 06:00:27.000000000 -0400
@@ -527,6 +527,10 @@ static long ds1374_wdt_ioctl(struct file
 		if (get_user(new_margin, (int __user *)arg))
 			return -EFAULT;
 
+		/* the hardware's tick rate is 4096 Hz, so
+		 * the counter value needs to be scaled accordingly
+		 */
+		new_margin <<= 12;
 		if (new_margin < 1 || new_margin > 16777216)
 			return -EINVAL;
 
@@ -535,7 +539,8 @@ static long ds1374_wdt_ioctl(struct file
 		ds1374_wdt_ping();
 		/* fallthrough */
 	case WDIOC_GETTIMEOUT:
-		return put_user(wdt_margin, (int __user *)arg);
+		/* when returning ... inverse is true */
+		return put_user((wdt_margin >> 12), (int __user *)arg);
 	case WDIOC_SETOPTIONS:
 		if (copy_from_user(&options, (int __user *)arg, sizeof(int)))
 			return -EFAULT;
@@ -543,14 +548,15 @@ static long ds1374_wdt_ioctl(struct file
 		if (options & WDIOS_DISABLECARD) {
 			pr_info("disable watchdog\n");
 			ds1374_wdt_disable();
+			return 0;
 		}
 
 		if (options & WDIOS_ENABLECARD) {
 			pr_info("enable watchdog\n");
 			ds1374_wdt_settimeout(wdt_margin);
 			ds1374_wdt_ping();
+			return 0;
 		}
-
 		return -EINVAL;
 	}
 	return -ENOTTY;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/scsi/lpfc/lpfc_init.c linux-libre-4.9.90-gnu/drivers/scsi/lpfc/lpfc_init.c
--- linux-libre-4.9.89-gnu/drivers/scsi/lpfc/lpfc_init.c	2018-03-22 16:22:47.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/scsi/lpfc/lpfc_init.c	2018-03-25 15:01:12.000000000 -0400
@@ -11312,6 +11312,7 @@ int
 lpfc_fof_queue_create(struct lpfc_hba *phba)
 {
 	struct lpfc_queue *qdesc;
+	uint32_t wqesize;
 
 	/* Create FOF EQ */
 	qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize,
@@ -11332,8 +11333,11 @@ lpfc_fof_queue_create(struct lpfc_hba *p
 		phba->sli4_hba.oas_cq = qdesc;
 
 		/* Create OAS WQ */
-		qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize,
+		wqesize = (phba->fcp_embed_io) ?
+				LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
+		qdesc = lpfc_sli4_queue_alloc(phba, wqesize,
 					      phba->sli4_hba.wq_ecount);
+
 		if (!qdesc)
 			goto out_error;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/scsi/lpfc/lpfc_sli.c linux-libre-4.9.90-gnu/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-4.9.89-gnu/drivers/scsi/lpfc/lpfc_sli.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/scsi/lpfc/lpfc_sli.c	2018-03-24 06:00:27.000000000 -0400
@@ -13696,6 +13696,9 @@ lpfc_wq_create(struct lpfc_hba *phba, st
 	case LPFC_Q_CREATE_VERSION_1:
 		bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1,
 		       wq->entry_count);
+		bf_set(lpfc_mbox_hdr_version, &shdr->request,
+		       LPFC_Q_CREATE_VERSION_1);
+
 		switch (wq->entry_size) {
 		default:
 		case 64:
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/scsi/mac_esp.c linux-libre-4.9.90-gnu/drivers/scsi/mac_esp.c
--- linux-libre-4.9.89-gnu/drivers/scsi/mac_esp.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/scsi/mac_esp.c	2018-03-24 06:00:27.000000000 -0400
@@ -55,6 +55,7 @@ struct mac_esp_priv {
 	int error;
 };
 static struct esp *esp_chips[2];
+static DEFINE_SPINLOCK(esp_chips_lock);
 
 #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \
 			       platform_get_drvdata((struct platform_device *) \
@@ -562,15 +563,18 @@ static int esp_mac_probe(struct platform
 	}
 
 	host->irq = IRQ_MAC_SCSI;
-	esp_chips[dev->id] = esp;
-	mb();
-	if (esp_chips[!dev->id] == NULL) {
-		err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
-		if (err < 0) {
-			esp_chips[dev->id] = NULL;
-			goto fail_free_priv;
-		}
+
+	/* The request_irq() call is intended to succeed for the first device
+	 * and fail for the second device.
+	 */
+	err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
+	spin_lock(&esp_chips_lock);
+	if (err < 0 && esp_chips[!dev->id] == NULL) {
+		spin_unlock(&esp_chips_lock);
+		goto fail_free_priv;
 	}
+	esp_chips[dev->id] = esp;
+	spin_unlock(&esp_chips_lock);
 
 	err = scsi_esp_register(esp, &dev->dev);
 	if (err)
@@ -579,8 +583,13 @@ static int esp_mac_probe(struct platform
 	return 0;
 
 fail_free_irq:
-	if (esp_chips[!dev->id] == NULL)
+	spin_lock(&esp_chips_lock);
+	esp_chips[dev->id] = NULL;
+	if (esp_chips[!dev->id] == NULL) {
+		spin_unlock(&esp_chips_lock);
 		free_irq(host->irq, esp);
+	} else
+		spin_unlock(&esp_chips_lock);
 fail_free_priv:
 	kfree(mep);
 fail_free_command_block:
@@ -599,9 +608,13 @@ static int esp_mac_remove(struct platfor
 
 	scsi_esp_unregister(esp);
 
+	spin_lock(&esp_chips_lock);
 	esp_chips[dev->id] = NULL;
-	if (!(esp_chips[0] || esp_chips[1]))
+	if (esp_chips[!dev->id] == NULL) {
+		spin_unlock(&esp_chips_lock);
 		free_irq(irq, NULL);
+	} else
+		spin_unlock(&esp_chips_lock);
 
 	kfree(mep);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/scsi/virtio_scsi.c linux-libre-4.9.90-gnu/drivers/scsi/virtio_scsi.c
--- linux-libre-4.9.89-gnu/drivers/scsi/virtio_scsi.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/scsi/virtio_scsi.c	2018-03-24 06:00:27.000000000 -0400
@@ -28,6 +28,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_devinfo.h>
 #include <linux/seqlock.h>
 
 #define VIRTIO_SCSI_MEMPOOL_SZ 64
@@ -705,6 +706,28 @@ static int virtscsi_device_reset(struct
 	return virtscsi_tmf(vscsi, cmd);
 }
 
+static int virtscsi_device_alloc(struct scsi_device *sdevice)
+{
+	/*
+	 * Passed through SCSI targets (e.g. with qemu's 'scsi-block')
+	 * may have transfer limits which come from the host SCSI
+	 * controller or something on the host side other than the
+	 * target itself.
+	 *
+	 * To make this work properly, the hypervisor can adjust the
+	 * target's VPD information to advertise these limits.  But
+	 * for that to work, the guest has to look at the VPD pages,
+	 * which we won't do by default if it is an SPC-2 device, even
+	 * if it does actually support it.
+	 *
+	 * So, set the blist to always try to read the VPD pages.
+	 */
+	sdevice->sdev_bflags = BLIST_TRY_VPD_PAGES;
+
+	return 0;
+}
+
+
 /**
  * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth
  * @sdev:	Virtscsi target whose queue depth to change
@@ -776,6 +799,7 @@ static struct scsi_host_template virtscs
 	.change_queue_depth = virtscsi_change_queue_depth,
 	.eh_abort_handler = virtscsi_abort,
 	.eh_device_reset_handler = virtscsi_device_reset,
+	.slave_alloc = virtscsi_device_alloc,
 
 	.can_queue = 1024,
 	.dma_boundary = UINT_MAX,
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/soc/fsl/qe/qe.c linux-libre-4.9.90-gnu/drivers/soc/fsl/qe/qe.c
--- linux-libre-4.9.89-gnu/drivers/soc/fsl/qe/qe.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/soc/fsl/qe/qe.c	2018-03-24 06:00:27.000000000 -0400
@@ -163,11 +163,15 @@ EXPORT_SYMBOL(qe_issue_cmd);
  */
 static unsigned int brg_clk = 0;
 
+#define CLK_GRAN	(1000)
+#define CLK_GRAN_LIMIT	(5)
+
 unsigned int qe_get_brg_clk(void)
 {
 	struct device_node *qe;
 	int size;
 	const u32 *prop;
+	unsigned int mod;
 
 	if (brg_clk)
 		return brg_clk;
@@ -185,6 +189,15 @@ unsigned int qe_get_brg_clk(void)
 
 	of_node_put(qe);
 
+	/* round this if near to a multiple of CLK_GRAN */
+	mod = brg_clk % CLK_GRAN;
+	if (mod) {
+		if (mod < CLK_GRAN_LIMIT)
+			brg_clk -= mod;
+		else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT))
+			brg_clk += CLK_GRAN - mod;
+	}
+
 	return brg_clk;
 }
 EXPORT_SYMBOL(qe_get_brg_clk);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/spi/spi-dw-mmio.c linux-libre-4.9.90-gnu/drivers/spi/spi-dw-mmio.c
--- linux-libre-4.9.89-gnu/drivers/spi/spi-dw-mmio.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/spi/spi-dw-mmio.c	2018-03-24 06:00:27.000000000 -0400
@@ -115,8 +115,8 @@ static int dw_spi_mmio_remove(struct pla
 {
 	struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
 
-	clk_disable_unprepare(dwsmmio->clk);
 	dw_spi_remove_host(&dwsmmio->dws);
+	clk_disable_unprepare(dwsmmio->clk);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/staging/android/ashmem.c linux-libre-4.9.90-gnu/drivers/staging/android/ashmem.c
--- linux-libre-4.9.89-gnu/drivers/staging/android/ashmem.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/staging/android/ashmem.c	2018-03-24 06:00:27.000000000 -0400
@@ -718,16 +718,14 @@ static int ashmem_pin_unpin(struct ashme
 	size_t pgstart, pgend;
 	int ret = -EINVAL;
 
+	if (unlikely(copy_from_user(&pin, p, sizeof(pin))))
+		return -EFAULT;
+
 	mutex_lock(&ashmem_mutex);
 
 	if (unlikely(!asma->file))
 		goto out_unlock;
 
-	if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) {
-		ret = -EFAULT;
-		goto out_unlock;
-	}
-
 	/* per custom, you can pass zero for len to mean "everything onward" */
 	if (!pin.len)
 		pin.len = PAGE_ALIGN(asma->size) - pin.offset;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/staging/unisys/visorhba/visorhba_main.c linux-libre-4.9.90-gnu/drivers/staging/unisys/visorhba/visorhba_main.c
--- linux-libre-4.9.89-gnu/drivers/staging/unisys/visorhba/visorhba_main.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/staging/unisys/visorhba/visorhba_main.c	2018-03-24 06:00:27.000000000 -0400
@@ -842,7 +842,7 @@ static void
 do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 {
 	struct scsi_device *scsidev;
-	unsigned char buf[36];
+	unsigned char *buf;
 	struct scatterlist *sg;
 	unsigned int i;
 	char *this_page;
@@ -857,6 +857,10 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cm
 		if (cmdrsp->scsi.no_disk_result == 0)
 			return;
 
+		buf = kzalloc(sizeof(char) * 36, GFP_KERNEL);
+		if (!buf)
+			return;
+
 		/* Linux scsi code wants a device at Lun 0
 		 * to issue report luns, but we don't want
 		 * a disk there so we'll present a processor
@@ -868,6 +872,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cm
 		if (scsi_sg_count(scsicmd) == 0) {
 			memcpy(scsi_sglist(scsicmd), buf,
 			       cmdrsp->scsi.bufflen);
+			kfree(buf);
 			return;
 		}
 
@@ -879,6 +884,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cm
 			memcpy(this_page, buf + bufind, sg[i].length);
 			kunmap_atomic(this_page_orig);
 		}
+		kfree(buf);
 	} else {
 		devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
 		for_each_vdisk_match(vdisk, devdata, scsidev) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/staging/wilc1000/linux_mon.c linux-libre-4.9.90-gnu/drivers/staging/wilc1000/linux_mon.c
--- linux-libre-4.9.89-gnu/drivers/staging/wilc1000/linux_mon.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/staging/wilc1000/linux_mon.c	2018-03-24 06:00:27.000000000 -0400
@@ -197,6 +197,8 @@ static netdev_tx_t WILC_WFI_mon_xmit(str
 
 	if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, &skb->data[4], 6)))) {
 		skb2 = dev_alloc_skb(skb->len + sizeof(struct wilc_wfi_radiotap_cb_hdr));
+		if (!skb2)
+			return -ENOMEM;
 
 		memcpy(skb_put(skb2, skb->len), skb->data, skb->len);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/target/target_core_file.c linux-libre-4.9.90-gnu/drivers/target/target_core_file.c
--- linux-libre-4.9.89-gnu/drivers/target/target_core_file.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/target/target_core_file.c	2018-03-24 06:00:27.000000000 -0400
@@ -276,12 +276,11 @@ static int fd_do_rw(struct se_cmd *cmd,
 	else
 		ret = vfs_iter_read(fd, &iter, &pos);
 
-	kfree(bvec);
-
 	if (is_write) {
 		if (ret < 0 || ret != data_length) {
 			pr_err("%s() write returned %d\n", __func__, ret);
-			return (ret < 0 ? ret : -EINVAL);
+			if (ret >= 0)
+				ret = -EINVAL;
 		}
 	} else {
 		/*
@@ -294,17 +293,29 @@ static int fd_do_rw(struct se_cmd *cmd,
 				pr_err("%s() returned %d, expecting %u for "
 						"S_ISBLK\n", __func__, ret,
 						data_length);
-				return (ret < 0 ? ret : -EINVAL);
+				if (ret >= 0)
+					ret = -EINVAL;
 			}
 		} else {
 			if (ret < 0) {
 				pr_err("%s() returned %d for non S_ISBLK\n",
 						__func__, ret);
-				return ret;
+			} else if (ret != data_length) {
+				/*
+				 * Short read case:
+				 * Probably some one truncate file under us.
+				 * We must explicitly zero sg-pages to prevent
+				 * expose uninizialized pages to userspace.
+				 */
+				if (ret < data_length)
+					ret += iov_iter_zero(data_length - ret, &iter);
+				else
+					ret = -EINVAL;
 			}
 		}
 	}
-	return 1;
+	kfree(bvec);
+	return ret;
 }
 
 static sense_reason_t
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/tty/serial/8250/8250_dw.c linux-libre-4.9.90-gnu/drivers/tty/serial/8250/8250_dw.c
--- linux-libre-4.9.89-gnu/drivers/tty/serial/8250/8250_dw.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/tty/serial/8250/8250_dw.c	2018-03-24 06:00:27.000000000 -0400
@@ -464,7 +464,8 @@ static int dw8250_probe(struct platform_
 	/* If no clock rate is defined, fail. */
 	if (!p->uartclk) {
 		dev_err(dev, "clock rate not defined\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto err_clk;
 	}
 
 	data->pclk = devm_clk_get(dev, "apb_pclk");
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/tty/tty_io.c linux-libre-4.9.90-gnu/drivers/tty/tty_io.c
--- linux-libre-4.9.89-gnu/drivers/tty/tty_io.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/tty/tty_io.c	2018-03-24 06:00:27.000000000 -0400
@@ -1702,6 +1702,8 @@ static void release_tty(struct tty_struc
 	if (tty->link)
 		tty->link->port->itty = NULL;
 	tty_buffer_cancel_work(tty->port);
+	if (tty->link)
+		tty_buffer_cancel_work(tty->link->port);
 
 	tty_kref_put(tty->link);
 	tty_kref_put(tty);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/usb/gadget/function/f_hid.c linux-libre-4.9.90-gnu/drivers/usb/gadget/function/f_hid.c
--- linux-libre-4.9.89-gnu/drivers/usb/gadget/function/f_hid.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/usb/gadget/function/f_hid.c	2018-03-24 06:00:27.000000000 -0400
@@ -284,6 +284,7 @@ static ssize_t f_hidg_write(struct file
 			    size_t count, loff_t *offp)
 {
 	struct f_hidg *hidg  = file->private_data;
+	struct usb_request *req;
 	unsigned long flags;
 	ssize_t status = -ENOMEM;
 
@@ -293,7 +294,7 @@ static ssize_t f_hidg_write(struct file
 	spin_lock_irqsave(&hidg->write_spinlock, flags);
 
 #define WRITE_COND (!hidg->write_pending)
-
+try_again:
 	/* write queue */
 	while (!WRITE_COND) {
 		spin_unlock_irqrestore(&hidg->write_spinlock, flags);
@@ -308,6 +309,7 @@ static ssize_t f_hidg_write(struct file
 	}
 
 	hidg->write_pending = 1;
+	req = hidg->req;
 	count  = min_t(unsigned, count, hidg->report_length);
 
 	spin_unlock_irqrestore(&hidg->write_spinlock, flags);
@@ -320,24 +322,38 @@ static ssize_t f_hidg_write(struct file
 		goto release_write_pending;
 	}
 
-	hidg->req->status   = 0;
-	hidg->req->zero     = 0;
-	hidg->req->length   = count;
-	hidg->req->complete = f_hidg_req_complete;
-	hidg->req->context  = hidg;
+	spin_lock_irqsave(&hidg->write_spinlock, flags);
+
+	/* we our function has been disabled by host */
+	if (!hidg->req) {
+		free_ep_req(hidg->in_ep, hidg->req);
+		/*
+		 * TODO
+		 * Should we fail with error here?
+		 */
+		goto try_again;
+	}
+
+	req->status   = 0;
+	req->zero     = 0;
+	req->length   = count;
+	req->complete = f_hidg_req_complete;
+	req->context  = hidg;
 
 	status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
 	if (status < 0) {
 		ERROR(hidg->func.config->cdev,
 			"usb_ep_queue error on int endpoint %zd\n", status);
-		goto release_write_pending;
+		goto release_write_pending_unlocked;
 	} else {
 		status = count;
 	}
+	spin_unlock_irqrestore(&hidg->write_spinlock, flags);
 
 	return status;
 release_write_pending:
 	spin_lock_irqsave(&hidg->write_spinlock, flags);
+release_write_pending_unlocked:
 	hidg->write_pending = 0;
 	spin_unlock_irqrestore(&hidg->write_spinlock, flags);
 
@@ -541,12 +557,23 @@ static void hidg_disable(struct usb_func
 		kfree(list);
 	}
 	spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+
+	spin_lock_irqsave(&hidg->write_spinlock, flags);
+	if (!hidg->write_pending) {
+		free_ep_req(hidg->in_ep, hidg->req);
+		hidg->write_pending = 1;
+	}
+
+	hidg->req = NULL;
+	spin_unlock_irqrestore(&hidg->write_spinlock, flags);
 }
 
 static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 {
 	struct usb_composite_dev		*cdev = f->config->cdev;
 	struct f_hidg				*hidg = func_to_hidg(f);
+	struct usb_request			*req_in = NULL;
+	unsigned long				flags;
 	int i, status = 0;
 
 	VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt);
@@ -567,6 +594,12 @@ static int hidg_set_alt(struct usb_funct
 			goto fail;
 		}
 		hidg->in_ep->driver_data = hidg;
+
+		req_in = hidg_alloc_ep_req(hidg->in_ep, hidg->report_length);
+		if (!req_in) {
+			status = -ENOMEM;
+			goto disable_ep_in;
+		}
 	}
 
 
@@ -578,12 +611,12 @@ static int hidg_set_alt(struct usb_funct
 					    hidg->out_ep);
 		if (status) {
 			ERROR(cdev, "config_ep_by_speed FAILED!\n");
-			goto fail;
+			goto free_req_in;
 		}
 		status = usb_ep_enable(hidg->out_ep);
 		if (status < 0) {
 			ERROR(cdev, "Enable OUT endpoint FAILED!\n");
-			goto fail;
+			goto free_req_in;
 		}
 		hidg->out_ep->driver_data = hidg;
 
@@ -599,17 +632,37 @@ static int hidg_set_alt(struct usb_funct
 				req->context  = hidg;
 				status = usb_ep_queue(hidg->out_ep, req,
 						      GFP_ATOMIC);
-				if (status)
+				if (status) {
 					ERROR(cdev, "%s queue req --> %d\n",
 						hidg->out_ep->name, status);
+					free_ep_req(hidg->out_ep, req);
+				}
 			} else {
-				usb_ep_disable(hidg->out_ep);
 				status = -ENOMEM;
-				goto fail;
+				goto disable_out_ep;
 			}
 		}
 	}
 
+	if (hidg->in_ep != NULL) {
+		spin_lock_irqsave(&hidg->write_spinlock, flags);
+		hidg->req = req_in;
+		hidg->write_pending = 0;
+		spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+
+		wake_up(&hidg->write_queue);
+	}
+	return 0;
+disable_out_ep:
+	usb_ep_disable(hidg->out_ep);
+free_req_in:
+	if (req_in)
+		free_ep_req(hidg->in_ep, req_in);
+
+disable_ep_in:
+	if (hidg->in_ep)
+		usb_ep_disable(hidg->in_ep);
+
 fail:
 	return status;
 }
@@ -658,12 +711,6 @@ static int hidg_bind(struct usb_configur
 		goto fail;
 	hidg->out_ep = ep;
 
-	/* preallocate request and buffer */
-	status = -ENOMEM;
-	hidg->req = alloc_ep_req(hidg->in_ep, hidg->report_length);
-	if (!hidg->req)
-		goto fail;
-
 	/* set descriptor dynamic values */
 	hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
 	hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
@@ -690,6 +737,8 @@ static int hidg_bind(struct usb_configur
 		goto fail;
 
 	spin_lock_init(&hidg->write_spinlock);
+	hidg->write_pending = 1;
+	hidg->req = NULL;
 	spin_lock_init(&hidg->read_spinlock);
 	init_waitqueue_head(&hidg->write_queue);
 	init_waitqueue_head(&hidg->read_queue);
@@ -954,10 +1003,6 @@ static void hidg_unbind(struct usb_confi
 	device_destroy(hidg_class, MKDEV(major, hidg->minor));
 	cdev_del(&hidg->cdev);
 
-	/* disable/free request and end point */
-	usb_ep_disable(hidg->in_ep);
-	free_ep_req(hidg->in_ep, hidg->req);
-
 	usb_free_all_descriptors(f);
 }
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/video/console/vgacon.c linux-libre-4.9.90-gnu/drivers/video/console/vgacon.c
--- linux-libre-4.9.89-gnu/drivers/video/console/vgacon.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/video/console/vgacon.c	2018-03-24 06:00:27.000000000 -0400
@@ -405,7 +405,10 @@ static const char *vgacon_startup(void)
 		vga_video_port_val = VGA_CRT_DM;
 		if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
 			static struct resource ega_console_resource =
-			    { .name = "ega", .start = 0x3B0, .end = 0x3BF };
+			    { .name	= "ega",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3B0,
+			      .end	= 0x3BF };
 			vga_video_type = VIDEO_TYPE_EGAM;
 			vga_vram_size = 0x8000;
 			display_desc = "EGA+";
@@ -413,9 +416,15 @@ static const char *vgacon_startup(void)
 					 &ega_console_resource);
 		} else {
 			static struct resource mda1_console_resource =
-			    { .name = "mda", .start = 0x3B0, .end = 0x3BB };
+			    { .name	= "mda",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3B0,
+			      .end	= 0x3BB };
 			static struct resource mda2_console_resource =
-			    { .name = "mda", .start = 0x3BF, .end = 0x3BF };
+			    { .name	= "mda",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3BF,
+			      .end	= 0x3BF };
 			vga_video_type = VIDEO_TYPE_MDA;
 			vga_vram_size = 0x2000;
 			display_desc = "*MDA";
@@ -437,15 +446,21 @@ static const char *vgacon_startup(void)
 			vga_vram_size = 0x8000;
 
 			if (!screen_info.orig_video_isVGA) {
-				static struct resource ega_console_resource
-				    = { .name = "ega", .start = 0x3C0, .end = 0x3DF };
+				static struct resource ega_console_resource =
+				    { .name	= "ega",
+				      .flags	= IORESOURCE_IO,
+				      .start	= 0x3C0,
+				      .end	= 0x3DF };
 				vga_video_type = VIDEO_TYPE_EGAC;
 				display_desc = "EGA";
 				request_resource(&ioport_resource,
 						 &ega_console_resource);
 			} else {
-				static struct resource vga_console_resource
-				    = { .name = "vga+", .start = 0x3C0, .end = 0x3DF };
+				static struct resource vga_console_resource =
+				    { .name	= "vga+",
+				      .flags	= IORESOURCE_IO,
+				      .start	= 0x3C0,
+				      .end	= 0x3DF };
 				vga_video_type = VIDEO_TYPE_VGAC;
 				display_desc = "VGA+";
 				request_resource(&ioport_resource,
@@ -489,7 +504,10 @@ static const char *vgacon_startup(void)
 			}
 		} else {
 			static struct resource cga_console_resource =
-			    { .name = "cga", .start = 0x3D4, .end = 0x3D5 };
+			    { .name	= "cga",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3D4,
+			      .end	= 0x3D5 };
 			vga_video_type = VIDEO_TYPE_CGA;
 			vga_vram_size = 0x2000;
 			display_desc = "*CGA";
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c linux-libre-4.9.90-gnu/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c
--- linux-libre-4.9.89-gnu/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c	2018-03-24 06:00:27.000000000 -0400
@@ -455,6 +455,8 @@ static int td028ttec1_panel_remove(struc
 }
 
 static const struct of_device_id td028ttec1_of_match[] = {
+	{ .compatible = "omapdss,tpo,td028ttec1", },
+	/* keep to not break older DTB */
 	{ .compatible = "omapdss,toppoly,td028ttec1", },
 	{},
 };
@@ -474,6 +476,7 @@ static struct spi_driver td028ttec1_spi_
 
 module_spi_driver(td028ttec1_spi_driver);
 
+MODULE_ALIAS("spi:tpo,td028ttec1");
 MODULE_ALIAS("spi:toppoly,td028ttec1");
 MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
 MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/video/fbdev/sm501fb.c linux-libre-4.9.90-gnu/drivers/video/fbdev/sm501fb.c
--- linux-libre-4.9.89-gnu/drivers/video/fbdev/sm501fb.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/video/fbdev/sm501fb.c	2018-03-24 06:00:27.000000000 -0400
@@ -1600,6 +1600,7 @@ static int sm501fb_start(struct sm501fb_
 	info->fbmem = ioremap(res->start, resource_size(res));
 	if (info->fbmem == NULL) {
 		dev_err(dev, "cannot remap framebuffer\n");
+		ret = -ENXIO;
 		goto err_mem_res;
 	}
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/video/fbdev/udlfb.c linux-libre-4.9.90-gnu/drivers/video/fbdev/udlfb.c
--- linux-libre-4.9.89-gnu/drivers/video/fbdev/udlfb.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/video/fbdev/udlfb.c	2018-03-24 06:00:27.000000000 -0400
@@ -1487,15 +1487,25 @@ static struct device_attribute fb_device
 static int dlfb_select_std_channel(struct dlfb_data *dev)
 {
 	int ret;
-	u8 set_def_chn[] = {	   0x57, 0xCD, 0xDC, 0xA7,
+	void *buf;
+	static const u8 set_def_chn[] = {
+				0x57, 0xCD, 0xDC, 0xA7,
 				0x1C, 0x88, 0x5E, 0x15,
 				0x60, 0xFE, 0xC6, 0x97,
 				0x16, 0x3D, 0x47, 0xF2  };
 
+	buf = kmemdup(set_def_chn, sizeof(set_def_chn), GFP_KERNEL);
+
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
 			NR_USB_REQUEST_CHANNEL,
 			(USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
-			set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
+			buf, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
+
+	kfree(buf);
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/drivers/watchdog/watchdog_dev.c linux-libre-4.9.90-gnu/drivers/watchdog/watchdog_dev.c
--- linux-libre-4.9.89-gnu/drivers/watchdog/watchdog_dev.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/drivers/watchdog/watchdog_dev.c	2018-03-24 06:00:27.000000000 -0400
@@ -760,6 +760,7 @@ static int watchdog_open(struct inode *i
 {
 	struct watchdog_core_data *wd_data;
 	struct watchdog_device *wdd;
+	bool hw_running;
 	int err;
 
 	/* Get the corresponding watchdog device */
@@ -779,7 +780,8 @@ static int watchdog_open(struct inode *i
 	 * If the /dev/watchdog device is open, we don't want the module
 	 * to be unloaded.
 	 */
-	if (!watchdog_hw_running(wdd) && !try_module_get(wdd->ops->owner)) {
+	hw_running = watchdog_hw_running(wdd);
+	if (!hw_running && !try_module_get(wdd->ops->owner)) {
 		err = -EBUSY;
 		goto out_clear;
 	}
@@ -790,7 +792,7 @@ static int watchdog_open(struct inode *i
 
 	file->private_data = wd_data;
 
-	if (!watchdog_hw_running(wdd))
+	if (!hw_running)
 		kref_get(&wd_data->kref);
 
 	/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/btrfs/file.c linux-libre-4.9.90-gnu/fs/btrfs/file.c
--- linux-libre-4.9.89-gnu/fs/btrfs/file.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/btrfs/file.c	2018-03-24 06:00:27.000000000 -0400
@@ -2817,8 +2817,10 @@ static long btrfs_fallocate(struct file
 			}
 			ret = btrfs_qgroup_reserve_data(inode, cur_offset,
 					last_byte - cur_offset);
-			if (ret < 0)
+			if (ret < 0) {
+				free_extent_map(em);
 				break;
+			}
 		} else {
 			/*
 			 * Do not need to reserve unwritten extent for this
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/btrfs/inode.c linux-libre-4.9.90-gnu/fs/btrfs/inode.c
--- linux-libre-4.9.89-gnu/fs/btrfs/inode.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/btrfs/inode.c	2018-03-24 06:00:27.000000000 -0400
@@ -567,8 +567,10 @@ cont:
 						     PAGE_SET_WRITEBACK |
 						     page_error_op |
 						     PAGE_END_WRITEBACK);
-			btrfs_free_reserved_data_space_noquota(inode, start,
-						end - start + 1);
+			if (ret == 0)
+				btrfs_free_reserved_data_space_noquota(inode,
+							       start,
+							       end - start + 1);
 			goto free_pages_out;
 		}
 	}
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/btrfs/send.c linux-libre-4.9.90-gnu/fs/btrfs/send.c
--- linux-libre-4.9.89-gnu/fs/btrfs/send.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/btrfs/send.c	2018-03-24 06:00:27.000000000 -0400
@@ -5156,13 +5156,19 @@ static int is_extent_unchanged(struct se
 	while (key.offset < ekey->offset + left_len) {
 		ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
 		right_type = btrfs_file_extent_type(eb, ei);
-		if (right_type != BTRFS_FILE_EXTENT_REG) {
+		if (right_type != BTRFS_FILE_EXTENT_REG &&
+		    right_type != BTRFS_FILE_EXTENT_INLINE) {
 			ret = 0;
 			goto out;
 		}
 
 		right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
-		right_len = btrfs_file_extent_num_bytes(eb, ei);
+		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
+			right_len = btrfs_file_extent_inline_len(eb, slot, ei);
+			right_len = PAGE_ALIGN(right_len);
+		} else {
+			right_len = btrfs_file_extent_num_bytes(eb, ei);
+		}
 		right_offset = btrfs_file_extent_offset(eb, ei);
 		right_gen = btrfs_file_extent_generation(eb, ei);
 
@@ -5176,6 +5182,19 @@ static int is_extent_unchanged(struct se
 			goto out;
 		}
 
+		/*
+		 * We just wanted to see if when we have an inline extent, what
+		 * follows it is a regular extent (wanted to check the above
+		 * condition for inline extents too). This should normally not
+		 * happen but it's possible for example when we have an inline
+		 * compressed extent representing data with a size matching
+		 * the page size (currently the same as sector size).
+		 */
+		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
+			ret = 0;
+			goto out;
+		}
+
 		left_offset_fixed = left_offset;
 		if (key.offset < ekey->offset) {
 			/* Fix the right offset for 2a and 7. */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/btrfs/volumes.c linux-libre-4.9.90-gnu/fs/btrfs/volumes.c
--- linux-libre-4.9.89-gnu/fs/btrfs/volumes.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/btrfs/volumes.c	2018-03-24 06:00:27.000000000 -0400
@@ -3765,6 +3765,7 @@ int btrfs_balance(struct btrfs_balance_c
 		  struct btrfs_ioctl_balance_args *bargs)
 {
 	struct btrfs_fs_info *fs_info = bctl->fs_info;
+	u64 meta_target, data_target;
 	u64 allowed;
 	int mixed = 0;
 	int ret;
@@ -3861,11 +3862,16 @@ int btrfs_balance(struct btrfs_balance_c
 		}
 	} while (read_seqretry(&fs_info->profiles_lock, seq));
 
-	if (btrfs_get_num_tolerated_disk_barrier_failures(bctl->meta.target) <
-		btrfs_get_num_tolerated_disk_barrier_failures(bctl->data.target)) {
+	/* if we're not converting, the target field is uninitialized */
+	meta_target = (bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) ?
+		bctl->meta.target : fs_info->avail_metadata_alloc_bits;
+	data_target = (bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) ?
+		bctl->data.target : fs_info->avail_data_alloc_bits;
+	if (btrfs_get_num_tolerated_disk_barrier_failures(meta_target) <
+		btrfs_get_num_tolerated_disk_barrier_failures(data_target)) {
 		btrfs_warn(fs_info,
 			   "metadata profile 0x%llx has lower redundancy than data profile 0x%llx",
-			   bctl->meta.target, bctl->data.target);
+			   meta_target, data_target);
 	}
 
 	if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/cifs/netmisc.c linux-libre-4.9.90-gnu/fs/cifs/netmisc.c
--- linux-libre-4.9.89-gnu/fs/cifs/netmisc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/cifs/netmisc.c	2018-03-24 06:00:27.000000000 -0400
@@ -980,10 +980,10 @@ struct timespec cnvrtDosUnixTm(__le16 le
 		cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
 	days = sd->Day;
 	month = sd->Month;
-	if ((days > 31) || (month > 12)) {
+	if (days < 1 || days > 31 || month < 1 || month > 12) {
 		cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days);
-		if (month > 12)
-			month = 12;
+		days = clamp(days, 1, 31);
+		month = clamp(month, 1, 12);
 	}
 	month -= 1;
 	days += total_days_of_prev_months[month];
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/cifs/sess.c linux-libre-4.9.90-gnu/fs/cifs/sess.c
--- linux-libre-4.9.89-gnu/fs/cifs/sess.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/cifs/sess.c	2018-03-24 06:00:27.000000000 -0400
@@ -344,13 +344,12 @@ void build_ntlmssp_negotiate_blob(unsign
 	/* BB is NTLMV2 session security format easier to use here? */
 	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |
 		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
-	if (ses->server->sign) {
+		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
+		NTLMSSP_NEGOTIATE_SEAL;
+	if (ses->server->sign)
 		flags |= NTLMSSP_NEGOTIATE_SIGN;
-		if (!ses->server->session_estab ||
-				ses->ntlmssp->sesskey_per_smbsess)
-			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
-	}
+	if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
+		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 
 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
 
@@ -407,13 +406,12 @@ int build_ntlmssp_auth_blob(unsigned cha
 	flags = NTLMSSP_NEGOTIATE_56 |
 		NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
 		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
-	if (ses->server->sign) {
+		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
+		NTLMSSP_NEGOTIATE_SEAL;
+	if (ses->server->sign)
 		flags |= NTLMSSP_NEGOTIATE_SIGN;
-		if (!ses->server->session_estab ||
-				ses->ntlmssp->sesskey_per_smbsess)
-			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
-	}
+	if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
+		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 
 	tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/cifs/smb2pdu.c linux-libre-4.9.90-gnu/fs/cifs/smb2pdu.c
--- linux-libre-4.9.89-gnu/fs/cifs/smb2pdu.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/cifs/smb2pdu.c	2018-03-24 06:00:27.000000000 -0400
@@ -707,15 +707,13 @@ SMB2_sess_establish_session(struct SMB2_
 	struct cifs_ses *ses = sess_data->ses;
 
 	mutex_lock(&ses->server->srv_mutex);
-	if (ses->server->sign && ses->server->ops->generate_signingkey) {
+	if (ses->server->ops->generate_signingkey) {
 		rc = ses->server->ops->generate_signingkey(ses);
-		kfree(ses->auth_key.response);
-		ses->auth_key.response = NULL;
 		if (rc) {
 			cifs_dbg(FYI,
 				"SMB3 session key generation failed\n");
 			mutex_unlock(&ses->server->srv_mutex);
-			goto keygen_exit;
+			return rc;
 		}
 	}
 	if (!ses->server->session_estab) {
@@ -729,12 +727,6 @@ SMB2_sess_establish_session(struct SMB2_
 	ses->status = CifsGood;
 	ses->need_reconnect = false;
 	spin_unlock(&GlobalMid_Lock);
-
-keygen_exit:
-	if (!ses->server->sign) {
-		kfree(ses->auth_key.response);
-		ses->auth_key.response = NULL;
-	}
 	return rc;
 }
 
@@ -1712,6 +1704,9 @@ SMB2_ioctl(const unsigned int xid, struc
 	} else
 		iov[0].iov_len = get_rfc1002_length(req) + 4;
 
+	/* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+	if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+		req->hdr.Flags |= SMB2_FLAGS_SIGNED;
 
 	rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
 	rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/jbd2/journal.c linux-libre-4.9.90-gnu/fs/jbd2/journal.c
--- linux-libre-4.9.89-gnu/fs/jbd2/journal.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/jbd2/journal.c	2018-03-24 06:00:27.000000000 -0400
@@ -691,8 +691,21 @@ int jbd2_log_wait_commit(journal_t *jour
 {
 	int err = 0;
 
-	jbd2_might_wait_for_commit(journal);
 	read_lock(&journal->j_state_lock);
+#ifdef CONFIG_PROVE_LOCKING
+	/*
+	 * Some callers make sure transaction is already committing and in that
+	 * case we cannot block on open handles anymore. So don't warn in that
+	 * case.
+	 */
+	if (tid_gt(tid, journal->j_commit_sequence) &&
+	    (!journal->j_committing_transaction ||
+	     journal->j_committing_transaction->t_tid != tid)) {
+		read_unlock(&journal->j_state_lock);
+		jbd2_might_wait_for_commit(journal);
+		read_lock(&journal->j_state_lock);
+	}
+#endif
 #ifdef CONFIG_JBD2_DEBUG
 	if (!tid_geq(journal->j_commit_request, tid)) {
 		printk(KERN_ERR
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/nfs/pagelist.c linux-libre-4.9.90-gnu/fs/nfs/pagelist.c
--- linux-libre-4.9.89-gnu/fs/nfs/pagelist.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/nfs/pagelist.c	2018-03-24 06:00:27.000000000 -0400
@@ -1262,8 +1262,10 @@ void nfs_pageio_cond_complete(struct nfs
 		mirror = &desc->pg_mirrors[midx];
 		if (!list_empty(&mirror->pg_list)) {
 			prev = nfs_list_entry(mirror->pg_list.prev);
-			if (index != prev->wb_index + 1)
-				nfs_pageio_complete_mirror(desc, midx);
+			if (index != prev->wb_index + 1) {
+				nfs_pageio_complete(desc);
+				break;
+			}
 		}
 	}
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/nfs/pnfs.c linux-libre-4.9.90-gnu/fs/nfs/pnfs.c
--- linux-libre-4.9.89-gnu/fs/nfs/pnfs.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/nfs/pnfs.c	2018-03-24 06:00:27.000000000 -0400
@@ -1953,8 +1953,6 @@ void pnfs_error_mark_layout_for_return(s
 
 	spin_lock(&inode->i_lock);
 	pnfs_set_plh_return_info(lo, range.iomode, 0);
-	/* Block LAYOUTGET */
-	set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
 	/*
 	 * mark all matching lsegs so that we are sure to have no live
 	 * segments at hand when sending layoutreturn. See pnfs_put_lseg()
@@ -2308,10 +2306,20 @@ pnfs_do_read(struct nfs_pageio_descripto
 	enum pnfs_try_status trypnfs;
 
 	trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg);
-	if (trypnfs == PNFS_TRY_AGAIN)
-		pnfs_read_resend_pnfs(hdr);
-	if (trypnfs == PNFS_NOT_ATTEMPTED || hdr->task.tk_status)
+	switch (trypnfs) {
+	case PNFS_NOT_ATTEMPTED:
 		pnfs_read_through_mds(desc, hdr);
+	case PNFS_ATTEMPTED:
+		break;
+	case PNFS_TRY_AGAIN:
+		/* cleanup hdr and prepare to redo pnfs */
+		if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
+			struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
+			list_splice_init(&hdr->pages, &mirror->pg_list);
+			mirror->pg_recoalesce = 1;
+		}
+		hdr->mds_ops->rpc_release(hdr);
+	}
 }
 
 static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/nfsd/nfs4proc.c linux-libre-4.9.90-gnu/fs/nfsd/nfs4proc.c
--- linux-libre-4.9.89-gnu/fs/nfsd/nfs4proc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/nfsd/nfs4proc.c	2018-03-24 06:00:27.000000000 -0400
@@ -1338,14 +1338,14 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
 	const struct nfsd4_layout_ops *ops;
 	struct nfs4_layout_stateid *ls;
 	__be32 nfserr;
-	int accmode;
+	int accmode = NFSD_MAY_READ_IF_EXEC;
 
 	switch (lgp->lg_seg.iomode) {
 	case IOMODE_READ:
-		accmode = NFSD_MAY_READ;
+		accmode |= NFSD_MAY_READ;
 		break;
 	case IOMODE_RW:
-		accmode = NFSD_MAY_READ | NFSD_MAY_WRITE;
+		accmode |= NFSD_MAY_READ | NFSD_MAY_WRITE;
 		break;
 	default:
 		dprintk("%s: invalid iomode %d\n",
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/nfsd/vfs.c linux-libre-4.9.90-gnu/fs/nfsd/vfs.c
--- linux-libre-4.9.89-gnu/fs/nfsd/vfs.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/nfsd/vfs.c	2018-03-24 06:00:27.000000000 -0400
@@ -94,6 +94,12 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, s
 	err = follow_down(&path);
 	if (err < 0)
 		goto out;
+	if (path.mnt == exp->ex_path.mnt && path.dentry == dentry &&
+	    nfsd_mountpoint(dentry, exp) == 2) {
+		/* This is only a mountpoint in some other namespace */
+		path_put(&path);
+		goto out;
+	}
 
 	exp2 = rqst_exp_get_by_name(rqstp, &path);
 	if (IS_ERR(exp2)) {
@@ -167,16 +173,26 @@ static int nfsd_lookup_parent(struct svc
 /*
  * For nfsd purposes, we treat V4ROOT exports as though there was an
  * export at *every* directory.
+ * We return:
+ * '1' if this dentry *must* be an export point,
+ * '2' if it might be, if there is really a mount here, and
+ * '0' if there is no chance of an export point here.
  */
 int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
 {
-	if (d_mountpoint(dentry))
+	if (!d_inode(dentry))
+		return 0;
+	if (exp->ex_flags & NFSEXP_V4ROOT)
 		return 1;
 	if (nfsd4_is_junction(dentry))
 		return 1;
-	if (!(exp->ex_flags & NFSEXP_V4ROOT))
-		return 0;
-	return d_inode(dentry) != NULL;
+	if (d_mountpoint(dentry))
+		/*
+		 * Might only be a mountpoint in a different namespace,
+		 * but we need to check.
+		 */
+		return 2;
+	return 0;
 }
 
 __be32
diff -druNp --no-dereference linux-libre-4.9.89-gnu/fs/orangefs/waitqueue.c linux-libre-4.9.90-gnu/fs/orangefs/waitqueue.c
--- linux-libre-4.9.89-gnu/fs/orangefs/waitqueue.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/fs/orangefs/waitqueue.c	2018-03-24 06:00:27.000000000 -0400
@@ -124,7 +124,14 @@ retry_servicing:
 		gossip_debug(GOSSIP_WAIT_DEBUG,
 			     "%s:client core is NOT in service.\n",
 			     __func__);
-		timeout = op_timeout_secs * HZ;
+		/*
+		 * Don't wait for the userspace component to return if
+		 * the filesystem is being umounted anyway.
+		 */
+		if (op->upcall.type == ORANGEFS_VFS_OP_FS_UMOUNT)
+			timeout = 0;
+		else
+			timeout = op_timeout_secs * HZ;
 	}
 	spin_unlock(&orangefs_request_list_lock);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/include/acpi/actbl2.h linux-libre-4.9.90-gnu/include/acpi/actbl2.h
--- linux-libre-4.9.89-gnu/include/acpi/actbl2.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/include/acpi/actbl2.h	2018-03-24 06:00:27.000000000 -0400
@@ -783,6 +783,15 @@ struct acpi_iort_smmu {
 #define ACPI_IORT_SMMU_DVM_SUPPORTED    (1)
 #define ACPI_IORT_SMMU_COHERENT_WALK    (1<<1)
 
+/* Global interrupt format */
+
+struct acpi_iort_smmu_gsi {
+	u32 nsg_irpt;
+	u32 nsg_irpt_flags;
+	u32 nsg_cfg_irpt;
+	u32 nsg_cfg_irpt_flags;
+};
+
 struct acpi_iort_smmu_v3 {
 	u64 base_address;	/* SMMUv3 base address */
 	u32 flags;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/include/linux/mlx5/driver.h linux-libre-4.9.90-gnu/include/linux/mlx5/driver.h
--- linux-libre-4.9.89-gnu/include/linux/mlx5/driver.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/include/linux/mlx5/driver.h	2018-03-24 06:00:27.000000000 -0400
@@ -380,8 +380,8 @@ struct mlx5_core_srq {
 	struct mlx5_core_rsc_common	common; /* must be first */
 	u32		srqn;
 	int		max;
-	int		max_gs;
-	int		max_avail_gather;
+	size_t		max_gs;
+	size_t		max_avail_gather;
 	int		wqe_shift;
 	void (*event)	(struct mlx5_core_srq *, enum mlx5_event);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/include/linux/posix-clock.h linux-libre-4.9.90-gnu/include/linux/posix-clock.h
--- linux-libre-4.9.89-gnu/include/linux/posix-clock.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/include/linux/posix-clock.h	2018-03-24 06:00:27.000000000 -0400
@@ -59,23 +59,23 @@ struct posix_clock_operations {
 
 	int  (*clock_adjtime)(struct posix_clock *pc, struct timex *tx);
 
-	int  (*clock_gettime)(struct posix_clock *pc, struct timespec *ts);
+	int  (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
 
-	int  (*clock_getres) (struct posix_clock *pc, struct timespec *ts);
+	int  (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts);
 
 	int  (*clock_settime)(struct posix_clock *pc,
-			      const struct timespec *ts);
+			      const struct timespec64 *ts);
 
 	int  (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
 
 	int  (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
 
 	void (*timer_gettime)(struct posix_clock *pc,
-			      struct k_itimer *kit, struct itimerspec *tsp);
+			      struct k_itimer *kit, struct itimerspec64 *tsp);
 
 	int  (*timer_settime)(struct posix_clock *pc,
 			      struct k_itimer *kit, int flags,
-			      struct itimerspec *tsp, struct itimerspec *old);
+			      struct itimerspec64 *tsp, struct itimerspec64 *old);
 	/*
 	 * Optional character device methods:
 	 */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/include/soc/fsl/qe/qe.h linux-libre-4.9.90-gnu/include/soc/fsl/qe/qe.h
--- linux-libre-4.9.89-gnu/include/soc/fsl/qe/qe.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/include/soc/fsl/qe/qe.h	2018-03-24 06:00:27.000000000 -0400
@@ -243,6 +243,7 @@ static inline int qe_alive_during_sleep(
 #define qe_muram_free cpm_muram_free
 #define qe_muram_addr cpm_muram_addr
 #define qe_muram_offset cpm_muram_offset
+#define qe_muram_dma cpm_muram_dma
 
 #define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) |  (_v), (_addr))
 #define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
diff -druNp --no-dereference linux-libre-4.9.89-gnu/kernel/irq/manage.c linux-libre-4.9.90-gnu/kernel/irq/manage.c
--- linux-libre-4.9.89-gnu/kernel/irq/manage.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/kernel/irq/manage.c	2018-03-24 06:00:27.000000000 -0400
@@ -1210,8 +1210,10 @@ __setup_irq(unsigned int irq, struct irq
 		 * set the trigger type must match. Also all must
 		 * agree on ONESHOT.
 		 */
+		unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data);
+
 		if (!((old->flags & new->flags) & IRQF_SHARED) ||
-		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
+		    (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
 		    ((old->flags ^ new->flags) & IRQF_ONESHOT))
 			goto mismatch;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/kernel/time/posix-clock.c linux-libre-4.9.90-gnu/kernel/time/posix-clock.c
--- linux-libre-4.9.89-gnu/kernel/time/posix-clock.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/kernel/time/posix-clock.c	2018-03-24 06:00:27.000000000 -0400
@@ -300,14 +300,17 @@ out:
 static int pc_clock_gettime(clockid_t id, struct timespec *ts)
 {
 	struct posix_clock_desc cd;
+	struct timespec64 ts64;
 	int err;
 
 	err = get_clock_desc(id, &cd);
 	if (err)
 		return err;
 
-	if (cd.clk->ops.clock_gettime)
-		err = cd.clk->ops.clock_gettime(cd.clk, ts);
+	if (cd.clk->ops.clock_gettime) {
+		err = cd.clk->ops.clock_gettime(cd.clk, &ts64);
+		*ts = timespec64_to_timespec(ts64);
+	}
 	else
 		err = -EOPNOTSUPP;
 
@@ -319,14 +322,17 @@ static int pc_clock_gettime(clockid_t id
 static int pc_clock_getres(clockid_t id, struct timespec *ts)
 {
 	struct posix_clock_desc cd;
+	struct timespec64 ts64;
 	int err;
 
 	err = get_clock_desc(id, &cd);
 	if (err)
 		return err;
 
-	if (cd.clk->ops.clock_getres)
-		err = cd.clk->ops.clock_getres(cd.clk, ts);
+	if (cd.clk->ops.clock_getres) {
+		err = cd.clk->ops.clock_getres(cd.clk, &ts64);
+		*ts = timespec64_to_timespec(ts64);
+	}
 	else
 		err = -EOPNOTSUPP;
 
@@ -337,6 +343,7 @@ static int pc_clock_getres(clockid_t id,
 
 static int pc_clock_settime(clockid_t id, const struct timespec *ts)
 {
+	struct timespec64 ts64 = timespec_to_timespec64(*ts);
 	struct posix_clock_desc cd;
 	int err;
 
@@ -350,7 +357,7 @@ static int pc_clock_settime(clockid_t id
 	}
 
 	if (cd.clk->ops.clock_settime)
-		err = cd.clk->ops.clock_settime(cd.clk, ts);
+		err = cd.clk->ops.clock_settime(cd.clk, &ts64);
 	else
 		err = -EOPNOTSUPP;
 out:
@@ -403,29 +410,36 @@ static void pc_timer_gettime(struct k_it
 {
 	clockid_t id = kit->it_clock;
 	struct posix_clock_desc cd;
+	struct itimerspec64 ts64;
 
 	if (get_clock_desc(id, &cd))
 		return;
 
-	if (cd.clk->ops.timer_gettime)
-		cd.clk->ops.timer_gettime(cd.clk, kit, ts);
-
+	if (cd.clk->ops.timer_gettime) {
+		cd.clk->ops.timer_gettime(cd.clk, kit, &ts64);
+		*ts = itimerspec64_to_itimerspec(&ts64);
+	}
 	put_clock_desc(&cd);
 }
 
 static int pc_timer_settime(struct k_itimer *kit, int flags,
 			    struct itimerspec *ts, struct itimerspec *old)
 {
+	struct itimerspec64 ts64 = itimerspec_to_itimerspec64(ts);
 	clockid_t id = kit->it_clock;
 	struct posix_clock_desc cd;
+	struct itimerspec64 old64;
 	int err;
 
 	err = get_clock_desc(id, &cd);
 	if (err)
 		return err;
 
-	if (cd.clk->ops.timer_settime)
-		err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old);
+	if (cd.clk->ops.timer_settime) {
+		err = cd.clk->ops.timer_settime(cd.clk, kit, flags, &ts64, &old64);
+		if (old)
+			*old = itimerspec64_to_itimerspec(&old64);
+	}
 	else
 		err = -EOPNOTSUPP;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/Makefile linux-libre-4.9.90-gnu/Makefile
--- linux-libre-4.9.89-gnu/Makefile	2018-03-22 15:40:35.000000000 -0400
+++ linux-libre-4.9.90-gnu/Makefile	2018-03-25 14:16:54.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 9
-SUBLEVEL = 89
+SUBLEVEL = 90
 EXTRAVERSION = -gnu
 NAME = Roaring Lionus
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/mm/memory-failure.c linux-libre-4.9.90-gnu/mm/memory-failure.c
--- linux-libre-4.9.89-gnu/mm/memory-failure.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/mm/memory-failure.c	2018-03-24 06:00:27.000000000 -0400
@@ -921,6 +921,7 @@ static int hwpoison_user_mappings(struct
 	int ret;
 	int kill = 1, forcekill;
 	struct page *hpage = *hpagep;
+	bool mlocked = PageMlocked(hpage);
 
 	/*
 	 * Here we are interested only in user-mapped pages, so skip any
@@ -985,6 +986,13 @@ static int hwpoison_user_mappings(struct
 		       pfn, page_mapcount(hpage));
 
 	/*
+	 * try_to_unmap() might put mlocked page in lru cache, so call
+	 * shake_page() again to ensure that it's flushed.
+	 */
+	if (mlocked)
+		shake_page(hpage, 0);
+
+	/*
 	 * Now that the dirty bit has been propagated to the
 	 * struct page and all unmaps done we can decide if
 	 * killing is needed or not.  Only kill when the page
diff -druNp --no-dereference linux-libre-4.9.89-gnu/mm/vmscan.c linux-libre-4.9.90-gnu/mm/vmscan.c
--- linux-libre-4.9.89-gnu/mm/vmscan.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/mm/vmscan.c	2018-03-24 06:00:27.000000000 -0400
@@ -2841,8 +2841,10 @@ static bool allow_direct_reclaim(pg_data
 
 	for (i = 0; i <= ZONE_NORMAL; i++) {
 		zone = &pgdat->node_zones[i];
-		if (!managed_zone(zone) ||
-		    pgdat_reclaimable_pages(pgdat) == 0)
+		if (!managed_zone(zone))
+			continue;
+
+		if (!zone_reclaimable_pages(zone))
 			continue;
 
 		pfmemalloc_reserve += min_wmark_pages(zone);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/mm/vmstat.c linux-libre-4.9.90-gnu/mm/vmstat.c
--- linux-libre-4.9.89-gnu/mm/vmstat.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/mm/vmstat.c	2018-03-24 06:00:27.000000000 -0400
@@ -1387,18 +1387,24 @@ static void zoneinfo_show_print(struct s
 		   zone->present_pages,
 		   zone->managed_pages);
 
-	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
-		seq_printf(m, "\n      %-12s %lu", vmstat_text[i],
-				zone_page_state(zone, i));
-
 	seq_printf(m,
 		   "\n        protection: (%ld",
 		   zone->lowmem_reserve[0]);
 	for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
 		seq_printf(m, ", %ld", zone->lowmem_reserve[i]);
-	seq_printf(m,
-		   ")"
-		   "\n  pagesets");
+	seq_putc(m, ')');
+
+	/* If unpopulated, no other information is useful */
+	if (!populated_zone(zone)) {
+		seq_putc(m, '\n');
+		return;
+	}
+
+	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+		seq_printf(m, "\n      %-12s %lu", vmstat_text[i],
+				zone_page_state(zone, i));
+
+	seq_printf(m, "\n  pagesets");
 	for_each_online_cpu(i) {
 		struct per_cpu_pageset *pageset;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/ipv4/tcp_input.c linux-libre-4.9.90-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.9.89-gnu/net/ipv4/tcp_input.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/ipv4/tcp_input.c	2018-03-24 06:00:27.000000000 -0400
@@ -5606,10 +5606,6 @@ void tcp_finish_connect(struct sock *sk,
 	else
 		tp->pred_flags = 0;
 
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
-	}
 }
 
 static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
@@ -5678,6 +5674,7 @@ static int tcp_rcv_synsent_state_process
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_fastopen_cookie foc = { .len = -1 };
 	int saved_clamp = tp->rx_opt.mss_clamp;
+	bool fastopen_fail;
 
 	tcp_parse_options(skb, &tp->rx_opt, 0, &foc);
 	if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
@@ -5781,10 +5778,15 @@ static int tcp_rcv_synsent_state_process
 
 		tcp_finish_connect(sk, skb);
 
-		if ((tp->syn_fastopen || tp->syn_data) &&
-		    tcp_rcv_fastopen_synack(sk, skb, &foc))
-			return -1;
+		fastopen_fail = (tp->syn_fastopen || tp->syn_data) &&
+				tcp_rcv_fastopen_synack(sk, skb, &foc);
 
+		if (!sock_flag(sk, SOCK_DEAD)) {
+			sk->sk_state_change(sk);
+			sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
+		}
+		if (fastopen_fail)
+			return -1;
 		if (sk->sk_write_pending ||
 		    icsk->icsk_accept_queue.rskq_defer_accept ||
 		    icsk->icsk_ack.pingpong) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/ipv6/ip6_vti.c linux-libre-4.9.90-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.9.89-gnu/net/ipv6/ip6_vti.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/ipv6/ip6_vti.c	2018-03-24 06:00:27.000000000 -0400
@@ -625,6 +625,7 @@ static void vti6_link_config(struct ip6_
 {
 	struct net_device *dev = t->dev;
 	struct __ip6_tnl_parm *p = &t->parms;
+	struct net_device *tdev = NULL;
 
 	memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
 	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -637,6 +638,25 @@ static void vti6_link_config(struct ip6_
 		dev->flags |= IFF_POINTOPOINT;
 	else
 		dev->flags &= ~IFF_POINTOPOINT;
+
+	if (p->flags & IP6_TNL_F_CAP_XMIT) {
+		int strict = (ipv6_addr_type(&p->raddr) &
+			      (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
+		struct rt6_info *rt = rt6_lookup(t->net,
+						 &p->raddr, &p->laddr,
+						 p->link, strict);
+
+		if (rt)
+			tdev = rt->dst.dev;
+		ip6_rt_put(rt);
+	}
+
+	if (!tdev && p->link)
+		tdev = __dev_get_by_index(t->net, p->link);
+
+	if (tdev)
+		dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
+				 IPV6_MIN_MTU);
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/ipv6/ndisc.c linux-libre-4.9.90-gnu/net/ipv6/ndisc.c
--- linux-libre-4.9.89-gnu/net/ipv6/ndisc.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/ipv6/ndisc.c	2018-03-24 06:00:27.000000000 -0400
@@ -1723,6 +1723,8 @@ static int ndisc_netdev_event(struct not
 	case NETDEV_CHANGEADDR:
 		neigh_changeaddr(&nd_tbl, dev);
 		fib6_run_gc(0, net, false);
+		/* fallthrough */
+	case NETDEV_UP:
 		idev = in6_dev_get(dev);
 		if (!idev)
 			break;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/cfg.c linux-libre-4.9.90-gnu/net/mac80211/cfg.c
--- linux-libre-4.9.89-gnu/net/mac80211/cfg.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/cfg.c	2018-03-24 06:00:27.000000000 -0400
@@ -620,10 +620,11 @@ void sta_set_rate_info_tx(struct sta_inf
 		int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
 		u16 brate;
 
-		sband = sta->local->hw.wiphy->bands[
-				ieee80211_get_sdata_band(sta->sdata)];
-		brate = sband->bitrates[rate->idx].bitrate;
-		rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
+		sband = ieee80211_get_sband(sta->sdata);
+		if (sband) {
+			brate = sband->bitrates[rate->idx].bitrate;
+			rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
+		}
 	}
 	if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
 		rinfo->bw = RATE_INFO_BW_40;
@@ -1218,10 +1219,11 @@ static int sta_apply_parameters(struct i
 	int ret = 0;
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
 	u32 mask, set;
 
-	sband = local->hw.wiphy->bands[band];
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return -EINVAL;
 
 	mask = params->sta_flags_mask;
 	set = params->sta_flags_set;
@@ -1354,7 +1356,7 @@ static int sta_apply_parameters(struct i
 		ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
 					 sband, params->supported_rates,
 					 params->supported_rates_len,
-					 &sta->sta.supp_rates[band]);
+					 &sta->sta.supp_rates[sband->band]);
 	}
 
 	if (params->ht_capa)
@@ -1370,8 +1372,8 @@ static int sta_apply_parameters(struct i
 		/* returned value is only needed for rc update, but the
 		 * rc isn't initialized here yet, so ignore it
 		 */
-		__ieee80211_vht_handle_opmode(sdata, sta,
-					      params->opmode_notif, band);
+		__ieee80211_vht_handle_opmode(sdata, sta, params->opmode_notif,
+					      sband->band);
 	}
 
 	if (params->support_p2p_ps >= 0)
@@ -2017,13 +2019,15 @@ static int ieee80211_change_bss(struct w
 				struct bss_parameters *params)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	enum nl80211_band band;
+	struct ieee80211_supported_band *sband;
 	u32 changed = 0;
 
 	if (!sdata_dereference(sdata->u.ap.beacon, sdata))
 		return -ENOENT;
 
-	band = ieee80211_get_sdata_band(sdata);
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return -EINVAL;
 
 	if (params->use_cts_prot >= 0) {
 		sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
@@ -2036,7 +2040,7 @@ static int ieee80211_change_bss(struct w
 	}
 
 	if (!sdata->vif.bss_conf.use_short_slot &&
-	    band == NL80211_BAND_5GHZ) {
+	    sband->band == NL80211_BAND_5GHZ) {
 		sdata->vif.bss_conf.use_short_slot = true;
 		changed |= BSS_CHANGED_ERP_SLOT;
 	}
@@ -2049,7 +2053,7 @@ static int ieee80211_change_bss(struct w
 
 	if (params->basic_rates) {
 		ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
-					 wiphy->bands[band],
+					 wiphy->bands[sband->band],
 					 params->basic_rates,
 					 params->basic_rates_len,
 					 &sdata->vif.bss_conf.basic_rates);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/ibss.c linux-libre-4.9.90-gnu/net/mac80211/ibss.c
--- linux-libre-4.9.89-gnu/net/mac80211/ibss.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/ibss.c	2018-03-24 06:00:27.000000000 -0400
@@ -994,7 +994,7 @@ static void ieee80211_update_sta_info(st
 	enum nl80211_band band = rx_status->band;
 	enum nl80211_bss_scan_width scan_width;
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
+	struct ieee80211_supported_band *sband;
 	bool rates_updated = false;
 	u32 supp_rates = 0;
 
@@ -1004,6 +1004,10 @@ static void ieee80211_update_sta_info(st
 	if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid))
 		return;
 
+	sband = local->hw.wiphy->bands[band];
+	if (WARN_ON(!sband))
+		return;
+
 	rcu_read_lock();
 	sta = sta_info_get(sdata, mgmt->sa);
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/ieee80211_i.h linux-libre-4.9.90-gnu/net/mac80211/ieee80211_i.h
--- linux-libre-4.9.89-gnu/net/mac80211/ieee80211_i.h	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/ieee80211_i.h	2018-03-24 06:00:27.000000000 -0400
@@ -991,21 +991,6 @@ sdata_assert_lock(struct ieee80211_sub_i
 	lockdep_assert_held(&sdata->wdev.mtx);
 }
 
-static inline enum nl80211_band
-ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
-{
-	enum nl80211_band band = NL80211_BAND_2GHZ;
-	struct ieee80211_chanctx_conf *chanctx_conf;
-
-	rcu_read_lock();
-	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-	if (!WARN_ON(!chanctx_conf))
-		band = chanctx_conf->def.chan->band;
-	rcu_read_unlock();
-
-	return band;
-}
-
 static inline int
 ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
 {
@@ -1410,6 +1395,27 @@ IEEE80211_WDEV_TO_SUB_IF(struct wireless
 	return container_of(wdev, struct ieee80211_sub_if_data, wdev);
 }
 
+static inline struct ieee80211_supported_band *
+ieee80211_get_sband(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_chanctx_conf *chanctx_conf;
+	enum nl80211_band band;
+
+	rcu_read_lock();
+	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+
+	if (WARN_ON(!chanctx_conf)) {
+		rcu_read_unlock();
+		return NULL;
+	}
+
+	band = chanctx_conf->def.chan->band;
+	rcu_read_unlock();
+
+	return local->hw.wiphy->bands[band];
+}
+
 /* this struct represents 802.11n's RA/TID combination */
 struct ieee80211_ra_tid {
 	u8 ra[ETH_ALEN];
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/mesh.c linux-libre-4.9.90-gnu/net/mac80211/mesh.c
--- linux-libre-4.9.89-gnu/net/mac80211/mesh.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/mesh.c	2018-03-24 06:00:27.000000000 -0400
@@ -63,6 +63,7 @@ bool mesh_matches_local(struct ieee80211
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 	u32 basic_rates = 0;
 	struct cfg80211_chan_def sta_chan_def;
+	struct ieee80211_supported_band *sband;
 
 	/*
 	 * As support for each feature is added, check for matching
@@ -83,7 +84,11 @@ bool mesh_matches_local(struct ieee80211
 	     (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
 		return false;
 
-	ieee80211_sta_get_rates(sdata, ie, ieee80211_get_sdata_band(sdata),
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return false;
+
+	ieee80211_sta_get_rates(sdata, ie, sband->band,
 				&basic_rates);
 
 	if (sdata->vif.bss_conf.basic_rates != basic_rates)
@@ -399,12 +404,13 @@ static int mesh_add_ds_params_ie(struct
 int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
 		       struct sk_buff *skb)
 {
-	struct ieee80211_local *local = sdata->local;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
 	struct ieee80211_supported_band *sband;
 	u8 *pos;
 
-	sband = local->hw.wiphy->bands[band];
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return -EINVAL;
+
 	if (!sband->ht_cap.ht_supported ||
 	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
 	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
@@ -462,12 +468,13 @@ int mesh_add_ht_oper_ie(struct ieee80211
 int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
 			struct sk_buff *skb)
 {
-	struct ieee80211_local *local = sdata->local;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
 	struct ieee80211_supported_band *sband;
 	u8 *pos;
 
-	sband = local->hw.wiphy->bands[band];
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return -EINVAL;
+
 	if (!sband->vht_cap.vht_supported ||
 	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
 	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
@@ -916,12 +923,16 @@ ieee80211_mesh_process_chnswitch(struct
 	struct cfg80211_csa_settings params;
 	struct ieee80211_csa_ie csa_ie;
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
+	struct ieee80211_supported_band *sband;
 	int err;
 	u32 sta_flags;
 
 	sdata_assert_lock(sdata);
 
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return false;
+
 	sta_flags = IEEE80211_STA_DISABLE_VHT;
 	switch (sdata->vif.bss_conf.chandef.width) {
 	case NL80211_CHAN_WIDTH_20_NOHT:
@@ -935,7 +946,7 @@ ieee80211_mesh_process_chnswitch(struct
 
 	memset(&params, 0, sizeof(params));
 	memset(&csa_ie, 0, sizeof(csa_ie));
-	err = ieee80211_parse_ch_switch_ie(sdata, elems, band,
+	err = ieee80211_parse_ch_switch_ie(sdata, elems, sband->band,
 					   sta_flags, sdata->vif.addr,
 					   &csa_ie);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/mesh_plink.c linux-libre-4.9.90-gnu/net/mac80211/mesh_plink.c
--- linux-libre-4.9.89-gnu/net/mac80211/mesh_plink.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/mesh_plink.c	2018-03-24 06:00:27.000000000 -0400
@@ -93,19 +93,23 @@ static inline void mesh_plink_fsm_restar
 static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_local *local = sdata->local;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
-	struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
+	struct ieee80211_supported_band *sband;
 	struct sta_info *sta;
 	u32 erp_rates = 0, changed = 0;
 	int i;
 	bool short_slot = false;
 
-	if (band == NL80211_BAND_5GHZ) {
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return changed;
+
+	if (sband->band == NL80211_BAND_5GHZ) {
 		/* (IEEE 802.11-2012 19.4.5) */
 		short_slot = true;
 		goto out;
-	} else if (band != NL80211_BAND_2GHZ)
+	} else if (sband->band != NL80211_BAND_2GHZ) {
 		goto out;
+	}
 
 	for (i = 0; i < sband->n_bitrates; i++)
 		if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
@@ -121,7 +125,7 @@ static u32 mesh_set_short_slot_time(stru
 			continue;
 
 		short_slot = false;
-		if (erp_rates & sta->sta.supp_rates[band])
+		if (erp_rates & sta->sta.supp_rates[sband->band])
 			short_slot = true;
 		 else
 			break;
@@ -247,7 +251,15 @@ static int mesh_plink_frame_tx(struct ie
 	mgmt->u.action.u.self_prot.action_code = action;
 
 	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
-		enum nl80211_band band = ieee80211_get_sdata_band(sdata);
+		struct ieee80211_supported_band *sband;
+		enum nl80211_band band;
+
+		sband = ieee80211_get_sband(sdata);
+		if (!sband) {
+			err = -EINVAL;
+			goto free;
+		}
+		band = sband->band;
 
 		/* capability info */
 		pos = skb_put(skb, 2);
@@ -393,13 +405,16 @@ static void mesh_sta_info_init(struct ie
 			       struct ieee802_11_elems *elems, bool insert)
 {
 	struct ieee80211_local *local = sdata->local;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
 	struct ieee80211_supported_band *sband;
 	u32 rates, basic_rates = 0, changed = 0;
 	enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;
 
-	sband = local->hw.wiphy->bands[band];
-	rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return;
+
+	rates = ieee80211_sta_get_rates(sdata, elems, sband->band,
+					&basic_rates);
 
 	spin_lock_bh(&sta->mesh->plink_lock);
 	sta->rx_stats.last_rx = jiffies;
@@ -410,9 +425,9 @@ static void mesh_sta_info_init(struct ie
 		goto out;
 	sta->mesh->processed_beacon = true;
 
-	if (sta->sta.supp_rates[band] != rates)
+	if (sta->sta.supp_rates[sband->band] != rates)
 		changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
-	sta->sta.supp_rates[band] = rates;
+	sta->sta.supp_rates[sband->band] = rates;
 
 	if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
 					      elems->ht_cap_elem, sta))
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/mlme.c linux-libre-4.9.90-gnu/net/mac80211/mlme.c
--- linux-libre-4.9.89-gnu/net/mac80211/mlme.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/mlme.c	2018-03-24 06:00:27.000000000 -0400
@@ -1851,11 +1851,16 @@ static u32 ieee80211_handle_bss_capabili
 					   u16 capab, bool erp_valid, u8 erp)
 {
 	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
+	struct ieee80211_supported_band *sband;
 	u32 changed = 0;
 	bool use_protection;
 	bool use_short_preamble;
 	bool use_short_slot;
 
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return changed;
+
 	if (erp_valid) {
 		use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
 		use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
@@ -1865,7 +1870,7 @@ static u32 ieee80211_handle_bss_capabili
 	}
 
 	use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
-	if (ieee80211_get_sdata_band(sdata) == NL80211_BAND_5GHZ)
+	if (sband->band == NL80211_BAND_5GHZ)
 		use_short_slot = true;
 
 	if (use_protection != bss_conf->use_cts_prot) {
@@ -2994,7 +2999,12 @@ static bool ieee80211_assoc_success(stru
 		goto out;
 	}
 
-	sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
+	sband = ieee80211_get_sband(sdata);
+	if (!sband) {
+		mutex_unlock(&sdata->local->sta_mtx);
+		ret = false;
+		goto out;
+	}
 
 	/* Set up internal HT/VHT capabilities */
 	if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/rate.c linux-libre-4.9.90-gnu/net/mac80211/rate.c
--- linux-libre-4.9.89-gnu/net/mac80211/rate.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/rate.c	2018-03-24 06:00:27.000000000 -0400
@@ -875,7 +875,9 @@ int rate_control_set_rates(struct ieee80
 	struct ieee80211_sta_rates *old;
 	struct ieee80211_supported_band *sband;
 
-	sband = hw->wiphy->bands[ieee80211_get_sdata_band(sta->sdata)];
+	sband = ieee80211_get_sband(sta->sdata);
+	if (!sband)
+		return -EINVAL;
 	rate_control_apply_mask_ratetbl(sta, sband, rates);
 	/*
 	 * mac80211 guarantees that this function will not be called
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/sta_info.c linux-libre-4.9.90-gnu/net/mac80211/sta_info.c
--- linux-libre-4.9.89-gnu/net/mac80211/sta_info.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/sta_info.c	2018-03-24 06:00:27.000000000 -0400
@@ -395,10 +395,15 @@ struct sta_info *sta_info_alloc(struct i
 	sta->sta.smps_mode = IEEE80211_SMPS_OFF;
 	if (sdata->vif.type == NL80211_IFTYPE_AP ||
 	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
-		struct ieee80211_supported_band *sband =
-			hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
-		u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
-				IEEE80211_HT_CAP_SM_PS_SHIFT;
+		struct ieee80211_supported_band *sband;
+		u8 smps;
+
+		sband = ieee80211_get_sband(sdata);
+		if (!sband)
+			goto free_txq;
+
+		smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
+			IEEE80211_HT_CAP_SM_PS_SHIFT;
 		/*
 		 * Assume that hostapd advertises our caps in the beacon and
 		 * this is the known_smps_mode for a station that just assciated
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/status.c linux-libre-4.9.90-gnu/net/mac80211/status.c
--- linux-libre-4.9.89-gnu/net/mac80211/status.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/status.c	2018-03-24 06:00:27.000000000 -0400
@@ -200,6 +200,7 @@ static void ieee80211_frame_acked(struct
 	}
 
 	if (ieee80211_is_action(mgmt->frame_control) &&
+	    !ieee80211_has_protected(mgmt->frame_control) &&
 	    mgmt->u.action.category == WLAN_CATEGORY_HT &&
 	    mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS &&
 	    ieee80211_sdata_running(sdata)) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/tdls.c linux-libre-4.9.90-gnu/net/mac80211/tdls.c
--- linux-libre-4.9.89-gnu/net/mac80211/tdls.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/tdls.c	2018-03-24 06:00:27.000000000 -0400
@@ -47,8 +47,7 @@ static void ieee80211_tdls_add_ext_capab
 			   NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
 	bool wider_band = ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) &&
 			  !ifmgd->tdls_wider_bw_prohibited;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
-	struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
+	struct ieee80211_supported_band *sband = ieee80211_get_sband(sdata);
 	bool vht = sband && sband->vht_cap.vht_supported;
 	u8 *pos = (void *)skb_put(skb, 10);
 
@@ -180,11 +179,14 @@ static void ieee80211_tdls_add_bss_coex_
 static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
 					u16 status_code)
 {
+	struct ieee80211_supported_band *sband;
+
 	/* The capability will be 0 when sending a failure code */
 	if (status_code != 0)
 		return 0;
 
-	if (ieee80211_get_sdata_band(sdata) == NL80211_BAND_2GHZ) {
+	sband = ieee80211_get_sband(sdata);
+	if (sband && sband->band == NL80211_BAND_2GHZ) {
 		return WLAN_CAPABILITY_SHORT_SLOT_TIME |
 		       WLAN_CAPABILITY_SHORT_PREAMBLE;
 	}
@@ -358,17 +360,20 @@ ieee80211_tdls_add_setup_start_ies(struc
 				   u8 action_code, bool initiator,
 				   const u8 *extra_ies, size_t extra_ies_len)
 {
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
-	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_supported_band *sband;
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_sta_ht_cap ht_cap;
 	struct ieee80211_sta_vht_cap vht_cap;
 	struct sta_info *sta = NULL;
 	size_t offset = 0, noffset;
 	u8 *pos;
 
-	ieee80211_add_srates_ie(sdata, skb, false, band);
-	ieee80211_add_ext_srates_ie(sdata, skb, false, band);
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return;
+
+	ieee80211_add_srates_ie(sdata, skb, false, sband->band);
+	ieee80211_add_ext_srates_ie(sdata, skb, false, sband->band);
 	ieee80211_tdls_add_supp_channels(sdata, skb);
 
 	/* add any custom IEs that go before Extended Capabilities */
@@ -439,7 +444,6 @@ ieee80211_tdls_add_setup_start_ies(struc
 	 * the same on all bands. The specification limits the setup to a
 	 * single HT-cap, so use the current band for now.
 	 */
-	sband = local->hw.wiphy->bands[band];
 	memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
 
 	if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
@@ -545,9 +549,13 @@ ieee80211_tdls_add_setup_cfm_ies(struct
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	size_t offset = 0, noffset;
 	struct sta_info *sta, *ap_sta;
-	enum nl80211_band band = ieee80211_get_sdata_band(sdata);
+	struct ieee80211_supported_band *sband;
 	u8 *pos;
 
+	sband = ieee80211_get_sband(sdata);
+	if (!sband)
+		return;
+
 	mutex_lock(&local->sta_mtx);
 
 	sta = sta_info_get(sdata, peer);
@@ -612,7 +620,8 @@ ieee80211_tdls_add_setup_cfm_ies(struct
 	ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
 
 	/* only include VHT-operation if not on the 2.4GHz band */
-	if (band != NL80211_BAND_2GHZ && sta->sta.vht_cap.vht_supported) {
+	if (sband->band != NL80211_BAND_2GHZ &&
+	    sta->sta.vht_cap.vht_supported) {
 		/*
 		 * if both peers support WIDER_BW, we can expand the chandef to
 		 * a wider compatible one, up to 80MHz
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/tx.c linux-libre-4.9.90-gnu/net/mac80211/tx.c
--- linux-libre-4.9.89-gnu/net/mac80211/tx.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/tx.c	2018-03-24 06:00:27.000000000 -0400
@@ -4182,7 +4182,10 @@ struct sk_buff *ieee80211_beacon_get_tim
 		return bcn;
 
 	shift = ieee80211_vif_get_shift(vif);
-	sband = hw->wiphy->bands[ieee80211_get_sdata_band(vif_to_sdata(vif))];
+	sband = ieee80211_get_sband(vif_to_sdata(vif));
+	if (!sband)
+		return bcn;
+
 	ieee80211_tx_monitor(hw_to_local(hw), copy, sband, 1, shift, false);
 
 	return bcn;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/mac80211/util.c linux-libre-4.9.90-gnu/net/mac80211/util.c
--- linux-libre-4.9.89-gnu/net/mac80211/util.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/mac80211/util.c	2018-03-24 06:00:27.000000000 -0400
@@ -1590,14 +1590,14 @@ u32 ieee80211_sta_get_rates(struct ieee8
 	size_t num_rates;
 	u32 supp_rates, rate_flags;
 	int i, j, shift;
+
 	sband = sdata->local->hw.wiphy->bands[band];
+	if (WARN_ON(!sband))
+		return 1;
 
 	rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
 	shift = ieee80211_vif_get_shift(&sdata->vif);
 
-	if (WARN_ON(!sband))
-		return 1;
-
 	num_rates = sband->n_bitrates;
 	supp_rates = 0;
 	for (i = 0; i < elems->supp_rates_len +
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/netfilter/ipvs/ip_vs_ctl.c linux-libre-4.9.90-gnu/net/netfilter/ipvs/ip_vs_ctl.c
--- linux-libre-4.9.89-gnu/net/netfilter/ipvs/ip_vs_ctl.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/netfilter/ipvs/ip_vs_ctl.c	2018-03-24 06:00:27.000000000 -0400
@@ -3092,6 +3092,17 @@ nla_put_failure:
 	return skb->len;
 }
 
+static bool ip_vs_is_af_valid(int af)
+{
+	if (af == AF_INET)
+		return true;
+#ifdef CONFIG_IP_VS_IPV6
+	if (af == AF_INET6 && ipv6_mod_enabled())
+		return true;
+#endif
+	return false;
+}
+
 static int ip_vs_genl_parse_service(struct netns_ipvs *ipvs,
 				    struct ip_vs_service_user_kern *usvc,
 				    struct nlattr *nla, int full_entry,
@@ -3118,11 +3129,7 @@ static int ip_vs_genl_parse_service(stru
 	memset(usvc, 0, sizeof(*usvc));
 
 	usvc->af = nla_get_u16(nla_af);
-#ifdef CONFIG_IP_VS_IPV6
-	if (usvc->af != AF_INET && usvc->af != AF_INET6)
-#else
-	if (usvc->af != AF_INET)
-#endif
+	if (!ip_vs_is_af_valid(usvc->af))
 		return -EAFNOSUPPORT;
 
 	if (nla_fwmark) {
@@ -3624,6 +3631,11 @@ static int ip_vs_genl_set_cmd(struct sk_
 		if (udest.af == 0)
 			udest.af = svc->af;
 
+		if (!ip_vs_is_af_valid(udest.af)) {
+			ret = -EAFNOSUPPORT;
+			goto out;
+		}
+
 		if (udest.af != svc->af && cmd != IPVS_CMD_DEL_DEST) {
 			/* The synchronization protocol is incompatible
 			 * with mixed family services
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/netfilter/nf_conntrack_helper.c linux-libre-4.9.90-gnu/net/netfilter/nf_conntrack_helper.c
--- linux-libre-4.9.89-gnu/net/netfilter/nf_conntrack_helper.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/netfilter/nf_conntrack_helper.c	2018-03-24 06:00:27.000000000 -0400
@@ -379,17 +379,33 @@ int nf_conntrack_helper_register(struct
 	struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
 	unsigned int h = helper_hash(&me->tuple);
 	struct nf_conntrack_helper *cur;
-	int ret = 0;
+	int ret = 0, i;
 
 	BUG_ON(me->expect_policy == NULL);
 	BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
 	BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1);
 
 	mutex_lock(&nf_ct_helper_mutex);
-	hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
-		if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple, &mask)) {
-			ret = -EEXIST;
-			goto out;
+	for (i = 0; i < nf_ct_helper_hsize; i++) {
+		hlist_for_each_entry(cur, &nf_ct_helper_hash[i], hnode) {
+			if (!strcmp(cur->name, me->name) &&
+			    (cur->tuple.src.l3num == NFPROTO_UNSPEC ||
+			     cur->tuple.src.l3num == me->tuple.src.l3num) &&
+			    cur->tuple.dst.protonum == me->tuple.dst.protonum) {
+				ret = -EEXIST;
+				goto out;
+			}
+		}
+	}
+
+	/* avoid unpredictable behaviour for auto_assign_helper */
+	if (!(me->flags & NF_CT_HELPER_F_USERSPACE)) {
+		hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
+			if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple,
+						     &mask)) {
+				ret = -EEXIST;
+				goto out;
+			}
 		}
 	}
 	hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/netfilter/nft_dynset.c linux-libre-4.9.90-gnu/net/netfilter/nft_dynset.c
--- linux-libre-4.9.89-gnu/net/netfilter/nft_dynset.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/netfilter/nft_dynset.c	2018-03-24 06:00:27.000000000 -0400
@@ -82,8 +82,7 @@ static void nft_dynset_eval(const struct
 		    nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
 			timeout = priv->timeout ? : set->timeout;
 			*nft_set_ext_expiration(ext) = jiffies + timeout;
-		} else if (sexpr == NULL)
-			goto out;
+		}
 
 		if (sexpr != NULL)
 			sexpr->ops->eval(sexpr, regs, pkt);
@@ -92,7 +91,7 @@ static void nft_dynset_eval(const struct
 			regs->verdict.code = NFT_BREAK;
 		return;
 	}
-out:
+
 	if (!priv->invert)
 		regs->verdict.code = NFT_BREAK;
 }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/netfilter/x_tables.c linux-libre-4.9.90-gnu/net/netfilter/x_tables.c
--- linux-libre-4.9.89-gnu/net/netfilter/x_tables.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/netfilter/x_tables.c	2018-03-24 06:00:27.000000000 -0400
@@ -1006,8 +1006,10 @@ struct xt_table *xt_find_table_lock(stru
 	list_for_each_entry(t, &init_net.xt.tables[af], list) {
 		if (strcmp(t->name, name))
 			continue;
-		if (!try_module_get(t->me))
+		if (!try_module_get(t->me)) {
+			mutex_unlock(&xt[af].mutex);
 			return NULL;
+		}
 
 		mutex_unlock(&xt[af].mutex);
 		if (t->table_init(net) != 0) {
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/netfilter/xt_CT.c linux-libre-4.9.90-gnu/net/netfilter/xt_CT.c
--- linux-libre-4.9.89-gnu/net/netfilter/xt_CT.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/netfilter/xt_CT.c	2018-03-24 06:00:27.000000000 -0400
@@ -168,8 +168,10 @@ xt_ct_set_timeout(struct nf_conn *ct, co
 		goto err_put_timeout;
 	}
 	timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
-	if (timeout_ext == NULL)
+	if (!timeout_ext) {
 		ret = -ENOMEM;
+		goto err_put_timeout;
+	}
 
 	rcu_read_unlock();
 	return ret;
@@ -201,6 +203,7 @@ static int xt_ct_tg_check(const struct x
 			  struct xt_ct_target_info_v1 *info)
 {
 	struct nf_conntrack_zone zone;
+	struct nf_conn_help *help;
 	struct nf_conn *ct;
 	int ret = -EOPNOTSUPP;
 
@@ -249,7 +252,7 @@ static int xt_ct_tg_check(const struct x
 	if (info->timeout[0]) {
 		ret = xt_ct_set_timeout(ct, par, info->timeout);
 		if (ret < 0)
-			goto err3;
+			goto err4;
 	}
 	__set_bit(IPS_CONFIRMED_BIT, &ct->status);
 	nf_conntrack_get(&ct->ct_general);
@@ -257,6 +260,10 @@ out:
 	info->ct = ct;
 	return 0;
 
+err4:
+	help = nfct_help(ct);
+	if (help)
+		module_put(help->helper->me);
 err3:
 	nf_ct_tmpl_free(ct);
 err2:
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/openvswitch/conntrack.c linux-libre-4.9.90-gnu/net/openvswitch/conntrack.c
--- linux-libre-4.9.89-gnu/net/openvswitch/conntrack.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/openvswitch/conntrack.c	2018-03-24 06:00:27.000000000 -0400
@@ -396,10 +396,38 @@ ovs_ct_expect_find(struct net *net, cons
 		   u16 proto, const struct sk_buff *skb)
 {
 	struct nf_conntrack_tuple tuple;
+	struct nf_conntrack_expect *exp;
 
 	if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, net, &tuple))
 		return NULL;
-	return __nf_ct_expect_find(net, zone, &tuple);
+
+	exp = __nf_ct_expect_find(net, zone, &tuple);
+	if (exp) {
+		struct nf_conntrack_tuple_hash *h;
+
+		/* Delete existing conntrack entry, if it clashes with the
+		 * expectation.  This can happen since conntrack ALGs do not
+		 * check for clashes between (new) expectations and existing
+		 * conntrack entries.  nf_conntrack_in() will check the
+		 * expectations only if a conntrack entry can not be found,
+		 * which can lead to OVS finding the expectation (here) in the
+		 * init direction, but which will not be removed by the
+		 * nf_conntrack_in() call, if a matching conntrack entry is
+		 * found instead.  In this case all init direction packets
+		 * would be reported as new related packets, while reply
+		 * direction packets would be reported as un-related
+		 * established packets.
+		 */
+		h = nf_conntrack_find_get(net, zone, &tuple);
+		if (h) {
+			struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
+
+			nf_ct_delete(ct, 0, 0);
+			nf_conntrack_put(&ct->ct_general);
+		}
+	}
+
+	return exp;
 }
 
 /* This replicates logic from nf_conntrack_core.c that is not exported. */
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/sunrpc/xprtrdma/verbs.c linux-libre-4.9.90-gnu/net/sunrpc/xprtrdma/verbs.c
--- linux-libre-4.9.89-gnu/net/sunrpc/xprtrdma/verbs.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/sunrpc/xprtrdma/verbs.c	2018-03-24 06:00:27.000000000 -0400
@@ -1054,6 +1054,7 @@ void
 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
 {
 	cancel_delayed_work_sync(&buf->rb_recovery_worker);
+	cancel_delayed_work_sync(&buf->rb_refresh_worker);
 
 	while (!list_empty(&buf->rb_recv_bufs)) {
 		struct rpcrdma_rep *rep;
diff -druNp --no-dereference linux-libre-4.9.89-gnu/net/tipc/node.c linux-libre-4.9.90-gnu/net/tipc/node.c
--- linux-libre-4.9.89-gnu/net/tipc/node.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/net/tipc/node.c	2018-03-24 06:00:27.000000000 -0400
@@ -2094,6 +2094,8 @@ int tipc_nl_node_get_monitor(struct sk_b
 	int err;
 
 	msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg.skb)
+		return -ENOMEM;
 	msg.portid = info->snd_portid;
 	msg.seq = info->snd_seq;
 
diff -druNp --no-dereference linux-libre-4.9.89-gnu/sound/pci/hda/patch_realtek.c linux-libre-4.9.90-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-4.9.89-gnu/sound/pci/hda/patch_realtek.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/sound/pci/hda/patch_realtek.c	2018-03-24 06:00:27.000000000 -0400
@@ -6780,6 +6780,7 @@ enum {
 	ALC668_FIXUP_DELL_DISABLE_AAMIX,
 	ALC668_FIXUP_DELL_XPS13,
 	ALC662_FIXUP_ASUS_Nx50,
+	ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
 	ALC668_FIXUP_ASUS_Nx51,
 	ALC891_FIXUP_HEADSET_MODE,
 	ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
@@ -7031,14 +7032,21 @@ static const struct hda_fixup alc662_fix
 		.chained = true,
 		.chain_id = ALC662_FIXUP_BASS_1A
 	},
+	[ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_headset_mode_alc668,
+		.chain_id = ALC662_FIXUP_BASS_CHMAP
+	},
 	[ALC668_FIXUP_ASUS_Nx51] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
-			{0x1a, 0x90170151}, /* bass speaker */
+			{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
+			{ 0x1a, 0x90170151 }, /* bass speaker */
+			{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
 			{}
 		},
 		.chained = true,
-		.chain_id = ALC662_FIXUP_BASS_CHMAP,
+		.chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
 	},
 	[ALC891_FIXUP_HEADSET_MODE] = {
 		.type = HDA_FIXUP_FUNC,
diff -druNp --no-dereference linux-libre-4.9.89-gnu/sound/soc/intel/atom/sst/sst_acpi.c linux-libre-4.9.90-gnu/sound/soc/intel/atom/sst/sst_acpi.c
--- linux-libre-4.9.89-gnu/sound/soc/intel/atom/sst/sst_acpi.c	2018-03-22 16:28:42.000000000 -0400
+++ linux-libre-4.9.90-gnu/sound/soc/intel/atom/sst/sst_acpi.c	2018-03-25 15:07:20.000000000 -0400
@@ -420,7 +420,21 @@ static const struct dmi_system_id byt_ta
 		.callback = byt_thinkpad10_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
+		},
+	},
+	{
+		.callback = byt_thinkpad10_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
+		},
+	},
+	{
+		.callback = byt_thinkpad10_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
 		},
 	},
 	{ }
diff -druNp --no-dereference linux-libre-4.9.89-gnu/sound/soc/intel/skylake/skl.c linux-libre-4.9.90-gnu/sound/soc/intel/skylake/skl.c
--- linux-libre-4.9.89-gnu/sound/soc/intel/skylake/skl.c	2018-03-22 16:28:27.000000000 -0400
+++ linux-libre-4.9.90-gnu/sound/soc/intel/skylake/skl.c	2018-03-25 15:07:05.000000000 -0400
@@ -457,7 +457,7 @@ static int probe_codec(struct hdac_ext_b
 	struct hdac_bus *bus = ebus_to_hbus(ebus);
 	unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
 		(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
-	unsigned int res;
+	unsigned int res = -1;
 
 	mutex_lock(&bus->cmd_mutex);
 	snd_hdac_bus_send_cmd(bus, cmd);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/sound/soc/sh/rcar/cmd.c linux-libre-4.9.90-gnu/sound/soc/sh/rcar/cmd.c
--- linux-libre-4.9.89-gnu/sound/soc/sh/rcar/cmd.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/sound/soc/sh/rcar/cmd.c	2018-03-24 06:00:27.000000000 -0400
@@ -82,6 +82,9 @@ static int rsnd_cmd_init(struct rsnd_mod
 			[9] = 0x2,
 		};
 
+		if (unlikely(!src))
+			return -EIO;
+
 		data = path[rsnd_mod_id(src)] |
 			cmd_case[rsnd_mod_id(src)] << 16;
 	}
diff -druNp --no-dereference linux-libre-4.9.89-gnu/tools/perf/tests/kmod-path.c linux-libre-4.9.90-gnu/tools/perf/tests/kmod-path.c
--- linux-libre-4.9.89-gnu/tools/perf/tests/kmod-path.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/tools/perf/tests/kmod-path.c	2018-03-24 06:00:27.000000000 -0400
@@ -61,6 +61,7 @@ int test__kmod_path__parse(int subtest _
 	M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_KERNEL, true);
 	M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_USER, false);
 
+#ifdef HAVE_ZLIB_SUPPORT
 	/* path                alloc_name  alloc_ext   kmod  comp  name   ext */
 	T("/xxxx/xxxx/x.ko.gz", true     , true      , true, true, "[x]", "gz");
 	T("/xxxx/xxxx/x.ko.gz", false    , true      , true, true, NULL , "gz");
@@ -96,6 +97,7 @@ int test__kmod_path__parse(int subtest _
 	M("x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
 	M("x.ko.gz", PERF_RECORD_MISC_KERNEL, true);
 	M("x.ko.gz", PERF_RECORD_MISC_USER, false);
+#endif
 
 	/* path            alloc_name  alloc_ext  kmod  comp   name             ext */
 	T("[test_module]", true      , true     , true, false, "[test_module]", NULL);
diff -druNp --no-dereference linux-libre-4.9.89-gnu/tools/testing/nvdimm/test/nfit.c linux-libre-4.9.90-gnu/tools/testing/nvdimm/test/nfit.c
--- linux-libre-4.9.89-gnu/tools/testing/nvdimm/test/nfit.c	2018-03-22 04:18:01.000000000 -0400
+++ linux-libre-4.9.90-gnu/tools/testing/nvdimm/test/nfit.c	2018-03-24 06:00:27.000000000 -0400
@@ -1908,6 +1908,7 @@ static __init int nfit_test_init(void)
 			put_device(&pdev->dev);
 			goto err_register;
 		}
+		get_device(&pdev->dev);
 
 		rc = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 		if (rc)
@@ -1926,6 +1927,10 @@ static __init int nfit_test_init(void)
 		if (instances[i])
 			platform_device_unregister(&instances[i]->pdev);
 	nfit_test_teardown();
+	for (i = 0; i < NUM_NFITS; i++)
+		if (instances[i])
+			put_device(&instances[i]->pdev.dev);
+
 	return rc;
 }
 
@@ -1933,10 +1938,13 @@ static __exit void nfit_test_exit(void)
 {
 	int i;
 
-	platform_driver_unregister(&nfit_test_driver);
 	for (i = 0; i < NUM_NFITS; i++)
 		platform_device_unregister(&instances[i]->pdev);
+	platform_driver_unregister(&nfit_test_driver);
 	nfit_test_teardown();
+
+	for (i = 0; i < NUM_NFITS; i++)
+		put_device(&instances[i]->pdev.dev);
 	class_destroy(nfit_test_dimm);
 }
 
