diff -druNp --no-dereference linux-libre-3.18.89-gnu/arch/arm/boot/dts/am335x-evmsk.dts linux-libre-3.18.90-gnu/arch/arm/boot/dts/am335x-evmsk.dts
--- linux-libre-3.18.89-gnu/arch/arm/boot/dts/am335x-evmsk.dts	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/arch/arm/boot/dts/am335x-evmsk.dts	2017-12-25 08:20:09.000000000 -0500
@@ -645,6 +645,7 @@
 	ti,non-removable;
 	bus-width = <4>;
 	cap-power-off-card;
+	keep-power-in-suspend;
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc2_pins>;
 };
diff -druNp --no-dereference linux-libre-3.18.89-gnu/arch/arm/boot/dts/dra7.dtsi linux-libre-3.18.90-gnu/arch/arm/boot/dts/dra7.dtsi
--- linux-libre-3.18.89-gnu/arch/arm/boot/dts/dra7.dtsi	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/arch/arm/boot/dts/dra7.dtsi	2017-12-25 08:20:09.000000000 -0500
@@ -118,6 +118,7 @@
 				device_type = "pci";
 				ranges = <0x81000000 0 0          0x03000 0 0x00010000
 					  0x82000000 0 0x20013000 0x13000 0 0xffed000>;
+				bus-range = <0x00 0xff>;
 				#interrupt-cells = <1>;
 				num-lanes = <1>;
 				ti,hwmods = "pcie1";
@@ -153,6 +154,7 @@
 				device_type = "pci";
 				ranges = <0x81000000 0 0          0x03000 0 0x00010000
 					  0x82000000 0 0x30013000 0x13000 0 0xffed000>;
+				bus-range = <0x00 0xff>;
 				#interrupt-cells = <1>;
 				num-lanes = <1>;
 				ti,hwmods = "pcie2";
diff -druNp --no-dereference linux-libre-3.18.89-gnu/arch/arm/mm/dma-mapping.c linux-libre-3.18.90-gnu/arch/arm/mm/dma-mapping.c
--- linux-libre-3.18.89-gnu/arch/arm/mm/dma-mapping.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/arch/arm/mm/dma-mapping.c	2017-12-25 08:20:09.000000000 -0500
@@ -749,13 +749,31 @@ static void arm_coherent_dma_free(struct
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
 }
 
+/*
+ * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
+ * that the intention is to allow exporting memory allocated via the
+ * coherent DMA APIs through the dma_buf API, which only accepts a
+ * scattertable.  This presents a couple of problems:
+ * 1. Not all memory allocated via the coherent DMA APIs is backed by
+ *    a struct page
+ * 2. Passing coherent DMA memory into the streaming APIs is not allowed
+ *    as we will try to flush the memory through a different alias to that
+ *    actually being used (and the flushes are redundant.)
+ */
 int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		 void *cpu_addr, dma_addr_t handle, size_t size,
 		 struct dma_attrs *attrs)
 {
-	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
+	unsigned long pfn = dma_to_pfn(dev, handle);
+	struct page *page;
 	int ret;
 
+	/* If the PFN is not valid, we do not have a struct page */
+	if (!pfn_valid(pfn))
+		return -ENXIO;
+
+	page = pfn_to_page(pfn);
+
 	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
 	if (unlikely(ret))
 		return ret;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/arch/arm64/mm/init.c linux-libre-3.18.90-gnu/arch/arm64/mm/init.c
--- linux-libre-3.18.89-gnu/arch/arm64/mm/init.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/arch/arm64/mm/init.c	2017-12-25 08:20:09.000000000 -0500
@@ -155,6 +155,8 @@ void __init arm64_memblock_init(void)
 	/* 4GB maximum for 32-bit only capable devices */
 	if (IS_ENABLED(CONFIG_ZONE_DMA))
 		dma_phys_limit = max_zone_dma_phys();
+
+	high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
 	dma_contiguous_reserve(dma_phys_limit);
 
 	memblock_allow_resize();
@@ -177,7 +179,6 @@ void __init bootmem_init(void)
 	sparse_init();
 	zone_sizes_init(min, max);
 
-	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
 	max_pfn = max_low_pfn = max;
 }
 
diff -druNp --no-dereference linux-libre-3.18.89-gnu/arch/x86/kvm/x86.c linux-libre-3.18.90-gnu/arch/x86/kvm/x86.c
--- linux-libre-3.18.89-gnu/arch/x86/kvm/x86.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/arch/x86/kvm/x86.c	2017-12-25 08:20:09.000000000 -0500
@@ -7783,11 +7783,11 @@ void kvm_arch_async_page_present(struct
 {
 	struct x86_exception fault;
 
-	trace_kvm_async_pf_ready(work->arch.token, work->gva);
 	if (work->wakeup_all)
 		work->arch.token = ~0; /* broadcast wakeup */
 	else
 		kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
+	trace_kvm_async_pf_ready(work->arch.token, work->gva);
 
 	if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) &&
 	    !apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) {
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/cpuidle/cpuidle-powernv.c linux-libre-3.18.90-gnu/drivers/cpuidle/cpuidle-powernv.c
--- linux-libre-3.18.89-gnu/drivers/cpuidle/cpuidle-powernv.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/cpuidle/cpuidle-powernv.c	2017-12-25 08:20:09.000000000 -0500
@@ -154,6 +154,24 @@ static int powernv_cpuidle_driver_init(v
 		drv->state_count += 1;
 	}
 
+	/*
+	 * On the PowerNV platform cpu_present may be less than cpu_possible in
+	 * cases when firmware detects the CPU, but it is not available to the
+	 * OS.  If CONFIG_HOTPLUG_CPU=n, then such CPUs are not hotplugable at
+	 * run time and hence cpu_devices are not created for those CPUs by the
+	 * generic topology_init().
+	 *
+	 * drv->cpumask defaults to cpu_possible_mask in
+	 * __cpuidle_driver_init().  This breaks cpuidle on PowerNV where
+	 * cpu_devices are not created for CPUs in cpu_possible_mask that
+	 * cannot be hot-added later at run time.
+	 *
+	 * Trying cpuidle_register_device() on a CPU without a cpu_device is
+	 * incorrect, so pass a correct CPU mask to the generic cpuidle driver.
+	 */
+
+	drv->cpumask = (struct cpumask *)cpu_present_mask;
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/cpuidle/sysfs.c linux-libre-3.18.90-gnu/drivers/cpuidle/sysfs.c
--- linux-libre-3.18.89-gnu/drivers/cpuidle/sysfs.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/cpuidle/sysfs.c	2017-12-25 08:20:09.000000000 -0500
@@ -613,6 +613,18 @@ int cpuidle_add_sysfs(struct cpuidle_dev
 	struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
 	int error;
 
+	/*
+	 * Return if cpu_device is not setup for this CPU.
+	 *
+	 * This could happen if the arch did not set up cpu_device
+	 * since this CPU is not in cpu_present mask and the
+	 * driver did not send a correct CPU mask during registration.
+	 * Without this check we would end up passing bogus
+	 * value for &cpu_dev->kobj in kobject_init_and_add()
+	 */
+	if (!cpu_dev)
+		return -ENODEV;
+
 	kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
 	if (!kdev)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/crypto/amcc/crypto4xx_core.h linux-libre-3.18.90-gnu/drivers/crypto/amcc/crypto4xx_core.h
--- linux-libre-3.18.89-gnu/drivers/crypto/amcc/crypto4xx_core.h	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/crypto/amcc/crypto4xx_core.h	2017-12-25 08:20:09.000000000 -0500
@@ -32,12 +32,12 @@
 #define PPC405EX_CE_RESET                       0x00000008
 
 #define CRYPTO4XX_CRYPTO_PRIORITY		300
-#define PPC4XX_LAST_PD				63
-#define PPC4XX_NUM_PD				64
-#define PPC4XX_LAST_GD				1023
+#define PPC4XX_NUM_PD				256
+#define PPC4XX_LAST_PD				(PPC4XX_NUM_PD - 1)
 #define PPC4XX_NUM_GD				1024
-#define PPC4XX_LAST_SD				63
-#define PPC4XX_NUM_SD				64
+#define PPC4XX_LAST_GD				(PPC4XX_NUM_GD - 1)
+#define PPC4XX_NUM_SD				256
+#define PPC4XX_LAST_SD				(PPC4XX_NUM_SD - 1)
 #define PPC4XX_SD_BUFFER_SIZE			2048
 
 #define PD_ENTRY_INUSE				1
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/hid/hid-core.c linux-libre-3.18.90-gnu/drivers/hid/hid-core.c
--- linux-libre-3.18.89-gnu/drivers/hid/hid-core.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/hid/hid-core.c	2017-12-25 08:20:09.000000000 -0500
@@ -1977,6 +1977,7 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/hid/hid-ids.h linux-libre-3.18.90-gnu/drivers/hid/hid-ids.h
--- linux-libre-3.18.89-gnu/drivers/hid/hid-ids.h	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/hid/hid-ids.h	2017-12-25 08:20:09.000000000 -0500
@@ -1000,6 +1000,7 @@
 
 #define USB_VENDOR_ID_XIN_MO			0x16c0
 #define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE	0x05e1
+#define USB_DEVICE_ID_THT_2P_ARCADE		0x75e1
 
 #define USB_VENDOR_ID_XIROKU		0x1477
 #define USB_DEVICE_ID_XIROKU_SPX	0x1006
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/hid/hid-xinmo.c linux-libre-3.18.90-gnu/drivers/hid/hid-xinmo.c
--- linux-libre-3.18.89-gnu/drivers/hid/hid-xinmo.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/hid/hid-xinmo.c	2017-12-25 08:20:09.000000000 -0500
@@ -46,6 +46,7 @@ static int xinmo_event(struct hid_device
 
 static const struct hid_device_id xinmo_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/hwmon/asus_atk0110.c linux-libre-3.18.90-gnu/drivers/hwmon/asus_atk0110.c
--- linux-libre-3.18.89-gnu/drivers/hwmon/asus_atk0110.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/hwmon/asus_atk0110.c	2017-12-25 08:20:09.000000000 -0500
@@ -646,6 +646,9 @@ static int atk_read_value(struct atk_sen
 		else
 			err = atk_read_value_new(sensor, value);
 
+		if (err)
+			return err;
+
 		sensor->is_valid = true;
 		sensor->last_updated = jiffies;
 		sensor->cached_value = *value;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/isdn/capi/kcapi.c linux-libre-3.18.90-gnu/drivers/isdn/capi/kcapi.c
--- linux-libre-3.18.89-gnu/drivers/isdn/capi/kcapi.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/isdn/capi/kcapi.c	2017-12-25 08:20:09.000000000 -0500
@@ -1032,6 +1032,7 @@ static int old_capi_manufacturer(unsigne
 						     sizeof(avmb1_carddef))))
 				return -EFAULT;
 			cdef.cardtype = AVM_CARDTYPE_B1;
+			cdef.cardnr = 0;
 		} else {
 			if ((retval = copy_from_user(&cdef, data,
 						     sizeof(avmb1_extcarddef))))
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/ethernet/intel/fm10k/fm10k_iov.c linux-libre-3.18.90-gnu/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
--- linux-libre-3.18.89-gnu/drivers/net/ethernet/intel/fm10k/fm10k_iov.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/ethernet/intel/fm10k/fm10k_iov.c	2017-12-25 08:20:09.000000000 -0500
@@ -145,6 +145,9 @@ process_mbx:
 		struct fm10k_mbx_info *mbx = &vf_info->mbx;
 		u16 glort = vf_info->glort;
 
+		/* process the SM mailbox first to drain outgoing messages */
+		hw->mbx.ops.process(hw, &hw->mbx);
+
 		/* verify port mapping is valid, if not reset port */
 		if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort))
 			hw->iov.ops.reset_lport(hw, vf_info);
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c linux-libre-3.18.90-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c
--- linux-libre-3.18.89-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c	2017-12-25 08:20:09.000000000 -0500
@@ -3814,8 +3814,12 @@ static void i40e_napi_enable_all(struct
 	if (!vsi->netdev)
 		return;
 
-	for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
-		napi_enable(&vsi->q_vectors[q_idx]->napi);
+	for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
+		struct i40e_q_vector *q_vector = vsi->q_vectors[q_idx];
+
+		if (q_vector->rx.ring || q_vector->tx.ring)
+			napi_enable(&q_vector->napi);
+	}
 }
 
 /**
@@ -3829,8 +3833,12 @@ static void i40e_napi_disable_all(struct
 	if (!vsi->netdev)
 		return;
 
-	for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
-		napi_disable(&vsi->q_vectors[q_idx]->napi);
+	for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
+		struct i40e_q_vector *q_vector = vsi->q_vectors[q_idx];
+
+		if (q_vector->rx.ring || q_vector->tx.ring)
+			napi_disable(&q_vector->napi);
+	}
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/ethernet/intel/igb/igb_main.c linux-libre-3.18.90-gnu/drivers/net/ethernet/intel/igb/igb_main.c
--- linux-libre-3.18.89-gnu/drivers/net/ethernet/intel/igb/igb_main.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/ethernet/intel/igb/igb_main.c	2017-12-25 08:20:09.000000000 -0500
@@ -3001,6 +3001,8 @@ static int igb_sw_init(struct igb_adapte
 	/* Setup and initialize a copy of the hw vlan table array */
 	adapter->shadow_vfta = kcalloc(E1000_VLAN_FILTER_TBL_SIZE, sizeof(u32),
 				       GFP_ATOMIC);
+	if (!adapter->shadow_vfta)
+		return -ENOMEM;
 
 	/* This call may decrease the number of queues */
 	if (igb_init_interrupt_scheme(adapter, true)) {
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/irda/vlsi_ir.c linux-libre-3.18.90-gnu/drivers/net/irda/vlsi_ir.c
--- linux-libre-3.18.89-gnu/drivers/net/irda/vlsi_ir.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/irda/vlsi_ir.c	2017-12-25 08:20:09.000000000 -0500
@@ -426,8 +426,9 @@ static struct vlsi_ring *vlsi_alloc_ring
 		memset(rd, 0, sizeof(*rd));
 		rd->hw = hwmap + i;
 		rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA);
-		if (rd->buf == NULL ||
-		    !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) {
+		if (rd->buf)
+			busaddr = pci_map_single(pdev, rd->buf, len, dir);
+		if (rd->buf == NULL || pci_dma_mapping_error(pdev, busaddr)) {
 			if (rd->buf) {
 				IRDA_ERROR("%s: failed to create PCI-MAP for %p",
 					   __func__, rd->buf);
@@ -438,8 +439,7 @@ static struct vlsi_ring *vlsi_alloc_ring
 				rd = r->rd + j;
 				busaddr = rd_get_addr(rd);
 				rd_set_addr_status(rd, 0, 0);
-				if (busaddr)
-					pci_unmap_single(pdev, busaddr, len, dir);
+				pci_unmap_single(pdev, busaddr, len, dir);
 				kfree(rd->buf);
 				rd->buf = NULL;
 			}
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/phy/at803x.c linux-libre-3.18.90-gnu/drivers/net/phy/at803x.c
--- linux-libre-3.18.89-gnu/drivers/net/phy/at803x.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/phy/at803x.c	2017-12-25 08:20:09.000000000 -0500
@@ -105,7 +105,7 @@ static int at803x_set_wol(struct phy_dev
 		mac = (const u8 *) ndev->dev_addr;
 
 		if (!is_valid_ether_addr(mac))
-			return -EFAULT;
+			return -EINVAL;
 
 		for (i = 0; i < 3; i++) {
 			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/usb/qmi_wwan.c linux-libre-3.18.90-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-3.18.89-gnu/drivers/net/usb/qmi_wwan.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/usb/qmi_wwan.c	2017-12-25 08:20:09.000000000 -0500
@@ -460,6 +460,10 @@ static const struct usb_device_id produc
 		USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69),
 		.driver_info        = (unsigned long)&qmi_wwan_info,
 	},
+	{	/* Motorola Mapphone devices with MDM6600 */
+		USB_VENDOR_AND_INTERFACE_INFO(0x22b8, USB_CLASS_VENDOR_SPEC, 0xfb, 0xff),
+		.driver_info        = (unsigned long)&qmi_wwan_info,
+	},
 
 	/* 2. Combined interface devices matching on class+protocol */
 	{	/* Huawei E367 and possibly others in "Windows mode" */
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/net/usb/r8152.c linux-libre-3.18.90-gnu/drivers/net/usb/r8152.c
--- linux-libre-3.18.89-gnu/drivers/net/usb/r8152.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/net/usb/r8152.c	2017-12-25 08:20:09.000000000 -0500
@@ -1252,6 +1252,7 @@ static int alloc_all_mem(struct r8152 *t
 	spin_lock_init(&tp->tx_lock);
 	INIT_LIST_HEAD(&tp->rx_done);
 	INIT_LIST_HEAD(&tp->tx_free);
+	INIT_LIST_HEAD(&tp->rx_done);
 	skb_queue_head_init(&tp->tx_queue);
 
 	for (i = 0; i < RTL8152_MAX_RX; i++) {
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/pci/iov.c linux-libre-3.18.90-gnu/drivers/pci/iov.c
--- linux-libre-3.18.89-gnu/drivers/pci/iov.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/pci/iov.c	2017-12-25 08:20:09.000000000 -0500
@@ -106,7 +106,6 @@ static int virtfn_add(struct pci_dev *de
 	pci_device_add(virtfn, virtfn->bus);
 	mutex_unlock(&iov->dev->sriov->lock);
 
-	pci_bus_add_device(virtfn);
 	sprintf(buf, "virtfn%u", id);
 	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
 	if (rc)
@@ -117,6 +116,8 @@ static int virtfn_add(struct pci_dev *de
 
 	kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
 
+	pci_bus_add_device(virtfn);
+
 	return 0;
 
 failed2:
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/pci/pci.c linux-libre-3.18.90-gnu/drivers/pci/pci.c
--- linux-libre-3.18.89-gnu/drivers/pci/pci.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/pci/pci.c	2017-12-25 08:20:09.000000000 -0500
@@ -3580,6 +3580,10 @@ static bool pci_bus_resetable(struct pci
 {
 	struct pci_dev *dev;
 
+
+	if (bus->self && (bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
+		return false;
+
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
 		    (dev->subordinate && !pci_bus_resetable(dev->subordinate)))
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/pci/pcie/aer/aerdrv_core.c linux-libre-3.18.90-gnu/drivers/pci/pcie/aer/aerdrv_core.c
--- linux-libre-3.18.89-gnu/drivers/pci/pcie/aer/aerdrv_core.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/pci/pcie/aer/aerdrv_core.c	2017-12-25 08:20:09.000000000 -0500
@@ -360,7 +360,14 @@ static pci_ers_result_t broadcast_error_
 		 * If the error is reported by an end point, we think this
 		 * error is related to the upstream link of the end point.
 		 */
-		pci_walk_bus(dev->bus, cb, &result_data);
+		if (state == pci_channel_io_normal)
+			/*
+			 * the error is non fatal so the bus is ok, just invoke
+			 * the callback for the function that logged the error.
+			 */
+			cb(dev, &result_data);
+		else
+			pci_walk_bus(dev->bus, cb, &result_data);
 	}
 
 	return result_data.result;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/s390/net/qeth_l3_main.c linux-libre-3.18.90-gnu/drivers/s390/net/qeth_l3_main.c
--- linux-libre-3.18.89-gnu/drivers/s390/net/qeth_l3_main.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/s390/net/qeth_l3_main.c	2017-12-25 08:20:09.000000000 -0500
@@ -2769,17 +2769,13 @@ static void qeth_l3_fill_af_iucv_hdr(str
 	char daddr[16];
 	struct af_iucv_trans_hdr *iucv_hdr;
 
-	skb_pull(skb, 14);
-	card->dev->header_ops->create(skb, card->dev, 0,
-				      card->dev->dev_addr, card->dev->dev_addr,
-				      card->dev->addr_len);
-	skb_pull(skb, 14);
-	iucv_hdr = (struct af_iucv_trans_hdr *)skb->data;
 	memset(hdr, 0, sizeof(struct qeth_hdr));
 	hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
 	hdr->hdr.l3.ext_flags = 0;
-	hdr->hdr.l3.length = skb->len;
+	hdr->hdr.l3.length = skb->len - ETH_HLEN;
 	hdr->hdr.l3.flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
+
+	iucv_hdr = (struct af_iucv_trans_hdr *) (skb->data + ETH_HLEN);
 	memset(daddr, 0, sizeof(daddr));
 	daddr[0] = 0xfe;
 	daddr[1] = 0x80;
@@ -2962,10 +2958,7 @@ static int qeth_l3_hard_start_xmit(struc
 	if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
 	    (skb_shinfo(skb)->nr_frags == 0)) {
 		new_skb = skb;
-		if (new_skb->protocol == ETH_P_AF_IUCV)
-			data_offset = 0;
-		else
-			data_offset = ETH_HLEN;
+		data_offset = ETH_HLEN;
 		hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
 		if (!hdr)
 			goto tx_drop;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c linux-libre-3.18.90-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
--- linux-libre-3.18.89-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c	2017-12-25 08:20:09.000000000 -0500
@@ -1262,6 +1262,7 @@ static void release_offload_resources(st
 		csk, csk->state, csk->flags, csk->tid);
 
 	cxgbi_sock_free_cpl_skbs(csk);
+	cxgbi_sock_purge_write_queue(csk);
 	if (csk->wr_cred != csk->wr_max_cred) {
 		cxgbi_sock_purge_wr_queue(csk);
 		cxgbi_sock_reset_wr_list(csk);
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/scsi/lpfc/lpfc_els.c linux-libre-3.18.90-gnu/drivers/scsi/lpfc/lpfc_els.c
--- linux-libre-3.18.89-gnu/drivers/scsi/lpfc/lpfc_els.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/scsi/lpfc/lpfc_els.c	2017-12-25 08:20:09.000000000 -0500
@@ -6870,7 +6870,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p
 			did, vport->port_state, ndlp->nlp_flag);
 
 		phba->fc_stat.elsRcvPRLI++;
-		if (vport->port_state < LPFC_DISC_AUTH) {
+		if ((vport->port_state < LPFC_DISC_AUTH) &&
+		    (vport->fc_flag & FC_FABRIC)) {
 			rjt_err = LSRJT_UNABLE_TPC;
 			rjt_exp = LSEXP_NOTHING_MORE;
 			break;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c linux-libre-3.18.90-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c
--- linux-libre-3.18.89-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c	2017-12-25 08:20:09.000000000 -0500
@@ -4737,7 +4737,8 @@ lpfc_nlp_remove(struct lpfc_vport *vport
 	lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
 	    !(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
-	    !(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
+	    !(ndlp->nlp_flag & NLP_RPI_REGISTERED) &&
+	    phba->sli_rev != LPFC_SLI_REV4) {
 		/* For this case we need to cleanup the default rpi
 		 * allocated by the firmware.
 		 */
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/scsi/lpfc/lpfc_hw4.h linux-libre-3.18.90-gnu/drivers/scsi/lpfc/lpfc_hw4.h
--- linux-libre-3.18.89-gnu/drivers/scsi/lpfc/lpfc_hw4.h	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/scsi/lpfc/lpfc_hw4.h	2017-12-25 08:20:09.000000000 -0500
@@ -2951,7 +2951,7 @@ struct lpfc_mbx_get_port_name {
 #define MB_CEQ_STATUS_QUEUE_FLUSHING		0x4
 #define MB_CQE_STATUS_DMA_FAILED		0x5
 
-#define LPFC_MBX_WR_CONFIG_MAX_BDE		8
+#define LPFC_MBX_WR_CONFIG_MAX_BDE		1
 struct lpfc_mbx_wr_object {
 	struct mbox_header header;
 	union {
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/usb/gadget/function/f_uvc.c linux-libre-3.18.90-gnu/drivers/usb/gadget/function/f_uvc.c
--- linux-libre-3.18.89-gnu/drivers/usb/gadget/function/f_uvc.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/usb/gadget/function/f_uvc.c	2017-12-25 08:20:09.000000000 -0500
@@ -612,6 +612,14 @@ uvc_function_bind(struct usb_configurati
 	opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
 	opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
 
+	/* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
+	if (opts->streaming_maxburst &&
+	    (opts->streaming_maxpacket % 1024) != 0) {
+		opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
+		INFO(cdev, "overriding streaming_maxpacket to %d\n",
+		     opts->streaming_maxpacket);
+	}
+
 	/* Fill in the FS/HS/SS Video Streaming specific descriptors from the
 	 * module parameters.
 	 *
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/usb/gadget/udc/pch_udc.c linux-libre-3.18.90-gnu/drivers/usb/gadget/udc/pch_udc.c
--- linux-libre-3.18.89-gnu/drivers/usb/gadget/udc/pch_udc.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/usb/gadget/udc/pch_udc.c	2017-12-25 08:20:09.000000000 -0500
@@ -1533,7 +1533,6 @@ static void pch_udc_free_dma_chain(struc
 		td = phys_to_virt(addr);
 		addr2 = (dma_addr_t)td->next;
 		pci_pool_free(dev->data_requests, td, addr);
-		td->next = 0x00;
 		addr = addr2;
 	}
 	req->chain_len = 1;
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/usb/host/xhci-plat.c linux-libre-3.18.90-gnu/drivers/usb/host/xhci-plat.c
--- linux-libre-3.18.89-gnu/drivers/usb/host/xhci-plat.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/usb/host/xhci-plat.c	2017-12-25 08:20:09.000000000 -0500
@@ -252,6 +252,7 @@ MODULE_DEVICE_TABLE(of, usb_xhci_of_matc
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
 	.driver	= {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
diff -druNp --no-dereference linux-libre-3.18.89-gnu/drivers/video/backlight/pwm_bl.c linux-libre-3.18.90-gnu/drivers/video/backlight/pwm_bl.c
--- linux-libre-3.18.89-gnu/drivers/video/backlight/pwm_bl.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/drivers/video/backlight/pwm_bl.c	2017-12-25 08:20:09.000000000 -0500
@@ -78,14 +78,17 @@ static void pwm_backlight_power_off(stru
 static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
 {
 	unsigned int lth = pb->lth_brightness;
-	int duty_cycle;
+	u64 duty_cycle;
 
 	if (pb->levels)
 		duty_cycle = pb->levels[brightness];
 	else
 		duty_cycle = brightness;
 
-	return (duty_cycle * (pb->period - lth) / pb->scale) + lth;
+	duty_cycle *= pb->period - lth;
+	do_div(duty_cycle, pb->scale);
+
+	return duty_cycle + lth;
 }
 
 static int pwm_backlight_update_status(struct backlight_device *bl)
diff -druNp --no-dereference linux-libre-3.18.89-gnu/Makefile linux-libre-3.18.90-gnu/Makefile
--- linux-libre-3.18.89-gnu/Makefile	2017-12-20 11:04:40.000000000 -0500
+++ linux-libre-3.18.90-gnu/Makefile	2017-12-25 13:44:55.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 18
-SUBLEVEL = 89
+SUBLEVEL = 90
 EXTRAVERSION =-gnu
 NAME = Diseased Newt
 
diff -druNp --no-dereference linux-libre-3.18.89-gnu/net/core/sysctl_net_core.c linux-libre-3.18.90-gnu/net/core/sysctl_net_core.c
--- linux-libre-3.18.89-gnu/net/core/sysctl_net_core.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/net/core/sysctl_net_core.c	2017-12-25 08:20:09.000000000 -0500
@@ -331,14 +331,16 @@ static struct ctl_table net_core_table[]
 		.data		= &sysctl_net_busy_poll,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
 	},
 	{
 		.procname	= "busy_read",
 		.data		= &sysctl_net_busy_read,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
 	},
 #endif
 #ifdef CONFIG_NET_SCHED
diff -druNp --no-dereference linux-libre-3.18.89-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-libre-3.18.90-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c
--- linux-libre-3.18.89-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/net/ipv4/netfilter/nf_nat_snmp_basic.c	2017-12-25 08:20:09.000000000 -0500
@@ -1260,16 +1260,6 @@ static const struct nf_conntrack_expect_
 	.timeout	= 180,
 };
 
-static struct nf_conntrack_helper snmp_helper __read_mostly = {
-	.me			= THIS_MODULE,
-	.help			= help,
-	.expect_policy		= &snmp_exp_policy,
-	.name			= "snmp",
-	.tuple.src.l3num	= AF_INET,
-	.tuple.src.u.udp.port	= cpu_to_be16(SNMP_PORT),
-	.tuple.dst.protonum	= IPPROTO_UDP,
-};
-
 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
 	.me			= THIS_MODULE,
 	.help			= help,
@@ -1288,17 +1278,10 @@ static struct nf_conntrack_helper snmp_t
 
 static int __init nf_nat_snmp_basic_init(void)
 {
-	int ret = 0;
-
 	BUG_ON(nf_nat_snmp_hook != NULL);
 	RCU_INIT_POINTER(nf_nat_snmp_hook, help);
 
-	ret = nf_conntrack_helper_register(&snmp_trap_helper);
-	if (ret < 0) {
-		nf_conntrack_helper_unregister(&snmp_helper);
-		return ret;
-	}
-	return ret;
+	return nf_conntrack_helper_register(&snmp_trap_helper);
 }
 
 static void __exit nf_nat_snmp_basic_fini(void)
diff -druNp --no-dereference linux-libre-3.18.89-gnu/net/netfilter/nfnetlink_cthelper.c linux-libre-3.18.90-gnu/net/netfilter/nfnetlink_cthelper.c
--- linux-libre-3.18.89-gnu/net/netfilter/nfnetlink_cthelper.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/net/netfilter/nfnetlink_cthelper.c	2017-12-25 08:20:09.000000000 -0500
@@ -32,6 +32,13 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
 MODULE_DESCRIPTION("nfnl_cthelper: User-space connection tracking helpers");
 
+struct nfnl_cthelper {
+	struct list_head		list;
+	struct nf_conntrack_helper	helper;
+};
+
+static LIST_HEAD(nfnl_cthelper_list);
+
 static int
 nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,
 			struct nf_conn *ct, enum ip_conntrack_info ctinfo)
@@ -205,18 +212,20 @@ nfnl_cthelper_create(const struct nlattr
 		     struct nf_conntrack_tuple *tuple)
 {
 	struct nf_conntrack_helper *helper;
+	struct nfnl_cthelper *nfcth;
 	int ret;
 
 	if (!tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_PRIV_DATA_LEN])
 		return -EINVAL;
 
-	helper = kzalloc(sizeof(struct nf_conntrack_helper), GFP_KERNEL);
-	if (helper == NULL)
+	nfcth = kzalloc(sizeof(*nfcth), GFP_KERNEL);
+	if (nfcth == NULL)
 		return -ENOMEM;
+	helper = &nfcth->helper;
 
 	ret = nfnl_cthelper_parse_expect_policy(helper, tb[NFCTH_POLICY]);
 	if (ret < 0)
-		goto err;
+		goto err1;
 
 	strncpy(helper->name, nla_data(tb[NFCTH_NAME]), NF_CT_HELPER_NAME_LEN);
 	helper->data_len = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
@@ -247,15 +256,101 @@ nfnl_cthelper_create(const struct nlattr
 
 	ret = nf_conntrack_helper_register(helper);
 	if (ret < 0)
-		goto err;
+		goto err2;
 
+	list_add_tail(&nfcth->list, &nfnl_cthelper_list);
 	return 0;
-err:
-	kfree(helper);
+err2:
+	kfree(helper->expect_policy);
+err1:
+	kfree(nfcth);
 	return ret;
 }
 
 static int
+nfnl_cthelper_update_policy_one(const struct nf_conntrack_expect_policy *policy,
+				struct nf_conntrack_expect_policy *new_policy,
+				const struct nlattr *attr)
+{
+	struct nlattr *tb[NFCTH_POLICY_MAX + 1];
+	int err;
+
+	err = nla_parse_nested(tb, NFCTH_POLICY_MAX, attr,
+			       nfnl_cthelper_expect_pol);
+	if (err < 0)
+		return err;
+
+	if (!tb[NFCTH_POLICY_NAME] ||
+	    !tb[NFCTH_POLICY_EXPECT_MAX] ||
+	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
+		return -EINVAL;
+
+	if (nla_strcmp(tb[NFCTH_POLICY_NAME], policy->name))
+		return -EBUSY;
+
+	new_policy->max_expected =
+		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
+	new_policy->timeout =
+		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT]));
+
+	return 0;
+}
+
+static int nfnl_cthelper_update_policy_all(struct nlattr *tb[],
+					   struct nf_conntrack_helper *helper)
+{
+	struct nf_conntrack_expect_policy new_policy[helper->expect_class_max + 1];
+	struct nf_conntrack_expect_policy *policy;
+	int i, err;
+
+	/* Check first that all policy attributes are well-formed, so we don't
+	 * leave things in inconsistent state on errors.
+	 */
+	for (i = 0; i < helper->expect_class_max + 1; i++) {
+
+		if (!tb[NFCTH_POLICY_SET + i])
+			return -EINVAL;
+
+		err = nfnl_cthelper_update_policy_one(&helper->expect_policy[i],
+						      &new_policy[i],
+						      tb[NFCTH_POLICY_SET + i]);
+		if (err < 0)
+			return err;
+	}
+	/* Now we can safely update them. */
+	for (i = 0; i < helper->expect_class_max + 1; i++) {
+		policy = (struct nf_conntrack_expect_policy *)
+				&helper->expect_policy[i];
+		policy->max_expected = new_policy->max_expected;
+		policy->timeout	= new_policy->timeout;
+	}
+
+	return 0;
+}
+
+static int nfnl_cthelper_update_policy(struct nf_conntrack_helper *helper,
+				       const struct nlattr *attr)
+{
+	struct nlattr *tb[NFCTH_POLICY_SET_MAX + 1];
+	unsigned int class_max;
+	int err;
+
+	err = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
+			       nfnl_cthelper_expect_policy_set);
+	if (err < 0)
+		return err;
+
+	if (!tb[NFCTH_POLICY_SET_NUM])
+		return -EINVAL;
+
+	class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
+	if (helper->expect_class_max + 1 != class_max)
+		return -EBUSY;
+
+	return nfnl_cthelper_update_policy_all(tb, helper);
+}
+
+static int
 nfnl_cthelper_update(const struct nlattr * const tb[],
 		     struct nf_conntrack_helper *helper)
 {
@@ -265,8 +360,7 @@ nfnl_cthelper_update(const struct nlattr
 		return -EBUSY;
 
 	if (tb[NFCTH_POLICY]) {
-		ret = nfnl_cthelper_parse_expect_policy(helper,
-							tb[NFCTH_POLICY]);
+		ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]);
 		if (ret < 0)
 			return ret;
 	}
@@ -295,7 +389,8 @@ nfnl_cthelper_new(struct sock *nfnl, str
 	const char *helper_name;
 	struct nf_conntrack_helper *cur, *helper = NULL;
 	struct nf_conntrack_tuple tuple;
-	int ret = 0, i;
+	struct nfnl_cthelper *nlcth;
+	int ret = 0;
 
 	if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE])
 		return -EINVAL;
@@ -306,31 +401,22 @@ nfnl_cthelper_new(struct sock *nfnl, str
 	if (ret < 0)
 		return ret;
 
-	rcu_read_lock();
-	for (i = 0; i < nf_ct_helper_hsize && !helper; i++) {
-		hlist_for_each_entry_rcu(cur, &nf_ct_helper_hash[i], hnode) {
+	list_for_each_entry(nlcth, &nfnl_cthelper_list, list) {
+		cur = &nlcth->helper;
 
-			/* skip non-userspace conntrack helpers. */
-			if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
-				continue;
+		if (strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
+			continue;
 
-			if (strncmp(cur->name, helper_name,
-					NF_CT_HELPER_NAME_LEN) != 0)
-				continue;
+		if ((tuple.src.l3num != cur->tuple.src.l3num ||
+		     tuple.dst.protonum != cur->tuple.dst.protonum))
+			continue;
 
-			if ((tuple.src.l3num != cur->tuple.src.l3num ||
-			     tuple.dst.protonum != cur->tuple.dst.protonum))
-				continue;
+		if (nlh->nlmsg_flags & NLM_F_EXCL)
+			return -EEXIST;
 
-			if (nlh->nlmsg_flags & NLM_F_EXCL) {
-				ret = -EEXIST;
-				goto err;
-			}
-			helper = cur;
-			break;
-		}
+		helper = cur;
+		break;
 	}
-	rcu_read_unlock();
 
 	if (helper == NULL)
 		ret = nfnl_cthelper_create(tb, &tuple);
@@ -338,9 +424,6 @@ nfnl_cthelper_new(struct sock *nfnl, str
 		ret = nfnl_cthelper_update(tb, helper);
 
 	return ret;
-err:
-	rcu_read_unlock();
-	return ret;
 }
 
 static int
@@ -504,11 +587,12 @@ static int
 nfnl_cthelper_get(struct sock *nfnl, struct sk_buff *skb,
 		  const struct nlmsghdr *nlh, const struct nlattr * const tb[])
 {
-	int ret = -ENOENT, i;
+	int ret = -ENOENT;
 	struct nf_conntrack_helper *cur;
 	struct sk_buff *skb2;
 	char *helper_name = NULL;
 	struct nf_conntrack_tuple tuple;
+	struct nfnl_cthelper *nlcth;
 	bool tuple_set = false;
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
@@ -529,45 +613,39 @@ nfnl_cthelper_get(struct sock *nfnl, str
 		tuple_set = true;
 	}
 
-	for (i = 0; i < nf_ct_helper_hsize; i++) {
-		hlist_for_each_entry_rcu(cur, &nf_ct_helper_hash[i], hnode) {
-
-			/* skip non-userspace conntrack helpers. */
-			if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
-				continue;
+	list_for_each_entry(nlcth, &nfnl_cthelper_list, list) {
+		cur = &nlcth->helper;
+		if (helper_name &&
+		    strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
+			continue;
 
-			if (helper_name && strncmp(cur->name, helper_name,
-						NF_CT_HELPER_NAME_LEN) != 0) {
-				continue;
-			}
-			if (tuple_set &&
-			    (tuple.src.l3num != cur->tuple.src.l3num ||
-			     tuple.dst.protonum != cur->tuple.dst.protonum))
-				continue;
+		if (tuple_set &&
+		    (tuple.src.l3num != cur->tuple.src.l3num ||
+		     tuple.dst.protonum != cur->tuple.dst.protonum))
+			continue;
 
-			skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-			if (skb2 == NULL) {
-				ret = -ENOMEM;
-				break;
-			}
+		skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+		if (skb2 == NULL) {
+			ret = -ENOMEM;
+			break;
+		}
 
-			ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).portid,
-						nlh->nlmsg_seq,
-						NFNL_MSG_TYPE(nlh->nlmsg_type),
-						NFNL_MSG_CTHELPER_NEW, cur);
-			if (ret <= 0) {
-				kfree_skb(skb2);
-				break;
-			}
+		ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).portid,
+					      nlh->nlmsg_seq,
+					      NFNL_MSG_TYPE(nlh->nlmsg_type),
+					      NFNL_MSG_CTHELPER_NEW, cur);
+		if (ret <= 0) {
+			kfree_skb(skb2);
+			break;
+		}
 
-			ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
-						MSG_DONTWAIT);
-			if (ret > 0)
-				ret = 0;
+		ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
+				      MSG_DONTWAIT);
+		if (ret > 0)
+			ret = 0;
 
-			/* this avoids a loop in nfnetlink. */
-			return ret == -EAGAIN ? -ENOBUFS : ret;
-		}
+		/* this avoids a loop in nfnetlink. */
+		return ret == -EAGAIN ? -ENOBUFS : ret;
 	}
 	return ret;
 }
@@ -578,10 +656,10 @@ nfnl_cthelper_del(struct sock *nfnl, str
 {
 	char *helper_name = NULL;
 	struct nf_conntrack_helper *cur;
-	struct hlist_node *tmp;
 	struct nf_conntrack_tuple tuple;
 	bool tuple_set = false, found = false;
-	int i, j = 0, ret;
+	struct nfnl_cthelper *nlcth, *n;
+	int j = 0, ret;
 
 	if (tb[NFCTH_NAME])
 		helper_name = nla_data(tb[NFCTH_NAME]);
@@ -594,28 +672,27 @@ nfnl_cthelper_del(struct sock *nfnl, str
 		tuple_set = true;
 	}
 
-	for (i = 0; i < nf_ct_helper_hsize; i++) {
-		hlist_for_each_entry_safe(cur, tmp, &nf_ct_helper_hash[i],
-								hnode) {
-			/* skip non-userspace conntrack helpers. */
-			if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
-				continue;
+	list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
+		cur = &nlcth->helper;
+		j++;
 
-			j++;
+		if (helper_name &&
+		    strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
+			continue;
 
-			if (helper_name && strncmp(cur->name, helper_name,
-						NF_CT_HELPER_NAME_LEN) != 0) {
-				continue;
-			}
-			if (tuple_set &&
-			    (tuple.src.l3num != cur->tuple.src.l3num ||
-			     tuple.dst.protonum != cur->tuple.dst.protonum))
-				continue;
+		if (tuple_set &&
+		    (tuple.src.l3num != cur->tuple.src.l3num ||
+		     tuple.dst.protonum != cur->tuple.dst.protonum))
+			continue;
 
-			found = true;
-			nf_conntrack_helper_unregister(cur);
-		}
+		found = true;
+		nf_conntrack_helper_unregister(cur);
+		kfree(cur->expect_policy);
+
+		list_del(&nlcth->list);
+		kfree(nlcth);
 	}
+
 	/* Make sure we return success if we flush and there is no helpers */
 	return (found || j == 0) ? 0 : -ENOENT;
 }
@@ -664,20 +741,16 @@ err_out:
 static void __exit nfnl_cthelper_exit(void)
 {
 	struct nf_conntrack_helper *cur;
-	struct hlist_node *tmp;
-	int i;
+	struct nfnl_cthelper *nlcth, *n;
 
 	nfnetlink_subsys_unregister(&nfnl_cthelper_subsys);
 
-	for (i=0; i<nf_ct_helper_hsize; i++) {
-		hlist_for_each_entry_safe(cur, tmp, &nf_ct_helper_hash[i],
-									hnode) {
-			/* skip non-userspace conntrack helpers. */
-			if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
-				continue;
+	list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
+		cur = &nlcth->helper;
 
-			nf_conntrack_helper_unregister(cur);
-		}
+		nf_conntrack_helper_unregister(cur);
+		kfree(cur->expect_policy);
+		kfree(nlcth);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.18.89-gnu/net/netlink/af_netlink.c linux-libre-3.18.90-gnu/net/netlink/af_netlink.c
--- linux-libre-3.18.89-gnu/net/netlink/af_netlink.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/net/netlink/af_netlink.c	2017-12-25 08:20:09.000000000 -0500
@@ -93,6 +93,44 @@ EXPORT_SYMBOL_GPL(nl_table);
 
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
 
+static struct lock_class_key nlk_cb_mutex_keys[MAX_LINKS];
+
+static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = {
+	"nlk_cb_mutex-ROUTE",
+	"nlk_cb_mutex-1",
+	"nlk_cb_mutex-USERSOCK",
+	"nlk_cb_mutex-FIREWALL",
+	"nlk_cb_mutex-SOCK_DIAG",
+	"nlk_cb_mutex-NFLOG",
+	"nlk_cb_mutex-XFRM",
+	"nlk_cb_mutex-SELINUX",
+	"nlk_cb_mutex-ISCSI",
+	"nlk_cb_mutex-AUDIT",
+	"nlk_cb_mutex-FIB_LOOKUP",
+	"nlk_cb_mutex-CONNECTOR",
+	"nlk_cb_mutex-NETFILTER",
+	"nlk_cb_mutex-IP6_FW",
+	"nlk_cb_mutex-DNRTMSG",
+	"nlk_cb_mutex-KOBJECT_UEVENT",
+	"nlk_cb_mutex-GENERIC",
+	"nlk_cb_mutex-17",
+	"nlk_cb_mutex-SCSITRANSPORT",
+	"nlk_cb_mutex-ECRYPTFS",
+	"nlk_cb_mutex-RDMA",
+	"nlk_cb_mutex-CRYPTO",
+	"nlk_cb_mutex-SMC",
+	"nlk_cb_mutex-23",
+	"nlk_cb_mutex-24",
+	"nlk_cb_mutex-25",
+	"nlk_cb_mutex-26",
+	"nlk_cb_mutex-27",
+	"nlk_cb_mutex-28",
+	"nlk_cb_mutex-29",
+	"nlk_cb_mutex-30",
+	"nlk_cb_mutex-31",
+	"nlk_cb_mutex-MAX_LINKS"
+};
+
 static int netlink_dump(struct sock *sk);
 static void netlink_skb_destructor(struct sk_buff *skb);
 
@@ -548,6 +586,9 @@ static int __netlink_create(struct net *
 	} else {
 		nlk->cb_mutex = &nlk->cb_def_mutex;
 		mutex_init(nlk->cb_mutex);
+		lockdep_set_class_and_name(nlk->cb_mutex,
+					   nlk_cb_mutex_keys + protocol,
+					   nlk_cb_mutex_key_strings[protocol]);
 	}
 	init_waitqueue_head(&nlk->wait);
 
diff -druNp --no-dereference linux-libre-3.18.89-gnu/sound/pci/hda/patch_realtek.c linux-libre-3.18.90-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-3.18.89-gnu/sound/pci/hda/patch_realtek.c	2017-12-20 04:01:34.000000000 -0500
+++ linux-libre-3.18.90-gnu/sound/pci/hda/patch_realtek.c	2017-12-25 08:20:09.000000000 -0500
@@ -4683,6 +4683,7 @@ enum {
 	ALC286_FIXUP_HP_GPIO_LED,
 	ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
 	ALC280_FIXUP_HP_DOCK_PINS,
+	ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
 	ALC280_FIXUP_HP_9480M,
 	ALC288_FIXUP_DELL_HEADSET_MODE,
 	ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
@@ -5216,6 +5217,16 @@ static const struct hda_fixup alc269_fix
 		.chained = true,
 		.chain_id = ALC280_FIXUP_HP_GPIO4
 	},
+	[ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x1b, 0x21011020 }, /* line-out */
+			{ 0x18, 0x2181103f }, /* line-in */
+			{ },
+		},
+		.chained = true,
+		.chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
+	},
 	[ALC280_FIXUP_HP_9480M] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc280_fixup_hp_9480m,
@@ -5388,7 +5399,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 	SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 	SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
-	SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
+	SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
 	SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 	SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 	SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -5544,6 +5555,7 @@ static const struct hda_model_fixup alc2
 	{.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
 	{.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
 	{.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
+	{.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
 	{.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
 	{.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
 	{.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
