diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/exynos3250-monk.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos3250-monk.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/exynos3250-monk.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos3250-monk.dts	2016-01-22 23:59:37.000000000 -0500
@@ -161,6 +161,7 @@
 };
 
 &exynos_usbphy {
+	vbus-supply = <&safeout_reg>;
 	status = "okay";
 };
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/exynos3250-rinato.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos3250-rinato.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/exynos3250-rinato.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos3250-rinato.dts	2016-01-22 23:59:37.000000000 -0500
@@ -153,6 +153,7 @@
 
 &exynos_usbphy {
 	status = "okay";
+	vbus-supply = <&safeout_reg>;
 };
 
 &hsotg {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/exynos4210-trats.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos4210-trats.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/exynos4210-trats.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos4210-trats.dts	2016-01-22 23:59:37.000000000 -0500
@@ -251,6 +251,7 @@
 
 &exynos_usbphy {
 	status = "okay";
+	vbus-supply = <&safe1_sreg>;
 };
 
 &fimd {
@@ -448,7 +449,6 @@
 
 			safe1_sreg: ESAFEOUT1 {
 			     regulator-name = "SAFEOUT1";
-			     regulator-always-on;
 			};
 
 			safe2_sreg: ESAFEOUT2 {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts	2016-01-22 23:59:37.000000000 -0500
@@ -248,6 +248,7 @@
 
 &exynos_usbphy {
 	status = "okay";
+	vbus-supply = <&safeout1_reg>;
 };
 
 &fimd {
@@ -486,7 +487,6 @@
 
 			safeout1_reg: ESAFEOUT1 {
 				regulator-name = "SAFEOUT1";
-				regulator-always-on;
 			};
 
 			safeout2_reg: ESAFEOUT2 {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/exynos4412-trats2.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos4412-trats2.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/exynos4412-trats2.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/exynos4412-trats2.dts	2016-01-22 23:59:37.000000000 -0500
@@ -391,6 +391,7 @@
 };
 
 &exynos_usbphy {
+	vbus-supply = <&esafeout1_reg>;
 	status = "okay";
 };
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/imx27.dtsi linux-libre-4.3.4-gnu/arch/arm/boot/dts/imx27.dtsi
--- linux-libre-4.3-gnu/arch/arm/boot/dts/imx27.dtsi	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/imx27.dtsi	2016-01-22 23:59:37.000000000 -0500
@@ -486,7 +486,10 @@
 				compatible = "fsl,imx27-usb";
 				reg = <0x10024000 0x200>;
 				interrupts = <56>;
-				clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+				clocks = <&clks IMX27_CLK_USB_IPG_GATE>,
+					<&clks IMX27_CLK_USB_AHB_GATE>,
+					<&clks IMX27_CLK_USB_DIV>;
+				clock-names = "ipg", "ahb", "per";
 				fsl,usbmisc = <&usbmisc 0>;
 				status = "disabled";
 			};
@@ -495,7 +498,10 @@
 				compatible = "fsl,imx27-usb";
 				reg = <0x10024200 0x200>;
 				interrupts = <54>;
-				clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+				clocks = <&clks IMX27_CLK_USB_IPG_GATE>,
+					<&clks IMX27_CLK_USB_AHB_GATE>,
+					<&clks IMX27_CLK_USB_DIV>;
+				clock-names = "ipg", "ahb", "per";
 				fsl,usbmisc = <&usbmisc 1>;
 				dr_mode = "host";
 				status = "disabled";
@@ -505,7 +511,10 @@
 				compatible = "fsl,imx27-usb";
 				reg = <0x10024400 0x200>;
 				interrupts = <55>;
-				clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+				clocks = <&clks IMX27_CLK_USB_IPG_GATE>,
+					<&clks IMX27_CLK_USB_AHB_GATE>,
+					<&clks IMX27_CLK_USB_DIV>;
+				clock-names = "ipg", "ahb", "per";
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
 				status = "disabled";
@@ -515,7 +524,6 @@
 				#index-cells = <1>;
 				compatible = "fsl,imx27-usbmisc";
 				reg = <0x10024600 0x200>;
-				clocks = <&clks IMX27_CLK_USB_AHB_GATE>;
 			};
 
 			sahara2: sahara@10025000 {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/omap5-uevm.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/omap5-uevm.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/omap5-uevm.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/omap5-uevm.dts	2016-01-22 23:59:37.000000000 -0500
@@ -31,6 +31,24 @@
 		regulator-max-microvolt = <3000000>;
 	};
 
+	mmc3_pwrseq: sdhci0_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&clk32kgaudio>;
+		clock-names = "ext_clock";
+	};
+
+	vmmcsdio_fixed: fixedregulator-mmcsdio {
+		compatible = "regulator-fixed";
+		regulator-name = "vmmcsdio_fixed";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&gpio5 12 GPIO_ACTIVE_HIGH>;	/* gpio140 WLAN_EN */
+		enable-active-high;
+		startup-delay-us = <70000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_pins>;
+	};
+
 	/* HS USB Host PHY on PORT 2 */
 	hsusb2_phy: hsusb2_phy {
 		compatible = "usb-nop-xceiv";
@@ -197,12 +215,20 @@
 		>;
 	};
 
-	mcspi4_pins: pinmux_mcspi4_pins {
+	mmc3_pins: pinmux_mmc3_pins {
 		pinctrl-single,pins = <
-			0x164 (PIN_INPUT | MUX_MODE1)		/*  mcspi4_clk */
-			0x168 (PIN_INPUT | MUX_MODE1)		/*  mcspi4_simo */
-			0x16a (PIN_INPUT | MUX_MODE1)		/*  mcspi4_somi */
-			0x16c (PIN_INPUT | MUX_MODE1)		/*  mcspi4_cs0 */
+			OMAP5_IOPAD(0x01a4, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_clk */
+			OMAP5_IOPAD(0x01a6, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_cmd */
+			OMAP5_IOPAD(0x01a8, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data0 */
+			OMAP5_IOPAD(0x01aa, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data1 */
+			OMAP5_IOPAD(0x01ac, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data2 */
+			OMAP5_IOPAD(0x01ae, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data3 */
+		>;
+	};
+
+	wlan_pins: pinmux_wlan_pins {
+		pinctrl-single,pins = <
+			OMAP5_IOPAD(0x1bc, PIN_OUTPUT | MUX_MODE6) /* mcspi1_clk.gpio5_140 */
 		>;
 	};
 
@@ -276,6 +302,12 @@
 			0x1A (PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
 		>;
 	};
+
+	wlcore_irq_pin: pinmux_wlcore_irq_pin {
+		pinctrl-single,pins = <
+			OMAP5_IOPAD(0x040, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE6)	/* llia_wakereqin.gpio1_wk14 */
+		>;
+	};
 };
 
 &mmc1 {
@@ -290,8 +322,25 @@
 };
 
 &mmc3 {
+	vmmc-supply = <&vmmcsdio_fixed>;
+	mmc-pwrseq = <&mmc3_pwrseq>;
 	bus-width = <4>;
-	ti,non-removable;
+	non-removable;
+	cap-power-off-card;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins &wlcore_irq_pin>;
+	interrupts-extended = <&gic GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH
+			       &omap5_pmx_core 0x168>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore@2 {
+		compatible = "ti,wl1271";
+		reg = <2>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;	/* gpio 14 */
+		ref-clock-frequency = <26000000>;
+	};
 };
 
 &mmc4 {
@@ -598,11 +647,6 @@
 	pinctrl-0 = <&mcspi3_pins>;
 };
 
-&mcspi4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcspi4_pins>;
-};
-
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart1_pins>;
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/sama5d4.dtsi linux-libre-4.3.4-gnu/arch/arm/boot/dts/sama5d4.dtsi
--- linux-libre-4.3-gnu/arch/arm/boot/dts/sama5d4.dtsi	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/sama5d4.dtsi	2016-01-22 23:59:37.000000000 -0500
@@ -939,11 +939,11 @@
 				reg = <0xf8018000 0x4000>;
 				interrupts = <33 IRQ_TYPE_LEVEL_HIGH 6>;
 				dmas = <&dma1
-					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
-					AT91_XDMAC_DT_PERID(4)>,
+					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+					| AT91_XDMAC_DT_PERID(4))>,
 				       <&dma1
-					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
-					AT91_XDMAC_DT_PERID(5)>;
+					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+					| AT91_XDMAC_DT_PERID(5))>;
 				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_i2c1>;
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/boot/dts/sun6i-a31-hummingbird.dts linux-libre-4.3.4-gnu/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
--- linux-libre-4.3-gnu/arch/arm/boot/dts/sun6i-a31-hummingbird.dts	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/boot/dts/sun6i-a31-hummingbird.dts	2016-01-22 23:59:37.000000000 -0500
@@ -184,18 +184,18 @@
 				regulator-name = "vcc-3v0";
 			};
 
-			vdd_cpu: dcdc2 {
+			vdd_gpu: dcdc2 {
 				regulator-always-on;
 				regulator-min-microvolt = <700000>;
 				regulator-max-microvolt = <1320000>;
-				regulator-name = "vdd-cpu";
+				regulator-name = "vdd-gpu";
 			};
 
-			vdd_gpu: dcdc3 {
+			vdd_cpu: dcdc3 {
 				regulator-always-on;
 				regulator-min-microvolt = <700000>;
 				regulator-max-microvolt = <1320000>;
-				regulator-name = "vdd-gpu";
+				regulator-name = "vdd-cpu";
 			};
 
 			vdd_sys_dll: dcdc4 {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/common/edma.c linux-libre-4.3.4-gnu/arch/arm/common/edma.c
--- linux-libre-4.3-gnu/arch/arm/common/edma.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/common/edma.c	2016-01-22 23:59:37.000000000 -0500
@@ -406,7 +406,8 @@ static irqreturn_t dma_irq_handler(int i
 					BIT(slot));
 			if (edma_cc[ctlr]->intr_data[channel].callback)
 				edma_cc[ctlr]->intr_data[channel].callback(
-					channel, EDMA_DMA_COMPLETE,
+					EDMA_CTLR_CHAN(ctlr, channel),
+					EDMA_DMA_COMPLETE,
 					edma_cc[ctlr]->intr_data[channel].data);
 		}
 	} while (sh_ipr);
@@ -460,7 +461,8 @@ static irqreturn_t dma_ccerr_handler(int
 					if (edma_cc[ctlr]->intr_data[k].
 								callback) {
 						edma_cc[ctlr]->intr_data[k].
-						callback(k,
+						callback(
+						EDMA_CTLR_CHAN(ctlr, k),
 						EDMA_DMA_CC_ERROR,
 						edma_cc[ctlr]->intr_data
 						[k].data);
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/include/asm/irq.h linux-libre-4.3.4-gnu/arch/arm/include/asm/irq.h
--- linux-libre-4.3-gnu/arch/arm/include/asm/irq.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/include/asm/irq.h	2016-01-22 23:59:37.000000000 -0500
@@ -40,6 +40,11 @@ extern void arch_trigger_all_cpu_backtra
 #define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x)
 #endif
 
+static inline int nr_legacy_irqs(void)
+{
+	return NR_IRQS_LEGACY;
+}
+
 #endif
 
 #endif
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/mach-at91/pm_suspend.S linux-libre-4.3.4-gnu/arch/arm/mach-at91/pm_suspend.S
--- linux-libre-4.3-gnu/arch/arm/mach-at91/pm_suspend.S	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/mach-at91/pm_suspend.S	2016-01-22 23:59:37.000000000 -0500
@@ -80,6 +80,8 @@ tmp2	.req	r5
  *	@r2: base address of second SDRAM Controller or 0 if not present
  *	@r3: pm information
  */
+/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
+	.align 3
 ENTRY(at91_pm_suspend_in_sram)
 	/* Save registers on stack */
 	stmfd	sp!, {r4 - r12, lr}
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/mach-pxa/include/mach/pxa27x.h linux-libre-4.3.4-gnu/arch/arm/mach-pxa/include/mach/pxa27x.h
--- linux-libre-4.3-gnu/arch/arm/mach-pxa/include/mach/pxa27x.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/mach-pxa/include/mach/pxa27x.h	2016-01-22 23:59:37.000000000 -0500
@@ -19,7 +19,7 @@
 #define ARB_CORE_PARK		(1<<24)	   /* Be parked with core when idle */
 #define ARB_LOCK_FLAG		(1<<23)	   /* Only Locking masters gain access to the bus */
 
-extern int __init pxa27x_set_pwrmode(unsigned int mode);
+extern int pxa27x_set_pwrmode(unsigned int mode);
 extern void pxa27x_cpu_pm_enter(suspend_state_t state);
 
 #endif /* __MACH_PXA27x_H */
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/mach-pxa/pxa27x.c linux-libre-4.3.4-gnu/arch/arm/mach-pxa/pxa27x.c
--- linux-libre-4.3-gnu/arch/arm/mach-pxa/pxa27x.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/mach-pxa/pxa27x.c	2016-01-22 23:59:37.000000000 -0500
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(pxa27x_configure_ac97r
  */
 static unsigned int pwrmode = PWRMODE_SLEEP;
 
-int __init pxa27x_set_pwrmode(unsigned int mode)
+int pxa27x_set_pwrmode(unsigned int mode)
 {
 	switch (mode) {
 	case PWRMODE_SLEEP:
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/mach-tegra/board-paz00.c linux-libre-4.3.4-gnu/arch/arm/mach-tegra/board-paz00.c
--- linux-libre-4.3-gnu/arch/arm/mach-tegra/board-paz00.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/mach-tegra/board-paz00.c	2016-01-22 23:59:37.000000000 -0500
@@ -39,8 +39,8 @@ static struct platform_device wifi_rfkil
 static struct gpiod_lookup_table wifi_gpio_lookup = {
 	.dev_id = "rfkill_gpio",
 	.table = {
-		GPIO_LOOKUP_IDX("tegra-gpio", 25, NULL, 0, 0),
-		GPIO_LOOKUP_IDX("tegra-gpio", 85, NULL, 1, 0),
+		GPIO_LOOKUP("tegra-gpio", 25, "reset", 0),
+		GPIO_LOOKUP("tegra-gpio", 85, "shutdown", 0),
 		{ },
 	},
 };
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/mm/dma-mapping.c linux-libre-4.3.4-gnu/arch/arm/mm/dma-mapping.c
--- linux-libre-4.3-gnu/arch/arm/mm/dma-mapping.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/mm/dma-mapping.c	2016-01-22 23:59:37.000000000 -0500
@@ -1407,12 +1407,19 @@ static int arm_iommu_mmap_attrs(struct d
 	unsigned long uaddr = vma->vm_start;
 	unsigned long usize = vma->vm_end - vma->vm_start;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+	unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	unsigned long off = vma->vm_pgoff;
 
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
 
 	if (!pages)
 		return -ENXIO;
 
+	if (off >= nr_pages || (usize >> PAGE_SHIFT) > nr_pages - off)
+		return -ENXIO;
+
+	pages += off;
+
 	do {
 		int ret = vm_insert_page(vma, uaddr, *pages++);
 		if (ret) {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm/vdso/vdsomunge.c linux-libre-4.3.4-gnu/arch/arm/vdso/vdsomunge.c
--- linux-libre-4.3-gnu/arch/arm/vdso/vdsomunge.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm/vdso/vdsomunge.c	2016-01-22 23:59:37.000000000 -0500
@@ -66,7 +66,7 @@
 	((((x) & 0x000000ff) << 24) | \
 	 (((x) & 0x0000ff00) <<  8) | \
 	 (((x) & 0x00ff0000) >>  8) | \
-	 (((x) & 0xff000000) << 24))
+	 (((x) & 0xff000000) >> 24))
 
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 #define HOST_ORDER ELFDATA2LSB
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm64/include/asm/irq.h linux-libre-4.3.4-gnu/arch/arm64/include/asm/irq.h
--- linux-libre-4.3-gnu/arch/arm64/include/asm/irq.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm64/include/asm/irq.h	2016-01-22 23:59:37.000000000 -0500
@@ -21,4 +21,9 @@ static inline void acpi_irq_init(void)
 }
 #define acpi_irq_init acpi_irq_init
 
+static inline int nr_legacy_irqs(void)
+{
+	return 0;
+}
+
 #endif
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm64/include/asm/ptrace.h linux-libre-4.3.4-gnu/arch/arm64/include/asm/ptrace.h
--- linux-libre-4.3-gnu/arch/arm64/include/asm/ptrace.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm64/include/asm/ptrace.h	2016-01-22 23:59:37.000000000 -0500
@@ -83,14 +83,14 @@
 #define compat_sp	regs[13]
 #define compat_lr	regs[14]
 #define compat_sp_hyp	regs[15]
-#define compat_sp_irq	regs[16]
-#define compat_lr_irq	regs[17]
-#define compat_sp_svc	regs[18]
-#define compat_lr_svc	regs[19]
-#define compat_sp_abt	regs[20]
-#define compat_lr_abt	regs[21]
-#define compat_sp_und	regs[22]
-#define compat_lr_und	regs[23]
+#define compat_lr_irq	regs[16]
+#define compat_sp_irq	regs[17]
+#define compat_lr_svc	regs[18]
+#define compat_sp_svc	regs[19]
+#define compat_lr_abt	regs[20]
+#define compat_sp_abt	regs[21]
+#define compat_lr_und	regs[22]
+#define compat_sp_und	regs[23]
 #define compat_r8_fiq	regs[24]
 #define compat_r9_fiq	regs[25]
 #define compat_r10_fiq	regs[26]
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/arm64/kernel/vmlinux.lds.S linux-libre-4.3.4-gnu/arch/arm64/kernel/vmlinux.lds.S
--- linux-libre-4.3-gnu/arch/arm64/kernel/vmlinux.lds.S	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/arm64/kernel/vmlinux.lds.S	2016-01-22 23:59:37.000000000 -0500
@@ -60,9 +60,12 @@ PECOFF_FILE_ALIGNMENT = 0x200;
 #define PECOFF_EDATA_PADDING
 #endif
 
-#ifdef CONFIG_DEBUG_ALIGN_RODATA
+#if defined(CONFIG_DEBUG_ALIGN_RODATA)
 #define ALIGN_DEBUG_RO			. = ALIGN(1<<SECTION_SHIFT);
 #define ALIGN_DEBUG_RO_MIN(min)		ALIGN_DEBUG_RO
+#elif defined(CONFIG_DEBUG_RODATA)
+#define ALIGN_DEBUG_RO			. = ALIGN(1<<PAGE_SHIFT);
+#define ALIGN_DEBUG_RO_MIN(min)		ALIGN_DEBUG_RO
 #else
 #define ALIGN_DEBUG_RO
 #define ALIGN_DEBUG_RO_MIN(min)		. = ALIGN(min);
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/mips/ath79/setup.c linux-libre-4.3.4-gnu/arch/mips/ath79/setup.c
--- linux-libre-4.3-gnu/arch/mips/ath79/setup.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/mips/ath79/setup.c	2016-01-22 23:59:37.000000000 -0500
@@ -216,9 +216,9 @@ void __init plat_mem_setup(void)
 					   AR71XX_RESET_SIZE);
 	ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
 					 AR71XX_PLL_SIZE);
+	ath79_detect_sys_type();
 	ath79_ddr_ctrl_init();
 
-	ath79_detect_sys_type();
 	if (mips_machtype != ATH79_MACH_GENERIC_OF)
 		detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/mips/include/asm/cdmm.h linux-libre-4.3.4-gnu/arch/mips/include/asm/cdmm.h
--- linux-libre-4.3-gnu/arch/mips/include/asm/cdmm.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/mips/include/asm/cdmm.h	2016-01-22 23:59:37.000000000 -0500
@@ -84,6 +84,17 @@ void mips_cdmm_driver_unregister(struct
 	module_driver(__mips_cdmm_driver, mips_cdmm_driver_register, \
 			mips_cdmm_driver_unregister)
 
+/*
+ * builtin_mips_cdmm_driver() - Helper macro for drivers that don't do anything
+ * special in init and have no exit. This eliminates some boilerplate. Each
+ * driver may only use this macro once, and calling it replaces device_initcall
+ * (or in some cases, the legacy __initcall). This is meant to be a direct
+ * parallel of module_mips_cdmm_driver() above but without the __exit stuff that
+ * is not used for builtin cases.
+ */
+#define builtin_mips_cdmm_driver(__mips_cdmm_driver) \
+	builtin_driver(__mips_cdmm_driver, mips_cdmm_driver_register)
+
 /* drivers/tty/mips_ejtag_fdc.c */
 
 #ifdef CONFIG_MIPS_EJTAG_FDC_EARLYCON
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/mips/kvm/emulate.c linux-libre-4.3.4-gnu/arch/mips/kvm/emulate.c
--- linux-libre-4.3-gnu/arch/mips/kvm/emulate.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/mips/kvm/emulate.c	2016-01-22 23:59:37.000000000 -0500
@@ -1581,7 +1581,7 @@ enum emulation_result kvm_mips_emulate_c
 
 	base = (inst >> 21) & 0x1f;
 	op_inst = (inst >> 16) & 0x1f;
-	offset = inst & 0xffff;
+	offset = (int16_t)inst;
 	cache = (inst >> 16) & 0x3;
 	op = (inst >> 18) & 0x7;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/mips/kvm/locore.S linux-libre-4.3.4-gnu/arch/mips/kvm/locore.S
--- linux-libre-4.3-gnu/arch/mips/kvm/locore.S	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/mips/kvm/locore.S	2016-01-22 23:59:37.000000000 -0500
@@ -165,9 +165,11 @@ FEXPORT(__kvm_mips_vcpu_run)
 
 FEXPORT(__kvm_mips_load_asid)
 	/* Set the ASID for the Guest Kernel */
-	INT_SLL	t0, t0, 1	/* with kseg0 @ 0x40000000, kernel */
-			        /* addresses shift to 0x80000000 */
-	bltz	t0, 1f		/* If kernel */
+	PTR_L	t0, VCPU_COP0(k1)
+	LONG_L	t0, COP0_STATUS(t0)
+	andi	t0, KSU_USER | ST0_ERL | ST0_EXL
+	xori	t0, KSU_USER
+	bnez	t0, 1f		/* If kernel */
 	 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
 	INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID    /* else user */
 1:
@@ -482,9 +484,11 @@ __kvm_mips_return_to_guest:
 	mtc0	t0, CP0_EPC
 
 	/* Set the ASID for the Guest Kernel */
-	INT_SLL	t0, t0, 1	/* with kseg0 @ 0x40000000, kernel */
-				/* addresses shift to 0x80000000 */
-	bltz	t0, 1f		/* If kernel */
+	PTR_L	t0, VCPU_COP0(k1)
+	LONG_L	t0, COP0_STATUS(t0)
+	andi	t0, KSU_USER | ST0_ERL | ST0_EXL
+	xori	t0, KSU_USER
+	bnez	t0, 1f		/* If kernel */
 	 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
 	INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID    /* else user */
 1:
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/mips/kvm/mips.c linux-libre-4.3.4-gnu/arch/mips/kvm/mips.c
--- linux-libre-4.3-gnu/arch/mips/kvm/mips.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/mips/kvm/mips.c	2016-01-22 23:59:37.000000000 -0500
@@ -279,7 +279,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 
 	if (!gebase) {
 		err = -ENOMEM;
-		goto out_free_cpu;
+		goto out_uninit_cpu;
 	}
 	kvm_debug("Allocated %d bytes for KVM Exception Handlers @ %p\n",
 		  ALIGN(size, PAGE_SIZE), gebase);
@@ -343,6 +343,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 out_free_gebase:
 	kfree(gebase);
 
+out_uninit_cpu:
+	kvm_vcpu_uninit(vcpu);
+
 out_free_cpu:
 	kfree(vcpu);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/mips/lantiq/clk.c linux-libre-4.3.4-gnu/arch/mips/lantiq/clk.c
--- linux-libre-4.3-gnu/arch/mips/lantiq/clk.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/mips/lantiq/clk.c	2016-01-22 23:59:37.000000000 -0500
@@ -99,6 +99,23 @@ int clk_set_rate(struct clk *clk, unsign
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (unlikely(!clk_good(clk)))
+		return 0;
+	if (clk->rates && *clk->rates) {
+		unsigned long *r = clk->rates;
+
+		while (*r && (*r != rate))
+			r++;
+		if (!*r) {
+			return clk->rate;
+		}
+	}
+	return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
 int clk_enable(struct clk *clk)
 {
 	if (unlikely(!clk_good(clk)))
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/s390/kernel/ptrace.c linux-libre-4.3.4-gnu/arch/s390/kernel/ptrace.c
--- linux-libre-4.3-gnu/arch/s390/kernel/ptrace.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/s390/kernel/ptrace.c	2016-01-22 23:59:37.000000000 -0500
@@ -244,7 +244,7 @@ static unsigned long __peek_user(struct
 			       ((addr_t) child->thread.fpu.vxrs + 2*offset);
 		else
 			tmp = *(addr_t *)
-			       ((addr_t) &child->thread.fpu.fprs + offset);
+			       ((addr_t) child->thread.fpu.fprs + offset);
 
 	} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
 		/*
@@ -388,7 +388,7 @@ static int __poke_user(struct task_struc
 				child->thread.fpu.vxrs + 2*offset) = data;
 		else
 			*(addr_t *)((addr_t)
-				&child->thread.fpu.fprs + offset) = data;
+				child->thread.fpu.fprs + offset) = data;
 
 	} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
 		/*
@@ -622,7 +622,7 @@ static u32 __peek_user_compat(struct tas
 			       ((addr_t) child->thread.fpu.vxrs + 2*offset);
 		else
 			tmp = *(__u32 *)
-			       ((addr_t) &child->thread.fpu.fprs + offset);
+			       ((addr_t) child->thread.fpu.fprs + offset);
 
 	} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
 		/*
@@ -747,7 +747,7 @@ static int __poke_user_compat(struct tas
 				child->thread.fpu.vxrs + 2*offset) = tmp;
 		else
 			*(__u32 *)((addr_t)
-				&child->thread.fpu.fprs + offset) = tmp;
+				child->thread.fpu.fprs + offset) = tmp;
 
 	} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
 		/*
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/s390/kvm/interrupt.c linux-libre-4.3.4-gnu/arch/s390/kvm/interrupt.c
--- linux-libre-4.3-gnu/arch/s390/kvm/interrupt.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/s390/kvm/interrupt.c	2016-01-22 23:59:37.000000000 -0500
@@ -1057,8 +1057,7 @@ static int __inject_extcall(struct kvm_v
 				   src_id, 0);
 
 	/* sending vcpu invalid */
-	if (src_id >= KVM_MAX_VCPUS ||
-	    kvm_get_vcpu(vcpu->kvm, src_id) == NULL)
+	if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL)
 		return -EINVAL;
 
 	if (sclp.has_sigpif)
@@ -1137,6 +1136,10 @@ static int __inject_sigp_emergency(struc
 	trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY,
 				   irq->u.emerg.code, 0);
 
+	/* sending vcpu invalid */
+	if (kvm_get_vcpu_by_id(vcpu->kvm, irq->u.emerg.code) == NULL)
+		return -EINVAL;
+
 	set_bit(irq->u.emerg.code, li->sigp_emerg_pending);
 	set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs);
 	atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/s390/kvm/kvm-s390.c linux-libre-4.3.4-gnu/arch/s390/kvm/kvm-s390.c
--- linux-libre-4.3-gnu/arch/s390/kvm/kvm-s390.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/s390/kvm/kvm-s390.c	2016-01-22 23:59:37.000000000 -0500
@@ -342,12 +342,16 @@ static int kvm_vm_ioctl_enable_cap(struc
 		r = 0;
 		break;
 	case KVM_CAP_S390_VECTOR_REGISTERS:
-		if (MACHINE_HAS_VX) {
+		mutex_lock(&kvm->lock);
+		if (atomic_read(&kvm->online_vcpus)) {
+			r = -EBUSY;
+		} else if (MACHINE_HAS_VX) {
 			set_kvm_facility(kvm->arch.model.fac->mask, 129);
 			set_kvm_facility(kvm->arch.model.fac->list, 129);
 			r = 0;
 		} else
 			r = -EINVAL;
+		mutex_unlock(&kvm->lock);
 		VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s",
 			 r ? "(not available)" : "(success)");
 		break;
@@ -1120,7 +1124,9 @@ int kvm_arch_init_vm(struct kvm *kvm, un
 	if (!kvm->arch.sca)
 		goto out_err;
 	spin_lock(&kvm_lock);
-	sca_offset = (sca_offset + 16) & 0x7f0;
+	sca_offset += 16;
+	if (sca_offset + sizeof(struct sca_block) > PAGE_SIZE)
+		sca_offset = 0;
 	kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset);
 	spin_unlock(&kvm_lock);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/s390/kvm/sigp.c linux-libre-4.3.4-gnu/arch/s390/kvm/sigp.c
--- linux-libre-4.3-gnu/arch/s390/kvm/sigp.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/s390/kvm/sigp.c	2016-01-22 23:59:37.000000000 -0500
@@ -291,12 +291,8 @@ static int handle_sigp_dst(struct kvm_vc
 			   u16 cpu_addr, u32 parameter, u64 *status_reg)
 {
 	int rc;
-	struct kvm_vcpu *dst_vcpu;
-
-	if (cpu_addr >= KVM_MAX_VCPUS)
-		return SIGP_CC_NOT_OPERATIONAL;
+	struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
 
-	dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
 	if (!dst_vcpu)
 		return SIGP_CC_NOT_OPERATIONAL;
 
@@ -478,7 +474,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_
 	trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
 
 	if (order_code == SIGP_EXTERNAL_CALL) {
-		dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
+		dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
 		BUG_ON(dest_vcpu == NULL);
 
 		kvm_s390_vcpu_wakeup(dest_vcpu);
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/s390/pci/pci_insn.c linux-libre-4.3.4-gnu/arch/s390/pci/pci_insn.c
--- linux-libre-4.3-gnu/arch/s390/pci/pci_insn.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/s390/pci/pci_insn.c	2016-01-22 23:59:37.000000000 -0500
@@ -16,11 +16,11 @@
 static inline void zpci_err_insn(u8 cc, u8 status, u64 req, u64 offset)
 {
 	struct {
-		u8 cc;
-		u8 status;
 		u64 req;
 		u64 offset;
-	} data = {cc, status, req, offset};
+		u8 cc;
+		u8 status;
+	} __packed data = {req, offset, cc, status};
 
 	zpci_err_hex(&data, sizeof(data));
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/include/asm/i8259.h linux-libre-4.3.4-gnu/arch/x86/include/asm/i8259.h
--- linux-libre-4.3-gnu/arch/x86/include/asm/i8259.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/include/asm/i8259.h	2016-01-22 23:59:37.000000000 -0500
@@ -60,6 +60,7 @@ struct legacy_pic {
 	void (*mask_all)(void);
 	void (*restore_mask)(void);
 	void (*init)(int auto_eoi);
+	int (*probe)(void);
 	int (*irq_pending)(unsigned int irq);
 	void (*make_irq)(unsigned int irq);
 };
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/include/asm/kvm_emulate.h linux-libre-4.3.4-gnu/arch/x86/include/asm/kvm_emulate.h
--- linux-libre-4.3-gnu/arch/x86/include/asm/kvm_emulate.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/include/asm/kvm_emulate.h	2016-01-22 23:59:37.000000000 -0500
@@ -112,6 +112,16 @@ struct x86_emulate_ops {
 			struct x86_exception *fault);
 
 	/*
+	 * read_phys: Read bytes of standard (non-emulated/special) memory.
+	 *            Used for descriptor reading.
+	 *  @addr:  [IN ] Physical address from which to read.
+	 *  @val:   [OUT] Value read from memory.
+	 *  @bytes: [IN ] Number of bytes to read from memory.
+	 */
+	int (*read_phys)(struct x86_emulate_ctxt *ctxt, unsigned long addr,
+			void *val, unsigned int bytes);
+
+	/*
 	 * write_std: Write bytes of standard (non-emulated/special) memory.
 	 *            Used for descriptor writing.
 	 *  @addr:  [IN ] Linear address to which to write.
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/include/uapi/asm/svm.h linux-libre-4.3.4-gnu/arch/x86/include/uapi/asm/svm.h
--- linux-libre-4.3-gnu/arch/x86/include/uapi/asm/svm.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/include/uapi/asm/svm.h	2016-01-22 23:59:37.000000000 -0500
@@ -100,6 +100,7 @@
 	{ SVM_EXIT_EXCP_BASE + UD_VECTOR,       "UD excp" }, \
 	{ SVM_EXIT_EXCP_BASE + PF_VECTOR,       "PF excp" }, \
 	{ SVM_EXIT_EXCP_BASE + NM_VECTOR,       "NM excp" }, \
+	{ SVM_EXIT_EXCP_BASE + AC_VECTOR,       "AC excp" }, \
 	{ SVM_EXIT_EXCP_BASE + MC_VECTOR,       "MC excp" }, \
 	{ SVM_EXIT_INTR,        "interrupt" }, \
 	{ SVM_EXIT_NMI,         "nmi" }, \
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/apic/vector.c linux-libre-4.3.4-gnu/arch/x86/kernel/apic/vector.c
--- linux-libre-4.3-gnu/arch/x86/kernel/apic/vector.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/apic/vector.c	2016-01-22 23:59:37.000000000 -0500
@@ -361,7 +361,11 @@ int __init arch_probe_nr_irqs(void)
 	if (nr < nr_irqs)
 		nr_irqs = nr;
 
-	return nr_legacy_irqs();
+	/*
+	 * We don't know if PIC is present at this point so we need to do
+	 * probe() to get the right number of legacy IRQs.
+	 */
+	return legacy_pic->probe();
 }
 
 #ifdef	CONFIG_X86_IO_APIC
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/cpu/common.c linux-libre-4.3.4-gnu/arch/x86/kernel/cpu/common.c
--- linux-libre-4.3-gnu/arch/x86/kernel/cpu/common.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/cpu/common.c	2016-01-22 23:59:37.000000000 -0500
@@ -273,10 +273,9 @@ __setup("nosmap", setup_disable_smap);
 
 static __always_inline void setup_smap(struct cpuinfo_x86 *c)
 {
-	unsigned long eflags;
+	unsigned long eflags = native_save_fl();
 
 	/* This should have been cleared long ago */
-	raw_local_save_flags(eflags);
 	BUG_ON(eflags & X86_EFLAGS_AC);
 
 	if (cpu_has(c, X86_FEATURE_SMAP)) {
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/fpu/signal.c linux-libre-4.3.4-gnu/arch/x86/kernel/fpu/signal.c
--- linux-libre-4.3-gnu/arch/x86/kernel/fpu/signal.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/fpu/signal.c	2016-01-22 23:59:37.000000000 -0500
@@ -385,20 +385,19 @@ fpu__alloc_mathframe(unsigned long sp, i
  */
 void fpu__init_prepare_fx_sw_frame(void)
 {
-	int fsave_header_size = sizeof(struct fregs_state);
 	int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
 
-	if (config_enabled(CONFIG_X86_32))
-		size += fsave_header_size;
-
 	fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
 	fx_sw_reserved.extended_size = size;
 	fx_sw_reserved.xfeatures = xfeatures_mask;
 	fx_sw_reserved.xstate_size = xstate_size;
 
-	if (config_enabled(CONFIG_IA32_EMULATION)) {
+	if (config_enabled(CONFIG_IA32_EMULATION) ||
+	    config_enabled(CONFIG_X86_32)) {
+		int fsave_header_size = sizeof(struct fregs_state);
+
 		fx_sw_reserved_ia32 = fx_sw_reserved;
-		fx_sw_reserved_ia32.extended_size += fsave_header_size;
+		fx_sw_reserved_ia32.extended_size = size + fsave_header_size;
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/fpu/xstate.c linux-libre-4.3.4-gnu/arch/x86/kernel/fpu/xstate.c
--- linux-libre-4.3-gnu/arch/x86/kernel/fpu/xstate.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/fpu/xstate.c	2016-01-22 23:59:37.000000000 -0500
@@ -402,7 +402,6 @@ void *get_xsave_addr(struct xregs_state
 	if (!boot_cpu_has(X86_FEATURE_XSAVE))
 		return NULL;
 
-	xsave = &current->thread.fpu.state.xsave;
 	/*
 	 * We should not ever be requesting features that we
 	 * have not enabled.  Remember that pcntxt_mask is
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/head_64.S linux-libre-4.3.4-gnu/arch/x86/kernel/head_64.S
--- linux-libre-4.3-gnu/arch/x86/kernel/head_64.S	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/head_64.S	2016-01-22 23:59:37.000000000 -0500
@@ -65,6 +65,9 @@ startup_64:
 	 * tables and then reload them.
 	 */
 
+	/* Sanitize CPU configuration */
+	call verify_cpu
+
 	/*
 	 * Compute the delta between the address I am compiled to run at and the
 	 * address I am actually running at.
@@ -174,6 +177,9 @@ ENTRY(secondary_startup_64)
 	 * after the boot processor executes this code.
 	 */
 
+	/* Sanitize CPU configuration */
+	call verify_cpu
+
 	movq	$(init_level4_pgt - __START_KERNEL_map), %rax
 1:
 
@@ -288,6 +294,8 @@ ENTRY(secondary_startup_64)
 	pushq	%rax		# target address in negative space
 	lretq
 
+#include "verify_cpu.S"
+
 #ifdef CONFIG_HOTPLUG_CPU
 /*
  * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/i8259.c linux-libre-4.3.4-gnu/arch/x86/kernel/i8259.c
--- linux-libre-4.3-gnu/arch/x86/kernel/i8259.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/i8259.c	2016-01-22 23:59:37.000000000 -0500
@@ -295,16 +295,11 @@ static void unmask_8259A(void)
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-static void init_8259A(int auto_eoi)
+static int probe_8259A(void)
 {
 	unsigned long flags;
 	unsigned char probe_val = ~(1 << PIC_CASCADE_IR);
 	unsigned char new_val;
-
-	i8259A_auto_eoi = auto_eoi;
-
-	raw_spin_lock_irqsave(&i8259A_lock, flags);
-
 	/*
 	 * Check to see if we have a PIC.
 	 * Mask all except the cascade and read
@@ -312,16 +307,28 @@ static void init_8259A(int auto_eoi)
 	 * have a PIC, we will read 0xff as opposed to the
 	 * value we wrote.
 	 */
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
+
 	outb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-2 */
 	outb(probe_val, PIC_MASTER_IMR);
 	new_val = inb(PIC_MASTER_IMR);
 	if (new_val != probe_val) {
 		printk(KERN_INFO "Using NULL legacy PIC\n");
 		legacy_pic = &null_legacy_pic;
-		raw_spin_unlock_irqrestore(&i8259A_lock, flags);
-		return;
 	}
 
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+	return nr_legacy_irqs();
+}
+
+static void init_8259A(int auto_eoi)
+{
+	unsigned long flags;
+
+	i8259A_auto_eoi = auto_eoi;
+
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
+
 	outb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
 
 	/*
@@ -379,6 +386,10 @@ static int legacy_pic_irq_pending_noop(u
 {
 	return 0;
 }
+static int legacy_pic_probe(void)
+{
+	return 0;
+}
 
 struct legacy_pic null_legacy_pic = {
 	.nr_legacy_irqs = 0,
@@ -388,6 +399,7 @@ struct legacy_pic null_legacy_pic = {
 	.mask_all = legacy_pic_noop,
 	.restore_mask = legacy_pic_noop,
 	.init = legacy_pic_int_noop,
+	.probe = legacy_pic_probe,
 	.irq_pending = legacy_pic_irq_pending_noop,
 	.make_irq = legacy_pic_uint_noop,
 };
@@ -400,6 +412,7 @@ struct legacy_pic default_legacy_pic = {
 	.mask_all = mask_8259A,
 	.restore_mask = unmask_8259A,
 	.init = init_8259A,
+	.probe = probe_8259A,
 	.irq_pending = i8259A_irq_pending,
 	.make_irq = make_8259A_irq,
 };
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/setup.c linux-libre-4.3.4-gnu/arch/x86/kernel/setup.c
--- linux-libre-4.3-gnu/arch/x86/kernel/setup.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/setup.c	2016-01-22 23:59:37.000000000 -0500
@@ -1180,7 +1180,7 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	clone_pgd_range(initial_page_table,
 			swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
-			KERNEL_PGD_PTRS);
+			min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
 #endif
 
 	tboot_probe();
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kernel/verify_cpu.S linux-libre-4.3.4-gnu/arch/x86/kernel/verify_cpu.S
--- linux-libre-4.3-gnu/arch/x86/kernel/verify_cpu.S	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kernel/verify_cpu.S	2016-01-22 23:59:37.000000000 -0500
@@ -34,10 +34,11 @@
 #include <asm/msr-index.h>
 
 verify_cpu:
-	pushfl				# Save caller passed flags
-	pushl	$0			# Kill any dangerous flags
-	popfl
+	pushf				# Save caller passed flags
+	push	$0			# Kill any dangerous flags
+	popf
 
+#ifndef __x86_64__
 	pushfl				# standard way to check for cpuid
 	popl	%eax
 	movl	%eax,%ebx
@@ -48,6 +49,7 @@ verify_cpu:
 	popl	%eax
 	cmpl	%eax,%ebx
 	jz	verify_cpu_no_longmode	# cpu has no cpuid
+#endif
 
 	movl	$0x0,%eax		# See if cpuid 1 is implemented
 	cpuid
@@ -130,10 +132,10 @@ verify_cpu_sse_test:
 	jmp	verify_cpu_sse_test	# try again
 
 verify_cpu_no_longmode:
-	popfl				# Restore caller passed flags
+	popf				# Restore caller passed flags
 	movl $1,%eax
 	ret
 verify_cpu_sse_ok:
-	popfl				# Restore caller passed flags
+	popf				# Restore caller passed flags
 	xorl %eax, %eax
 	ret
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kvm/emulate.c linux-libre-4.3.4-gnu/arch/x86/kvm/emulate.c
--- linux-libre-4.3-gnu/arch/x86/kvm/emulate.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kvm/emulate.c	2016-01-22 23:59:37.000000000 -0500
@@ -2272,8 +2272,8 @@ static int emulator_has_longmode(struct
 #define GET_SMSTATE(type, smbase, offset)				  \
 	({								  \
 	 type __val;							  \
-	 int r = ctxt->ops->read_std(ctxt, smbase + offset, &__val,       \
-				     sizeof(__val), NULL);		  \
+	 int r = ctxt->ops->read_phys(ctxt, smbase + offset, &__val,      \
+				      sizeof(__val));			  \
 	 if (r != X86EMUL_CONTINUE)					  \
 		 return X86EMUL_UNHANDLEABLE;				  \
 	 __val;								  \
@@ -2484,17 +2484,36 @@ static int em_rsm(struct x86_emulate_ctx
 
 	/*
 	 * Get back to real mode, to prepare a safe state in which to load
-	 * CR0/CR3/CR4/EFER.  Also this will ensure that addresses passed
-	 * to read_std/write_std are not virtual.
-	 *
-	 * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
+	 * CR0/CR3/CR4/EFER.  It's all a bit more complicated if the vCPU
+	 * supports long mode.
 	 */
+	cr4 = ctxt->ops->get_cr(ctxt, 4);
+	if (emulator_has_longmode(ctxt)) {
+		struct desc_struct cs_desc;
+
+		/* Zero CR4.PCIDE before CR0.PG.  */
+		if (cr4 & X86_CR4_PCIDE) {
+			ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
+			cr4 &= ~X86_CR4_PCIDE;
+		}
+
+		/* A 32-bit code segment is required to clear EFER.LMA.  */
+		memset(&cs_desc, 0, sizeof(cs_desc));
+		cs_desc.type = 0xb;
+		cs_desc.s = cs_desc.g = cs_desc.p = 1;
+		ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
+	}
+
+	/* For the 64-bit case, this will clear EFER.LMA.  */
 	cr0 = ctxt->ops->get_cr(ctxt, 0);
 	if (cr0 & X86_CR0_PE)
 		ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
-	cr4 = ctxt->ops->get_cr(ctxt, 4);
+
+	/* Now clear CR4.PAE (which must be done before clearing EFER.LME).  */
 	if (cr4 & X86_CR4_PAE)
 		ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
+
+	/* And finally go back to 32-bit mode.  */
 	efer = 0;
 	ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
 
@@ -4455,7 +4474,7 @@ static const struct opcode twobyte_table
 	F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
 	/* 0xA8 - 0xAF */
 	I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
-	II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
+	II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
 	F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
 	F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
 	F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kvm/lapic.c linux-libre-4.3.4-gnu/arch/x86/kvm/lapic.c
--- linux-libre-4.3-gnu/arch/x86/kvm/lapic.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kvm/lapic.c	2016-01-22 23:59:37.000000000 -0500
@@ -348,6 +348,8 @@ void kvm_apic_update_irr(struct kvm_vcpu
 	struct kvm_lapic *apic = vcpu->arch.apic;
 
 	__kvm_apic_update_irr(pir, apic->regs);
+
+	kvm_make_request(KVM_REQ_EVENT, vcpu);
 }
 EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kvm/svm.c linux-libre-4.3.4-gnu/arch/x86/kvm/svm.c
--- linux-libre-4.3-gnu/arch/x86/kvm/svm.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kvm/svm.c	2016-01-22 23:59:37.000000000 -0500
@@ -1086,7 +1086,7 @@ static u64 svm_compute_tsc_offset(struct
 	return target_tsc - tsc;
 }
 
-static void init_vmcb(struct vcpu_svm *svm, bool init_event)
+static void init_vmcb(struct vcpu_svm *svm)
 {
 	struct vmcb_control_area *control = &svm->vmcb->control;
 	struct vmcb_save_area *save = &svm->vmcb->save;
@@ -1107,6 +1107,7 @@ static void init_vmcb(struct vcpu_svm *s
 	set_exception_intercept(svm, PF_VECTOR);
 	set_exception_intercept(svm, UD_VECTOR);
 	set_exception_intercept(svm, MC_VECTOR);
+	set_exception_intercept(svm, AC_VECTOR);
 
 	set_intercept(svm, INTERCEPT_INTR);
 	set_intercept(svm, INTERCEPT_NMI);
@@ -1157,8 +1158,7 @@ static void init_vmcb(struct vcpu_svm *s
 	init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
 	init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
 
-	if (!init_event)
-		svm_set_efer(&svm->vcpu, 0);
+	svm_set_efer(&svm->vcpu, 0);
 	save->dr6 = 0xffff0ff0;
 	kvm_set_rflags(&svm->vcpu, 2);
 	save->rip = 0x0000fff0;
@@ -1212,7 +1212,7 @@ static void svm_vcpu_reset(struct kvm_vc
 		if (kvm_vcpu_is_reset_bsp(&svm->vcpu))
 			svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
 	}
-	init_vmcb(svm, init_event);
+	init_vmcb(svm);
 
 	kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy);
 	kvm_register_write(vcpu, VCPU_REGS_RDX, eax);
@@ -1268,7 +1268,7 @@ static struct kvm_vcpu *svm_create_vcpu(
 	clear_page(svm->vmcb);
 	svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
 	svm->asid_generation = 0;
-	init_vmcb(svm, false);
+	init_vmcb(svm);
 
 	svm_init_osvw(&svm->vcpu);
 
@@ -1796,6 +1796,12 @@ static int ud_interception(struct vcpu_s
 	return 1;
 }
 
+static int ac_interception(struct vcpu_svm *svm)
+{
+	kvm_queue_exception_e(&svm->vcpu, AC_VECTOR, 0);
+	return 1;
+}
+
 static void svm_fpu_activate(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -1890,7 +1896,7 @@ static int shutdown_interception(struct
 	 * so reinitialize it.
 	 */
 	clear_page(svm->vmcb);
-	init_vmcb(svm, false);
+	init_vmcb(svm);
 
 	kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
 	return 0;
@@ -3371,6 +3377,7 @@ static int (*const svm_exit_handlers[])(
 	[SVM_EXIT_EXCP_BASE + PF_VECTOR]	= pf_interception,
 	[SVM_EXIT_EXCP_BASE + NM_VECTOR]	= nm_interception,
 	[SVM_EXIT_EXCP_BASE + MC_VECTOR]	= mc_interception,
+	[SVM_EXIT_EXCP_BASE + AC_VECTOR]	= ac_interception,
 	[SVM_EXIT_INTR]				= intr_interception,
 	[SVM_EXIT_NMI]				= nmi_interception,
 	[SVM_EXIT_SMI]				= nop_on_interception,
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kvm/vmx.c linux-libre-4.3.4-gnu/arch/x86/kvm/vmx.c
--- linux-libre-4.3-gnu/arch/x86/kvm/vmx.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kvm/vmx.c	2016-01-22 23:59:37.000000000 -0500
@@ -1567,7 +1567,7 @@ static void update_exception_bitmap(stru
 	u32 eb;
 
 	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
-	     (1u << NM_VECTOR) | (1u << DB_VECTOR);
+	     (1u << NM_VECTOR) | (1u << DB_VECTOR) | (1u << AC_VECTOR);
 	if ((vcpu->guest_debug &
 	     (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
 	    (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
@@ -4771,8 +4771,7 @@ static void vmx_vcpu_reset(struct kvm_vc
 	vmx_set_cr0(vcpu, cr0); /* enter rmode */
 	vmx->vcpu.arch.cr0 = cr0;
 	vmx_set_cr4(vcpu, 0);
-	if (!init_event)
-		vmx_set_efer(vcpu, 0);
+	vmx_set_efer(vcpu, 0);
 	vmx_fpu_activate(vcpu);
 	update_exception_bitmap(vcpu);
 
@@ -5104,6 +5103,9 @@ static int handle_exception(struct kvm_v
 		return handle_rmode_exception(vcpu, ex_no, error_code);
 
 	switch (ex_no) {
+	case AC_VECTOR:
+		kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
+		return 1;
 	case DB_VECTOR:
 		dr6 = vmcs_readl(EXIT_QUALIFICATION);
 		if (!(vcpu->guest_debug &
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/kvm/x86.c linux-libre-4.3.4-gnu/arch/x86/kvm/x86.c
--- linux-libre-4.3-gnu/arch/x86/kvm/x86.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/kvm/x86.c	2016-01-22 23:59:37.000000000 -0500
@@ -622,7 +622,9 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, u
 	if ((cr0 ^ old_cr0) & update_bits)
 		kvm_mmu_reset_context(vcpu);
 
-	if ((cr0 ^ old_cr0) & X86_CR0_CD)
+	if (((cr0 ^ old_cr0) & X86_CR0_CD) &&
+	    kvm_arch_has_noncoherent_dma(vcpu->kvm) &&
+	    !kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
 		kvm_zap_gfn_range(vcpu->kvm, 0, ~0ULL);
 
 	return 0;
@@ -4059,6 +4061,15 @@ static int kvm_read_guest_virt_system(st
 	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception);
 }
 
+static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt,
+		unsigned long addr, void *val, unsigned int bytes)
+{
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+	int r = kvm_vcpu_read_guest(vcpu, addr, val, bytes);
+
+	return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE;
+}
+
 int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
 				       gva_t addr, void *val,
 				       unsigned int bytes,
@@ -4794,6 +4805,7 @@ static const struct x86_emulate_ops emul
 	.write_gpr           = emulator_write_gpr,
 	.read_std            = kvm_read_guest_virt_system,
 	.write_std           = kvm_write_guest_virt_system,
+	.read_phys           = kvm_read_guest_phys_system,
 	.fetch               = kvm_fetch_guest_virt,
 	.read_emulated       = emulator_read_emulated,
 	.write_emulated      = emulator_write_emulated,
diff -druNp --no-dereference linux-libre-4.3-gnu/arch/x86/mm/mpx.c linux-libre-4.3.4-gnu/arch/x86/mm/mpx.c
--- linux-libre-4.3-gnu/arch/x86/mm/mpx.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/arch/x86/mm/mpx.c	2016-01-22 23:59:37.000000000 -0500
@@ -585,6 +585,29 @@ static unsigned long mpx_bd_entry_to_bt_
 }
 
 /*
+ * We only want to do a 4-byte get_user() on 32-bit.  Otherwise,
+ * we might run off the end of the bounds table if we are on
+ * a 64-bit kernel and try to get 8 bytes.
+ */
+int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret,
+		long __user *bd_entry_ptr)
+{
+	u32 bd_entry_32;
+	int ret;
+
+	if (is_64bit_mm(mm))
+		return get_user(*bd_entry_ret, bd_entry_ptr);
+
+	/*
+	 * Note that get_user() uses the type of the *pointer* to
+	 * establish the size of the get, not the destination.
+	 */
+	ret = get_user(bd_entry_32, (u32 __user *)bd_entry_ptr);
+	*bd_entry_ret = bd_entry_32;
+	return ret;
+}
+
+/*
  * Get the base of bounds tables pointed by specific bounds
  * directory entry.
  */
@@ -604,7 +627,7 @@ static int get_bt_addr(struct mm_struct
 		int need_write = 0;
 
 		pagefault_disable();
-		ret = get_user(bd_entry, bd_entry_ptr);
+		ret = get_user_bd_entry(mm, &bd_entry, bd_entry_ptr);
 		pagefault_enable();
 		if (!ret)
 			break;
@@ -699,11 +722,23 @@ static unsigned long mpx_get_bt_entry_of
  */
 static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
 {
-	unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
-	if (is_64bit_mm(mm))
-		return virt_space / MPX_BD_NR_ENTRIES_64;
-	else
-		return virt_space / MPX_BD_NR_ENTRIES_32;
+	unsigned long long virt_space;
+	unsigned long long GB = (1ULL << 30);
+
+	/*
+	 * This covers 32-bit emulation as well as 32-bit kernels
+	 * running on 64-bit harware.
+	 */
+	if (!is_64bit_mm(mm))
+		return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;
+
+	/*
+	 * 'x86_virt_bits' returns what the hardware is capable
+	 * of, and returns the full >32-bit adddress space when
+	 * running 32-bit kernels on 64-bit hardware.
+	 */
+	virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
+	return virt_space / MPX_BD_NR_ENTRIES_64;
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.3-gnu/block/blk-merge.c linux-libre-4.3.4-gnu/block/blk-merge.c
--- linux-libre-4.3-gnu/block/blk-merge.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/block/blk-merge.c	2016-01-22 23:59:37.000000000 -0500
@@ -91,7 +91,7 @@ static struct bio *blk_bio_segment_split
 
 			seg_size += bv.bv_len;
 			bvprv = bv;
-			bvprvp = &bv;
+			bvprvp = &bvprv;
 			sectors += bv.bv_len >> 9;
 			continue;
 		}
@@ -101,7 +101,7 @@ new_segment:
 
 		nsegs++;
 		bvprv = bv;
-		bvprvp = &bv;
+		bvprvp = &bvprv;
 		seg_size = bv.bv_len;
 		sectors += bv.bv_len >> 9;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/certs/.gitignore linux-libre-4.3.4-gnu/certs/.gitignore
--- linux-libre-4.3-gnu/certs/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.3.4-gnu/certs/.gitignore	2016-01-22 23:59:37.000000000 -0500
@@ -0,0 +1,4 @@
+#
+# Generated files
+#
+x509_certificate_list
diff -druNp --no-dereference linux-libre-4.3-gnu/crypto/asymmetric_keys/x509_cert_parser.c linux-libre-4.3.4-gnu/crypto/asymmetric_keys/x509_cert_parser.c
--- linux-libre-4.3-gnu/crypto/asymmetric_keys/x509_cert_parser.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/crypto/asymmetric_keys/x509_cert_parser.c	2016-01-22 23:59:37.000000000 -0500
@@ -531,7 +531,11 @@ int x509_decode_time(time64_t *_t,  size
 	if (*p != 'Z')
 		goto unsupported_time;
 
-	mon_len = month_lengths[mon];
+	if (year < 1970 ||
+	    mon < 1 || mon > 12)
+		goto invalid_time;
+
+	mon_len = month_lengths[mon - 1];
 	if (mon == 2) {
 		if (year % 4 == 0) {
 			mon_len = 29;
@@ -543,14 +547,12 @@ int x509_decode_time(time64_t *_t,  size
 		}
 	}
 
-	if (year < 1970 ||
-	    mon < 1 || mon > 12 ||
-	    day < 1 || day > mon_len ||
-	    hour < 0 || hour > 23 ||
-	    min < 0 || min > 59 ||
-	    sec < 0 || sec > 59)
+	if (day < 1 || day > mon_len ||
+	    hour > 23 ||
+	    min > 59 ||
+	    sec > 59)
 		goto invalid_time;
-	
+
 	*_t = mktime64(year, mon, day, hour, min, sec);
 	return 0;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/Documentation/devicetree/bindings/usb/dwc3.txt linux-libre-4.3.4-gnu/Documentation/devicetree/bindings/usb/dwc3.txt
--- linux-libre-4.3-gnu/Documentation/devicetree/bindings/usb/dwc3.txt	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/Documentation/devicetree/bindings/usb/dwc3.txt	2016-01-22 23:59:37.000000000 -0500
@@ -35,6 +35,8 @@ Optional properties:
 			LTSSM during USB3 Compliance mode.
  - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy.
  - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy.
+ - snps,dis_enblslpm_quirk: when set clears the enblslpm in GUSB2PHYCFG,
+			disabling the suspend signal to the PHY.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
 			utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff -druNp --no-dereference linux-libre-4.3-gnu/Documentation/filesystems/proc.txt linux-libre-4.3.4-gnu/Documentation/filesystems/proc.txt
--- linux-libre-4.3-gnu/Documentation/filesystems/proc.txt	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/Documentation/filesystems/proc.txt	2016-01-22 23:59:37.000000000 -0500
@@ -140,7 +140,8 @@ Table 1-1: Process specific entries in /
  stat		Process status
  statm		Process memory status information
  status		Process status in human readable form
- wchan		If CONFIG_KALLSYMS is set, a pre-decoded wchan
+ wchan		Present with CONFIG_KALLSYMS=y: it shows the kernel function
+		symbol the task is blocked in - or "0" if not blocked.
  pagemap	Page table
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
  smaps		a extension based on maps, showing the memory consumption of
@@ -310,7 +311,7 @@ Table 1-4: Contents of the stat files (a
   blocked       bitmap of blocked signals
   sigign        bitmap of ignored signals
   sigcatch      bitmap of caught signals
-  wchan         address where process went to sleep
+  0		(place holder, used to be the wchan address, use /proc/PID/wchan instead)
   0             (place holder)
   0             (place holder)
   exit_signal   signal to send to parent thread on exit
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/acpi/osl.c linux-libre-4.3.4-gnu/drivers/acpi/osl.c
--- linux-libre-4.3-gnu/drivers/acpi/osl.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/acpi/osl.c	2016-01-22 23:59:37.000000000 -0500
@@ -81,6 +81,7 @@ static struct workqueue_struct *kacpid_w
 static struct workqueue_struct *kacpi_notify_wq;
 static struct workqueue_struct *kacpi_hotplug_wq;
 static bool acpi_os_initialized;
+unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
 
 /*
  * This list of permanent mappings is for memory that may be accessed from
@@ -856,17 +857,19 @@ acpi_os_install_interrupt_handler(u32 gs
 		acpi_irq_handler = NULL;
 		return AE_NOT_ACQUIRED;
 	}
+	acpi_sci_irq = irq;
 
 	return AE_OK;
 }
 
-acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
+acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
 {
-	if (irq != acpi_gbl_FADT.sci_interrupt)
+	if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid())
 		return AE_BAD_PARAMETER;
 
-	free_irq(irq, acpi_irq);
+	free_irq(acpi_sci_irq, acpi_irq);
 	acpi_irq_handler = NULL;
+	acpi_sci_irq = INVALID_ACPI_IRQ;
 
 	return AE_OK;
 }
@@ -1180,8 +1183,8 @@ void acpi_os_wait_events_complete(void)
 	 * Make sure the GPE handler or the fixed event handler is not used
 	 * on another CPU after removal.
 	 */
-	if (acpi_irq_handler)
-		synchronize_hardirq(acpi_gbl_FADT.sci_interrupt);
+	if (acpi_sci_irq_valid())
+		synchronize_hardirq(acpi_sci_irq);
 	flush_workqueue(kacpid_wq);
 	flush_workqueue(kacpi_notify_wq);
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/acpi/sleep.c linux-libre-4.3.4-gnu/drivers/acpi/sleep.c
--- linux-libre-4.3-gnu/drivers/acpi/sleep.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/acpi/sleep.c	2016-01-22 23:59:37.000000000 -0500
@@ -632,14 +632,16 @@ static int acpi_freeze_prepare(void)
 	acpi_enable_wakeup_devices(ACPI_STATE_S0);
 	acpi_enable_all_wakeup_gpes();
 	acpi_os_wait_events_complete();
-	enable_irq_wake(acpi_gbl_FADT.sci_interrupt);
+	if (acpi_sci_irq_valid())
+		enable_irq_wake(acpi_sci_irq);
 	return 0;
 }
 
 static void acpi_freeze_restore(void)
 {
 	acpi_disable_wakeup_devices(ACPI_STATE_S0);
-	disable_irq_wake(acpi_gbl_FADT.sci_interrupt);
+	if (acpi_sci_irq_valid())
+		disable_irq_wake(acpi_sci_irq);
 	acpi_enable_all_runtime_gpes();
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/block/rbd.c linux-libre-4.3.4-gnu/drivers/block/rbd.c
--- linux-libre-4.3-gnu/drivers/block/rbd.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/block/rbd.c	2016-01-22 23:59:37.000000000 -0500
@@ -3444,6 +3444,7 @@ static void rbd_queue_workfn(struct work
 		goto err_rq;
 	}
 	img_request->rq = rq;
+	snapc = NULL; /* img_request consumes a ref */
 
 	if (op_type == OBJ_OP_DISCARD)
 		result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/bluetooth/ath3k.c linux-libre-4.3.4-gnu/drivers/bluetooth/ath3k.c
--- linux-libre-4.3-gnu/drivers/bluetooth/ath3k.c	2015-11-01 23:38:27.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/bluetooth/ath3k.c	2016-01-23 08:21:09.000000000 -0500
@@ -93,6 +93,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x04CA, 0x300f) },
 	{ USB_DEVICE(0x04CA, 0x3010) },
 	{ USB_DEVICE(0x0930, 0x0219) },
+	{ USB_DEVICE(0x0930, 0x021c) },
 	{ USB_DEVICE(0x0930, 0x0220) },
 	{ USB_DEVICE(0x0930, 0x0227) },
 	{ USB_DEVICE(0x0b05, 0x17d0) },
@@ -104,6 +105,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x0CF3, 0x311F) },
 	{ USB_DEVICE(0x0cf3, 0x3121) },
 	{ USB_DEVICE(0x0CF3, 0x817a) },
+	{ USB_DEVICE(0x0CF3, 0x817b) },
 	{ USB_DEVICE(0x0cf3, 0xe003) },
 	{ USB_DEVICE(0x0CF3, 0xE004) },
 	{ USB_DEVICE(0x0CF3, 0xE005) },
@@ -153,6 +155,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
@@ -164,6 +167,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0CF3, 0x817b), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe006), .driver_info = BTUSB_ATH3012 },
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/bluetooth/btusb.c linux-libre-4.3.4-gnu/drivers/bluetooth/btusb.c
--- linux-libre-4.3-gnu/drivers/bluetooth/btusb.c	2015-11-01 23:38:42.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/bluetooth/btusb.c	2016-01-23 08:21:26.000000000 -0500
@@ -195,6 +195,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
@@ -206,6 +207,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x817b), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/char/tpm/tpm_crb.c linux-libre-4.3.4-gnu/drivers/char/tpm/tpm_crb.c
--- linux-libre-4.3-gnu/drivers/char/tpm/tpm_crb.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/char/tpm/tpm_crb.c	2016-01-22 23:59:37.000000000 -0500
@@ -34,12 +34,6 @@ enum crb_defaults {
 	CRB_ACPI_START_INDEX = 1,
 };
 
-enum crb_start_method {
-	CRB_SM_ACPI_START = 2,
-	CRB_SM_CRB = 7,
-	CRB_SM_CRB_WITH_ACPI_START = 8,
-};
-
 struct acpi_tpm2 {
 	struct acpi_table_header hdr;
 	u16 platform_class;
@@ -220,12 +214,6 @@ static int crb_acpi_add(struct acpi_devi
 	u64 pa;
 	int rc;
 
-	chip = tpmm_chip_alloc(dev, &tpm_crb);
-	if (IS_ERR(chip))
-		return PTR_ERR(chip);
-
-	chip->flags = TPM_CHIP_FLAG_TPM2;
-
 	status = acpi_get_table(ACPI_SIG_TPM2, 1,
 				(struct acpi_table_header **) &buf);
 	if (ACPI_FAILURE(status)) {
@@ -233,13 +221,15 @@ static int crb_acpi_add(struct acpi_devi
 		return -ENODEV;
 	}
 
-	/* At least some versions of AMI BIOS have a bug that TPM2 table has
-	 * zero address for the control area and therefore we must fail.
-	*/
-	if (!buf->control_area_pa) {
-		dev_err(dev, "TPM2 ACPI table has a zero address for the control area\n");
-		return -EINVAL;
-	}
+	/* Should the FIFO driver handle this? */
+	if (buf->start_method == TPM2_START_FIFO)
+		return -ENODEV;
+
+	chip = tpmm_chip_alloc(dev, &tpm_crb);
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+
+	chip->flags = TPM_CHIP_FLAG_TPM2;
 
 	if (buf->hdr.length < sizeof(struct acpi_tpm2)) {
 		dev_err(dev, "TPM2 ACPI table has wrong size");
@@ -259,11 +249,11 @@ static int crb_acpi_add(struct acpi_devi
 	 * report only ACPI start but in practice seems to require both
 	 * ACPI start and CRB start.
 	 */
-	if (sm == CRB_SM_CRB || sm == CRB_SM_CRB_WITH_ACPI_START ||
+	if (sm == TPM2_START_CRB || sm == TPM2_START_FIFO ||
 	    !strcmp(acpi_device_hid(device), "MSFT0101"))
 		priv->flags |= CRB_FL_CRB_START;
 
-	if (sm == CRB_SM_ACPI_START || sm == CRB_SM_CRB_WITH_ACPI_START)
+	if (sm == TPM2_START_ACPI || sm == TPM2_START_CRB_WITH_ACPI)
 		priv->flags |= CRB_FL_ACPI_START;
 
 	priv->cca = (struct crb_control_area __iomem *)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/char/tpm/tpm.h linux-libre-4.3.4-gnu/drivers/char/tpm/tpm.h
--- linux-libre-4.3-gnu/drivers/char/tpm/tpm.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/char/tpm/tpm.h	2016-01-22 23:59:37.000000000 -0500
@@ -115,6 +115,13 @@ enum tpm2_startup_types {
 	TPM2_SU_STATE	= 0x0001,
 };
 
+enum tpm2_start_method {
+	TPM2_START_ACPI = 2,
+	TPM2_START_FIFO = 6,
+	TPM2_START_CRB = 7,
+	TPM2_START_CRB_WITH_ACPI = 8,
+};
+
 struct tpm_chip;
 
 struct tpm_vendor_specific {
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/char/tpm/tpm_tis.c linux-libre-4.3.4-gnu/drivers/char/tpm/tpm_tis.c
--- linux-libre-4.3-gnu/drivers/char/tpm/tpm_tis.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/char/tpm/tpm_tis.c	2016-01-22 23:59:37.000000000 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005, 2006 IBM Corporation
- * Copyright (C) 2014 Intel Corporation
+ * Copyright (C) 2014, 2015 Intel Corporation
  *
  * Authors:
  * Leendert van Doorn <leendert@watson.ibm.com>
@@ -28,6 +28,7 @@
 #include <linux/wait.h>
 #include <linux/acpi.h>
 #include <linux/freezer.h>
+#include <acpi/actbl2.h>
 #include "tpm.h"
 
 enum tis_access {
@@ -65,6 +66,17 @@ enum tis_defaults {
 	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
 };
 
+struct tpm_info {
+	unsigned long start;
+	unsigned long len;
+	unsigned int irq;
+};
+
+static struct tpm_info tis_default_info = {
+	.start = TIS_MEM_BASE,
+	.len = TIS_MEM_LEN,
+	.irq = 0,
+};
 
 /* Some timeout values are needed before it is known whether the chip is
  * TPM 1.0 or TPM 2.0.
@@ -91,26 +103,54 @@ struct priv_data {
 };
 
 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
-static int is_itpm(struct pnp_dev *dev)
+static int has_hid(struct acpi_device *dev, const char *hid)
 {
-	struct acpi_device *acpi = pnp_acpi_device(dev);
 	struct acpi_hardware_id *id;
 
-	if (!acpi)
-		return 0;
-
-	list_for_each_entry(id, &acpi->pnp.ids, list) {
-		if (!strcmp("INTC0102", id->id))
+	list_for_each_entry(id, &dev->pnp.ids, list)
+		if (!strcmp(hid, id->id))
 			return 1;
-	}
 
 	return 0;
 }
+
+static inline int is_itpm(struct acpi_device *dev)
+{
+	return has_hid(dev, "INTC0102");
+}
+
+static inline int is_fifo(struct acpi_device *dev)
+{
+	struct acpi_table_tpm2 *tbl;
+	acpi_status st;
+
+	/* TPM 1.2 FIFO */
+	if (!has_hid(dev, "MSFT0101"))
+		return 1;
+
+	st = acpi_get_table(ACPI_SIG_TPM2, 1,
+			    (struct acpi_table_header **) &tbl);
+	if (ACPI_FAILURE(st)) {
+		dev_err(&dev->dev, "failed to get TPM2 ACPI table\n");
+		return 0;
+	}
+
+	if (le32_to_cpu(tbl->start_method) != TPM2_START_FIFO)
+		return 0;
+
+	/* TPM 2.0 FIFO */
+	return 1;
+}
 #else
-static inline int is_itpm(struct pnp_dev *dev)
+static inline int is_itpm(struct acpi_device *dev)
 {
 	return 0;
 }
+
+static inline int is_fifo(struct acpi_device *dev)
+{
+	return 1;
+}
 #endif
 
 /* Before we attempt to access the TPM we must see that the valid bit is set.
@@ -600,9 +640,8 @@ static void tpm_tis_remove(struct tpm_ch
 	release_locality(chip, chip->vendor.locality, 1);
 }
 
-static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
-			resource_size_t start, resource_size_t len,
-			unsigned int irq)
+static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
+			acpi_handle acpi_dev_handle)
 {
 	u32 vendor, intfcaps, intmask;
 	int rc, i, irq_s, irq_e, probe;
@@ -622,7 +661,7 @@ static int tpm_tis_init(struct device *d
 	chip->acpi_dev_handle = acpi_dev_handle;
 #endif
 
-	chip->vendor.iobase = devm_ioremap(dev, start, len);
+	chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len);
 	if (!chip->vendor.iobase)
 		return -EIO;
 
@@ -707,7 +746,7 @@ static int tpm_tis_init(struct device *d
 		  chip->vendor.iobase +
 		  TPM_INT_ENABLE(chip->vendor.locality));
 	if (interrupts)
-		chip->vendor.irq = irq;
+		chip->vendor.irq = tpm_info->irq;
 	if (interrupts && !chip->vendor.irq) {
 		irq_s =
 		    ioread8(chip->vendor.iobase +
@@ -890,27 +929,27 @@ static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm
 static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
 				      const struct pnp_device_id *pnp_id)
 {
-	resource_size_t start, len;
-	unsigned int irq = 0;
+	struct tpm_info tpm_info = tis_default_info;
 	acpi_handle acpi_dev_handle = NULL;
 
-	start = pnp_mem_start(pnp_dev, 0);
-	len = pnp_mem_len(pnp_dev, 0);
+	tpm_info.start = pnp_mem_start(pnp_dev, 0);
+	tpm_info.len = pnp_mem_len(pnp_dev, 0);
 
 	if (pnp_irq_valid(pnp_dev, 0))
-		irq = pnp_irq(pnp_dev, 0);
+		tpm_info.irq = pnp_irq(pnp_dev, 0);
 	else
 		interrupts = false;
 
-	if (is_itpm(pnp_dev))
-		itpm = true;
-
 #ifdef CONFIG_ACPI
-	if (pnp_acpi_device(pnp_dev))
+	if (pnp_acpi_device(pnp_dev)) {
+		if (is_itpm(pnp_acpi_device(pnp_dev)))
+			itpm = true;
+
 		acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle;
+	}
 #endif
 
-	return tpm_tis_init(&pnp_dev->dev, acpi_dev_handle, start, len, irq);
+	return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle);
 }
 
 static struct pnp_device_id tpm_pnp_tbl[] = {
@@ -930,6 +969,7 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
 static void tpm_tis_pnp_remove(struct pnp_dev *dev)
 {
 	struct tpm_chip *chip = pnp_get_drvdata(dev);
+
 	tpm_chip_unregister(chip);
 	tpm_tis_remove(chip);
 }
@@ -950,6 +990,79 @@ module_param_string(hid, tpm_pnp_tbl[TIS
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 #endif
 
+#ifdef CONFIG_ACPI
+static int tpm_check_resource(struct acpi_resource *ares, void *data)
+{
+	struct tpm_info *tpm_info = (struct tpm_info *) data;
+	struct resource res;
+
+	if (acpi_dev_resource_interrupt(ares, 0, &res)) {
+		tpm_info->irq = res.start;
+	} else if (acpi_dev_resource_memory(ares, &res)) {
+		tpm_info->start = res.start;
+		tpm_info->len = resource_size(&res);
+	}
+
+	return 1;
+}
+
+static int tpm_tis_acpi_init(struct acpi_device *acpi_dev)
+{
+	struct list_head resources;
+	struct tpm_info tpm_info = tis_default_info;
+	int ret;
+
+	if (!is_fifo(acpi_dev))
+		return -ENODEV;
+
+	INIT_LIST_HEAD(&resources);
+	ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource,
+				     &tpm_info);
+	if (ret < 0)
+		return ret;
+
+	acpi_dev_free_resource_list(&resources);
+
+	if (!tpm_info.irq)
+		interrupts = false;
+
+	if (is_itpm(acpi_dev))
+		itpm = true;
+
+	return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle);
+}
+
+static int tpm_tis_acpi_remove(struct acpi_device *dev)
+{
+	struct tpm_chip *chip = dev_get_drvdata(&dev->dev);
+
+	tpm_chip_unregister(chip);
+	tpm_tis_remove(chip);
+
+	return 0;
+}
+
+static struct acpi_device_id tpm_acpi_tbl[] = {
+	{"MSFT0101", 0},	/* TPM 2.0 */
+	/* Add new here */
+	{"", 0},		/* User Specified */
+	{"", 0}			/* Terminator */
+};
+MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl);
+
+static struct acpi_driver tis_acpi_driver = {
+	.name = "tpm_tis",
+	.ids = tpm_acpi_tbl,
+	.ops = {
+		.add = tpm_tis_acpi_init,
+		.remove = tpm_tis_acpi_remove,
+	},
+	.drv = {
+		.pm = &tpm_tis_pm,
+	},
+};
+#endif
+
 static struct platform_driver tis_drv = {
 	.driver = {
 		.name		= "tpm_tis",
@@ -966,9 +1079,25 @@ static int __init init_tis(void)
 {
 	int rc;
 #ifdef CONFIG_PNP
-	if (!force)
-		return pnp_register_driver(&tis_pnp_driver);
+	if (!force) {
+		rc = pnp_register_driver(&tis_pnp_driver);
+		if (rc)
+			return rc;
+	}
+#endif
+#ifdef CONFIG_ACPI
+	if (!force) {
+		rc = acpi_bus_register_driver(&tis_acpi_driver);
+		if (rc) {
+#ifdef CONFIG_PNP
+			pnp_unregister_driver(&tis_pnp_driver);
+#endif
+			return rc;
+		}
+	}
 #endif
+	if (!force)
+		return 0;
 
 	rc = platform_driver_register(&tis_drv);
 	if (rc < 0)
@@ -978,7 +1107,7 @@ static int __init init_tis(void)
 		rc = PTR_ERR(pdev);
 		goto err_dev;
 	}
-	rc = tpm_tis_init(&pdev->dev, NULL, TIS_MEM_BASE, TIS_MEM_LEN, 0);
+	rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL);
 	if (rc)
 		goto err_init;
 	return 0;
@@ -992,9 +1121,14 @@ err_dev:
 static void __exit cleanup_tis(void)
 {
 	struct tpm_chip *chip;
-#ifdef CONFIG_PNP
+#if defined(CONFIG_PNP) || defined(CONFIG_ACPI)
 	if (!force) {
+#ifdef CONFIG_ACPI
+		acpi_bus_unregister_driver(&tis_acpi_driver);
+#endif
+#ifdef CONFIG_PNP
 		pnp_unregister_driver(&tis_pnp_driver);
+#endif
 		return;
 	}
 #endif
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/clk/bcm/clk-iproc-pll.c linux-libre-4.3.4-gnu/drivers/clk/bcm/clk-iproc-pll.c
--- linux-libre-4.3-gnu/drivers/clk/bcm/clk-iproc-pll.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/clk/bcm/clk-iproc-pll.c	2016-01-22 23:59:37.000000000 -0500
@@ -345,8 +345,8 @@ static unsigned long iproc_pll_recalc_ra
 	struct iproc_pll *pll = clk->pll;
 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
 	u32 val;
-	u64 ndiv;
-	unsigned int ndiv_int, ndiv_frac, pdiv;
+	u64 ndiv, ndiv_int, ndiv_frac;
+	unsigned int pdiv;
 
 	if (parent_rate == 0)
 		return 0;
@@ -366,22 +366,19 @@ static unsigned long iproc_pll_recalc_ra
 	val = readl(pll->pll_base + ctrl->ndiv_int.offset);
 	ndiv_int = (val >> ctrl->ndiv_int.shift) &
 		bit_mask(ctrl->ndiv_int.width);
-	ndiv = (u64)ndiv_int << ctrl->ndiv_int.shift;
+	ndiv = ndiv_int << 20;
 
 	if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
 		val = readl(pll->pll_base + ctrl->ndiv_frac.offset);
 		ndiv_frac = (val >> ctrl->ndiv_frac.shift) &
 			bit_mask(ctrl->ndiv_frac.width);
-
-		if (ndiv_frac != 0)
-			ndiv = ((u64)ndiv_int << ctrl->ndiv_int.shift) |
-				ndiv_frac;
+		ndiv += ndiv_frac;
 	}
 
 	val = readl(pll->pll_base + ctrl->pdiv.offset);
 	pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
 
-	clk->rate = (ndiv * parent_rate) >> ctrl->ndiv_int.shift;
+	clk->rate = (ndiv * parent_rate) >> 20;
 
 	if (pdiv == 0)
 		clk->rate *= 2;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/clk/versatile/clk-icst.c linux-libre-4.3.4-gnu/drivers/clk/versatile/clk-icst.c
--- linux-libre-4.3-gnu/drivers/clk/versatile/clk-icst.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/clk/versatile/clk-icst.c	2016-01-22 23:59:37.000000000 -0500
@@ -157,8 +157,10 @@ struct clk *icst_clk_register(struct dev
 	icst->lockreg = base + desc->lock_offset;
 
 	clk = clk_register(dev, &icst->hw);
-	if (IS_ERR(clk))
+	if (IS_ERR(clk)) {
+		kfree(pclone);
 		kfree(icst);
+	}
 
 	return clk;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/firewire/ohci.c linux-libre-4.3.4-gnu/drivers/firewire/ohci.c
--- linux-libre-4.3-gnu/drivers/firewire/ohci.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/firewire/ohci.c	2016-01-22 23:59:37.000000000 -0500
@@ -3675,6 +3675,11 @@ static int pci_probe(struct pci_dev *dev
 
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
 	ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
+	/* JMicron JMB38x often shows 0 at first read, just ignore it */
+	if (!ohci->it_context_support) {
+		ohci_notice(ohci, "overriding IsoXmitIntMask\n");
+		ohci->it_context_support = 0xf;
+	}
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
 	ohci->it_context_mask = ohci->it_context_support;
 	ohci->n_it = hweight32(ohci->it_context_mask);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/media/pci/cobalt/Kconfig linux-libre-4.3.4-gnu/drivers/media/pci/cobalt/Kconfig
--- linux-libre-4.3-gnu/drivers/media/pci/cobalt/Kconfig	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/media/pci/cobalt/Kconfig	2016-01-22 23:59:37.000000000 -0500
@@ -1,6 +1,6 @@
 config VIDEO_COBALT
 	tristate "Cisco Cobalt support"
-	depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER
+	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
 	depends on PCI_MSI && MTD_COMPLEX_MAPPINGS
 	depends on GPIOLIB || COMPILE_TEST
 	depends on SND
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/mfd/twl6040.c linux-libre-4.3.4-gnu/drivers/mfd/twl6040.c
--- linux-libre-4.3-gnu/drivers/mfd/twl6040.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/mfd/twl6040.c	2016-01-22 23:59:37.000000000 -0500
@@ -647,6 +647,8 @@ static int twl6040_probe(struct i2c_clie
 
 	twl6040->clk32k = devm_clk_get(&client->dev, "clk32k");
 	if (IS_ERR(twl6040->clk32k)) {
+		if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
 		dev_info(&client->dev, "clk32k is not handled\n");
 		twl6040->clk32k = NULL;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/bonding/bond_main.c linux-libre-4.3.4-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-4.3-gnu/drivers/net/bonding/bond_main.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/bonding/bond_main.c	2016-01-22 23:59:37.000000000 -0500
@@ -1749,6 +1749,7 @@ err_undo_flags:
 					    slave_dev->dev_addr))
 			eth_hw_addr_random(bond_dev);
 		if (bond_dev->type != ARPHRD_ETHER) {
+			dev_close(bond_dev);
 			ether_setup(bond_dev);
 			bond_dev->flags |= IFF_MASTER;
 			bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/can/dev.c linux-libre-4.3.4-gnu/drivers/net/can/dev.c
--- linux-libre-4.3-gnu/drivers/net/can/dev.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/can/dev.c	2016-01-22 23:59:37.000000000 -0500
@@ -915,7 +915,7 @@ static int can_fill_info(struct sk_buff
 	     nla_put(skb, IFLA_CAN_BITTIMING_CONST,
 		     sizeof(*priv->bittiming_const), priv->bittiming_const)) ||
 
-	    nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) ||
+	    nla_put(skb, IFLA_CAN_CLOCK, sizeof(priv->clock), &priv->clock) ||
 	    nla_put_u32(skb, IFLA_CAN_STATE, state) ||
 	    nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
 	    nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/can/sja1000/sja1000.c linux-libre-4.3.4-gnu/drivers/net/can/sja1000/sja1000.c
--- linux-libre-4.3-gnu/drivers/net/can/sja1000/sja1000.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/can/sja1000/sja1000.c	2016-01-22 23:59:37.000000000 -0500
@@ -218,6 +218,9 @@ static void sja1000_start(struct net_dev
 	priv->write_reg(priv, SJA1000_RXERR, 0x0);
 	priv->read_reg(priv, SJA1000_ECC);
 
+	/* clear interrupt flags */
+	priv->read_reg(priv, SJA1000_IR);
+
 	/* leave reset mode */
 	set_normal_mode(dev);
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c linux-libre-4.3.4-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c	2016-01-22 23:59:37.000000000 -0500
@@ -1016,13 +1016,12 @@ static int atl1c_setup_ring_resources(st
 		sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
 		8 * 4;
 
-	ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
-				&ring_header->dma);
+	ring_header->desc = dma_zalloc_coherent(&pdev->dev, ring_header->size,
+						&ring_header->dma, GFP_KERNEL);
 	if (unlikely(!ring_header->desc)) {
-		dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+		dev_err(&pdev->dev, "could not get memory for DMA buffer\n");
 		goto err_nomem;
 	}
-	memset(ring_header->desc, 0, ring_header->size);
 	/* init TPD ring */
 
 	tpd_ring[0].dma = roundup(ring_header->dma, 8);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c linux-libre-4.3.4-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2016-01-22 23:59:37.000000000 -0500
@@ -907,8 +907,10 @@ static void bcmgenet_power_up(struct bcm
 	}
 
 	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
-	if (mode == GENET_POWER_PASSIVE)
+	if (mode == GENET_POWER_PASSIVE) {
 		bcmgenet_phy_power_set(priv->dev, true);
+		bcmgenet_mii_reset(priv->dev);
+	}
 }
 
 /* ioctl handle special commands that are not present in ethtool. */
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h linux-libre-4.3.4-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h
--- linux-libre-4.3-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.h	2016-01-22 23:59:37.000000000 -0500
@@ -674,6 +674,7 @@ int bcmgenet_mii_init(struct net_device
 int bcmgenet_mii_config(struct net_device *dev);
 int bcmgenet_mii_probe(struct net_device *dev);
 void bcmgenet_mii_exit(struct net_device *dev);
+void bcmgenet_mii_reset(struct net_device *dev);
 void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
 void bcmgenet_mii_setup(struct net_device *dev);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c linux-libre-4.3.4-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c	2016-01-22 23:59:37.000000000 -0500
@@ -163,6 +163,7 @@ void bcmgenet_mii_setup(struct net_devic
 	phy_print_status(phydev);
 }
 
+
 static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
 					  struct fixed_phy_status *status)
 {
@@ -172,6 +173,22 @@ static int bcmgenet_fixed_phy_link_updat
 	return 0;
 }
 
+/* Perform a voluntary PHY software reset, since the EPHY is very finicky about
+ * not doing it and will start corrupting packets
+ */
+void bcmgenet_mii_reset(struct net_device *dev)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+
+	if (GENET_IS_V4(priv))
+		return;
+
+	if (priv->phydev) {
+		phy_init_hw(priv->phydev);
+		phy_start_aneg(priv->phydev);
+	}
+}
+
 void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -214,6 +231,7 @@ static void bcmgenet_internal_phy_setup(
 	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
 	reg |= EXT_PWR_DN_EN_LD;
 	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+	bcmgenet_mii_reset(dev);
 }
 
 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/cavium/thunder/nicvf_main.c linux-libre-4.3.4-gnu/drivers/net/ethernet/cavium/thunder/nicvf_main.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/cavium/thunder/nicvf_main.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/cavium/thunder/nicvf_main.c	2016-01-22 23:59:37.000000000 -0500
@@ -1583,8 +1583,14 @@ err_disable_device:
 static void nicvf_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct nicvf *nic = netdev_priv(netdev);
-	struct net_device *pnetdev = nic->pnicvf->netdev;
+	struct nicvf *nic;
+	struct net_device *pnetdev;
+
+	if (!netdev)
+		return;
+
+	nic = netdev_priv(netdev);
+	pnetdev = nic->pnicvf->netdev;
 
 	/* Check if this Qset is assigned to different VF.
 	 * If yes, clean primary and all secondary Qsets.
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/freescale/gianfar.c linux-libre-4.3.4-gnu/drivers/net/ethernet/freescale/gianfar.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/freescale/gianfar.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/freescale/gianfar.c	2016-01-22 23:59:37.000000000 -0500
@@ -894,7 +894,8 @@ static int gfar_of_init(struct platform_
 				     FSL_GIANFAR_DEV_HAS_VLAN |
 				     FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
 				     FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
-				     FSL_GIANFAR_DEV_HAS_TIMER;
+				     FSL_GIANFAR_DEV_HAS_TIMER |
+				     FSL_GIANFAR_DEV_HAS_RX_FILER;
 
 	err = of_property_read_string(np, "phy-connection-type", &ctype);
 
@@ -1393,8 +1394,9 @@ static int gfar_probe(struct platform_de
 		priv->rx_queue[i]->rxic = DEFAULT_RXIC;
 	}
 
-	/* always enable rx filer */
-	priv->rx_filer_enable = 1;
+	/* Always enable rx filer if available */
+	priv->rx_filer_enable =
+	    (priv->device_flags & FSL_GIANFAR_DEV_HAS_RX_FILER) ? 1 : 0;
 	/* Enable most messages by default */
 	priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
 	/* use pritority h/w tx queue scheduling for single queue devices */
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/freescale/gianfar.h linux-libre-4.3.4-gnu/drivers/net/ethernet/freescale/gianfar.h
--- linux-libre-4.3-gnu/drivers/net/ethernet/freescale/gianfar.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/freescale/gianfar.h	2016-01-22 23:59:37.000000000 -0500
@@ -917,6 +917,7 @@ struct gfar {
 #define FSL_GIANFAR_DEV_HAS_BD_STASHING		0x00000200
 #define FSL_GIANFAR_DEV_HAS_BUF_STASHING	0x00000400
 #define FSL_GIANFAR_DEV_HAS_TIMER		0x00000800
+#define FSL_GIANFAR_DEV_HAS_RX_FILER		0x00002000
 
 #if (MAXGROUPS == 2)
 #define DEFAULT_MAPPING 	0xAA
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/marvell/mvneta.c linux-libre-4.3.4-gnu/drivers/net/ethernet/marvell/mvneta.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/marvell/mvneta.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/marvell/mvneta.c	2016-01-22 23:59:37.000000000 -0500
@@ -949,7 +949,7 @@ static void mvneta_defaults_set(struct m
 	/* Set CPU queue access map - all CPUs have access to all RX
 	 * queues and to all TX queues
 	 */
-	for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++)
+	for_each_present_cpu(cpu)
 		mvreg_write(pp, MVNETA_CPU_MAP(cpu),
 			    (MVNETA_CPU_RXQ_ACCESS_ALL_MASK |
 			     MVNETA_CPU_TXQ_ACCESS_ALL_MASK));
@@ -1533,12 +1533,16 @@ static int mvneta_rx(struct mvneta_port
 		}
 
 		skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size);
-		if (!skb)
-			goto err_drop_frame;
 
+		/* After refill old buffer has to be unmapped regardless
+		 * the skb is successfully built or not.
+		 */
 		dma_unmap_single(dev->dev.parent, phys_addr,
 				 MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
 
+		if (!skb)
+			goto err_drop_frame;
+
 		rcvd_pkts++;
 		rcvd_bytes += rx_bytes;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c linux-libre-4.3.4-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2016-01-22 23:59:37.000000000 -0500
@@ -4934,26 +4934,41 @@ static void rem_slave_counters(struct ml
 	struct res_counter *counter;
 	struct res_counter *tmp;
 	int err;
-	int index;
+	int *counters_arr = NULL;
+	int i, j;
 
 	err = move_all_busy(dev, slave, RES_COUNTER);
 	if (err)
 		mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n",
 			  slave);
 
-	spin_lock_irq(mlx4_tlock(dev));
-	list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
-		if (counter->com.owner == slave) {
-			index = counter->com.res_id;
-			rb_erase(&counter->com.node,
-				 &tracker->res_tree[RES_COUNTER]);
-			list_del(&counter->com.list);
-			kfree(counter);
-			__mlx4_counter_free(dev, index);
+	counters_arr = kmalloc_array(dev->caps.max_counters,
+				     sizeof(*counters_arr), GFP_KERNEL);
+	if (!counters_arr)
+		return;
+
+	do {
+		i = 0;
+		j = 0;
+		spin_lock_irq(mlx4_tlock(dev));
+		list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
+			if (counter->com.owner == slave) {
+				counters_arr[i++] = counter->com.res_id;
+				rb_erase(&counter->com.node,
+					 &tracker->res_tree[RES_COUNTER]);
+				list_del(&counter->com.list);
+				kfree(counter);
+			}
+		}
+		spin_unlock_irq(mlx4_tlock(dev));
+
+		while (j < i) {
+			__mlx4_counter_free(dev, counters_arr[j++]);
 			mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
 		}
-	}
-	spin_unlock_irq(mlx4_tlock(dev));
+	} while (i);
+
+	kfree(counters_arr);
 }
 
 static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c linux-libre-4.3.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2016-01-22 23:59:37.000000000 -0500
@@ -1332,6 +1332,42 @@ static int mlx5e_modify_tir_lro(struct m
 	return err;
 }
 
+static int mlx5e_refresh_tir_self_loopback_enable(struct mlx5_core_dev *mdev,
+						  u32 tirn)
+{
+	void *in;
+	int inlen;
+	int err;
+
+	inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
+	in = mlx5_vzalloc(inlen);
+	if (!in)
+		return -ENOMEM;
+
+	MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
+
+	err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
+
+	kvfree(in);
+
+	return err;
+}
+
+static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv)
+{
+	int err;
+	int i;
+
+	for (i = 0; i < MLX5E_NUM_TT; i++) {
+		err = mlx5e_refresh_tir_self_loopback_enable(priv->mdev,
+							     priv->tirn[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int mlx5e_set_dev_port_mtu(struct net_device *netdev)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -1367,13 +1403,20 @@ int mlx5e_open_locked(struct net_device
 
 	err = mlx5e_set_dev_port_mtu(netdev);
 	if (err)
-		return err;
+		goto err_clear_state_opened_flag;
 
 	err = mlx5e_open_channels(priv);
 	if (err) {
 		netdev_err(netdev, "%s: mlx5e_open_channels failed, %d\n",
 			   __func__, err);
-		return err;
+		goto err_clear_state_opened_flag;
+	}
+
+	err = mlx5e_refresh_tirs_self_loopback_enable(priv);
+	if (err) {
+		netdev_err(netdev, "%s: mlx5e_refresh_tirs_self_loopback_enable failed, %d\n",
+			   __func__, err);
+		goto err_close_channels;
 	}
 
 	mlx5e_update_carrier(priv);
@@ -1382,6 +1425,12 @@ int mlx5e_open_locked(struct net_device
 	schedule_delayed_work(&priv->update_stats_work, 0);
 
 	return 0;
+
+err_close_channels:
+	mlx5e_close_channels(priv);
+err_clear_state_opened_flag:
+	clear_bit(MLX5E_STATE_OPENED, &priv->state);
+	return err;
 }
 
 static int mlx5e_open(struct net_device *netdev)
@@ -1899,6 +1948,9 @@ static int mlx5e_check_required_hca_cap(
 			       "Not creating net device, some required device capabilities are missing\n");
 		return -ENOTSUPP;
 	}
+	if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable))
+		mlx5_core_warn(mdev, "Self loop back prevention is not supported\n");
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/qualcomm/qca_spi.c linux-libre-4.3.4-gnu/drivers/net/ethernet/qualcomm/qca_spi.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/qualcomm/qca_spi.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/qualcomm/qca_spi.c	2016-01-22 23:59:37.000000000 -0500
@@ -736,9 +736,8 @@ qcaspi_netdev_tx_timeout(struct net_devi
 	netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
 		    jiffies, jiffies - dev->trans_start);
 	qca->net_dev->stats.tx_errors++;
-	/* wake the queue if there is room */
-	if (qcaspi_tx_ring_has_space(&qca->txr))
-		netif_wake_queue(dev);
+	/* Trigger tx queue flush and QCA7000 reset */
+	qca->sync = QCASPI_SYNC_UNKNOWN;
 }
 
 static int
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/realtek/r8169.c linux-libre-4.3.4-gnu/drivers/net/ethernet/realtek/r8169.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/realtek/r8169.c	2015-11-01 23:32:02.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/realtek/r8169.c	2016-01-23 08:14:32.000000000 -0500
@@ -7411,15 +7411,15 @@ process_pkt:
 
 			rtl8169_rx_vlan_tag(desc, skb);
 
+			if (skb->pkt_type == PACKET_MULTICAST)
+				dev->stats.multicast++;
+
 			napi_gro_receive(&tp->napi, skb);
 
 			u64_stats_update_begin(&tp->rx_stats.syncp);
 			tp->rx_stats.packets++;
 			tp->rx_stats.bytes += pkt_size;
 			u64_stats_update_end(&tp->rx_stats.syncp);
-
-			if (skb->pkt_type == PACKET_MULTICAST)
-				dev->stats.multicast++;
 		}
 release_descriptor:
 		desc->opts2 = 0;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/renesas/sh_eth.c linux-libre-4.3.4-gnu/drivers/net/ethernet/renesas/sh_eth.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/renesas/sh_eth.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/renesas/sh_eth.c	2016-01-22 23:59:37.000000000 -0500
@@ -1481,6 +1481,7 @@ static int sh_eth_rx(struct net_device *
 		if (mdp->cd->shift_rd0)
 			desc_status >>= 16;
 
+		skb = mdp->rx_skbuff[entry];
 		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
 				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
 			ndev->stats.rx_errors++;
@@ -1496,12 +1497,11 @@ static int sh_eth_rx(struct net_device *
 				ndev->stats.rx_missed_errors++;
 			if (desc_status & RD_RFS10)
 				ndev->stats.rx_over_errors++;
-		} else {
+		} else	if (skb) {
 			if (!mdp->cd->hw_swap)
 				sh_eth_soft_swap(
 					phys_to_virt(ALIGN(rxdesc->addr, 4)),
 					pkt_len + 2);
-			skb = mdp->rx_skbuff[entry];
 			mdp->rx_skbuff[entry] = NULL;
 			if (mdp->cd->rpadir)
 				skb_reserve(skb, NET_IP_ALIGN);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/sfc/ef10.c linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/ef10.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/sfc/ef10.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/ef10.c	2016-01-22 23:59:37.000000000 -0500
@@ -1849,7 +1849,9 @@ static void efx_ef10_tx_write(struct efx
 	unsigned int write_ptr;
 	efx_qword_t *txd;
 
-	BUG_ON(tx_queue->write_count == tx_queue->insert_count);
+	tx_queue->xmit_more_available = false;
+	if (unlikely(tx_queue->write_count == tx_queue->insert_count))
+		return;
 
 	do {
 		write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/sfc/farch.c linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/farch.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/sfc/farch.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/farch.c	2016-01-22 23:59:37.000000000 -0500
@@ -321,7 +321,9 @@ void efx_farch_tx_write(struct efx_tx_qu
 	unsigned write_ptr;
 	unsigned old_write_count = tx_queue->write_count;
 
-	BUG_ON(tx_queue->write_count == tx_queue->insert_count);
+	tx_queue->xmit_more_available = false;
+	if (unlikely(tx_queue->write_count == tx_queue->insert_count))
+		return;
 
 	do {
 		write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/sfc/net_driver.h linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/net_driver.h
--- linux-libre-4.3-gnu/drivers/net/ethernet/sfc/net_driver.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/net_driver.h	2016-01-22 23:59:37.000000000 -0500
@@ -219,6 +219,7 @@ struct efx_tx_buffer {
  * @tso_packets: Number of packets via the TSO xmit path
  * @pushes: Number of times the TX push feature has been used
  * @pio_packets: Number of times the TX PIO feature has been used
+ * @xmit_more_available: Are any packets waiting to be pushed to the NIC
  * @empty_read_count: If the completion path has seen the queue as empty
  *	and the transmission path has not yet checked this, the value of
  *	@read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0.
@@ -253,6 +254,7 @@ struct efx_tx_queue {
 	unsigned int tso_packets;
 	unsigned int pushes;
 	unsigned int pio_packets;
+	bool xmit_more_available;
 	/* Statistics to supplement MAC stats */
 	unsigned long tx_packets;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/sfc/tx.c linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/tx.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/sfc/tx.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/sfc/tx.c	2016-01-22 23:59:37.000000000 -0500
@@ -431,8 +431,20 @@ finish_packet:
 	efx_tx_maybe_stop_queue(tx_queue);
 
 	/* Pass off to hardware */
-	if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq))
+	if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq)) {
+		struct efx_tx_queue *txq2 = efx_tx_queue_partner(tx_queue);
+
+		/* There could be packets left on the partner queue if those
+		 * SKBs had skb->xmit_more set. If we do not push those they
+		 * could be left for a long time and cause a netdev watchdog.
+		 */
+		if (txq2->xmit_more_available)
+			efx_nic_push_buffers(txq2);
+
 		efx_nic_push_buffers(tx_queue);
+	} else {
+		tx_queue->xmit_more_available = skb->xmit_more;
+	}
 
 	tx_queue->tx_packets++;
 
@@ -722,6 +734,7 @@ void efx_init_tx_queue(struct efx_tx_que
 	tx_queue->read_count = 0;
 	tx_queue->old_read_count = 0;
 	tx_queue->empty_read_count = 0 | EFX_EMPTY_COUNT_VALID;
+	tx_queue->xmit_more_available = false;
 
 	/* Set up TX descriptor ring */
 	efx_nic_init_tx(tx_queue);
@@ -747,6 +760,7 @@ void efx_fini_tx_queue(struct efx_tx_que
 
 		++tx_queue->read_count;
 	}
+	tx_queue->xmit_more_available = false;
 	netdev_tx_reset_queue(tx_queue->core_txq);
 }
 
@@ -1302,8 +1316,20 @@ static int efx_enqueue_skb_tso(struct ef
 	efx_tx_maybe_stop_queue(tx_queue);
 
 	/* Pass off to hardware */
-	if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq))
+	if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq)) {
+		struct efx_tx_queue *txq2 = efx_tx_queue_partner(tx_queue);
+
+		/* There could be packets left on the partner queue if those
+		 * SKBs had skb->xmit_more set. If we do not push those they
+		 * could be left for a long time and cause a netdev watchdog.
+		 */
+		if (txq2->xmit_more_available)
+			efx_nic_push_buffers(txq2);
+
 		efx_nic_push_buffers(tx_queue);
+	} else {
+		tx_queue->xmit_more_available = skb->xmit_more;
+	}
 
 	tx_queue->tso_bursts++;
 	return NETDEV_TX_OK;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c linux-libre-4.3.4-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
--- linux-libre-4.3-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c	2016-01-22 23:59:37.000000000 -0500
@@ -721,10 +721,13 @@ static int stmmac_get_ts_info(struct net
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 
-	if ((priv->hwts_tx_en) && (priv->hwts_rx_en)) {
+	if ((priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) {
 
-		info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
+		info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+					SOF_TIMESTAMPING_TX_HARDWARE |
+					SOF_TIMESTAMPING_RX_SOFTWARE |
 					SOF_TIMESTAMPING_RX_HARDWARE |
+					SOF_TIMESTAMPING_SOFTWARE |
 					SOF_TIMESTAMPING_RAW_HARDWARE;
 
 		if (priv->ptp_clock)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/phy/broadcom.c linux-libre-4.3.4-gnu/drivers/net/phy/broadcom.c
--- linux-libre-4.3-gnu/drivers/net/phy/broadcom.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/phy/broadcom.c	2016-01-22 23:59:37.000000000 -0500
@@ -675,7 +675,7 @@ static struct mdio_device_id __maybe_unu
 	{ PHY_ID_BCM5461, 0xfffffff0 },
 	{ PHY_ID_BCM54616S, 0xfffffff0 },
 	{ PHY_ID_BCM5464, 0xfffffff0 },
-	{ PHY_ID_BCM5482, 0xfffffff0 },
+	{ PHY_ID_BCM5481, 0xfffffff0 },
 	{ PHY_ID_BCM5482, 0xfffffff0 },
 	{ PHY_ID_BCM50610, 0xfffffff0 },
 	{ PHY_ID_BCM50610M, 0xfffffff0 },
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/phy/micrel.c linux-libre-4.3.4-gnu/drivers/net/phy/micrel.c
--- linux-libre-4.3-gnu/drivers/net/phy/micrel.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/phy/micrel.c	2016-01-22 23:59:37.000000000 -0500
@@ -339,9 +339,18 @@ static int ksz9021_config_init(struct ph
 {
 	const struct device *dev = &phydev->dev;
 	const struct device_node *of_node = dev->of_node;
+	const struct device *dev_walker;
 
-	if (!of_node && dev->parent->of_node)
-		of_node = dev->parent->of_node;
+	/* The Micrel driver has a deprecated option to place phy OF
+	 * properties in the MAC node. Walk up the tree of devices to
+	 * find a device with an OF node.
+	 */
+	dev_walker = &phydev->dev;
+	do {
+		of_node = dev_walker->of_node;
+		dev_walker = dev_walker->parent;
+
+	} while (!of_node && dev_walker);
 
 	if (of_node) {
 		ksz9021_load_values_from_of(phydev, of_node,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ppp/pppoe.c linux-libre-4.3.4-gnu/drivers/net/ppp/pppoe.c
--- linux-libre-4.3-gnu/drivers/net/ppp/pppoe.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ppp/pppoe.c	2016-01-22 23:59:37.000000000 -0500
@@ -568,6 +568,9 @@ static int pppoe_create(struct net *net,
 	sk->sk_family		= PF_PPPOX;
 	sk->sk_protocol		= PX_PROTO_OE;
 
+	INIT_WORK(&pppox_sk(sk)->proto.pppoe.padt_work,
+		  pppoe_unbind_sock_work);
+
 	return 0;
 }
 
@@ -632,8 +635,6 @@ static int pppoe_connect(struct socket *
 
 	lock_sock(sk);
 
-	INIT_WORK(&po->proto.pppoe.padt_work, pppoe_unbind_sock_work);
-
 	error = -EINVAL;
 	if (sp->sa_protocol != PX_PROTO_OE)
 		goto end;
@@ -663,8 +664,13 @@ static int pppoe_connect(struct socket *
 			po->pppoe_dev = NULL;
 		}
 
-		memset(sk_pppox(po) + 1, 0,
-		       sizeof(struct pppox_sock) - sizeof(struct sock));
+		po->pppoe_ifindex = 0;
+		memset(&po->pppoe_pa, 0, sizeof(po->pppoe_pa));
+		memset(&po->pppoe_relay, 0, sizeof(po->pppoe_relay));
+		memset(&po->chan, 0, sizeof(po->chan));
+		po->next = NULL;
+		po->num = 0;
+
 		sk->sk_state = PPPOX_NONE;
 	}
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/ppp/pptp.c linux-libre-4.3.4-gnu/drivers/net/ppp/pptp.c
--- linux-libre-4.3-gnu/drivers/net/ppp/pptp.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/ppp/pptp.c	2016-01-22 23:59:37.000000000 -0500
@@ -418,6 +418,9 @@ static int pptp_bind(struct socket *sock
 	struct pptp_opt *opt = &po->proto.pptp;
 	int error = 0;
 
+	if (sockaddr_len < sizeof(struct sockaddr_pppox))
+		return -EINVAL;
+
 	lock_sock(sk);
 
 	opt->src_addr = sp->sa_addr.pptp;
@@ -439,6 +442,9 @@ static int pptp_connect(struct socket *s
 	struct flowi4 fl4;
 	int error = 0;
 
+	if (sockaddr_len < sizeof(struct sockaddr_pppox))
+		return -EINVAL;
+
 	if (sp->sa_protocol != PX_PROTO_PPTP)
 		return -EINVAL;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/usb/cdc_mbim.c linux-libre-4.3.4-gnu/drivers/net/usb/cdc_mbim.c
--- linux-libre-4.3-gnu/drivers/net/usb/cdc_mbim.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/usb/cdc_mbim.c	2016-01-22 23:59:37.000000000 -0500
@@ -158,7 +158,7 @@ static int cdc_mbim_bind(struct usbnet *
 	if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
 		goto err;
 
-	ret = cdc_ncm_bind_common(dev, intf, data_altsetting, 0);
+	ret = cdc_ncm_bind_common(dev, intf, data_altsetting, dev->driver_info->data);
 	if (ret)
 		goto err;
 
@@ -582,6 +582,26 @@ static const struct driver_info cdc_mbim
 	.tx_fixup = cdc_mbim_tx_fixup,
 };
 
+/* The spefication explicitly allows NDPs to be placed anywhere in the
+ * frame, but some devices fail unless the NDP is placed after the IP
+ * packets.  Using the CDC_NCM_FLAG_NDP_TO_END flags to force this
+ * behaviour.
+ *
+ * Note: The current implementation of this feature restricts each NTB
+ * to a single NDP, implying that multiplexed sessions cannot share an
+ * NTB. This might affect performace for multiplexed sessions.
+ */
+static const struct driver_info cdc_mbim_info_ndp_to_end = {
+	.description = "CDC MBIM",
+	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+	.bind = cdc_mbim_bind,
+	.unbind = cdc_mbim_unbind,
+	.manage_power = cdc_mbim_manage_power,
+	.rx_fixup = cdc_mbim_rx_fixup,
+	.tx_fixup = cdc_mbim_tx_fixup,
+	.data = CDC_NCM_FLAG_NDP_TO_END,
+};
+
 static const struct usb_device_id mbim_devs[] = {
 	/* This duplicate NCM entry is intentional. MBIM devices can
 	 * be disguised as NCM by default, and this is necessary to
@@ -597,6 +617,10 @@ static const struct usb_device_id mbim_d
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bdb, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info,
 	},
+	/* Huawei E3372 fails unless NDP comes after the IP packets */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x12d1, 0x157d, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+	  .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
+	},
 	/* default entry */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info_zlp,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/usb/cdc_ncm.c linux-libre-4.3.4-gnu/drivers/net/usb/cdc_ncm.c
--- linux-libre-4.3-gnu/drivers/net/usb/cdc_ncm.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/usb/cdc_ncm.c	2016-01-22 23:59:37.000000000 -0500
@@ -1006,10 +1006,18 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm
 	* NTH16 header as we would normally do. NDP isn't written to the SKB yet, and
 	* the wNdpIndex field in the header is actually not consistent with reality. It will be later.
 	*/
-	if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)
+	if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) {
 		if (ctx->delayed_ndp16->dwSignature == sign)
 			return ctx->delayed_ndp16;
 
+		/* We can only push a single NDP to the end. Return
+		 * NULL to send what we've already got and queue this
+		 * skb for later.
+		 */
+		else if (ctx->delayed_ndp16->dwSignature)
+			return NULL;
+	}
+
 	/* follow the chain of NDPs, looking for a match */
 	while (ndpoffset) {
 		ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb->data + ndpoffset);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/usb/qmi_wwan.c linux-libre-4.3.4-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-4.3-gnu/drivers/net/usb/qmi_wwan.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/usb/qmi_wwan.c	2016-01-22 23:59:37.000000000 -0500
@@ -775,6 +775,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x2357, 0x9000, 4)},	/* TP-LINK MA260 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)},	/* Telit LE920 */
+	{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},	/* XS Stick W100-2 from 4G Systems */
 	{QMI_FIXED_INTF(0x0b3c, 0xc000, 4)},	/* Olivetti Olicard 100 */
 	{QMI_FIXED_INTF(0x0b3c, 0xc001, 4)},	/* Olivetti Olicard 120 */
 	{QMI_FIXED_INTF(0x0b3c, 0xc002, 4)},	/* Olivetti Olicard 140 */
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/usb/r8152.c linux-libre-4.3.4-gnu/drivers/net/usb/r8152.c
--- linux-libre-4.3-gnu/drivers/net/usb/r8152.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/usb/r8152.c	2016-01-22 23:59:37.000000000 -0500
@@ -3067,17 +3067,6 @@ static int rtl8152_open(struct net_devic
 
 	mutex_lock(&tp->control);
 
-	/* The WORK_ENABLE may be set when autoresume occurs */
-	if (test_bit(WORK_ENABLE, &tp->flags)) {
-		clear_bit(WORK_ENABLE, &tp->flags);
-		usb_kill_urb(tp->intr_urb);
-		cancel_delayed_work_sync(&tp->schedule);
-
-		/* disable the tx/rx, if the workqueue has enabled them. */
-		if (netif_carrier_ok(netdev))
-			tp->rtl_ops.disable(tp);
-	}
-
 	tp->rtl_ops.up(tp);
 
 	rtl8152_set_speed(tp, AUTONEG_ENABLE,
@@ -3124,12 +3113,6 @@ static int rtl8152_close(struct net_devi
 	} else {
 		mutex_lock(&tp->control);
 
-		/* The autosuspend may have been enabled and wouldn't
-		 * be disable when autoresume occurs, because the
-		 * netif_running() would be false.
-		 */
-		rtl_runtime_suspend_enable(tp, false);
-
 		tp->rtl_ops.down(tp);
 
 		mutex_unlock(&tp->control);
@@ -3512,7 +3495,7 @@ static int rtl8152_resume(struct usb_int
 		netif_device_attach(tp->netdev);
 	}
 
-	if (netif_running(tp->netdev)) {
+	if (netif_running(tp->netdev) && tp->netdev->flags & IFF_UP) {
 		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
 			rtl_runtime_suspend_enable(tp, false);
 			clear_bit(SELECTIVE_SUSPEND, &tp->flags);
@@ -3532,6 +3515,8 @@ static int rtl8152_resume(struct usb_int
 		}
 		usb_submit_urb(tp->intr_urb, GFP_KERNEL);
 	} else if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+		if (tp->netdev->flags & IFF_UP)
+			rtl_runtime_suspend_enable(tp, false);
 		clear_bit(SELECTIVE_SUSPEND, &tp->flags);
 	}
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/vrf.c linux-libre-4.3.4-gnu/drivers/net/vrf.c
--- linux-libre-4.3-gnu/drivers/net/vrf.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/vrf.c	2016-01-22 23:59:37.000000000 -0500
@@ -608,7 +608,6 @@ static int vrf_newlink(struct net *src_n
 
 out_fail:
 	kfree(vrf_ptr);
-	free_netdev(dev);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/ath/ath10k/core.c linux-libre-4.3.4-gnu/drivers/net/wireless/ath/ath10k/core.c
--- linux-libre-4.3-gnu/drivers/net/wireless/ath/ath10k/core.c	2015-11-01 23:35:47.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/ath/ath10k/core.c	2016-01-23 08:18:12.000000000 -0500
@@ -142,12 +142,17 @@ static const char *const ath10k_core_fw_
 	[ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",
 	[ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
 	[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
+	[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
 };
 
 static unsigned int ath10k_core_get_fw_feature_str(char *buf,
 						   size_t buf_len,
 						   enum ath10k_fw_features feat)
 {
+	/* make sure that ath10k_core_fw_feature_str[] gets updated */
+	BUILD_BUG_ON(ARRAY_SIZE(ath10k_core_fw_feature_str) !=
+		     ATH10K_FW_FEATURE_COUNT);
+
 	if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||
 	    WARN_ON(!ath10k_core_fw_feature_str[feat])) {
 		return scnprintf(buf, buf_len, "bit%d", feat);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/ath/ath10k/mac.c linux-libre-4.3.4-gnu/drivers/net/wireless/ath/ath10k/mac.c
--- linux-libre-4.3-gnu/drivers/net/wireless/ath/ath10k/mac.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/ath/ath10k/mac.c	2016-01-22 23:59:37.000000000 -0500
@@ -2083,7 +2083,8 @@ static void ath10k_peer_assoc_h_ht(struc
 	enum ieee80211_band band;
 	const u8 *ht_mcs_mask;
 	const u16 *vht_mcs_mask;
-	int i, n, max_nss;
+	int i, n;
+	u8 max_nss;
 	u32 stbc;
 
 	lockdep_assert_held(&ar->conf_mutex);
@@ -2168,7 +2169,7 @@ static void ath10k_peer_assoc_h_ht(struc
 			arg->peer_ht_rates.rates[i] = i;
 	} else {
 		arg->peer_ht_rates.num_rates = n;
-		arg->peer_num_spatial_streams = max_nss;
+		arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
 	}
 
 	ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
@@ -4055,7 +4056,7 @@ static int ath10k_config(struct ieee8021
 
 static u32 get_nss_from_chainmask(u16 chain_mask)
 {
-	if ((chain_mask & 0x15) == 0x15)
+	if ((chain_mask & 0xf) == 0xf)
 		return 4;
 	else if ((chain_mask & 0x7) == 0x7)
 		return 3;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c linux-libre-4.3.4-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c
--- linux-libre-4.3-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c	2016-01-22 23:59:37.000000000 -0500
@@ -423,14 +423,21 @@ static const struct pci_device_id iwl_hw
 /* 8000 Series */
 	{IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x0130, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x1130, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x0132, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x1132, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x01F0, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x0012, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x1012, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x1150, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)},
-	{IWL_PCI_DEVICE(0x24F4, 0x1130, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8260_2ac_cfg)},
@@ -438,18 +445,28 @@ static const struct pci_device_id iwl_hw
 	{IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x8110, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x9110, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x8130, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x9130, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x8132, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x9132, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x8150, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x9150, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x0044, iwl8260_2n_cfg)},
 	{IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8260_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)},
 #endif /* CONFIG_IWLMVM */
 
 	{0}
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c linux-libre-4.3.4-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c
--- linux-libre-4.3-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c	2016-01-22 23:59:37.000000000 -0500
@@ -592,10 +592,8 @@ static int iwl_pcie_prepare_card_hw(stru
 
 		do {
 			ret = iwl_pcie_set_hw_ready(trans);
-			if (ret >= 0) {
-				ret = 0;
-				goto out;
-			}
+			if (ret >= 0)
+				return 0;
 
 			usleep_range(200, 1000);
 			t += 200;
@@ -605,10 +603,6 @@ static int iwl_pcie_prepare_card_hw(stru
 
 	IWL_ERR(trans, "Couldn't prepare the card\n");
 
-out:
-	iwl_clear_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
-		      CSR_RESET_LINK_PWR_MGMT_DISABLED);
-
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/mwifiex/debugfs.c linux-libre-4.3.4-gnu/drivers/net/wireless/mwifiex/debugfs.c
--- linux-libre-4.3-gnu/drivers/net/wireless/mwifiex/debugfs.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/mwifiex/debugfs.c	2016-01-22 23:59:37.000000000 -0500
@@ -731,7 +731,7 @@ mwifiex_rdeeprom_read(struct file *file,
 		(struct mwifiex_private *) file->private_data;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *) addr;
-	int pos = 0, ret = 0, i;
+	int pos, ret, i;
 	u8 value[MAX_EEPROM_DATA];
 
 	if (!buf)
@@ -739,7 +739,7 @@ mwifiex_rdeeprom_read(struct file *file,
 
 	if (saved_offset == -1) {
 		/* No command has been given */
-		pos += snprintf(buf, PAGE_SIZE, "0");
+		pos = snprintf(buf, PAGE_SIZE, "0");
 		goto done;
 	}
 
@@ -748,17 +748,17 @@ mwifiex_rdeeprom_read(struct file *file,
 				  (u16) saved_bytes, value);
 	if (ret) {
 		ret = -EINVAL;
-		goto done;
+		goto out_free;
 	}
 
-	pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
+	pos = snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
 
 	for (i = 0; i < saved_bytes; i++)
-		pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]);
-
-	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+		pos += scnprintf(buf + pos, PAGE_SIZE - pos, "%d ", value[i]);
 
 done:
+	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+out_free:
 	free_page(addr);
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/mwifiex/pcie.c linux-libre-4.3.4-gnu/drivers/net/wireless/mwifiex/pcie.c
--- linux-libre-4.3-gnu/drivers/net/wireless/mwifiex/pcie.c	2015-11-01 23:35:16.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/mwifiex/pcie.c	2016-01-23 08:17:39.000000000 -0500
@@ -1815,7 +1815,6 @@ static int mwifiex_pcie_event_complete(s
 	if (!card->evt_buf_list[rdptr]) {
 		skb_push(skb, INTF_HEADER_LEN);
 		skb_put(skb, MAX_EVENT_SIZE - skb->len);
-		memset(skb->data, 0, MAX_EVENT_SIZE);
 		if (mwifiex_map_pci_memory(adapter, skb,
 					   MAX_EVENT_SIZE,
 					   PCI_DMA_FROMDEVICE))
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/net/wireless/mwifiex/scan.c linux-libre-4.3.4-gnu/drivers/net/wireless/mwifiex/scan.c
--- linux-libre-4.3-gnu/drivers/net/wireless/mwifiex/scan.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/net/wireless/mwifiex/scan.c	2016-01-22 23:59:37.000000000 -0500
@@ -1889,7 +1889,7 @@ mwifiex_active_scan_req_for_passive_chan
 	u8 id = 0;
 	struct mwifiex_user_scan_cfg  *user_scan_cfg;
 
-	if (adapter->active_scan_triggered) {
+	if (adapter->active_scan_triggered || !priv->scan_request) {
 		adapter->active_scan_triggered = false;
 		return 0;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/nfc/st-nci/spi.c linux-libre-4.3.4-gnu/drivers/nfc/st-nci/spi.c
--- linux-libre-4.3-gnu/drivers/nfc/st-nci/spi.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/nfc/st-nci/spi.c	2016-01-22 23:59:37.000000000 -0500
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/nfc.h>
+#include <net/nfc/nci.h>
 #include <linux/platform_data/st-nci.h>
 
 #include "ndlc.h"
@@ -94,7 +95,8 @@ static int st_nci_spi_write(void *phy_id
 	struct st_nci_spi_phy *phy = phy_id;
 	struct spi_device *dev = phy->spi_dev;
 	struct sk_buff *skb_rx;
-	u8 buf[ST_NCI_SPI_MAX_SIZE];
+	u8 buf[ST_NCI_SPI_MAX_SIZE + NCI_DATA_HDR_SIZE +
+	       ST_NCI_FRAME_HEADROOM + ST_NCI_FRAME_TAILROOM];
 	struct spi_transfer spi_xfer = {
 		.tx_buf = skb->data,
 		.rx_buf = buf,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c linux-libre-4.3.4-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
--- linux-libre-4.3-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c	2016-01-22 23:59:37.000000000 -0500
@@ -584,7 +584,7 @@ static void pm8xxx_gpio_dbg_show(struct
 }
 
 #else
-#define msm_gpio_dbg_show NULL
+#define pm8xxx_gpio_dbg_show NULL
 #endif
 
 static struct gpio_chip pm8xxx_gpio_template = {
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c linux-libre-4.3.4-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c
--- linux-libre-4.3-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c	2016-01-22 23:59:37.000000000 -0500
@@ -639,7 +639,7 @@ static void pm8xxx_mpp_dbg_show(struct s
 }
 
 #else
-#define msm_mpp_dbg_show NULL
+#define pm8xxx_mpp_dbg_show NULL
 #endif
 
 static struct gpio_chip pm8xxx_mpp_template = {
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c linux-libre-4.3.4-gnu/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
--- linux-libre-4.3-gnu/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c	2016-01-22 23:59:37.000000000 -0500
@@ -539,6 +539,12 @@ static int uniphier_pmx_set_one_mux(stru
 	unsigned reg, reg_end, shift, mask;
 	int ret;
 
+	/* some pins need input-enabling */
+	ret = uniphier_conf_pin_input_enable(pctldev,
+					     &pctldev->desc->pins[pin], 1);
+	if (ret)
+		return ret;
+
 	reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
 	reg_end = reg + reg_stride;
 	shift = pin * mux_bits % 32;
@@ -563,9 +569,7 @@ static int uniphier_pmx_set_one_mux(stru
 			return ret;
 	}
 
-	/* some pins need input-enabling */
-	return uniphier_conf_pin_input_enable(pctldev,
-					      &pctldev->desc->pins[pin], 1);
+	return 0;
 }
 
 static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/platform/x86/toshiba_acpi.c linux-libre-4.3.4-gnu/drivers/platform/x86/toshiba_acpi.c
--- linux-libre-4.3-gnu/drivers/platform/x86/toshiba_acpi.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/platform/x86/toshiba_acpi.c	2016-01-22 23:59:37.000000000 -0500
@@ -2676,6 +2676,7 @@ static int toshiba_acpi_add(struct acpi_
 	ret = toshiba_function_keys_get(dev, &special_functions);
 	dev->kbd_function_keys_supported = !ret;
 
+	dev->hotkey_event_type = 0;
 	if (toshiba_acpi_setup_keyboard(dev))
 		pr_info("Unable to activate hotkeys\n");
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h linux-libre-4.3.4-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
--- linux-libre-4.3-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h	2016-01-22 23:59:37.000000000 -0500
@@ -680,7 +680,7 @@ void lnet_debug_peer(lnet_nid_t nid);
 static inline void
 lnet_peer_set_alive(lnet_peer_t *lp)
 {
-	lp->lp_last_alive = lp->lp_last_query = get_seconds();
+	lp->lp_last_alive = lp->lp_last_query = jiffies;
 	if (!lp->lp_alive)
 		lnet_notify_locked(lp, 0, 1, lp->lp_last_alive);
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/staging/rtl8712/usb_intf.c linux-libre-4.3.4-gnu/drivers/staging/rtl8712/usb_intf.c
--- linux-libre-4.3-gnu/drivers/staging/rtl8712/usb_intf.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/staging/rtl8712/usb_intf.c	2016-01-22 23:59:37.000000000 -0500
@@ -144,6 +144,7 @@ static struct usb_device_id rtl871x_usb_
 	{USB_DEVICE(0x0DF6, 0x0058)},
 	{USB_DEVICE(0x0DF6, 0x0049)},
 	{USB_DEVICE(0x0DF6, 0x004C)},
+	{USB_DEVICE(0x0DF6, 0x006C)},
 	{USB_DEVICE(0x0DF6, 0x0064)},
 	/* Skyworth */
 	{USB_DEVICE(0x14b2, 0x3300)},
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/tty/mips_ejtag_fdc.c linux-libre-4.3.4-gnu/drivers/tty/mips_ejtag_fdc.c
--- linux-libre-4.3-gnu/drivers/tty/mips_ejtag_fdc.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/tty/mips_ejtag_fdc.c	2016-01-22 23:59:37.000000000 -0500
@@ -1048,38 +1048,6 @@ err_destroy_ports:
 	return ret;
 }
 
-static int mips_ejtag_fdc_tty_remove(struct mips_cdmm_device *dev)
-{
-	struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev);
-	struct mips_ejtag_fdc_tty_port *dport;
-	int nport;
-	unsigned int cfg;
-
-	if (priv->irq >= 0) {
-		raw_spin_lock_irq(&priv->lock);
-		cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
-		/* Disable interrupts */
-		cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES);
-		cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
-		cfg |= REG_FDCFG_RXINTTHRES_DISABLED;
-		mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
-		raw_spin_unlock_irq(&priv->lock);
-	} else {
-		priv->removing = true;
-		del_timer_sync(&priv->poll_timer);
-	}
-	kthread_stop(priv->thread);
-	if (dev->cpu == 0)
-		mips_ejtag_fdc_con.tty_drv = NULL;
-	tty_unregister_driver(priv->driver);
-	for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) {
-		dport = &priv->ports[nport];
-		tty_port_destroy(&dport->port);
-	}
-	put_tty_driver(priv->driver);
-	return 0;
-}
-
 static int mips_ejtag_fdc_tty_cpu_down(struct mips_cdmm_device *dev)
 {
 	struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev);
@@ -1152,12 +1120,11 @@ static struct mips_cdmm_driver mips_ejta
 		.name	= "mips_ejtag_fdc",
 	},
 	.probe		= mips_ejtag_fdc_tty_probe,
-	.remove		= mips_ejtag_fdc_tty_remove,
 	.cpu_down	= mips_ejtag_fdc_tty_cpu_down,
 	.cpu_up		= mips_ejtag_fdc_tty_cpu_up,
 	.id_table	= mips_ejtag_fdc_tty_ids,
 };
-module_mips_cdmm_driver(mips_ejtag_fdc_tty_driver);
+builtin_mips_cdmm_driver(mips_ejtag_fdc_tty_driver);
 
 static int __init mips_ejtag_fdc_init_console(void)
 {
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/tty/n_tty.c linux-libre-4.3.4-gnu/drivers/tty/n_tty.c
--- linux-libre-4.3-gnu/drivers/tty/n_tty.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/tty/n_tty.c	2016-01-22 23:59:37.000000000 -0500
@@ -169,7 +169,7 @@ static inline int tty_copy_to_user(struc
 {
 	struct n_tty_data *ldata = tty->disc_data;
 
-	tty_audit_add_data(tty, to, n, ldata->icanon);
+	tty_audit_add_data(tty, from, n, ldata->icanon);
 	return copy_to_user(to, from, n);
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/tty/tty_audit.c linux-libre-4.3.4-gnu/drivers/tty/tty_audit.c
--- linux-libre-4.3-gnu/drivers/tty/tty_audit.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/tty/tty_audit.c	2016-01-22 23:59:37.000000000 -0500
@@ -265,7 +265,7 @@ static struct tty_audit_buf *tty_audit_b
  *
  *	Audit @data of @size from @tty, if necessary.
  */
-void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
+void tty_audit_add_data(struct tty_struct *tty, const void *data,
 			size_t size, unsigned icanon)
 {
 	struct tty_audit_buf *buf;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/tty/tty_io.c linux-libre-4.3.4-gnu/drivers/tty/tty_io.c
--- linux-libre-4.3-gnu/drivers/tty/tty_io.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/tty/tty_io.c	2016-01-22 23:59:37.000000000 -0500
@@ -1282,18 +1282,22 @@ int tty_send_xchar(struct tty_struct *tt
 	int	was_stopped = tty->stopped;
 
 	if (tty->ops->send_xchar) {
+		down_read(&tty->termios_rwsem);
 		tty->ops->send_xchar(tty, ch);
+		up_read(&tty->termios_rwsem);
 		return 0;
 	}
 
 	if (tty_write_lock(tty, 0) < 0)
 		return -ERESTARTSYS;
 
+	down_read(&tty->termios_rwsem);
 	if (was_stopped)
 		start_tty(tty);
 	tty->ops->write(tty, &ch, 1);
 	if (was_stopped)
 		stop_tty(tty);
+	up_read(&tty->termios_rwsem);
 	tty_write_unlock(tty);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/tty/tty_ioctl.c linux-libre-4.3.4-gnu/drivers/tty/tty_ioctl.c
--- linux-libre-4.3-gnu/drivers/tty/tty_ioctl.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/tty/tty_ioctl.c	2016-01-22 23:59:37.000000000 -0500
@@ -1147,16 +1147,12 @@ int n_tty_ioctl_helper(struct tty_struct
 			spin_unlock_irq(&tty->flow_lock);
 			break;
 		case TCIOFF:
-			down_read(&tty->termios_rwsem);
 			if (STOP_CHAR(tty) != __DISABLED_CHAR)
 				retval = tty_send_xchar(tty, STOP_CHAR(tty));
-			up_read(&tty->termios_rwsem);
 			break;
 		case TCION:
-			down_read(&tty->termios_rwsem);
 			if (START_CHAR(tty) != __DISABLED_CHAR)
 				retval = tty_send_xchar(tty, START_CHAR(tty));
-			up_read(&tty->termios_rwsem);
 			break;
 		default:
 			return -EINVAL;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/chipidea/ci_hdrc_imx.c linux-libre-4.3.4-gnu/drivers/usb/chipidea/ci_hdrc_imx.c
--- linux-libre-4.3-gnu/drivers/usb/chipidea/ci_hdrc_imx.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/chipidea/ci_hdrc_imx.c	2016-01-22 23:59:37.000000000 -0500
@@ -73,6 +73,12 @@ struct ci_hdrc_imx_data {
 	struct imx_usbmisc_data *usbmisc_data;
 	bool supports_runtime_pm;
 	bool in_lpm;
+	/* SoC before i.mx6 (except imx23/imx28) needs three clks */
+	bool need_three_clks;
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+	struct clk *clk_per;
+	/* --------------------------------- */
 };
 
 /* Common functions shared by usbmisc drivers */
@@ -124,6 +130,102 @@ static struct imx_usbmisc_data *usbmisc_
 }
 
 /* End of common functions shared by usbmisc drivers*/
+static int imx_get_clks(struct device *dev)
+{
+	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+	int ret = 0;
+
+	data->clk_ipg = devm_clk_get(dev, "ipg");
+	if (IS_ERR(data->clk_ipg)) {
+		/* If the platform only needs one clocks */
+		data->clk = devm_clk_get(dev, NULL);
+		if (IS_ERR(data->clk)) {
+			ret = PTR_ERR(data->clk);
+			dev_err(dev,
+				"Failed to get clks, err=%ld,%ld\n",
+				PTR_ERR(data->clk), PTR_ERR(data->clk_ipg));
+			return ret;
+		}
+		return ret;
+	}
+
+	data->clk_ahb = devm_clk_get(dev, "ahb");
+	if (IS_ERR(data->clk_ahb)) {
+		ret = PTR_ERR(data->clk_ahb);
+		dev_err(dev,
+			"Failed to get ahb clock, err=%d\n", ret);
+		return ret;
+	}
+
+	data->clk_per = devm_clk_get(dev, "per");
+	if (IS_ERR(data->clk_per)) {
+		ret = PTR_ERR(data->clk_per);
+		dev_err(dev,
+			"Failed to get per clock, err=%d\n", ret);
+		return ret;
+	}
+
+	data->need_three_clks = true;
+	return ret;
+}
+
+static int imx_prepare_enable_clks(struct device *dev)
+{
+	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (data->need_three_clks) {
+		ret = clk_prepare_enable(data->clk_ipg);
+		if (ret) {
+			dev_err(dev,
+				"Failed to prepare/enable ipg clk, err=%d\n",
+				ret);
+			return ret;
+		}
+
+		ret = clk_prepare_enable(data->clk_ahb);
+		if (ret) {
+			dev_err(dev,
+				"Failed to prepare/enable ahb clk, err=%d\n",
+				ret);
+			clk_disable_unprepare(data->clk_ipg);
+			return ret;
+		}
+
+		ret = clk_prepare_enable(data->clk_per);
+		if (ret) {
+			dev_err(dev,
+				"Failed to prepare/enable per clk, err=%d\n",
+				ret);
+			clk_disable_unprepare(data->clk_ahb);
+			clk_disable_unprepare(data->clk_ipg);
+			return ret;
+		}
+	} else {
+		ret = clk_prepare_enable(data->clk);
+		if (ret) {
+			dev_err(dev,
+				"Failed to prepare/enable clk, err=%d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static void imx_disable_unprepare_clks(struct device *dev)
+{
+	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+
+	if (data->need_three_clks) {
+		clk_disable_unprepare(data->clk_per);
+		clk_disable_unprepare(data->clk_ahb);
+		clk_disable_unprepare(data->clk_ipg);
+	} else {
+		clk_disable_unprepare(data->clk);
+	}
+}
 
 static int ci_hdrc_imx_probe(struct platform_device *pdev)
 {
@@ -142,23 +244,18 @@ static int ci_hdrc_imx_probe(struct plat
 	if (!data)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, data);
 	data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
 	if (IS_ERR(data->usbmisc_data))
 		return PTR_ERR(data->usbmisc_data);
 
-	data->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(data->clk)) {
-		dev_err(&pdev->dev,
-			"Failed to get clock, err=%ld\n", PTR_ERR(data->clk));
-		return PTR_ERR(data->clk);
-	}
+	ret = imx_get_clks(&pdev->dev);
+	if (ret)
+		return ret;
 
-	ret = clk_prepare_enable(data->clk);
-	if (ret) {
-		dev_err(&pdev->dev,
-			"Failed to prepare or enable clock, err=%d\n", ret);
+	ret = imx_prepare_enable_clks(&pdev->dev);
+	if (ret)
 		return ret;
-	}
 
 	data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
 	if (IS_ERR(data->phy)) {
@@ -201,8 +298,6 @@ static int ci_hdrc_imx_probe(struct plat
 		goto disable_device;
 	}
 
-	platform_set_drvdata(pdev, data);
-
 	if (data->supports_runtime_pm) {
 		pm_runtime_set_active(&pdev->dev);
 		pm_runtime_enable(&pdev->dev);
@@ -215,7 +310,7 @@ static int ci_hdrc_imx_probe(struct plat
 disable_device:
 	ci_hdrc_remove_device(data->ci_pdev);
 err_clk:
-	clk_disable_unprepare(data->clk);
+	imx_disable_unprepare_clks(&pdev->dev);
 	return ret;
 }
 
@@ -229,7 +324,7 @@ static int ci_hdrc_imx_remove(struct pla
 		pm_runtime_put_noidle(&pdev->dev);
 	}
 	ci_hdrc_remove_device(data->ci_pdev);
-	clk_disable_unprepare(data->clk);
+	imx_disable_unprepare_clks(&pdev->dev);
 
 	return 0;
 }
@@ -241,7 +336,7 @@ static int imx_controller_suspend(struct
 
 	dev_dbg(dev, "at %s\n", __func__);
 
-	clk_disable_unprepare(data->clk);
+	imx_disable_unprepare_clks(dev);
 	data->in_lpm = true;
 
 	return 0;
@@ -259,7 +354,7 @@ static int imx_controller_resume(struct
 		return 0;
 	}
 
-	ret = clk_prepare_enable(data->clk);
+	ret = imx_prepare_enable_clks(dev);
 	if (ret)
 		return ret;
 
@@ -274,7 +369,7 @@ static int imx_controller_resume(struct
 	return 0;
 
 clk_disable:
-	clk_disable_unprepare(data->clk);
+	imx_disable_unprepare_clks(dev);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/chipidea/debug.c linux-libre-4.3.4-gnu/drivers/usb/chipidea/debug.c
--- linux-libre-4.3-gnu/drivers/usb/chipidea/debug.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/chipidea/debug.c	2016-01-22 23:59:37.000000000 -0500
@@ -322,8 +322,10 @@ static ssize_t ci_role_write(struct file
 		return -EINVAL;
 
 	pm_runtime_get_sync(ci->dev);
+	disable_irq(ci->irq);
 	ci_role_stop(ci);
 	ret = ci_role_start(ci, role);
+	enable_irq(ci->irq);
 	pm_runtime_put_sync(ci->dev);
 
 	return ret ? ret : count;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/chipidea/udc.c linux-libre-4.3.4-gnu/drivers/usb/chipidea/udc.c
--- linux-libre-4.3-gnu/drivers/usb/chipidea/udc.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/chipidea/udc.c	2016-01-22 23:59:37.000000000 -0500
@@ -1751,6 +1751,22 @@ static int ci_udc_start(struct usb_gadge
 	return retval;
 }
 
+static void ci_udc_stop_for_otg_fsm(struct ci_hdrc *ci)
+{
+	if (!ci_otg_is_fsm_mode(ci))
+		return;
+
+	mutex_lock(&ci->fsm.lock);
+	if (ci->fsm.otg->state == OTG_STATE_A_PERIPHERAL) {
+		ci->fsm.a_bidl_adis_tmout = 1;
+		ci_hdrc_otg_fsm_start(ci);
+	} else if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) {
+		ci->fsm.protocol = PROTO_UNDEF;
+		ci->fsm.otg->state = OTG_STATE_UNDEFINED;
+	}
+	mutex_unlock(&ci->fsm.lock);
+}
+
 /**
  * ci_udc_stop: unregister a gadget driver
  */
@@ -1775,6 +1791,7 @@ static int ci_udc_stop(struct usb_gadget
 	ci->driver = NULL;
 	spin_unlock_irqrestore(&ci->lock, flags);
 
+	ci_udc_stop_for_otg_fsm(ci);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/class/cdc-acm.c linux-libre-4.3.4-gnu/drivers/usb/class/cdc-acm.c
--- linux-libre-4.3-gnu/drivers/usb/class/cdc-acm.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/class/cdc-acm.c	2016-01-22 23:59:37.000000000 -0500
@@ -1838,6 +1838,11 @@ static const struct usb_device_id acm_id
 	},
 #endif
 
+	/* Exclude Infineon Flash Loader utility */
+	{ USB_DEVICE(0x058b, 0x0041),
+	.driver_info = IGNORE_DEVICE,
+	},
+
 	/* control interfaces without any protocol set */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_PROTO_NONE) },
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/class/usblp.c linux-libre-4.3.4-gnu/drivers/usb/class/usblp.c
--- linux-libre-4.3-gnu/drivers/usb/class/usblp.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/class/usblp.c	2016-01-22 23:59:37.000000000 -0500
@@ -884,11 +884,11 @@ static int usblp_wwait(struct usblp *usb
 
 	add_wait_queue(&usblp->wwait, &waita);
 	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
 		if (mutex_lock_interruptible(&usblp->mut)) {
 			rc = -EINTR;
 			break;
 		}
+		set_current_state(TASK_INTERRUPTIBLE);
 		rc = usblp_wtest(usblp, nonblock);
 		mutex_unlock(&usblp->mut);
 		if (rc <= 0)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/core/config.c linux-libre-4.3.4-gnu/drivers/usb/core/config.c
--- linux-libre-4.3-gnu/drivers/usb/core/config.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/core/config.c	2016-01-22 23:59:37.000000000 -0500
@@ -115,7 +115,8 @@ static void usb_parse_ss_endpoint_compan
 		   USB_SS_MULT(desc->bmAttributes) > 3) {
 		dev_warn(ddev, "Isoc endpoint has Mult of %d in "
 				"config %d interface %d altsetting %d ep %d: "
-				"setting to 3\n", desc->bmAttributes + 1,
+				"setting to 3\n",
+				USB_SS_MULT(desc->bmAttributes),
 				cfgno, inum, asnum, ep->desc.bEndpointAddress);
 		ep->ss_ep_comp.bmAttributes = 2;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/core/hub.c linux-libre-4.3.4-gnu/drivers/usb/core/hub.c
--- linux-libre-4.3-gnu/drivers/usb/core/hub.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/core/hub.c	2016-01-22 23:59:37.000000000 -0500
@@ -124,6 +124,10 @@ struct usb_hub *usb_hub_to_struct_hub(st
 
 int usb_device_supports_lpm(struct usb_device *udev)
 {
+	/* Some devices have trouble with LPM */
+	if (udev->quirks & USB_QUIRK_NO_LPM)
+		return 0;
+
 	/* USB 2.1 (and greater) devices indicate LPM support through
 	 * their USB 2.0 Extended Capabilities BOS descriptor.
 	 */
@@ -4503,6 +4507,8 @@ hub_port_init (struct usb_hub *hub, stru
 		goto fail;
 	}
 
+	usb_detect_quirks(udev);
+
 	if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
 		retval = usb_get_bos_descriptor(udev);
 		if (!retval) {
@@ -4701,7 +4707,6 @@ static void hub_port_connect(struct usb_
 		if (status < 0)
 			goto loop;
 
-		usb_detect_quirks(udev);
 		if (udev->quirks & USB_QUIRK_DELAY_INIT)
 			msleep(1000);
 
@@ -5317,9 +5322,6 @@ static int usb_reset_and_verify_device(s
 	if (udev->usb2_hw_lpm_enabled == 1)
 		usb_set_usb2_hardware_lpm(udev, 0);
 
-	bos = udev->bos;
-	udev->bos = NULL;
-
 	/* Disable LPM and LTM while we reset the device and reinstall the alt
 	 * settings.  Device-initiated LPM settings, and system exit latency
 	 * settings are cleared when the device is reset, so we have to set
@@ -5328,15 +5330,18 @@ static int usb_reset_and_verify_device(s
 	ret = usb_unlocked_disable_lpm(udev);
 	if (ret) {
 		dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__);
-		goto re_enumerate;
+		goto re_enumerate_no_bos;
 	}
 	ret = usb_disable_ltm(udev);
 	if (ret) {
 		dev_err(&udev->dev, "%s Failed to disable LTM\n.",
 				__func__);
-		goto re_enumerate;
+		goto re_enumerate_no_bos;
 	}
 
+	bos = udev->bos;
+	udev->bos = NULL;
+
 	for (i = 0; i < SET_CONFIG_TRIES; ++i) {
 
 		/* ep0 maxpacket size may change; let the HCD know about it.
@@ -5433,10 +5438,11 @@ done:
 	return 0;
 
 re_enumerate:
-	/* LPM state doesn't matter when we're about to destroy the device. */
-	hub_port_logical_disconnect(parent_hub, port1);
 	usb_release_bos_descriptor(udev);
 	udev->bos = bos;
+re_enumerate_no_bos:
+	/* LPM state doesn't matter when we're about to destroy the device. */
+	hub_port_logical_disconnect(parent_hub, port1);
 	return -ENODEV;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/core/quirks.c linux-libre-4.3.4-gnu/drivers/usb/core/quirks.c
--- linux-libre-4.3-gnu/drivers/usb/core/quirks.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/core/quirks.c	2016-01-22 23:59:37.000000000 -0500
@@ -199,6 +199,12 @@ static const struct usb_device_id usb_qu
 	{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+	/* Blackmagic Design Intensity Shuttle */
+	{ USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
+
+	/* Blackmagic Design UltraStudio SDI */
+	{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
+
 	{ }  /* terminating entry must be last */
 };
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/dwc3/core.c linux-libre-4.3.4-gnu/drivers/usb/dwc3/core.c
--- linux-libre-4.3-gnu/drivers/usb/dwc3/core.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/dwc3/core.c	2016-01-22 23:59:37.000000000 -0500
@@ -488,6 +488,9 @@ static int dwc3_phy_setup(struct dwc3 *d
 	if (dwc->dis_u2_susphy_quirk)
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
+	if (dwc->dis_enblslpm_quirk)
+		reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
 	return 0;
@@ -507,12 +510,18 @@ static int dwc3_core_init(struct dwc3 *d
 
 	reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
 	/* This should read as U3 followed by revision number */
-	if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
+	if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
+		/* Detected DWC_usb3 IP */
+		dwc->revision = reg;
+	} else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
+		/* Detected DWC_usb31 IP */
+		dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
+		dwc->revision |= DWC3_REVISION_IS_DWC31;
+	} else {
 		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
 		ret = -ENODEV;
 		goto err0;
 	}
-	dwc->revision = reg;
 
 	/*
 	 * Write Linux Version Code to our GUID register so it's easy to figure
@@ -879,6 +888,8 @@ static int dwc3_probe(struct platform_de
 				"snps,dis_u3_susphy_quirk");
 		dwc->dis_u2_susphy_quirk = of_property_read_bool(node,
 				"snps,dis_u2_susphy_quirk");
+	dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
+				"snps,dis_enblslpm_quirk");
 
 		dwc->tx_de_emphasis_quirk = of_property_read_bool(node,
 				"snps,tx_de_emphasis_quirk");
@@ -909,6 +920,7 @@ static int dwc3_probe(struct platform_de
 		dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk;
 		dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk;
 		dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk;
+		dwc->dis_enblslpm_quirk = pdata->dis_enblslpm_quirk;
 
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		if (pdata->tx_de_emphasis)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/dwc3/core.h linux-libre-4.3.4-gnu/drivers/usb/dwc3/core.h
--- linux-libre-4.3-gnu/drivers/usb/dwc3/core.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/dwc3/core.h	2016-01-22 23:59:37.000000000 -0500
@@ -108,6 +108,9 @@
 #define DWC3_GPRTBIMAP_FS0	0xc188
 #define DWC3_GPRTBIMAP_FS1	0xc18c
 
+#define DWC3_VER_NUMBER		0xc1a0
+#define DWC3_VER_TYPE		0xc1a4
+
 #define DWC3_GUSB2PHYCFG(n)	(0xc200 + (n * 0x04))
 #define DWC3_GUSB2I2CCTL(n)	(0xc240 + (n * 0x04))
 
@@ -175,6 +178,7 @@
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI	(1 << 4)
+#define DWC3_GUSB2PHYCFG_ENBLSLPM	(1 << 8)
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
@@ -712,6 +716,8 @@ struct dwc3_scratchpad_array {
  * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk
  * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
+ * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
+ *                      disabling the suspend signal to the PHY.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 	0	- -6dB de-emphasis
@@ -766,6 +772,14 @@ struct dwc3 {
 	u32			num_event_buffers;
 	u32			u1u2;
 	u32			maximum_speed;
+
+	/*
+	 * All 3.1 IP version constants are greater than the 3.0 IP
+	 * version constants. This works for most version checks in
+	 * dwc3. However, in the future, this may not apply as
+	 * features may be developed on newer versions of the 3.0 IP
+	 * that are not in the 3.1 IP.
+	 */
 	u32			revision;
 
 #define DWC3_REVISION_173A	0x5533173a
@@ -788,6 +802,13 @@ struct dwc3 {
 #define DWC3_REVISION_270A	0x5533270a
 #define DWC3_REVISION_280A	0x5533280a
 
+/*
+ * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really
+ * just so dwc31 revisions are always larger than dwc3.
+ */
+#define DWC3_REVISION_IS_DWC31		0x80000000
+#define DWC3_USB31_REVISION_110A	(0x3131302a | DWC3_REVISION_IS_USB31)
+
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_state	ep0state;
 	enum dwc3_link_state	link_state;
@@ -841,6 +862,7 @@ struct dwc3 {
 	unsigned		rx_detect_poll_quirk:1;
 	unsigned		dis_u3_susphy_quirk:1;
 	unsigned		dis_u2_susphy_quirk:1;
+	unsigned		dis_enblslpm_quirk:1;
 
 	unsigned		tx_de_emphasis_quirk:1;
 	unsigned		tx_de_emphasis:2;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/dwc3/dwc3-pci.c linux-libre-4.3.4-gnu/drivers/usb/dwc3/dwc3-pci.c
--- linux-libre-4.3-gnu/drivers/usb/dwc3/dwc3-pci.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/dwc3/dwc3-pci.c	2016-01-22 23:59:37.000000000 -0500
@@ -27,6 +27,8 @@
 #include "platform_data.h"
 
 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf
 #define PCI_DEVICE_ID_INTEL_BYT		0x0f37
 #define PCI_DEVICE_ID_INTEL_MRFLD	0x119e
 #define PCI_DEVICE_ID_INTEL_BSW		0x22B7
@@ -106,6 +108,22 @@ static int dwc3_pci_quirks(struct pci_de
 		}
 	}
 
+	if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS &&
+	    (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 ||
+	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI ||
+	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) {
+
+		struct dwc3_platform_data pdata;
+
+		memset(&pdata, 0, sizeof(pdata));
+		pdata.usb3_lpm_capable = true;
+		pdata.has_lpm_erratum = true;
+		pdata.dis_enblslpm_quirk = true;
+
+		return platform_device_add_data(pci_get_drvdata(pdev), &pdata,
+						sizeof(pdata));
+	}
+
 	return 0;
 }
 
@@ -178,6 +196,14 @@ static const struct pci_device_id dwc3_p
 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
 	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI),
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31),
+	},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/dwc3/gadget.c linux-libre-4.3.4-gnu/drivers/usb/dwc3/gadget.c
--- linux-libre-4.3-gnu/drivers/usb/dwc3/gadget.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/dwc3/gadget.c	2016-01-22 23:59:37.000000000 -0500
@@ -1872,27 +1872,32 @@ static int dwc3_cleanup_done_reqs(struct
 	unsigned int		i;
 	int			ret;
 
-	req = next_request(&dep->req_queued);
-	if (!req) {
-		WARN_ON_ONCE(1);
-		return 1;
-	}
-	i = 0;
 	do {
-		slot = req->start_slot + i;
-		if ((slot == DWC3_TRB_NUM - 1) &&
+		req = next_request(&dep->req_queued);
+		if (!req) {
+			WARN_ON_ONCE(1);
+			return 1;
+		}
+		i = 0;
+		do {
+			slot = req->start_slot + i;
+			if ((slot == DWC3_TRB_NUM - 1) &&
 				usb_endpoint_xfer_isoc(dep->endpoint.desc))
-			slot++;
-		slot %= DWC3_TRB_NUM;
-		trb = &dep->trb_pool[slot];
+				slot++;
+			slot %= DWC3_TRB_NUM;
+			trb = &dep->trb_pool[slot];
+
+			ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
+					event, status);
+			if (ret)
+				break;
+		} while (++i < req->request.num_mapped_sgs);
+
+		dwc3_gadget_giveback(dep, req, status);
 
-		ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
-				event, status);
 		if (ret)
 			break;
-	} while (++i < req->request.num_mapped_sgs);
-
-	dwc3_gadget_giveback(dep, req, status);
+	} while (1);
 
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 			list_empty(&dep->req_queued)) {
@@ -2718,12 +2723,34 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 	}
 
 	dwc->gadget.ops			= &dwc3_gadget_ops;
-	dwc->gadget.max_speed		= USB_SPEED_SUPER;
 	dwc->gadget.speed		= USB_SPEED_UNKNOWN;
 	dwc->gadget.sg_supported	= true;
 	dwc->gadget.name		= "dwc3-gadget";
 
 	/*
+	 * FIXME We might be setting max_speed to <SUPER, however versions
+	 * <2.20a of dwc3 have an issue with metastability (documented
+	 * elsewhere in this driver) which tells us we can't set max speed to
+	 * anything lower than SUPER.
+	 *
+	 * Because gadget.max_speed is only used by composite.c and function
+	 * drivers (i.e. it won't go into dwc3's registers) we are allowing this
+	 * to happen so we avoid sending SuperSpeed Capability descriptor
+	 * together with our BOS descriptor as that could confuse host into
+	 * thinking we can handle super speed.
+	 *
+	 * Note that, in fact, we won't even support GetBOS requests when speed
+	 * is less than super speed because we don't have means, yet, to tell
+	 * composite.c that we are USB 2.0 + LPM ECN.
+	 */
+	if (dwc->revision < DWC3_REVISION_220A)
+		dwc3_trace(trace_dwc3_gadget,
+				"Changing max_speed on rev %08x\n",
+				dwc->revision);
+
+	dwc->gadget.max_speed		= dwc->maximum_speed;
+
+	/*
 	 * Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
 	 * on ep out.
 	 */
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/dwc3/platform_data.h linux-libre-4.3.4-gnu/drivers/usb/dwc3/platform_data.h
--- linux-libre-4.3-gnu/drivers/usb/dwc3/platform_data.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/dwc3/platform_data.h	2016-01-22 23:59:37.000000000 -0500
@@ -42,6 +42,7 @@ struct dwc3_platform_data {
 	unsigned rx_detect_poll_quirk:1;
 	unsigned dis_u3_susphy_quirk:1;
 	unsigned dis_u2_susphy_quirk:1;
+	unsigned dis_enblslpm_quirk:1;
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c linux-libre-4.3.4-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c
--- linux-libre-4.3-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c	2016-01-22 23:59:37.000000000 -0500
@@ -1633,7 +1633,7 @@ static irqreturn_t usba_udc_irq(int irq,
 	spin_lock(&udc->lock);
 
 	int_enb = usba_int_enb_get(udc);
-	status = usba_readl(udc, INT_STA) & int_enb;
+	status = usba_readl(udc, INT_STA) & (int_enb | USBA_HIGH_SPEED);
 	DBG(DBG_INT, "irq, status=%#08x\n", status);
 
 	if (status & USBA_DET_SUSPEND) {
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/gadget/udc/net2280.c linux-libre-4.3.4-gnu/drivers/usb/gadget/udc/net2280.c
--- linux-libre-4.3-gnu/drivers/usb/gadget/udc/net2280.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/gadget/udc/net2280.c	2016-01-22 23:59:37.000000000 -0500
@@ -1913,7 +1913,7 @@ static void defect7374_disable_data_eps(
 
 	for (i = 1; i < 5; i++) {
 		ep = &dev->ep[i];
-		writel(0, &ep->cfg->ep_cfg);
+		writel(i, &ep->cfg->ep_cfg);
 	}
 
 	/* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/gadget/udc/pxa27x_udc.c linux-libre-4.3.4-gnu/drivers/usb/gadget/udc/pxa27x_udc.c
--- linux-libre-4.3-gnu/drivers/usb/gadget/udc/pxa27x_udc.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/gadget/udc/pxa27x_udc.c	2016-01-22 23:59:37.000000000 -0500
@@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platfo
 	udc->pullup_resume = udc->pullup_on;
 	dplus_pullup(udc, 0);
 
+	if (udc->driver)
+		udc->driver->disconnect(&udc->gadget);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/host/ehci-orion.c linux-libre-4.3.4-gnu/drivers/usb/host/ehci-orion.c
--- linux-libre-4.3-gnu/drivers/usb/host/ehci-orion.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/host/ehci-orion.c	2016-01-22 23:59:37.000000000 -0500
@@ -224,7 +224,8 @@ static int ehci_orion_drv_probe(struct p
 	priv->phy = devm_phy_optional_get(&pdev->dev, "usb");
 	if (IS_ERR(priv->phy)) {
 		err = PTR_ERR(priv->phy);
-		goto err_phy_get;
+		if (err != -ENOSYS)
+			goto err_phy_get;
 	} else {
 		err = phy_init(priv->phy);
 		if (err)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/host/ohci-at91.c linux-libre-4.3.4-gnu/drivers/usb/host/ohci-at91.c
--- linux-libre-4.3-gnu/drivers/usb/host/ohci-at91.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/host/ohci-at91.c	2016-01-22 23:59:37.000000000 -0500
@@ -473,6 +473,8 @@ static int ohci_hcd_at91_drv_probe(struc
 	if (!pdata)
 		return -ENOMEM;
 
+	pdev->dev.platform_data = pdata;
+
 	if (!of_property_read_u32(np, "num-ports", &ports))
 		pdata->ports = ports;
 
@@ -483,6 +485,7 @@ static int ohci_hcd_at91_drv_probe(struc
 		 */
 		if (i >= pdata->ports) {
 			pdata->vbus_pin[i] = -EINVAL;
+			pdata->overcurrent_pin[i] = -EINVAL;
 			continue;
 		}
 
@@ -513,10 +516,8 @@ static int ohci_hcd_at91_drv_probe(struc
 	}
 
 	at91_for_each_port(i) {
-		if (i >= pdata->ports) {
-			pdata->overcurrent_pin[i] = -EINVAL;
-			continue;
-		}
+		if (i >= pdata->ports)
+			break;
 
 		pdata->overcurrent_pin[i] =
 			of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
@@ -552,8 +553,6 @@ static int ohci_hcd_at91_drv_probe(struc
 		}
 	}
 
-	pdev->dev.platform_data = pdata;
-
 	device_init_wakeup(&pdev->dev, 1);
 	return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/host/whci/qset.c linux-libre-4.3.4-gnu/drivers/usb/host/whci/qset.c
--- linux-libre-4.3-gnu/drivers/usb/host/whci/qset.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/host/whci/qset.c	2016-01-22 23:59:37.000000000 -0500
@@ -377,6 +377,10 @@ static int qset_fill_page_list(struct wh
 	if (std->pl_virt == NULL)
 		return -ENOMEM;
 	std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
+	if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr)) {
+		kfree(std->pl_virt);
+		return -EFAULT;
+	}
 
 	for (p = 0; p < std->num_pointers; p++) {
 		std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/host/xhci.c linux-libre-4.3.4-gnu/drivers/usb/host/xhci.c
--- linux-libre-4.3-gnu/drivers/usb/host/xhci.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/host/xhci.c	2016-01-22 23:59:37.000000000 -0500
@@ -175,6 +175,16 @@ int xhci_reset(struct xhci_hcd *xhci)
 	command |= CMD_RESET;
 	writel(command, &xhci->op_regs->command);
 
+	/* Existing Intel xHCI controllers require a delay of 1 mS,
+	 * after setting the CMD_RESET bit, and before accessing any
+	 * HC registers. This allows the HC to complete the
+	 * reset operation and be ready for HC register access.
+	 * Without this delay, the subsequent HC register access,
+	 * may result in a system hang very rarely.
+	 */
+	if (xhci->quirks & XHCI_INTEL_HOST)
+		udelay(1000);
+
 	ret = xhci_handshake(&xhci->op_regs->command,
 			CMD_RESET, 0, 10 * 1000 * 1000);
 	if (ret)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/host/xhci-ring.c linux-libre-4.3.4-gnu/drivers/usb/host/xhci-ring.c
--- linux-libre-4.3-gnu/drivers/usb/host/xhci-ring.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/host/xhci-ring.c	2016-01-22 23:59:37.000000000 -0500
@@ -3914,28 +3914,6 @@ cleanup:
 	return ret;
 }
 
-static int ep_ring_is_processing(struct xhci_hcd *xhci,
-		int slot_id, unsigned int ep_index)
-{
-	struct xhci_virt_device *xdev;
-	struct xhci_ring *ep_ring;
-	struct xhci_ep_ctx *ep_ctx;
-	struct xhci_virt_ep *xep;
-	dma_addr_t hw_deq;
-
-	xdev = xhci->devs[slot_id];
-	xep = &xhci->devs[slot_id]->eps[ep_index];
-	ep_ring = xep->ring;
-	ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
-
-	if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) != EP_STATE_RUNNING)
-		return 0;
-
-	hw_deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK;
-	return (hw_deq !=
-		xhci_trb_virt_to_dma(ep_ring->enq_seg, ep_ring->enqueue));
-}
-
 /*
  * Check transfer ring to guarantee there is enough room for the urb.
  * Update ISO URB start_frame and interval.
@@ -4001,10 +3979,12 @@ int xhci_queue_isoc_tx_prepare(struct xh
 	}
 
 	/* Calculate the start frame and put it in urb->start_frame. */
-	if (HCC_CFC(xhci->hcc_params) &&
-			ep_ring_is_processing(xhci, slot_id, ep_index)) {
-		urb->start_frame = xep->next_frame_id;
-		goto skip_start_over;
+	if (HCC_CFC(xhci->hcc_params) && !list_empty(&ep_ring->td_list)) {
+		if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) ==
+				EP_STATE_RUNNING) {
+			urb->start_frame = xep->next_frame_id;
+			goto skip_start_over;
+		}
 	}
 
 	start_frame = readl(&xhci->run_regs->microframe_index);
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/musb/Kconfig linux-libre-4.3.4-gnu/drivers/usb/musb/Kconfig
--- linux-libre-4.3-gnu/drivers/usb/musb/Kconfig	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/musb/Kconfig	2016-01-22 23:59:37.000000000 -0500
@@ -159,7 +159,7 @@ config USB_TI_CPPI_DMA
 
 config USB_TI_CPPI41_DMA
 	bool 'TI CPPI 4.1 (AM335x)'
-	depends on ARCH_OMAP
+	depends on ARCH_OMAP && DMADEVICES
 	select TI_CPPI41
 
 config USB_TUSB_OMAP_DMA
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/musb/musb_core.c linux-libre-4.3.4-gnu/drivers/usb/musb/musb_core.c
--- linux-libre-4.3-gnu/drivers/usb/musb/musb_core.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/musb/musb_core.c	2016-01-22 23:59:37.000000000 -0500
@@ -132,7 +132,7 @@ static inline struct musb *dev_to_musb(s
 /*-------------------------------------------------------------------------*/
 
 #ifndef CONFIG_BLACKFIN
-static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
+static int musb_ulpi_read(struct usb_phy *phy, u32 reg)
 {
 	void __iomem *addr = phy->io_priv;
 	int	i = 0;
@@ -151,7 +151,7 @@ static int musb_ulpi_read(struct usb_phy
 	 * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
 	 */
 
-	musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
+	musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
 	musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
 			MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
 
@@ -176,7 +176,7 @@ out:
 	return ret;
 }
 
-static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
+static int musb_ulpi_write(struct usb_phy *phy, u32 val, u32 reg)
 {
 	void __iomem *addr = phy->io_priv;
 	int	i = 0;
@@ -191,8 +191,8 @@ static int musb_ulpi_write(struct usb_ph
 	power &= ~MUSB_POWER_SUSPENDM;
 	musb_writeb(addr, MUSB_POWER, power);
 
-	musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
-	musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
+	musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
+	musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)val);
 	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
 
 	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/phy/phy-omap-otg.c linux-libre-4.3.4-gnu/drivers/usb/phy/phy-omap-otg.c
--- linux-libre-4.3-gnu/drivers/usb/phy/phy-omap-otg.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/phy/phy-omap-otg.c	2016-01-22 23:59:37.000000000 -0500
@@ -105,7 +105,6 @@ static int omap_otg_probe(struct platfor
 	extcon = extcon_get_extcon_dev(config->extcon);
 	if (!extcon)
 		return -EPROBE_DEFER;
-	otg_dev->extcon = extcon;
 
 	otg_dev = devm_kzalloc(&pdev->dev, sizeof(*otg_dev), GFP_KERNEL);
 	if (!otg_dev)
@@ -115,6 +114,7 @@ static int omap_otg_probe(struct platfor
 	if (IS_ERR(otg_dev->base))
 		return PTR_ERR(otg_dev->base);
 
+	otg_dev->extcon = extcon;
 	otg_dev->id_nb.notifier_call = omap_otg_id_notifier;
 	otg_dev->vbus_nb.notifier_call = omap_otg_vbus_notifier;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/serial/cp210x.c linux-libre-4.3.4-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-4.3-gnu/drivers/usb/serial/cp210x.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/serial/cp210x.c	2016-01-22 23:59:37.000000000 -0500
@@ -132,7 +132,6 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
-	{ USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
 	{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
 	{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/serial/option.c linux-libre-4.3.4-gnu/drivers/usb/serial/option.c
--- linux-libre-4.3-gnu/drivers/usb/serial/option.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/serial/option.c	2016-01-22 23:59:37.000000000 -0500
@@ -162,6 +162,7 @@ static void option_instat_callback(struc
 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED	0x9001
 #define NOVATELWIRELESS_PRODUCT_E362		0x9010
 #define NOVATELWIRELESS_PRODUCT_E371		0x9011
+#define NOVATELWIRELESS_PRODUCT_U620L		0x9022
 #define NOVATELWIRELESS_PRODUCT_G2		0xA010
 #define NOVATELWIRELESS_PRODUCT_MC551		0xB001
 
@@ -357,6 +358,7 @@ static void option_instat_callback(struc
 /* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
  * It seems to contain a Qualcomm QSC6240/6290 chipset            */
 #define FOUR_G_SYSTEMS_PRODUCT_W14		0x9603
+#define FOUR_G_SYSTEMS_PRODUCT_W100		0x9b01
 
 /* iBall 3.5G connect wireless modem */
 #define IBALL_3_5G_CONNECT			0x9605
@@ -522,6 +524,11 @@ static const struct option_blacklist_inf
 	.sendsetup = BIT(0) | BIT(1),
 };
 
+static const struct option_blacklist_info four_g_w100_blacklist = {
+	.sendsetup = BIT(1) | BIT(2),
+	.reserved = BIT(3),
+};
+
 static const struct option_blacklist_info alcatel_x200_blacklist = {
 	.sendsetup = BIT(0) | BIT(1),
 	.reserved = BIT(4),
@@ -1060,6 +1067,7 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U620L, 0xff, 0x00, 0x00) },
 
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
@@ -1653,6 +1661,9 @@ static const struct usb_device_id option
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
   	  .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
   	},
+	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100),
+	  .driver_info = (kernel_ulong_t)&four_g_w100_blacklist
+	},
 	{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/serial/qcserial.c linux-libre-4.3.4-gnu/drivers/usb/serial/qcserial.c
--- linux-libre-4.3-gnu/drivers/usb/serial/qcserial.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/serial/qcserial.c	2016-01-22 23:59:37.000000000 -0500
@@ -22,6 +22,8 @@
 #define DRIVER_AUTHOR "Qualcomm Inc"
 #define DRIVER_DESC "Qualcomm USB Serial driver"
 
+#define QUECTEL_EC20_PID	0x9215
+
 /* standard device layouts supported by this driver */
 enum qcserial_layouts {
 	QCSERIAL_G2K = 0,	/* Gobi 2000 */
@@ -153,6 +155,8 @@ static const struct usb_device_id id_tab
 	{DEVICE_SWI(0x1199, 0x9056)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9060)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9061)},	/* Sierra Wireless Modem */
+	{DEVICE_SWI(0x1199, 0x9070)},	/* Sierra Wireless MC74xx/EM74xx */
+	{DEVICE_SWI(0x1199, 0x9071)},	/* Sierra Wireless MC74xx/EM74xx */
 	{DEVICE_SWI(0x413c, 0x81a2)},	/* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a3)},	/* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a4)},	/* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
@@ -167,6 +171,38 @@ static const struct usb_device_id id_tab
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
+static int handle_quectel_ec20(struct device *dev, int ifnum)
+{
+	int altsetting = 0;
+
+	/*
+	 * Quectel EC20 Mini PCIe LTE module layout:
+	 * 0: DM/DIAG (use libqcdm from ModemManager for communication)
+	 * 1: NMEA
+	 * 2: AT-capable modem port
+	 * 3: Modem interface
+	 * 4: NDIS
+	 */
+	switch (ifnum) {
+	case 0:
+		dev_dbg(dev, "Quectel EC20 DM/DIAG interface found\n");
+		break;
+	case 1:
+		dev_dbg(dev, "Quectel EC20 NMEA GPS interface found\n");
+		break;
+	case 2:
+	case 3:
+		dev_dbg(dev, "Quectel EC20 Modem port found\n");
+		break;
+	case 4:
+		/* Don't claim the QMI/net interface */
+		altsetting = -1;
+		break;
+	}
+
+	return altsetting;
+}
+
 static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 {
 	struct usb_host_interface *intf = serial->interface->cur_altsetting;
@@ -176,6 +212,10 @@ static int qcprobe(struct usb_serial *se
 	__u8 ifnum;
 	int altsetting = -1;
 
+	/* we only support vendor specific functions */
+	if (intf->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+		goto done;
+
 	nintf = serial->dev->actconfig->desc.bNumInterfaces;
 	dev_dbg(dev, "Num Interfaces = %d\n", nintf);
 	ifnum = intf->desc.bInterfaceNumber;
@@ -235,6 +275,12 @@ static int qcprobe(struct usb_serial *se
 			altsetting = -1;
 		break;
 	case QCSERIAL_G2K:
+		/* handle non-standard layouts */
+		if (nintf == 5 && id->idProduct == QUECTEL_EC20_PID) {
+			altsetting = handle_quectel_ec20(dev, ifnum);
+			goto done;
+		}
+
 		/*
 		 * Gobi 2K+ USB layout:
 		 * 0: QMI/net
@@ -295,29 +341,39 @@ static int qcprobe(struct usb_serial *se
 		break;
 	case QCSERIAL_HWI:
 		/*
-		 * Huawei layout:
-		 * 0: AT-capable modem port
-		 * 1: DM/DIAG
-		 * 2: AT-capable modem port
-		 * 3: CCID-compatible PCSC interface
-		 * 4: QMI/net
-		 * 5: NMEA
+		 * Huawei devices map functions by subclass + protocol
+		 * instead of interface numbers. The protocol identify
+		 * a specific function, while the subclass indicate a
+		 * specific firmware source
+		 *
+		 * This is a blacklist of functions known to be
+		 * non-serial.  The rest are assumed to be serial and
+		 * will be handled by this driver
 		 */
-		switch (ifnum) {
-		case 0:
-		case 2:
-			dev_dbg(dev, "Modem port found\n");
-			break;
-		case 1:
-			dev_dbg(dev, "DM/DIAG interface found\n");
-			break;
-		case 5:
-			dev_dbg(dev, "NMEA GPS interface found\n");
-			break;
-		default:
-			/* don't claim any unsupported interface */
+		switch (intf->desc.bInterfaceProtocol) {
+			/* QMI combined (qmi_wwan) */
+		case 0x07:
+		case 0x37:
+		case 0x67:
+			/* QMI data (qmi_wwan) */
+		case 0x08:
+		case 0x38:
+		case 0x68:
+			/* QMI control (qmi_wwan) */
+		case 0x09:
+		case 0x39:
+		case 0x69:
+			/* NCM like (huawei_cdc_ncm) */
+		case 0x16:
+		case 0x46:
+		case 0x76:
 			altsetting = -1;
 			break;
+		default:
+			dev_dbg(dev, "Huawei type serial port found (%02x/%02x/%02x)\n",
+				intf->desc.bInterfaceClass,
+				intf->desc.bInterfaceSubClass,
+				intf->desc.bInterfaceProtocol);
 		}
 		break;
 	default:
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/serial/ti_usb_3410_5052.c linux-libre-4.3.4-gnu/drivers/usb/serial/ti_usb_3410_5052.c
--- linux-libre-4.3-gnu/drivers/usb/serial/ti_usb_3410_5052.c	2015-11-01 23:43:00.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/serial/ti_usb_3410_5052.c	2016-01-23 08:25:06.000000000 -0500
@@ -159,6 +159,7 @@ static const struct usb_device_id ti_id_
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+	{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
 	{ }	/* terminator */
 };
 
@@ -191,6 +192,7 @@ static const struct usb_device_id ti_id_
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+	{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
 	{ }	/* terminator */
 };
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/serial/ti_usb_3410_5052.h linux-libre-4.3.4-gnu/drivers/usb/serial/ti_usb_3410_5052.h
--- linux-libre-4.3-gnu/drivers/usb/serial/ti_usb_3410_5052.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/serial/ti_usb_3410_5052.h	2016-01-22 23:59:37.000000000 -0500
@@ -56,6 +56,10 @@
 #define ABBOTT_PRODUCT_ID		ABBOTT_STEREO_PLUG_ID
 #define ABBOTT_STRIP_PORT_ID		0x3420
 
+/* Honeywell vendor and product IDs */
+#define HONEYWELL_VENDOR_ID		0x10ac
+#define HONEYWELL_HGI80_PRODUCT_ID	0x0102  /* Honeywell HGI80 */
+
 /* Commands */
 #define TI_GET_VERSION			0x01
 #define TI_GET_PORT_STATUS		0x02
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/serial/usb-serial-simple.c linux-libre-4.3.4-gnu/drivers/usb/serial/usb-serial-simple.c
--- linux-libre-4.3-gnu/drivers/usb/serial/usb-serial-simple.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/serial/usb-serial-simple.c	2016-01-22 23:59:37.000000000 -0500
@@ -53,6 +53,7 @@ DEVICE(funsoft, FUNSOFT_IDS);
 
 /* Infineon Flashloader driver */
 #define FLASHLOADER_IDS()		\
+	{ USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
 	{ USB_DEVICE(0x8087, 0x0716) }
 DEVICE(flashloader, FLASHLOADER_IDS);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/storage/uas.c linux-libre-4.3.4-gnu/drivers/usb/storage/uas.c
--- linux-libre-4.3-gnu/drivers/usb/storage/uas.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/storage/uas.c	2016-01-22 23:59:37.000000000 -0500
@@ -796,6 +796,10 @@ static int uas_slave_configure(struct sc
 	if (devinfo->flags & US_FL_NO_REPORT_OPCODES)
 		sdev->no_report_opcodes = 1;
 
+	/* A few buggy USB-ATA bridges don't understand FUA */
+	if (devinfo->flags & US_FL_BROKEN_FUA)
+		sdev->broken_fua = 1;
+
 	scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/storage/unusual_devs.h linux-libre-4.3.4-gnu/drivers/usb/storage/unusual_devs.h
--- linux-libre-4.3-gnu/drivers/usb/storage/unusual_devs.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/storage/unusual_devs.h	2016-01-22 23:59:37.000000000 -0500
@@ -1987,7 +1987,7 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x
 		US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Michael Büsch <m@bues.ch> */
-UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0114,
+UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
 		"JMicron",
 		"USB to ATA/ATAPI Bridge",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/usb/storage/unusual_uas.h linux-libre-4.3.4-gnu/drivers/usb/storage/unusual_uas.h
--- linux-libre-4.3-gnu/drivers/usb/storage/unusual_uas.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/usb/storage/unusual_uas.h	2016-01-22 23:59:37.000000000 -0500
@@ -132,7 +132,7 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x99
 		"JMicron",
 		"JMS567",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-		US_FL_NO_REPORT_OPCODES),
+		US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),
 
 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
 UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
diff -druNp --no-dereference linux-libre-4.3-gnu/drivers/xen/events/events_base.c linux-libre-4.3.4-gnu/drivers/xen/events/events_base.c
--- linux-libre-4.3-gnu/drivers/xen/events/events_base.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/drivers/xen/events/events_base.c	2016-01-22 23:59:37.000000000 -0500
@@ -39,6 +39,7 @@
 #include <asm/irq.h>
 #include <asm/idle.h>
 #include <asm/io_apic.h>
+#include <asm/i8259.h>
 #include <asm/xen/pci.h>
 #include <xen/page.h>
 #endif
@@ -420,7 +421,7 @@ static int __must_check xen_allocate_irq
 		return xen_allocate_irq_dynamic();
 
 	/* Legacy IRQ descriptors are already allocated by the arch. */
-	if (gsi < NR_IRQS_LEGACY)
+	if (gsi < nr_legacy_irqs())
 		irq = gsi;
 	else
 		irq = irq_alloc_desc_at(gsi, -1);
@@ -446,7 +447,7 @@ static void xen_free_irq(unsigned irq)
 	kfree(info);
 
 	/* Legacy IRQ descriptors are managed by the arch. */
-	if (irq < NR_IRQS_LEGACY)
+	if (irq < nr_legacy_irqs())
 		return;
 
 	irq_free_desc(irq);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/ctree.h linux-libre-4.3.4-gnu/fs/btrfs/ctree.h
--- linux-libre-4.3-gnu/fs/btrfs/ctree.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/ctree.h	2016-01-22 23:59:37.000000000 -0500
@@ -3398,7 +3398,7 @@ int btrfs_set_disk_extent_flags(struct b
 int btrfs_free_extent(struct btrfs_trans_handle *trans,
 		      struct btrfs_root *root,
 		      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
-		      u64 owner, u64 offset, int no_quota);
+		      u64 owner, u64 offset);
 
 int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len,
 			       int delalloc);
@@ -3411,7 +3411,7 @@ int btrfs_finish_extent_commit(struct bt
 int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 			 struct btrfs_root *root,
 			 u64 bytenr, u64 num_bytes, u64 parent,
-			 u64 root_objectid, u64 owner, u64 offset, int no_quota);
+			 u64 root_objectid, u64 owner, u64 offset);
 
 int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
 				   struct btrfs_root *root);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/delayed-ref.c linux-libre-4.3.4-gnu/fs/btrfs/delayed-ref.c
--- linux-libre-4.3-gnu/fs/btrfs/delayed-ref.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/delayed-ref.c	2016-01-22 23:59:37.000000000 -0500
@@ -197,6 +197,119 @@ static inline void drop_delayed_ref(stru
 		trans->delayed_ref_updates--;
 }
 
+static bool merge_ref(struct btrfs_trans_handle *trans,
+		      struct btrfs_delayed_ref_root *delayed_refs,
+		      struct btrfs_delayed_ref_head *head,
+		      struct btrfs_delayed_ref_node *ref,
+		      u64 seq)
+{
+	struct btrfs_delayed_ref_node *next;
+	bool done = false;
+
+	next = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node,
+				list);
+	while (!done && &next->list != &head->ref_list) {
+		int mod;
+		struct btrfs_delayed_ref_node *next2;
+
+		next2 = list_next_entry(next, list);
+
+		if (next == ref)
+			goto next;
+
+		if (seq && next->seq >= seq)
+			goto next;
+
+		if (next->type != ref->type)
+			goto next;
+
+		if ((ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
+		     ref->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
+		    comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref),
+				   btrfs_delayed_node_to_tree_ref(next),
+				   ref->type))
+			goto next;
+		if ((ref->type == BTRFS_EXTENT_DATA_REF_KEY ||
+		     ref->type == BTRFS_SHARED_DATA_REF_KEY) &&
+		    comp_data_refs(btrfs_delayed_node_to_data_ref(ref),
+				   btrfs_delayed_node_to_data_ref(next)))
+			goto next;
+
+		if (ref->action == next->action) {
+			mod = next->ref_mod;
+		} else {
+			if (ref->ref_mod < next->ref_mod) {
+				swap(ref, next);
+				done = true;
+			}
+			mod = -next->ref_mod;
+		}
+
+		drop_delayed_ref(trans, delayed_refs, head, next);
+		ref->ref_mod += mod;
+		if (ref->ref_mod == 0) {
+			drop_delayed_ref(trans, delayed_refs, head, ref);
+			done = true;
+		} else {
+			/*
+			 * Can't have multiples of the same ref on a tree block.
+			 */
+			WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
+				ref->type == BTRFS_SHARED_BLOCK_REF_KEY);
+		}
+next:
+		next = next2;
+	}
+
+	return done;
+}
+
+void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
+			      struct btrfs_fs_info *fs_info,
+			      struct btrfs_delayed_ref_root *delayed_refs,
+			      struct btrfs_delayed_ref_head *head)
+{
+	struct btrfs_delayed_ref_node *ref;
+	u64 seq = 0;
+
+	assert_spin_locked(&head->lock);
+
+	if (list_empty(&head->ref_list))
+		return;
+
+	/* We don't have too many refs to merge for data. */
+	if (head->is_data)
+		return;
+
+	spin_lock(&fs_info->tree_mod_seq_lock);
+	if (!list_empty(&fs_info->tree_mod_seq_list)) {
+		struct seq_list *elem;
+
+		elem = list_first_entry(&fs_info->tree_mod_seq_list,
+					struct seq_list, list);
+		seq = elem->seq;
+	}
+	spin_unlock(&fs_info->tree_mod_seq_lock);
+
+	ref = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node,
+			       list);
+	while (&ref->list != &head->ref_list) {
+		if (seq && ref->seq >= seq)
+			goto next;
+
+		if (merge_ref(trans, delayed_refs, head, ref, seq)) {
+			if (list_empty(&head->ref_list))
+				break;
+			ref = list_first_entry(&head->ref_list,
+					       struct btrfs_delayed_ref_node,
+					       list);
+			continue;
+		}
+next:
+		ref = list_next_entry(ref, list);
+	}
+}
+
 int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,
 			    struct btrfs_delayed_ref_root *delayed_refs,
 			    u64 seq)
@@ -292,8 +405,7 @@ add_delayed_ref_tail_merge(struct btrfs_
 	exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
 			   list);
 	/* No need to compare bytenr nor is_head */
-	if (exist->type != ref->type || exist->no_quota != ref->no_quota ||
-	    exist->seq != ref->seq)
+	if (exist->type != ref->type || exist->seq != ref->seq)
 		goto add_tail;
 
 	if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY ||
@@ -524,7 +636,7 @@ add_delayed_tree_ref(struct btrfs_fs_inf
 		     struct btrfs_delayed_ref_head *head_ref,
 		     struct btrfs_delayed_ref_node *ref, u64 bytenr,
 		     u64 num_bytes, u64 parent, u64 ref_root, int level,
-		     int action, int no_quota)
+		     int action)
 {
 	struct btrfs_delayed_tree_ref *full_ref;
 	struct btrfs_delayed_ref_root *delayed_refs;
@@ -546,7 +658,6 @@ add_delayed_tree_ref(struct btrfs_fs_inf
 	ref->action = action;
 	ref->is_head = 0;
 	ref->in_tree = 1;
-	ref->no_quota = no_quota;
 	ref->seq = seq;
 
 	full_ref = btrfs_delayed_node_to_tree_ref(ref);
@@ -579,7 +690,7 @@ add_delayed_data_ref(struct btrfs_fs_inf
 		     struct btrfs_delayed_ref_head *head_ref,
 		     struct btrfs_delayed_ref_node *ref, u64 bytenr,
 		     u64 num_bytes, u64 parent, u64 ref_root, u64 owner,
-		     u64 offset, int action, int no_quota)
+		     u64 offset, int action)
 {
 	struct btrfs_delayed_data_ref *full_ref;
 	struct btrfs_delayed_ref_root *delayed_refs;
@@ -602,7 +713,6 @@ add_delayed_data_ref(struct btrfs_fs_inf
 	ref->action = action;
 	ref->is_head = 0;
 	ref->in_tree = 1;
-	ref->no_quota = no_quota;
 	ref->seq = seq;
 
 	full_ref = btrfs_delayed_node_to_data_ref(ref);
@@ -633,17 +743,13 @@ int btrfs_add_delayed_tree_ref(struct bt
 			       struct btrfs_trans_handle *trans,
 			       u64 bytenr, u64 num_bytes, u64 parent,
 			       u64 ref_root,  int level, int action,
-			       struct btrfs_delayed_extent_op *extent_op,
-			       int no_quota)
+			       struct btrfs_delayed_extent_op *extent_op)
 {
 	struct btrfs_delayed_tree_ref *ref;
 	struct btrfs_delayed_ref_head *head_ref;
 	struct btrfs_delayed_ref_root *delayed_refs;
 	struct btrfs_qgroup_extent_record *record = NULL;
 
-	if (!is_fstree(ref_root) || !fs_info->quota_enabled)
-		no_quota = 0;
-
 	BUG_ON(extent_op && extent_op->is_data);
 	ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
 	if (!ref)
@@ -672,8 +778,7 @@ int btrfs_add_delayed_tree_ref(struct bt
 					bytenr, num_bytes, action, 0);
 
 	add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
-				   num_bytes, parent, ref_root, level, action,
-				   no_quota);
+			     num_bytes, parent, ref_root, level, action);
 	spin_unlock(&delayed_refs->lock);
 
 	return 0;
@@ -694,17 +799,13 @@ int btrfs_add_delayed_data_ref(struct bt
 			       u64 bytenr, u64 num_bytes,
 			       u64 parent, u64 ref_root,
 			       u64 owner, u64 offset, int action,
-			       struct btrfs_delayed_extent_op *extent_op,
-			       int no_quota)
+			       struct btrfs_delayed_extent_op *extent_op)
 {
 	struct btrfs_delayed_data_ref *ref;
 	struct btrfs_delayed_ref_head *head_ref;
 	struct btrfs_delayed_ref_root *delayed_refs;
 	struct btrfs_qgroup_extent_record *record = NULL;
 
-	if (!is_fstree(ref_root) || !fs_info->quota_enabled)
-		no_quota = 0;
-
 	BUG_ON(extent_op && !extent_op->is_data);
 	ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
 	if (!ref)
@@ -740,7 +841,7 @@ int btrfs_add_delayed_data_ref(struct bt
 
 	add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
 				   num_bytes, parent, ref_root, owner, offset,
-				   action, no_quota);
+				   action);
 	spin_unlock(&delayed_refs->lock);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/delayed-ref.h linux-libre-4.3.4-gnu/fs/btrfs/delayed-ref.h
--- linux-libre-4.3-gnu/fs/btrfs/delayed-ref.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/delayed-ref.h	2016-01-22 23:59:37.000000000 -0500
@@ -68,7 +68,6 @@ struct btrfs_delayed_ref_node {
 
 	unsigned int action:8;
 	unsigned int type:8;
-	unsigned int no_quota:1;
 	/* is this node still in the rbtree? */
 	unsigned int is_head:1;
 	unsigned int in_tree:1;
@@ -233,15 +232,13 @@ int btrfs_add_delayed_tree_ref(struct bt
 			       struct btrfs_trans_handle *trans,
 			       u64 bytenr, u64 num_bytes, u64 parent,
 			       u64 ref_root, int level, int action,
-			       struct btrfs_delayed_extent_op *extent_op,
-			       int no_quota);
+			       struct btrfs_delayed_extent_op *extent_op);
 int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
 			       struct btrfs_trans_handle *trans,
 			       u64 bytenr, u64 num_bytes,
 			       u64 parent, u64 ref_root,
 			       u64 owner, u64 offset, int action,
-			       struct btrfs_delayed_extent_op *extent_op,
-			       int no_quota);
+			       struct btrfs_delayed_extent_op *extent_op);
 int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
 				struct btrfs_trans_handle *trans,
 				u64 bytenr, u64 num_bytes,
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/extent-tree.c linux-libre-4.3.4-gnu/fs/btrfs/extent-tree.c
--- linux-libre-4.3-gnu/fs/btrfs/extent-tree.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/extent-tree.c	2016-01-22 23:59:37.000000000 -0500
@@ -95,8 +95,7 @@ static int alloc_reserved_tree_block(str
 				     struct btrfs_root *root,
 				     u64 parent, u64 root_objectid,
 				     u64 flags, struct btrfs_disk_key *key,
-				     int level, struct btrfs_key *ins,
-				     int no_quota);
+				     int level, struct btrfs_key *ins);
 static int do_chunk_alloc(struct btrfs_trans_handle *trans,
 			  struct btrfs_root *extent_root, u64 flags,
 			  int force);
@@ -2009,8 +2008,7 @@ int btrfs_discard_extent(struct btrfs_ro
 int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 			 struct btrfs_root *root,
 			 u64 bytenr, u64 num_bytes, u64 parent,
-			 u64 root_objectid, u64 owner, u64 offset,
-			 int no_quota)
+			 u64 root_objectid, u64 owner, u64 offset)
 {
 	int ret;
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -2022,12 +2020,12 @@ int btrfs_inc_extent_ref(struct btrfs_tr
 		ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
 					num_bytes,
 					parent, root_objectid, (int)owner,
-					BTRFS_ADD_DELAYED_REF, NULL, no_quota);
+					BTRFS_ADD_DELAYED_REF, NULL);
 	} else {
 		ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
 					num_bytes,
 					parent, root_objectid, owner, offset,
-					BTRFS_ADD_DELAYED_REF, NULL, no_quota);
+					BTRFS_ADD_DELAYED_REF, NULL);
 	}
 	return ret;
 }
@@ -2048,15 +2046,11 @@ static int __btrfs_inc_extent_ref(struct
 	u64 num_bytes = node->num_bytes;
 	u64 refs;
 	int ret;
-	int no_quota = node->no_quota;
 
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
 
-	if (!is_fstree(root_objectid) || !root->fs_info->quota_enabled)
-		no_quota = 1;
-
 	path->reada = 1;
 	path->leave_spinning = 1;
 	/* this will setup the path even if it fails to insert the back ref */
@@ -2291,8 +2285,7 @@ static int run_delayed_tree_ref(struct b
 						parent, ref_root,
 						extent_op->flags_to_set,
 						&extent_op->key,
-						ref->level, &ins,
-						node->no_quota);
+						ref->level, &ins);
 	} else if (node->action == BTRFS_ADD_DELAYED_REF) {
 		ret = __btrfs_inc_extent_ref(trans, root, node,
 					     parent, ref_root,
@@ -2433,7 +2426,21 @@ static noinline int __btrfs_run_delayed_
 			}
 		}
 
+		/*
+		 * We need to try and merge add/drops of the same ref since we
+		 * can run into issues with relocate dropping the implicit ref
+		 * and then it being added back again before the drop can
+		 * finish.  If we merged anything we need to re-loop so we can
+		 * get a good ref.
+		 * Or we can get node references of the same type that weren't
+		 * merged when created due to bumps in the tree mod seq, and
+		 * we need to merge them to prevent adding an inline extent
+		 * backref before dropping it (triggering a BUG_ON at
+		 * insert_inline_extent_backref()).
+		 */
 		spin_lock(&locked_ref->lock);
+		btrfs_merge_delayed_refs(trans, fs_info, delayed_refs,
+					 locked_ref);
 
 		/*
 		 * locked_ref is the head node, so we have to go one
@@ -3109,7 +3116,7 @@ static int __btrfs_mod_ref(struct btrfs_
 	int level;
 	int ret = 0;
 	int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
-			    u64, u64, u64, u64, u64, u64, int);
+			    u64, u64, u64, u64, u64, u64);
 
 
 	if (btrfs_test_is_dummy_root(root))
@@ -3150,15 +3157,14 @@ static int __btrfs_mod_ref(struct btrfs_
 			key.offset -= btrfs_file_extent_offset(buf, fi);
 			ret = process_func(trans, root, bytenr, num_bytes,
 					   parent, ref_root, key.objectid,
-					   key.offset, 1);
+					   key.offset);
 			if (ret)
 				goto fail;
 		} else {
 			bytenr = btrfs_node_blockptr(buf, i);
 			num_bytes = root->nodesize;
 			ret = process_func(trans, root, bytenr, num_bytes,
-					   parent, ref_root, level - 1, 0,
-					   1);
+					   parent, ref_root, level - 1, 0);
 			if (ret)
 				goto fail;
 		}
@@ -6233,7 +6239,6 @@ static int __btrfs_free_extent(struct bt
 	int extent_slot = 0;
 	int found_extent = 0;
 	int num_to_del = 1;
-	int no_quota = node->no_quota;
 	u32 item_size;
 	u64 refs;
 	u64 bytenr = node->bytenr;
@@ -6242,9 +6247,6 @@ static int __btrfs_free_extent(struct bt
 	bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
 						 SKINNY_METADATA);
 
-	if (!info->quota_enabled || !is_fstree(root_objectid))
-		no_quota = 1;
-
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
@@ -6570,7 +6572,7 @@ void btrfs_free_tree_block(struct btrfs_
 					buf->start, buf->len,
 					parent, root->root_key.objectid,
 					btrfs_header_level(buf),
-					BTRFS_DROP_DELAYED_REF, NULL, 0);
+					BTRFS_DROP_DELAYED_REF, NULL);
 		BUG_ON(ret); /* -ENOMEM */
 	}
 
@@ -6618,7 +6620,7 @@ out:
 /* Can return -ENOMEM */
 int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
-		      u64 owner, u64 offset, int no_quota)
+		      u64 owner, u64 offset)
 {
 	int ret;
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -6641,13 +6643,13 @@ int btrfs_free_extent(struct btrfs_trans
 		ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
 					num_bytes,
 					parent, root_objectid, (int)owner,
-					BTRFS_DROP_DELAYED_REF, NULL, no_quota);
+					BTRFS_DROP_DELAYED_REF, NULL);
 	} else {
 		ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
 						num_bytes,
 						parent, root_objectid, owner,
 						offset, BTRFS_DROP_DELAYED_REF,
-						NULL, no_quota);
+						NULL);
 	}
 	return ret;
 }
@@ -7429,8 +7431,7 @@ static int alloc_reserved_tree_block(str
 				     struct btrfs_root *root,
 				     u64 parent, u64 root_objectid,
 				     u64 flags, struct btrfs_disk_key *key,
-				     int level, struct btrfs_key *ins,
-				     int no_quota)
+				     int level, struct btrfs_key *ins)
 {
 	int ret;
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -7520,7 +7521,7 @@ int btrfs_alloc_reserved_file_extent(str
 	ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid,
 					 ins->offset, 0,
 					 root_objectid, owner, offset,
-					 BTRFS_ADD_DELAYED_EXTENT, NULL, 0);
+					 BTRFS_ADD_DELAYED_EXTENT, NULL);
 	return ret;
 }
 
@@ -7734,7 +7735,7 @@ struct extent_buffer *btrfs_alloc_tree_b
 						 ins.objectid, ins.offset,
 						 parent, root_objectid, level,
 						 BTRFS_ADD_DELAYED_EXTENT,
-						 extent_op, 0);
+						 extent_op);
 		if (ret)
 			goto out_free_delayed;
 	}
@@ -8282,7 +8283,7 @@ skip:
 			}
 		}
 		ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
-				root->root_key.objectid, level - 1, 0, 0);
+				root->root_key.objectid, level - 1, 0);
 		BUG_ON(ret); /* -ENOMEM */
 	}
 	btrfs_tree_unlock(next);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/file.c linux-libre-4.3.4-gnu/fs/btrfs/file.c
--- linux-libre-4.3-gnu/fs/btrfs/file.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/file.c	2016-01-22 23:59:37.000000000 -0500
@@ -756,8 +756,16 @@ next_slot:
 		}
 
 		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
-		if (key.objectid > ino ||
-		    key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
+
+		if (key.objectid > ino)
+			break;
+		if (WARN_ON_ONCE(key.objectid < ino) ||
+		    key.type < BTRFS_EXTENT_DATA_KEY) {
+			ASSERT(del_nr == 0);
+			path->slots[0]++;
+			goto next_slot;
+		}
+		if (key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
 			break;
 
 		fi = btrfs_item_ptr(leaf, path->slots[0],
@@ -776,8 +784,8 @@ next_slot:
 				btrfs_file_extent_inline_len(leaf,
 						     path->slots[0], fi);
 		} else {
-			WARN_ON(1);
-			extent_end = search_start;
+			/* can't happen */
+			BUG();
 		}
 
 		/*
@@ -847,7 +855,7 @@ next_slot:
 						disk_bytenr, num_bytes, 0,
 						root->root_key.objectid,
 						new_key.objectid,
-						start - extent_offset, 1);
+						start - extent_offset);
 				BUG_ON(ret); /* -ENOMEM */
 			}
 			key.offset = start;
@@ -925,7 +933,7 @@ delete_extent_item:
 						disk_bytenr, num_bytes, 0,
 						root->root_key.objectid,
 						key.objectid, key.offset -
-						extent_offset, 0);
+						extent_offset);
 				BUG_ON(ret); /* -ENOMEM */
 				inode_sub_bytes(inode,
 						extent_end - key.offset);
@@ -1204,7 +1212,7 @@ again:
 
 		ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0,
 					   root->root_key.objectid,
-					   ino, orig_offset, 1);
+					   ino, orig_offset);
 		BUG_ON(ret); /* -ENOMEM */
 
 		if (split == start) {
@@ -1231,7 +1239,7 @@ again:
 		del_nr++;
 		ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
 					0, root->root_key.objectid,
-					ino, orig_offset, 0);
+					ino, orig_offset);
 		BUG_ON(ret); /* -ENOMEM */
 	}
 	other_start = 0;
@@ -1248,7 +1256,7 @@ again:
 		del_nr++;
 		ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
 					0, root->root_key.objectid,
-					ino, orig_offset, 0);
+					ino, orig_offset);
 		BUG_ON(ret); /* -ENOMEM */
 	}
 	if (del_nr == 0) {
@@ -1868,8 +1876,13 @@ int btrfs_sync_file(struct file *file, l
 	struct btrfs_log_ctx ctx;
 	int ret = 0;
 	bool full_sync = 0;
-	const u64 len = end - start + 1;
+	u64 len;
 
+	/*
+	 * The range length can be represented by u64, we have to do the typecasts
+	 * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
+	 */
+	len = (u64)end - (u64)start + 1;
 	trace_btrfs_sync_file(file, datasync);
 
 	/*
@@ -2057,8 +2070,7 @@ int btrfs_sync_file(struct file *file, l
 			}
 		}
 		if (!full_sync) {
-			ret = btrfs_wait_ordered_range(inode, start,
-						       end - start + 1);
+			ret = btrfs_wait_ordered_range(inode, start, len);
 			if (ret) {
 				btrfs_end_transaction(trans, root);
 				goto out;
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/inode.c linux-libre-4.3.4-gnu/fs/btrfs/inode.c
--- linux-libre-4.3-gnu/fs/btrfs/inode.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/inode.c	2016-01-22 23:59:37.000000000 -0500
@@ -1294,8 +1294,14 @@ next_slot:
 		num_bytes = 0;
 		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
 
-		if (found_key.objectid > ino ||
-		    found_key.type > BTRFS_EXTENT_DATA_KEY ||
+		if (found_key.objectid > ino)
+			break;
+		if (WARN_ON_ONCE(found_key.objectid < ino) ||
+		    found_key.type < BTRFS_EXTENT_DATA_KEY) {
+			path->slots[0]++;
+			goto next_slot;
+		}
+		if (found_key.type > BTRFS_EXTENT_DATA_KEY ||
 		    found_key.offset > end)
 			break;
 
@@ -2573,7 +2579,7 @@ again:
 	ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
 			new->disk_len, 0,
 			backref->root_id, backref->inum,
-			new->file_pos, 0);	/* start - extent_offset */
+			new->file_pos);	/* start - extent_offset */
 	if (ret) {
 		btrfs_abort_transaction(trans, root, ret);
 		goto out_free_path;
@@ -4217,6 +4223,47 @@ static int truncate_space_check(struct b
 
 }
 
+static int truncate_inline_extent(struct inode *inode,
+				  struct btrfs_path *path,
+				  struct btrfs_key *found_key,
+				  const u64 item_end,
+				  const u64 new_size)
+{
+	struct extent_buffer *leaf = path->nodes[0];
+	int slot = path->slots[0];
+	struct btrfs_file_extent_item *fi;
+	u32 size = (u32)(new_size - found_key->offset);
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+
+	fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
+
+	if (btrfs_file_extent_compression(leaf, fi) != BTRFS_COMPRESS_NONE) {
+		loff_t offset = new_size;
+		loff_t page_end = ALIGN(offset, PAGE_CACHE_SIZE);
+
+		/*
+		 * Zero out the remaining of the last page of our inline extent,
+		 * instead of directly truncating our inline extent here - that
+		 * would be much more complex (decompressing all the data, then
+		 * compressing the truncated data, which might be bigger than
+		 * the size of the inline extent, resize the extent, etc).
+		 * We release the path because to get the page we might need to
+		 * read the extent item from disk (data not in the page cache).
+		 */
+		btrfs_release_path(path);
+		return btrfs_truncate_page(inode, offset, page_end - offset, 0);
+	}
+
+	btrfs_set_file_extent_ram_bytes(leaf, fi, size);
+	size = btrfs_file_extent_calc_inline_size(size);
+	btrfs_truncate_item(root, path, size, 1);
+
+	if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
+		inode_sub_bytes(inode, item_end + 1 - new_size);
+
+	return 0;
+}
+
 /*
  * this can truncate away extent items, csum items and directory items.
  * It starts at a high offset and removes keys until it can't find
@@ -4411,27 +4458,40 @@ search_again:
 			 * special encodings
 			 */
 			if (!del_item &&
-			    btrfs_file_extent_compression(leaf, fi) == 0 &&
 			    btrfs_file_extent_encryption(leaf, fi) == 0 &&
 			    btrfs_file_extent_other_encoding(leaf, fi) == 0) {
-				u32 size = new_size - found_key.offset;
-
-				if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
-					inode_sub_bytes(inode, item_end + 1 -
-							new_size);
 
 				/*
-				 * update the ram bytes to properly reflect
-				 * the new size of our item
+				 * Need to release path in order to truncate a
+				 * compressed extent. So delete any accumulated
+				 * extent items so far.
 				 */
-				btrfs_set_file_extent_ram_bytes(leaf, fi, size);
-				size =
-				    btrfs_file_extent_calc_inline_size(size);
-				btrfs_truncate_item(root, path, size, 1);
+				if (btrfs_file_extent_compression(leaf, fi) !=
+				    BTRFS_COMPRESS_NONE && pending_del_nr) {
+					err = btrfs_del_items(trans, root, path,
+							      pending_del_slot,
+							      pending_del_nr);
+					if (err) {
+						btrfs_abort_transaction(trans,
+									root,
+									err);
+						goto error;
+					}
+					pending_del_nr = 0;
+				}
+
+				err = truncate_inline_extent(inode, path,
+							     &found_key,
+							     item_end,
+							     new_size);
+				if (err) {
+					btrfs_abort_transaction(trans,
+								root, err);
+					goto error;
+				}
 			} else if (test_bit(BTRFS_ROOT_REF_COWS,
 					    &root->state)) {
-				inode_sub_bytes(inode, item_end + 1 -
-						found_key.offset);
+				inode_sub_bytes(inode, item_end + 1 - new_size);
 			}
 		}
 delete:
@@ -4461,7 +4521,7 @@ delete:
 			ret = btrfs_free_extent(trans, root, extent_start,
 						extent_num_bytes, 0,
 						btrfs_header_owner(leaf),
-						ino, extent_offset, 0);
+						ino, extent_offset);
 			BUG_ON(ret);
 			if (btrfs_should_throttle_delayed_refs(trans, root))
 				btrfs_async_run_delayed_refs(root,
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/ioctl.c linux-libre-4.3.4-gnu/fs/btrfs/ioctl.c
--- linux-libre-4.3-gnu/fs/btrfs/ioctl.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/ioctl.c	2016-01-22 23:59:37.000000000 -0500
@@ -3203,41 +3203,6 @@ out:
 	return ret;
 }
 
-/* Helper to check and see if this root currently has a ref on the given disk
- * bytenr.  If it does then we need to update the quota for this root.  This
- * doesn't do anything if quotas aren't enabled.
- */
-static int check_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
-		     u64 disko)
-{
-	struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem);
-	struct ulist *roots;
-	struct ulist_iterator uiter;
-	struct ulist_node *root_node = NULL;
-	int ret;
-
-	if (!root->fs_info->quota_enabled)
-		return 1;
-
-	btrfs_get_tree_mod_seq(root->fs_info, &tree_mod_seq_elem);
-	ret = btrfs_find_all_roots(trans, root->fs_info, disko,
-				   tree_mod_seq_elem.seq, &roots);
-	if (ret < 0)
-		goto out;
-	ret = 0;
-	ULIST_ITER_INIT(&uiter);
-	while ((root_node = ulist_next(roots, &uiter))) {
-		if (root_node->val == root->objectid) {
-			ret = 1;
-			break;
-		}
-	}
-	ulist_free(roots);
-out:
-	btrfs_put_tree_mod_seq(root->fs_info, &tree_mod_seq_elem);
-	return ret;
-}
-
 static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
 				     struct inode *inode,
 				     u64 endoff,
@@ -3328,6 +3293,150 @@ static void clone_update_extent_map(stru
 			&BTRFS_I(inode)->runtime_flags);
 }
 
+/*
+ * Make sure we do not end up inserting an inline extent into a file that has
+ * already other (non-inline) extents. If a file has an inline extent it can
+ * not have any other extents and the (single) inline extent must start at the
+ * file offset 0. Failing to respect these rules will lead to file corruption,
+ * resulting in EIO errors on read/write operations, hitting BUG_ON's in mm, etc
+ *
+ * We can have extents that have been already written to disk or we can have
+ * dirty ranges still in delalloc, in which case the extent maps and items are
+ * created only when we run delalloc, and the delalloc ranges might fall outside
+ * the range we are currently locking in the inode's io tree. So we check the
+ * inode's i_size because of that (i_size updates are done while holding the
+ * i_mutex, which we are holding here).
+ * We also check to see if the inode has a size not greater than "datal" but has
+ * extents beyond it, due to an fallocate with FALLOC_FL_KEEP_SIZE (and we are
+ * protected against such concurrent fallocate calls by the i_mutex).
+ *
+ * If the file has no extents but a size greater than datal, do not allow the
+ * copy because we would need turn the inline extent into a non-inline one (even
+ * with NO_HOLES enabled). If we find our destination inode only has one inline
+ * extent, just overwrite it with the source inline extent if its size is less
+ * than the source extent's size, or we could copy the source inline extent's
+ * data into the destination inode's inline extent if the later is greater then
+ * the former.
+ */
+static int clone_copy_inline_extent(struct inode *src,
+				    struct inode *dst,
+				    struct btrfs_trans_handle *trans,
+				    struct btrfs_path *path,
+				    struct btrfs_key *new_key,
+				    const u64 drop_start,
+				    const u64 datal,
+				    const u64 skip,
+				    const u64 size,
+				    char *inline_data)
+{
+	struct btrfs_root *root = BTRFS_I(dst)->root;
+	const u64 aligned_end = ALIGN(new_key->offset + datal,
+				      root->sectorsize);
+	int ret;
+	struct btrfs_key key;
+
+	if (new_key->offset > 0)
+		return -EOPNOTSUPP;
+
+	key.objectid = btrfs_ino(dst);
+	key.type = BTRFS_EXTENT_DATA_KEY;
+	key.offset = 0;
+	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+	if (ret < 0) {
+		return ret;
+	} else if (ret > 0) {
+		if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
+			ret = btrfs_next_leaf(root, path);
+			if (ret < 0)
+				return ret;
+			else if (ret > 0)
+				goto copy_inline_extent;
+		}
+		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+		if (key.objectid == btrfs_ino(dst) &&
+		    key.type == BTRFS_EXTENT_DATA_KEY) {
+			ASSERT(key.offset > 0);
+			return -EOPNOTSUPP;
+		}
+	} else if (i_size_read(dst) <= datal) {
+		struct btrfs_file_extent_item *ei;
+		u64 ext_len;
+
+		/*
+		 * If the file size is <= datal, make sure there are no other
+		 * extents following (can happen do to an fallocate call with
+		 * the flag FALLOC_FL_KEEP_SIZE).
+		 */
+		ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
+				    struct btrfs_file_extent_item);
+		/*
+		 * If it's an inline extent, it can not have other extents
+		 * following it.
+		 */
+		if (btrfs_file_extent_type(path->nodes[0], ei) ==
+		    BTRFS_FILE_EXTENT_INLINE)
+			goto copy_inline_extent;
+
+		ext_len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
+		if (ext_len > aligned_end)
+			return -EOPNOTSUPP;
+
+		ret = btrfs_next_item(root, path);
+		if (ret < 0) {
+			return ret;
+		} else if (ret == 0) {
+			btrfs_item_key_to_cpu(path->nodes[0], &key,
+					      path->slots[0]);
+			if (key.objectid == btrfs_ino(dst) &&
+			    key.type == BTRFS_EXTENT_DATA_KEY)
+				return -EOPNOTSUPP;
+		}
+	}
+
+copy_inline_extent:
+	/*
+	 * We have no extent items, or we have an extent at offset 0 which may
+	 * or may not be inlined. All these cases are dealt the same way.
+	 */
+	if (i_size_read(dst) > datal) {
+		/*
+		 * If the destination inode has an inline extent...
+		 * This would require copying the data from the source inline
+		 * extent into the beginning of the destination's inline extent.
+		 * But this is really complex, both extents can be compressed
+		 * or just one of them, which would require decompressing and
+		 * re-compressing data (which could increase the new compressed
+		 * size, not allowing the compressed data to fit anymore in an
+		 * inline extent).
+		 * So just don't support this case for now (it should be rare,
+		 * we are not really saving space when cloning inline extents).
+		 */
+		return -EOPNOTSUPP;
+	}
+
+	btrfs_release_path(path);
+	ret = btrfs_drop_extents(trans, root, dst, drop_start, aligned_end, 1);
+	if (ret)
+		return ret;
+	ret = btrfs_insert_empty_item(trans, root, path, new_key, size);
+	if (ret)
+		return ret;
+
+	if (skip) {
+		const u32 start = btrfs_file_extent_calc_inline_size(0);
+
+		memmove(inline_data + start, inline_data + start + skip, datal);
+	}
+
+	write_extent_buffer(path->nodes[0], inline_data,
+			    btrfs_item_ptr_offset(path->nodes[0],
+						  path->slots[0]),
+			    size);
+	inode_add_bytes(dst, datal);
+
+	return 0;
+}
+
 /**
  * btrfs_clone() - clone a range from inode file to another
  *
@@ -3352,9 +3461,7 @@ static int btrfs_clone(struct inode *src
 	u32 nritems;
 	int slot;
 	int ret;
-	int no_quota;
 	const u64 len = olen_aligned;
-	u64 last_disko = 0;
 	u64 last_dest_end = destoff;
 
 	ret = -ENOMEM;
@@ -3400,7 +3507,6 @@ static int btrfs_clone(struct inode *src
 
 		nritems = btrfs_header_nritems(path->nodes[0]);
 process_slot:
-		no_quota = 1;
 		if (path->slots[0] >= nritems) {
 			ret = btrfs_next_leaf(BTRFS_I(src)->root, path);
 			if (ret < 0)
@@ -3552,35 +3658,13 @@ process_slot:
 				btrfs_set_file_extent_num_bytes(leaf, extent,
 								datal);
 
-				/*
-				 * We need to look up the roots that point at
-				 * this bytenr and see if the new root does.  If
-				 * it does not we need to make sure we update
-				 * quotas appropriately.
-				 */
-				if (disko && root != BTRFS_I(src)->root &&
-				    disko != last_disko) {
-					no_quota = check_ref(trans, root,
-							     disko);
-					if (no_quota < 0) {
-						btrfs_abort_transaction(trans,
-									root,
-									ret);
-						btrfs_end_transaction(trans,
-								      root);
-						ret = no_quota;
-						goto out;
-					}
-				}
-
 				if (disko) {
 					inode_add_bytes(inode, datal);
 					ret = btrfs_inc_extent_ref(trans, root,
 							disko, diskl, 0,
 							root->root_key.objectid,
 							btrfs_ino(inode),
-							new_key.offset - datao,
-							no_quota);
+							new_key.offset - datao);
 					if (ret) {
 						btrfs_abort_transaction(trans,
 									root,
@@ -3594,21 +3678,6 @@ process_slot:
 			} else if (type == BTRFS_FILE_EXTENT_INLINE) {
 				u64 skip = 0;
 				u64 trim = 0;
-				u64 aligned_end = 0;
-
-				/*
-				 * Don't copy an inline extent into an offset
-				 * greater than zero. Having an inline extent
-				 * at such an offset results in chaos as btrfs
-				 * isn't prepared for such cases. Just skip
-				 * this case for the same reasons as commented
-				 * at btrfs_ioctl_clone().
-				 */
-				if (last_dest_end > 0) {
-					ret = -EOPNOTSUPP;
-					btrfs_end_transaction(trans, root);
-					goto out;
-				}
 
 				if (off > key.offset) {
 					skip = off - key.offset;
@@ -3626,42 +3695,22 @@ process_slot:
 				size -= skip + trim;
 				datal -= skip + trim;
 
-				aligned_end = ALIGN(new_key.offset + datal,
-						    root->sectorsize);
-				ret = btrfs_drop_extents(trans, root, inode,
-							 drop_start,
-							 aligned_end,
-							 1);
+				ret = clone_copy_inline_extent(src, inode,
+							       trans, path,
+							       &new_key,
+							       drop_start,
+							       datal,
+							       skip, size, buf);
 				if (ret) {
 					if (ret != -EOPNOTSUPP)
 						btrfs_abort_transaction(trans,
-							root, ret);
-					btrfs_end_transaction(trans, root);
-					goto out;
-				}
-
-				ret = btrfs_insert_empty_item(trans, root, path,
-							      &new_key, size);
-				if (ret) {
-					btrfs_abort_transaction(trans, root,
-								ret);
+									root,
+									ret);
 					btrfs_end_transaction(trans, root);
 					goto out;
 				}
-
-				if (skip) {
-					u32 start =
-					  btrfs_file_extent_calc_inline_size(0);
-					memmove(buf+start, buf+start+skip,
-						datal);
-				}
-
 				leaf = path->nodes[0];
 				slot = path->slots[0];
-				write_extent_buffer(leaf, buf,
-					    btrfs_item_ptr_offset(leaf, slot),
-					    size);
-				inode_add_bytes(inode, datal);
 			}
 
 			/* If we have an implicit hole (NO_HOLES feature). */
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/relocation.c linux-libre-4.3.4-gnu/fs/btrfs/relocation.c
--- linux-libre-4.3-gnu/fs/btrfs/relocation.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/relocation.c	2016-01-22 23:59:37.000000000 -0500
@@ -1716,7 +1716,7 @@ int replace_file_extents(struct btrfs_tr
 		ret = btrfs_inc_extent_ref(trans, root, new_bytenr,
 					   num_bytes, parent,
 					   btrfs_header_owner(leaf),
-					   key.objectid, key.offset, 1);
+					   key.objectid, key.offset);
 		if (ret) {
 			btrfs_abort_transaction(trans, root, ret);
 			break;
@@ -1724,7 +1724,7 @@ int replace_file_extents(struct btrfs_tr
 
 		ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
 					parent, btrfs_header_owner(leaf),
-					key.objectid, key.offset, 1);
+					key.objectid, key.offset);
 		if (ret) {
 			btrfs_abort_transaction(trans, root, ret);
 			break;
@@ -1900,23 +1900,21 @@ again:
 
 		ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize,
 					path->nodes[level]->start,
-					src->root_key.objectid, level - 1, 0,
-					1);
+					src->root_key.objectid, level - 1, 0);
 		BUG_ON(ret);
 		ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize,
 					0, dest->root_key.objectid, level - 1,
-					0, 1);
+					0);
 		BUG_ON(ret);
 
 		ret = btrfs_free_extent(trans, src, new_bytenr, blocksize,
 					path->nodes[level]->start,
-					src->root_key.objectid, level - 1, 0,
-					1);
+					src->root_key.objectid, level - 1, 0);
 		BUG_ON(ret);
 
 		ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize,
 					0, dest->root_key.objectid, level - 1,
-					0, 1);
+					0);
 		BUG_ON(ret);
 
 		btrfs_unlock_up_safe(path, 0);
@@ -2745,7 +2743,7 @@ static int do_relocation(struct btrfs_tr
 						node->eb->start, blocksize,
 						upper->eb->start,
 						btrfs_header_owner(upper->eb),
-						node->level, 0, 1);
+						node->level, 0);
 			BUG_ON(ret);
 
 			ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/send.c linux-libre-4.3.4-gnu/fs/btrfs/send.c
--- linux-libre-4.3-gnu/fs/btrfs/send.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/send.c	2016-01-22 23:59:37.000000000 -0500
@@ -2353,8 +2353,14 @@ static int send_subvol_begin(struct send
 	}
 
 	TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen);
-	TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
-			sctx->send_root->root_item.uuid);
+
+	if (!btrfs_is_empty_uuid(sctx->send_root->root_item.received_uuid))
+		TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
+			    sctx->send_root->root_item.received_uuid);
+	else
+		TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
+			    sctx->send_root->root_item.uuid);
+
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID,
 		    le64_to_cpu(sctx->send_root->root_item.ctransid));
 	if (parent_root) {
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/tree-log.c linux-libre-4.3.4-gnu/fs/btrfs/tree-log.c
--- linux-libre-4.3-gnu/fs/btrfs/tree-log.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/tree-log.c	2016-01-22 23:59:37.000000000 -0500
@@ -691,7 +691,7 @@ static noinline int replay_one_extent(st
 				ret = btrfs_inc_extent_ref(trans, root,
 						ins.objectid, ins.offset,
 						0, root->root_key.objectid,
-						key->objectid, offset, 0);
+						key->objectid, offset);
 				if (ret)
 					goto out;
 			} else {
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/btrfs/xattr.c linux-libre-4.3.4-gnu/fs/btrfs/xattr.c
--- linux-libre-4.3-gnu/fs/btrfs/xattr.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/btrfs/xattr.c	2016-01-22 23:59:37.000000000 -0500
@@ -313,8 +313,10 @@ ssize_t btrfs_listxattr(struct dentry *d
 		/* check to make sure this item is what we want */
 		if (found_key.objectid != key.objectid)
 			break;
-		if (found_key.type != BTRFS_XATTR_ITEM_KEY)
+		if (found_key.type > BTRFS_XATTR_ITEM_KEY)
 			break;
+		if (found_key.type < BTRFS_XATTR_ITEM_KEY)
+			goto next;
 
 		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
 		if (verify_dir_item(root, leaf, di))
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ceph/mds_client.c linux-libre-4.3.4-gnu/fs/ceph/mds_client.c
--- linux-libre-4.3-gnu/fs/ceph/mds_client.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ceph/mds_client.c	2016-01-22 23:59:37.000000000 -0500
@@ -1935,7 +1935,7 @@ static struct ceph_msg *create_request_m
 
 	len = sizeof(*head) +
 		pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) +
-		sizeof(struct timespec);
+		sizeof(struct ceph_timespec);
 
 	/* calculate (max) length for cap releases */
 	len += sizeof(struct ceph_mds_request_release) *
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/debugfs/inode.c linux-libre-4.3.4-gnu/fs/debugfs/inode.c
--- linux-libre-4.3-gnu/fs/debugfs/inode.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/debugfs/inode.c	2016-01-22 23:59:37.000000000 -0500
@@ -271,8 +271,12 @@ static struct dentry *start_creating(con
 		dput(dentry);
 		dentry = ERR_PTR(-EEXIST);
 	}
-	if (IS_ERR(dentry))
+
+	if (IS_ERR(dentry)) {
 		mutex_unlock(&d_inode(parent)->i_mutex);
+		simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+	}
+
 	return dentry;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ext4/crypto.c linux-libre-4.3.4-gnu/fs/ext4/crypto.c
--- linux-libre-4.3-gnu/fs/ext4/crypto.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ext4/crypto.c	2016-01-22 23:59:37.000000000 -0500
@@ -411,7 +411,13 @@ int ext4_encrypted_zeroout(struct inode
 	ext4_lblk_t		lblk = ex->ee_block;
 	ext4_fsblk_t		pblk = ext4_ext_pblock(ex);
 	unsigned int		len = ext4_ext_get_actual_len(ex);
-	int			err = 0;
+	int			ret, err = 0;
+
+#if 0
+	ext4_msg(inode->i_sb, KERN_CRIT,
+		 "ext4_encrypted_zeroout ino %lu lblk %u len %u",
+		 (unsigned long) inode->i_ino, lblk, len);
+#endif
 
 	BUG_ON(inode->i_sb->s_blocksize != PAGE_CACHE_SIZE);
 
@@ -437,17 +443,26 @@ int ext4_encrypted_zeroout(struct inode
 			goto errout;
 		}
 		bio->bi_bdev = inode->i_sb->s_bdev;
-		bio->bi_iter.bi_sector = pblk;
-		err = bio_add_page(bio, ciphertext_page,
+		bio->bi_iter.bi_sector =
+			pblk << (inode->i_sb->s_blocksize_bits - 9);
+		ret = bio_add_page(bio, ciphertext_page,
 				   inode->i_sb->s_blocksize, 0);
-		if (err) {
+		if (ret != inode->i_sb->s_blocksize) {
+			/* should never happen! */
+			ext4_msg(inode->i_sb, KERN_ERR,
+				 "bio_add_page failed: %d", ret);
+			WARN_ON(1);
 			bio_put(bio);
+			err = -EIO;
 			goto errout;
 		}
 		err = submit_bio_wait(WRITE, bio);
+		if ((err == 0) && bio->bi_error)
+			err = -EIO;
 		bio_put(bio);
 		if (err)
 			goto errout;
+		lblk++; pblk++;
 	}
 	err = 0;
 errout:
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ext4/ext4_jbd2.c linux-libre-4.3.4-gnu/fs/ext4/ext4_jbd2.c
--- linux-libre-4.3-gnu/fs/ext4/ext4_jbd2.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ext4/ext4_jbd2.c	2016-01-22 23:59:37.000000000 -0500
@@ -88,13 +88,13 @@ int __ext4_journal_stop(const char *wher
 		return 0;
 	}
 
+	err = handle->h_err;
 	if (!handle->h_transaction) {
-		err = jbd2_journal_stop(handle);
-		return handle->h_err ? handle->h_err : err;
+		rc = jbd2_journal_stop(handle);
+		return err ? err : rc;
 	}
 
 	sb = handle->h_transaction->t_journal->j_private;
-	err = handle->h_err;
 	rc = jbd2_journal_stop(handle);
 
 	if (!err)
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ext4/extents.c linux-libre-4.3.4-gnu/fs/ext4/extents.c
--- linux-libre-4.3-gnu/fs/ext4/extents.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ext4/extents.c	2016-01-22 23:59:37.000000000 -0500
@@ -3558,6 +3558,9 @@ static int ext4_ext_convert_to_initializ
 		max_zeroout = sbi->s_extent_max_zeroout_kb >>
 			(inode->i_sb->s_blocksize_bits - 10);
 
+	if (ext4_encrypted_inode(inode))
+		max_zeroout = 0;
+
 	/* If extent is less than s_max_zeroout_kb, zeroout directly */
 	if (max_zeroout && (ee_len <= max_zeroout)) {
 		err = ext4_ext_zeroout(inode, ex);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ext4/page-io.c linux-libre-4.3.4-gnu/fs/ext4/page-io.c
--- linux-libre-4.3-gnu/fs/ext4/page-io.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ext4/page-io.c	2016-01-22 23:59:37.000000000 -0500
@@ -425,6 +425,7 @@ int ext4_bio_write_page(struct ext4_io_s
 	struct buffer_head *bh, *head;
 	int ret = 0;
 	int nr_submitted = 0;
+	int nr_to_submit = 0;
 
 	blocksize = 1 << inode->i_blkbits;
 
@@ -477,11 +478,13 @@ int ext4_bio_write_page(struct ext4_io_s
 			unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
 		}
 		set_buffer_async_write(bh);
+		nr_to_submit++;
 	} while ((bh = bh->b_this_page) != head);
 
 	bh = head = page_buffers(page);
 
-	if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
+	if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
+	    nr_to_submit) {
 		data_page = ext4_encrypt(inode, page);
 		if (IS_ERR(data_page)) {
 			ret = PTR_ERR(data_page);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ext4/super.c linux-libre-4.3.4-gnu/fs/ext4/super.c
--- linux-libre-4.3-gnu/fs/ext4/super.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ext4/super.c	2016-01-22 23:59:37.000000000 -0500
@@ -394,9 +394,13 @@ static void ext4_handle_error(struct sup
 		smp_wmb();
 		sb->s_flags |= MS_RDONLY;
 	}
-	if (test_opt(sb, ERRORS_PANIC))
+	if (test_opt(sb, ERRORS_PANIC)) {
+		if (EXT4_SB(sb)->s_journal &&
+		  !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
+			return;
 		panic("EXT4-fs (device %s): panic forced after error\n",
 			sb->s_id);
+	}
 }
 
 #define ext4_error_ratelimit(sb)					\
@@ -585,8 +589,12 @@ void __ext4_abort(struct super_block *sb
 			jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
 		save_error_info(sb, function, line);
 	}
-	if (test_opt(sb, ERRORS_PANIC))
+	if (test_opt(sb, ERRORS_PANIC)) {
+		if (EXT4_SB(sb)->s_journal &&
+		  !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
+			return;
 		panic("EXT4-fs panic from previous error\n");
+	}
 }
 
 void __ext4_msg(struct super_block *sb,
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/jbd2/journal.c linux-libre-4.3.4-gnu/fs/jbd2/journal.c
--- linux-libre-4.3-gnu/fs/jbd2/journal.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/jbd2/journal.c	2016-01-22 23:59:37.000000000 -0500
@@ -2071,8 +2071,12 @@ static void __journal_abort_soft (journa
 
 	__jbd2_journal_abort_hard(journal);
 
-	if (errno)
+	if (errno) {
 		jbd2_journal_update_sb_errno(journal);
+		write_lock(&journal->j_state_lock);
+		journal->j_flags |= JBD2_REC_ERR;
+		write_unlock(&journal->j_state_lock);
+	}
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/nfs/inode.c linux-libre-4.3.4-gnu/fs/nfs/inode.c
--- linux-libre-4.3-gnu/fs/nfs/inode.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/nfs/inode.c	2016-01-22 23:59:37.000000000 -0500
@@ -1824,7 +1824,11 @@ static int nfs_update_inode(struct inode
 		if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0)
 			nfsi->attr_gencount = fattr->gencount;
 	}
-	invalid &= ~NFS_INO_INVALID_ATTR;
+
+	/* Don't declare attrcache up to date if there were no attrs! */
+	if (fattr->valid != 0)
+		invalid &= ~NFS_INO_INVALID_ATTR;
+
 	/* Don't invalidate the data if we were to blame */
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
 				|| S_ISLNK(inode->i_mode)))
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/nfs/nfs4client.c linux-libre-4.3.4-gnu/fs/nfs/nfs4client.c
--- linux-libre-4.3-gnu/fs/nfs/nfs4client.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/nfs/nfs4client.c	2016-01-22 23:59:37.000000000 -0500
@@ -33,7 +33,7 @@ static int nfs_get_cb_ident_idr(struct n
 		return ret;
 	idr_preload(GFP_KERNEL);
 	spin_lock(&nn->nfs_client_lock);
-	ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT);
+	ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT);
 	if (ret >= 0)
 		clp->cl_cb_ident = ret;
 	spin_unlock(&nn->nfs_client_lock);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/nfs/pnfs.c linux-libre-4.3.4-gnu/fs/nfs/pnfs.c
--- linux-libre-4.3-gnu/fs/nfs/pnfs.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/nfs/pnfs.c	2016-01-22 23:59:37.000000000 -0500
@@ -872,33 +872,38 @@ send_layoutget(struct pnfs_layout_hdr *l
 
 	dprintk("--> %s\n", __func__);
 
-	lgp = kzalloc(sizeof(*lgp), gfp_flags);
-	if (lgp == NULL)
-		return NULL;
+	/*
+	 * Synchronously retrieve layout information from server and
+	 * store in lseg. If we race with a concurrent seqid morphing
+	 * op, then re-send the LAYOUTGET.
+	 */
+	do {
+		lgp = kzalloc(sizeof(*lgp), gfp_flags);
+		if (lgp == NULL)
+			return NULL;
 
-	i_size = i_size_read(ino);
+		i_size = i_size_read(ino);
 
-	lgp->args.minlength = PAGE_CACHE_SIZE;
-	if (lgp->args.minlength > range->length)
-		lgp->args.minlength = range->length;
-	if (range->iomode == IOMODE_READ) {
-		if (range->offset >= i_size)
-			lgp->args.minlength = 0;
-		else if (i_size - range->offset < lgp->args.minlength)
-			lgp->args.minlength = i_size - range->offset;
-	}
-	lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
-	lgp->args.range = *range;
-	lgp->args.type = server->pnfs_curr_ld->id;
-	lgp->args.inode = ino;
-	lgp->args.ctx = get_nfs_open_context(ctx);
-	lgp->gfp_flags = gfp_flags;
-	lgp->cred = lo->plh_lc_cred;
+		lgp->args.minlength = PAGE_CACHE_SIZE;
+		if (lgp->args.minlength > range->length)
+			lgp->args.minlength = range->length;
+		if (range->iomode == IOMODE_READ) {
+			if (range->offset >= i_size)
+				lgp->args.minlength = 0;
+			else if (i_size - range->offset < lgp->args.minlength)
+				lgp->args.minlength = i_size - range->offset;
+		}
+		lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
+		lgp->args.range = *range;
+		lgp->args.type = server->pnfs_curr_ld->id;
+		lgp->args.inode = ino;
+		lgp->args.ctx = get_nfs_open_context(ctx);
+		lgp->gfp_flags = gfp_flags;
+		lgp->cred = lo->plh_lc_cred;
+
+		lseg = nfs4_proc_layoutget(lgp, gfp_flags);
+	} while (lseg == ERR_PTR(-EAGAIN));
 
-	/* Synchronously retrieve layout information from server and
-	 * store in lseg.
-	 */
-	lseg = nfs4_proc_layoutget(lgp, gfp_flags);
 	if (IS_ERR(lseg)) {
 		switch (PTR_ERR(lseg)) {
 		case -ENOMEM:
@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutge
 		/* existing state ID, make sure the sequence number matches. */
 		if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
 			dprintk("%s forget reply due to sequence\n", __func__);
+			status = -EAGAIN;
 			goto out_forget_reply;
 		}
 		pnfs_set_layout_stateid(lo, &res->stateid, false);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/nfsd/nfs4state.c linux-libre-4.3.4-gnu/fs/nfsd/nfs4state.c
--- linux-libre-4.3-gnu/fs/nfsd/nfs4state.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/nfsd/nfs4state.c	2016-01-22 23:59:37.000000000 -0500
@@ -765,16 +765,68 @@ void nfs4_unhash_stid(struct nfs4_stid *
 	s->sc_type = 0;
 }
 
-static void
+/**
+ * nfs4_get_existing_delegation - Discover if this delegation already exists
+ * @clp:     a pointer to the nfs4_client we're granting a delegation to
+ * @fp:      a pointer to the nfs4_file we're granting a delegation on
+ *
+ * Return:
+ *      On success: NULL if an existing delegation was not found.
+ *
+ *      On error: -EAGAIN if one was previously granted to this nfs4_client
+ *                 for this nfs4_file.
+ *
+ */
+
+static int
+nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
+{
+	struct nfs4_delegation *searchdp = NULL;
+	struct nfs4_client *searchclp = NULL;
+
+	lockdep_assert_held(&state_lock);
+	lockdep_assert_held(&fp->fi_lock);
+
+	list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) {
+		searchclp = searchdp->dl_stid.sc_client;
+		if (clp == searchclp) {
+			return -EAGAIN;
+		}
+	}
+	return 0;
+}
+
+/**
+ * hash_delegation_locked - Add a delegation to the appropriate lists
+ * @dp:     a pointer to the nfs4_delegation we are adding.
+ * @fp:     a pointer to the nfs4_file we're granting a delegation on
+ *
+ * Return:
+ *      On success: NULL if the delegation was successfully hashed.
+ *
+ *      On error: -EAGAIN if one was previously granted to this
+ *                 nfs4_client for this nfs4_file. Delegation is not hashed.
+ *
+ */
+
+static int
 hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
 {
+	int status;
+	struct nfs4_client *clp = dp->dl_stid.sc_client;
+
 	lockdep_assert_held(&state_lock);
 	lockdep_assert_held(&fp->fi_lock);
 
+	status = nfs4_get_existing_delegation(clp, fp);
+	if (status)
+		return status;
+	++fp->fi_delegees;
 	atomic_inc(&dp->dl_stid.sc_count);
 	dp->dl_stid.sc_type = NFS4_DELEG_STID;
 	list_add(&dp->dl_perfile, &fp->fi_delegations);
-	list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
+	list_add(&dp->dl_perclnt, &clp->cl_delegations);
+	return 0;
 }
 
 static bool
@@ -3360,6 +3412,7 @@ static void init_open_stateid(struct nfs
 	stp->st_access_bmap = 0;
 	stp->st_deny_bmap = 0;
 	stp->st_openstp = NULL;
+	init_rwsem(&stp->st_rwsem);
 	spin_lock(&oo->oo_owner.so_client->cl_lock);
 	list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
 	spin_lock(&fp->fi_lock);
@@ -3945,6 +3998,18 @@ static struct file_lock *nfs4_alloc_init
 	return fl;
 }
 
+/**
+ * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer
+ * @dp:   a pointer to the nfs4_delegation we're adding.
+ *
+ * Return:
+ *      On success: Return code will be 0 on success.
+ *
+ *      On error: -EAGAIN if there was an existing delegation.
+ *                 nonzero if there is an error in other cases.
+ *
+ */
+
 static int nfs4_setlease(struct nfs4_delegation *dp)
 {
 	struct nfs4_file *fp = dp->dl_stid.sc_file;
@@ -3976,16 +4041,19 @@ static int nfs4_setlease(struct nfs4_del
 		goto out_unlock;
 	/* Race breaker */
 	if (fp->fi_deleg_file) {
-		status = 0;
-		++fp->fi_delegees;
-		hash_delegation_locked(dp, fp);
+		status = hash_delegation_locked(dp, fp);
 		goto out_unlock;
 	}
 	fp->fi_deleg_file = filp;
-	fp->fi_delegees = 1;
-	hash_delegation_locked(dp, fp);
+	fp->fi_delegees = 0;
+	status = hash_delegation_locked(dp, fp);
 	spin_unlock(&fp->fi_lock);
 	spin_unlock(&state_lock);
+	if (status) {
+		/* Should never happen, this is a new fi_deleg_file  */
+		WARN_ON_ONCE(1);
+		goto out_fput;
+	}
 	return 0;
 out_unlock:
 	spin_unlock(&fp->fi_lock);
@@ -4005,6 +4073,15 @@ nfs4_set_delegation(struct nfs4_client *
 	if (fp->fi_had_conflict)
 		return ERR_PTR(-EAGAIN);
 
+	spin_lock(&state_lock);
+	spin_lock(&fp->fi_lock);
+	status = nfs4_get_existing_delegation(clp, fp);
+	spin_unlock(&fp->fi_lock);
+	spin_unlock(&state_lock);
+
+	if (status)
+		return ERR_PTR(status);
+
 	dp = alloc_init_deleg(clp, fh, odstate);
 	if (!dp)
 		return ERR_PTR(-ENOMEM);
@@ -4023,9 +4100,7 @@ nfs4_set_delegation(struct nfs4_client *
 		status = -EAGAIN;
 		goto out_unlock;
 	}
-	++fp->fi_delegees;
-	hash_delegation_locked(dp, fp);
-	status = 0;
+	status = hash_delegation_locked(dp, fp);
 out_unlock:
 	spin_unlock(&fp->fi_lock);
 	spin_unlock(&state_lock);
@@ -4187,15 +4262,20 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	 */
 	if (stp) {
 		/* Stateid was found, this is an OPEN upgrade */
+		down_read(&stp->st_rwsem);
 		status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
-		if (status)
+		if (status) {
+			up_read(&stp->st_rwsem);
 			goto out;
+		}
 	} else {
 		stp = open->op_stp;
 		open->op_stp = NULL;
 		init_open_stateid(stp, fp, open);
+		down_read(&stp->st_rwsem);
 		status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
 		if (status) {
+			up_read(&stp->st_rwsem);
 			release_open_stateid(stp);
 			goto out;
 		}
@@ -4207,6 +4287,7 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	}
 	update_stateid(&stp->st_stid.sc_stateid);
 	memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+	up_read(&stp->st_rwsem);
 
 	if (nfsd4_has_session(&resp->cstate)) {
 		if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
@@ -4819,10 +4900,13 @@ static __be32 nfs4_seqid_op_checks(struc
 		 * revoked delegations are kept only for free_stateid.
 		 */
 		return nfserr_bad_stateid;
+	down_write(&stp->st_rwsem);
 	status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
-	if (status)
-		return status;
-	return nfs4_check_fh(current_fh, &stp->st_stid);
+	if (status == nfs_ok)
+		status = nfs4_check_fh(current_fh, &stp->st_stid);
+	if (status != nfs_ok)
+		up_write(&stp->st_rwsem);
+	return status;
 }
 
 /* 
@@ -4869,6 +4953,7 @@ static __be32 nfs4_preprocess_confirmed_
 		return status;
 	oo = openowner(stp->st_stateowner);
 	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
+		up_write(&stp->st_rwsem);
 		nfs4_put_stid(&stp->st_stid);
 		return nfserr_bad_stateid;
 	}
@@ -4899,11 +4984,14 @@ nfsd4_open_confirm(struct svc_rqst *rqst
 		goto out;
 	oo = openowner(stp->st_stateowner);
 	status = nfserr_bad_stateid;
-	if (oo->oo_flags & NFS4_OO_CONFIRMED)
+	if (oo->oo_flags & NFS4_OO_CONFIRMED) {
+		up_write(&stp->st_rwsem);
 		goto put_stateid;
+	}
 	oo->oo_flags |= NFS4_OO_CONFIRMED;
 	update_stateid(&stp->st_stid.sc_stateid);
 	memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+	up_write(&stp->st_rwsem);
 	dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
 		__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
 
@@ -4982,6 +5070,7 @@ nfsd4_open_downgrade(struct svc_rqst *rq
 	memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
 	status = nfs_ok;
 put_stateid:
+	up_write(&stp->st_rwsem);
 	nfs4_put_stid(&stp->st_stid);
 out:
 	nfsd4_bump_seqid(cstate, status);
@@ -5035,6 +5124,7 @@ nfsd4_close(struct svc_rqst *rqstp, stru
 		goto out; 
 	update_stateid(&stp->st_stid.sc_stateid);
 	memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+	up_write(&stp->st_rwsem);
 
 	nfsd4_close_open_stateid(stp);
 
@@ -5260,6 +5350,7 @@ init_lock_stateid(struct nfs4_ol_stateid
 	stp->st_access_bmap = 0;
 	stp->st_deny_bmap = open_stp->st_deny_bmap;
 	stp->st_openstp = open_stp;
+	init_rwsem(&stp->st_rwsem);
 	list_add(&stp->st_locks, &open_stp->st_locks);
 	list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
 	spin_lock(&fp->fi_lock);
@@ -5428,6 +5519,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 					&open_stp, nn);
 		if (status)
 			goto out;
+		up_write(&open_stp->st_rwsem);
 		open_sop = openowner(open_stp->st_stateowner);
 		status = nfserr_bad_stateid;
 		if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
@@ -5435,6 +5527,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 			goto out;
 		status = lookup_or_create_lock_state(cstate, open_stp, lock,
 							&lock_stp, &new);
+		if (status == nfs_ok)
+			down_write(&lock_stp->st_rwsem);
 	} else {
 		status = nfs4_preprocess_seqid_op(cstate,
 				       lock->lk_old_lock_seqid,
@@ -5540,6 +5634,8 @@ out:
 		    seqid_mutating_err(ntohl(status)))
 			lock_sop->lo_owner.so_seqid++;
 
+		up_write(&lock_stp->st_rwsem);
+
 		/*
 		 * If this is a new, never-before-used stateid, and we are
 		 * returning an error, then just go ahead and release it.
@@ -5709,6 +5805,7 @@ nfsd4_locku(struct svc_rqst *rqstp, stru
 fput:
 	fput(filp);
 put_stateid:
+	up_write(&stp->st_rwsem);
 	nfs4_put_stid(&stp->st_stid);
 out:
 	nfsd4_bump_seqid(cstate, status);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/nfsd/state.h linux-libre-4.3.4-gnu/fs/nfsd/state.h
--- linux-libre-4.3-gnu/fs/nfsd/state.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/nfsd/state.h	2016-01-22 23:59:37.000000000 -0500
@@ -534,15 +534,16 @@ struct nfs4_file {
  * Better suggestions welcome.
  */
 struct nfs4_ol_stateid {
-	struct nfs4_stid    st_stid; /* must be first field */
-	struct list_head              st_perfile;
-	struct list_head              st_perstateowner;
-	struct list_head              st_locks;
-	struct nfs4_stateowner      * st_stateowner;
-	struct nfs4_clnt_odstate    * st_clnt_odstate;
-	unsigned char                 st_access_bmap;
-	unsigned char                 st_deny_bmap;
-	struct nfs4_ol_stateid         * st_openstp;
+	struct nfs4_stid		st_stid;
+	struct list_head		st_perfile;
+	struct list_head		st_perstateowner;
+	struct list_head		st_locks;
+	struct nfs4_stateowner		*st_stateowner;
+	struct nfs4_clnt_odstate	*st_clnt_odstate;
+	unsigned char			st_access_bmap;
+	unsigned char			st_deny_bmap;
+	struct nfs4_ol_stateid		*st_openstp;
+	struct rw_semaphore		st_rwsem;
 };
 
 static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/ocfs2/namei.c linux-libre-4.3.4-gnu/fs/ocfs2/namei.c
--- linux-libre-4.3-gnu/fs/ocfs2/namei.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/ocfs2/namei.c	2016-01-22 23:59:37.000000000 -0500
@@ -374,6 +374,8 @@ static int ocfs2_mknod(struct inode *dir
 		mlog_errno(status);
 		goto leave;
 	}
+	/* update inode->i_mode after mask with "umask". */
+	inode->i_mode = mode;
 
 	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
 							    S_ISDIR(mode),
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/proc/array.c linux-libre-4.3.4-gnu/fs/proc/array.c
--- linux-libre-4.3-gnu/fs/proc/array.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/proc/array.c	2016-01-22 23:59:37.000000000 -0500
@@ -375,7 +375,7 @@ int proc_pid_status(struct seq_file *m,
 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task, int whole)
 {
-	unsigned long vsize, eip, esp, wchan = ~0UL;
+	unsigned long vsize, eip, esp, wchan = 0;
 	int priority, nice;
 	int tty_pgrp = -1, tty_nr = 0;
 	sigset_t sigign, sigcatch;
@@ -507,7 +507,19 @@ static int do_task_stat(struct seq_file
 	seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
-	seq_put_decimal_ull(m, ' ', wchan);
+
+	/*
+	 * We used to output the absolute kernel address, but that's an
+	 * information leak - so instead we show a 0/1 flag here, to signal
+	 * to user-space whether there's a wchan field in /proc/PID/wchan.
+	 *
+	 * This works with older implementations of procps as well.
+	 */
+	if (wchan)
+		seq_puts(m, " 1");
+	else
+		seq_puts(m, " 0");
+
 	seq_put_decimal_ull(m, ' ', 0);
 	seq_put_decimal_ull(m, ' ', 0);
 	seq_put_decimal_ll(m, ' ', task->exit_signal);
diff -druNp --no-dereference linux-libre-4.3-gnu/fs/proc/base.c linux-libre-4.3.4-gnu/fs/proc/base.c
--- linux-libre-4.3-gnu/fs/proc/base.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/fs/proc/base.c	2016-01-22 23:59:37.000000000 -0500
@@ -430,13 +430,10 @@ static int proc_pid_wchan(struct seq_fil
 
 	wchan = get_wchan(task);
 
-	if (lookup_symbol_name(wchan, symname) < 0) {
-		if (!ptrace_may_access(task, PTRACE_MODE_READ))
-			return 0;
-		seq_printf(m, "%lu", wchan);
-	} else {
+	if (wchan && ptrace_may_access(task, PTRACE_MODE_READ) && !lookup_symbol_name(wchan, symname))
 		seq_printf(m, "%s", symname);
-	}
+	else
+		seq_putc(m, '0');
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/acpi.h linux-libre-4.3.4-gnu/include/linux/acpi.h
--- linux-libre-4.3-gnu/include/linux/acpi.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/acpi.h	2016-01-22 23:59:37.000000000 -0500
@@ -193,6 +193,12 @@ int acpi_ioapic_registered(acpi_handle h
 void acpi_irq_stats_init(void);
 extern u32 acpi_irq_handled;
 extern u32 acpi_irq_not_handled;
+extern unsigned int acpi_sci_irq;
+#define INVALID_ACPI_IRQ	((unsigned)-1)
+static inline bool acpi_sci_irq_valid(void)
+{
+	return acpi_sci_irq != INVALID_ACPI_IRQ;
+}
 
 extern int sbf_port;
 extern unsigned long acpi_realmode_flags;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/ipv6.h linux-libre-4.3.4-gnu/include/linux/ipv6.h
--- linux-libre-4.3-gnu/include/linux/ipv6.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/ipv6.h	2016-01-22 23:59:37.000000000 -0500
@@ -227,7 +227,7 @@ struct ipv6_pinfo {
 	struct ipv6_ac_socklist	*ipv6_ac_list;
 	struct ipv6_fl_socklist __rcu *ipv6_fl_list;
 
-	struct ipv6_txoptions	*opt;
+	struct ipv6_txoptions __rcu	*opt;
 	struct sk_buff		*pktoptions;
 	struct sk_buff		*rxpmtu;
 	struct inet6_cork	cork;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/jbd2.h linux-libre-4.3.4-gnu/include/linux/jbd2.h
--- linux-libre-4.3-gnu/include/linux/jbd2.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/jbd2.h	2016-01-22 23:59:37.000000000 -0500
@@ -1046,6 +1046,7 @@ struct journal_s
 #define JBD2_ABORT_ON_SYNCDATA_ERR	0x040	/* Abort the journal on file
 						 * data write error in ordered
 						 * mode */
+#define JBD2_REC_ERR	0x080	/* The errno in the sb has been recorded */
 
 /*
  * Function declarations for the journaling transaction and buffer
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/kvm_host.h linux-libre-4.3.4-gnu/include/linux/kvm_host.h
--- linux-libre-4.3-gnu/include/linux/kvm_host.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/kvm_host.h	2016-01-22 23:59:37.000000000 -0500
@@ -442,6 +442,17 @@ static inline struct kvm_vcpu *kvm_get_v
 	     (vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \
 	     idx++)
 
+static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id)
+{
+	struct kvm_vcpu *vcpu;
+	int i;
+
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		if (vcpu->vcpu_id == id)
+			return vcpu;
+	return NULL;
+}
+
 #define kvm_for_each_memslot(memslot, slots)	\
 	for (memslot = &slots->memslots[0];	\
 	      memslot < slots->memslots + KVM_MEM_SLOTS_NUM && memslot->npages;\
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/mlx5/mlx5_ifc.h linux-libre-4.3.4-gnu/include/linux/mlx5/mlx5_ifc.h
--- linux-libre-4.3-gnu/include/linux/mlx5/mlx5_ifc.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/mlx5/mlx5_ifc.h	2016-01-22 23:59:37.000000000 -0500
@@ -453,26 +453,28 @@ struct mlx5_ifc_per_protocol_networking_
 	u8         lro_cap[0x1];
 	u8         lro_psh_flag[0x1];
 	u8         lro_time_stamp[0x1];
-	u8         reserved_0[0x6];
+	u8         reserved_0[0x3];
+	u8         self_lb_en_modifiable[0x1];
+	u8         reserved_1[0x2];
 	u8         max_lso_cap[0x5];
-	u8         reserved_1[0x4];
+	u8         reserved_2[0x4];
 	u8         rss_ind_tbl_cap[0x4];
-	u8         reserved_2[0x3];
+	u8         reserved_3[0x3];
 	u8         tunnel_lso_const_out_ip_id[0x1];
-	u8         reserved_3[0x2];
+	u8         reserved_4[0x2];
 	u8         tunnel_statless_gre[0x1];
 	u8         tunnel_stateless_vxlan[0x1];
 
-	u8         reserved_4[0x20];
+	u8         reserved_5[0x20];
 
-	u8         reserved_5[0x10];
+	u8         reserved_6[0x10];
 	u8         lro_min_mss_size[0x10];
 
-	u8         reserved_6[0x120];
+	u8         reserved_7[0x120];
 
 	u8         lro_timer_supported_periods[4][0x20];
 
-	u8         reserved_7[0x600];
+	u8         reserved_8[0x600];
 };
 
 struct mlx5_ifc_roce_cap_bits {
@@ -4051,9 +4053,11 @@ struct mlx5_ifc_modify_tis_in_bits {
 };
 
 struct mlx5_ifc_modify_tir_bitmask_bits {
-	u8	   reserved[0x20];
+	u8	   reserved_0[0x20];
 
-	u8         reserved1[0x1f];
+	u8         reserved_1[0x1b];
+	u8         self_lb_en[0x1];
+	u8         reserved_2[0x3];
 	u8         lro[0x1];
 };
 
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/tty.h linux-libre-4.3.4-gnu/include/linux/tty.h
--- linux-libre-4.3-gnu/include/linux/tty.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/tty.h	2016-01-22 23:59:37.000000000 -0500
@@ -605,7 +605,7 @@ extern void n_tty_inherit_ops(struct tty
 
 /* tty_audit.c */
 #ifdef CONFIG_AUDIT
-extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
+extern void tty_audit_add_data(struct tty_struct *tty, const void *data,
 			       size_t size, unsigned icanon);
 extern void tty_audit_exit(void);
 extern void tty_audit_fork(struct signal_struct *sig);
@@ -613,8 +613,8 @@ extern void tty_audit_tiocsti(struct tty
 extern void tty_audit_push(struct tty_struct *tty);
 extern int tty_audit_push_current(void);
 #else
-static inline void tty_audit_add_data(struct tty_struct *tty,
-		unsigned char *data, size_t size, unsigned icanon)
+static inline void tty_audit_add_data(struct tty_struct *tty, const void *data,
+				      size_t size, unsigned icanon)
 {
 }
 static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch)
diff -druNp --no-dereference linux-libre-4.3-gnu/include/linux/usb/quirks.h linux-libre-4.3.4-gnu/include/linux/usb/quirks.h
--- linux-libre-4.3-gnu/include/linux/usb/quirks.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/linux/usb/quirks.h	2016-01-22 23:59:37.000000000 -0500
@@ -47,4 +47,7 @@
 /* device generates spurious wakeup, ignore remote wakeup capability */
 #define USB_QUIRK_IGNORE_REMOTE_WAKEUP		BIT(9)
 
+/* device can't handle Link Power Management */
+#define USB_QUIRK_NO_LPM			BIT(10)
+
 #endif /* __LINUX_USB_QUIRKS_H */
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/af_unix.h linux-libre-4.3.4-gnu/include/net/af_unix.h
--- linux-libre-4.3-gnu/include/net/af_unix.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/af_unix.h	2016-01-22 23:59:37.000000000 -0500
@@ -62,6 +62,7 @@ struct unix_sock {
 #define UNIX_GC_CANDIDATE	0
 #define UNIX_GC_MAYBE_CYCLE	1
 	struct socket_wq	peer_wq;
+	wait_queue_t		peer_wake;
 };
 
 static inline struct unix_sock *unix_sk(const struct sock *sk)
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/bluetooth/hci_core.h linux-libre-4.3.4-gnu/include/net/bluetooth/hci_core.h
--- linux-libre-4.3-gnu/include/net/bluetooth/hci_core.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/bluetooth/hci_core.h	2016-01-22 23:59:37.000000000 -0500
@@ -469,6 +469,7 @@ struct hci_conn {
 	struct delayed_work auto_accept_work;
 	struct delayed_work idle_work;
 	struct delayed_work le_conn_timeout;
+	struct work_struct  le_scan_cleanup;
 
 	struct device	dev;
 	struct dentry	*debugfs;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/dst.h linux-libre-4.3.4-gnu/include/net/dst.h
--- linux-libre-4.3-gnu/include/net/dst.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/dst.h	2016-01-22 23:59:37.000000000 -0500
@@ -322,6 +322,39 @@ static inline void skb_dst_force(struct
 	}
 }
 
+/**
+ * dst_hold_safe - Take a reference on a dst if possible
+ * @dst: pointer to dst entry
+ *
+ * This helper returns false if it could not safely
+ * take a reference on a dst.
+ */
+static inline bool dst_hold_safe(struct dst_entry *dst)
+{
+	if (dst->flags & DST_NOCACHE)
+		return atomic_inc_not_zero(&dst->__refcnt);
+	dst_hold(dst);
+	return true;
+}
+
+/**
+ * skb_dst_force_safe - makes sure skb dst is refcounted
+ * @skb: buffer
+ *
+ * If dst is not yet refcounted and not destroyed, grab a ref on it.
+ */
+static inline void skb_dst_force_safe(struct sk_buff *skb)
+{
+	if (skb_dst_is_noref(skb)) {
+		struct dst_entry *dst = skb_dst(skb);
+
+		if (!dst_hold_safe(dst))
+			dst = NULL;
+
+		skb->_skb_refdst = (unsigned long)dst;
+	}
+}
+
 
 /**
  *	__skb_tunnel_rx - prepare skb for rx reinsert
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/dst_metadata.h linux-libre-4.3.4-gnu/include/net/dst_metadata.h
--- linux-libre-4.3-gnu/include/net/dst_metadata.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/dst_metadata.h	2016-01-22 23:59:37.000000000 -0500
@@ -63,12 +63,13 @@ static inline struct metadata_dst *tun_r
 static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
 {
 	struct metadata_dst *md_dst = skb_metadata_dst(skb);
-	int md_size = md_dst->u.tun_info.options_len;
+	int md_size;
 	struct metadata_dst *new_md;
 
 	if (!md_dst)
 		return ERR_PTR(-EINVAL);
 
+	md_size = md_dst->u.tun_info.options_len;
 	new_md = metadata_dst_alloc(md_size, GFP_ATOMIC);
 	if (!new_md)
 		return ERR_PTR(-ENOMEM);
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/inet_common.h linux-libre-4.3.4-gnu/include/net/inet_common.h
--- linux-libre-4.3-gnu/include/net/inet_common.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/inet_common.h	2016-01-22 23:59:37.000000000 -0500
@@ -41,7 +41,8 @@ int inet_recv_error(struct sock *sk, str
 
 static inline void inet_ctl_sock_destroy(struct sock *sk)
 {
-	sock_release(sk->sk_socket);
+	if (sk)
+		sock_release(sk->sk_socket);
 }
 
 #endif
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/inetpeer.h linux-libre-4.3.4-gnu/include/net/inetpeer.h
--- linux-libre-4.3-gnu/include/net/inetpeer.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/inetpeer.h	2016-01-22 23:59:37.000000000 -0500
@@ -78,6 +78,7 @@ void inet_initpeers(void) __init;
 static inline void inetpeer_set_addr_v4(struct inetpeer_addr *iaddr, __be32 ip)
 {
 	iaddr->a4.addr = ip;
+	iaddr->a4.vif = 0;
 	iaddr->family = AF_INET;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/ip6_fib.h linux-libre-4.3.4-gnu/include/net/ip6_fib.h
--- linux-libre-4.3-gnu/include/net/ip6_fib.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/ip6_fib.h	2016-01-22 23:59:37.000000000 -0500
@@ -167,7 +167,8 @@ static inline void rt6_update_expires(st
 
 static inline u32 rt6_get_cookie(const struct rt6_info *rt)
 {
-	if (rt->rt6i_flags & RTF_PCPU || unlikely(rt->dst.flags & DST_NOCACHE))
+	if (rt->rt6i_flags & RTF_PCPU ||
+	    (unlikely(rt->dst.flags & DST_NOCACHE) && rt->dst.from))
 		rt = (struct rt6_info *)(rt->dst.from);
 
 	return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/ip6_tunnel.h linux-libre-4.3.4-gnu/include/net/ip6_tunnel.h
--- linux-libre-4.3-gnu/include/net/ip6_tunnel.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/ip6_tunnel.h	2016-01-22 23:59:37.000000000 -0500
@@ -90,11 +90,12 @@ static inline void ip6tunnel_xmit(struct
 	err = ip6_local_out_sk(sk, skb);
 
 	if (net_xmit_eval(err) == 0) {
-		struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
+		struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats);
 		u64_stats_update_begin(&tstats->syncp);
 		tstats->tx_bytes += pkt_len;
 		tstats->tx_packets++;
 		u64_stats_update_end(&tstats->syncp);
+		put_cpu_ptr(tstats);
 	} else {
 		stats->tx_errors++;
 		stats->tx_aborted_errors++;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/ip_fib.h linux-libre-4.3.4-gnu/include/net/ip_fib.h
--- linux-libre-4.3-gnu/include/net/ip_fib.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/ip_fib.h	2016-01-22 23:59:37.000000000 -0500
@@ -317,7 +317,7 @@ void fib_flush_external(struct net *net)
 
 /* Exported by fib_semantics.c */
 int ip_fib_check_default(__be32 gw, struct net_device *dev);
-int fib_sync_down_dev(struct net_device *dev, unsigned long event);
+int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
 int fib_sync_down_addr(struct net *net, __be32 local);
 int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
 void fib_select_multipath(struct fib_result *res);
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/ip_tunnels.h linux-libre-4.3.4-gnu/include/net/ip_tunnels.h
--- linux-libre-4.3-gnu/include/net/ip_tunnels.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/ip_tunnels.h	2016-01-22 23:59:37.000000000 -0500
@@ -287,12 +287,13 @@ static inline void iptunnel_xmit_stats(i
 				       struct pcpu_sw_netstats __percpu *stats)
 {
 	if (err > 0) {
-		struct pcpu_sw_netstats *tstats = this_cpu_ptr(stats);
+		struct pcpu_sw_netstats *tstats = get_cpu_ptr(stats);
 
 		u64_stats_update_begin(&tstats->syncp);
 		tstats->tx_bytes += err;
 		tstats->tx_packets++;
 		u64_stats_update_end(&tstats->syncp);
+		put_cpu_ptr(tstats);
 	} else if (err < 0) {
 		err_stats->tx_errors++;
 		err_stats->tx_aborted_errors++;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/ipv6.h linux-libre-4.3.4-gnu/include/net/ipv6.h
--- linux-libre-4.3-gnu/include/net/ipv6.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/ipv6.h	2016-01-22 23:59:37.000000000 -0500
@@ -205,6 +205,7 @@ extern rwlock_t ip6_ra_lock;
  */
 
 struct ipv6_txoptions {
+	atomic_t		refcnt;
 	/* Length of this structure */
 	int			tot_len;
 
@@ -217,7 +218,7 @@ struct ipv6_txoptions {
 	struct ipv6_opt_hdr	*dst0opt;
 	struct ipv6_rt_hdr	*srcrt;	/* Routing Header */
 	struct ipv6_opt_hdr	*dst1opt;
-
+	struct rcu_head		rcu;
 	/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
 };
 
@@ -252,6 +253,24 @@ struct ipv6_fl_socklist {
 	struct rcu_head			rcu;
 };
 
+static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
+{
+	struct ipv6_txoptions *opt;
+
+	rcu_read_lock();
+	opt = rcu_dereference(np->opt);
+	if (opt && !atomic_inc_not_zero(&opt->refcnt))
+		opt = NULL;
+	rcu_read_unlock();
+	return opt;
+}
+
+static inline void txopt_put(struct ipv6_txoptions *opt)
+{
+	if (opt && atomic_dec_and_test(&opt->refcnt))
+		kfree_rcu(opt, rcu);
+}
+
 struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label);
 struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
 					 struct ip6_flowlabel *fl,
@@ -490,6 +509,7 @@ struct ip6_create_arg {
 	u32 user;
 	const struct in6_addr *src;
 	const struct in6_addr *dst;
+	int iif;
 	u8 ecn;
 };
 
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/ndisc.h linux-libre-4.3.4-gnu/include/net/ndisc.h
--- linux-libre-4.3-gnu/include/net/ndisc.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/ndisc.h	2016-01-22 23:59:37.000000000 -0500
@@ -182,8 +182,7 @@ int ndisc_rcv(struct sk_buff *skb);
 
 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 		   const struct in6_addr *solicit,
-		   const struct in6_addr *daddr, const struct in6_addr *saddr,
-		   struct sk_buff *oskb);
+		   const struct in6_addr *daddr, const struct in6_addr *saddr);
 
 void ndisc_send_rs(struct net_device *dev,
 		   const struct in6_addr *saddr, const struct in6_addr *daddr);
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/sch_generic.h linux-libre-4.3.4-gnu/include/net/sch_generic.h
--- linux-libre-4.3-gnu/include/net/sch_generic.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/sch_generic.h	2016-01-22 23:59:37.000000000 -0500
@@ -61,6 +61,9 @@ struct Qdisc {
 				      */
 #define TCQ_F_WARN_NONWC	(1 << 16)
 #define TCQ_F_CPUSTATS		0x20 /* run using percpu statistics */
+#define TCQ_F_NOPARENT		0x40 /* root of its hierarchy :
+				      * qdisc_tree_decrease_qlen() should stop.
+				      */
 	u32			limit;
 	const struct Qdisc_ops	*ops;
 	struct qdisc_size_table	__rcu *stab;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/sock.h linux-libre-4.3.4-gnu/include/net/sock.h
--- linux-libre-4.3-gnu/include/net/sock.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/sock.h	2016-01-22 23:59:37.000000000 -0500
@@ -387,6 +387,7 @@ struct sock {
 				sk_no_check_rx : 1,
 				sk_userlocks : 4,
 				sk_protocol  : 8,
+#define SK_PROTOCOL_MAX U8_MAX
 				sk_type      : 16;
 	kmemcheck_bitfield_end(flags);
 	int			sk_wmem_queued;
@@ -724,6 +725,8 @@ enum sock_flags {
 	SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
 };
 
+#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
+
 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
 {
 	nsk->sk_flags = osk->sk_flags;
@@ -798,7 +801,7 @@ void sk_stream_write_space(struct sock *
 static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
 {
 	/* dont let skb dst not refcounted, we are going to leave rcu lock */
-	skb_dst_force(skb);
+	skb_dst_force_safe(skb);
 
 	if (!sk->sk_backlog.tail)
 		sk->sk_backlog.head = skb;
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/switchdev.h linux-libre-4.3.4-gnu/include/net/switchdev.h
--- linux-libre-4.3-gnu/include/net/switchdev.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/switchdev.h	2016-01-22 23:59:37.000000000 -0500
@@ -272,7 +272,7 @@ static inline int switchdev_port_fdb_dum
 					  struct net_device *filter_dev,
 					  int idx)
 {
-	return -EOPNOTSUPP;
+       return idx;
 }
 
 static inline void switchdev_port_fwd_mark_set(struct net_device *dev,
diff -druNp --no-dereference linux-libre-4.3-gnu/include/net/vxlan.h linux-libre-4.3.4-gnu/include/net/vxlan.h
--- linux-libre-4.3-gnu/include/net/vxlan.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/net/vxlan.h	2016-01-22 23:59:37.000000000 -0500
@@ -79,7 +79,7 @@ struct vxlanhdr {
 };
 
 /* VXLAN header flags. */
-#define VXLAN_HF_RCO BIT(24)
+#define VXLAN_HF_RCO BIT(21)
 #define VXLAN_HF_VNI BIT(27)
 #define VXLAN_HF_GBP BIT(31)
 
diff -druNp --no-dereference linux-libre-4.3-gnu/include/uapi/linux/Kbuild linux-libre-4.3.4-gnu/include/uapi/linux/Kbuild
--- linux-libre-4.3-gnu/include/uapi/linux/Kbuild	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/include/uapi/linux/Kbuild	2016-01-22 23:59:37.000000000 -0500
@@ -186,6 +186,7 @@ header-y += if_tunnel.h
 header-y += if_vlan.h
 header-y += if_x25.h
 header-y += igmp.h
+header-y += ila.h
 header-y += in6.h
 header-y += inet_diag.h
 header-y += in.h
diff -druNp --no-dereference linux-libre-4.3-gnu/kernel/bpf/arraymap.c linux-libre-4.3.4-gnu/kernel/bpf/arraymap.c
--- linux-libre-4.3-gnu/kernel/bpf/arraymap.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/kernel/bpf/arraymap.c	2016-01-22 23:59:37.000000000 -0500
@@ -104,7 +104,7 @@ static int array_map_update_elem(struct
 		/* all elements already exist */
 		return -EEXIST;
 
-	memcpy(array->value + array->elem_size * index, value, array->elem_size);
+	memcpy(array->value + array->elem_size * index, value, map->value_size);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/kernel/.gitignore linux-libre-4.3.4-gnu/kernel/.gitignore
--- linux-libre-4.3-gnu/kernel/.gitignore	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/kernel/.gitignore	2016-01-22 23:59:37.000000000 -0500
@@ -5,4 +5,3 @@ config_data.h
 config_data.gz
 timeconst.h
 hz.bc
-x509_certificate_list
diff -druNp --no-dereference linux-libre-4.3-gnu/lib/rhashtable.c linux-libre-4.3.4-gnu/lib/rhashtable.c
--- linux-libre-4.3-gnu/lib/rhashtable.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/lib/rhashtable.c	2016-01-22 23:59:37.000000000 -0500
@@ -503,10 +503,11 @@ int rhashtable_walk_init(struct rhashtab
 	if (!iter->walker)
 		return -ENOMEM;
 
-	mutex_lock(&ht->mutex);
-	iter->walker->tbl = rht_dereference(ht->tbl, ht);
+	spin_lock(&ht->lock);
+	iter->walker->tbl =
+		rcu_dereference_protected(ht->tbl, lockdep_is_held(&ht->lock));
 	list_add(&iter->walker->list, &iter->walker->tbl->walkers);
-	mutex_unlock(&ht->mutex);
+	spin_unlock(&ht->lock);
 
 	return 0;
 }
@@ -520,10 +521,10 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_init);
  */
 void rhashtable_walk_exit(struct rhashtable_iter *iter)
 {
-	mutex_lock(&iter->ht->mutex);
+	spin_lock(&iter->ht->lock);
 	if (iter->walker->tbl)
 		list_del(&iter->walker->list);
-	mutex_unlock(&iter->ht->mutex);
+	spin_unlock(&iter->ht->lock);
 	kfree(iter->walker);
 }
 EXPORT_SYMBOL_GPL(rhashtable_walk_exit);
@@ -547,14 +548,12 @@ int rhashtable_walk_start(struct rhashta
 {
 	struct rhashtable *ht = iter->ht;
 
-	mutex_lock(&ht->mutex);
+	rcu_read_lock();
 
+	spin_lock(&ht->lock);
 	if (iter->walker->tbl)
 		list_del(&iter->walker->list);
-
-	rcu_read_lock();
-
-	mutex_unlock(&ht->mutex);
+	spin_unlock(&ht->lock);
 
 	if (!iter->walker->tbl) {
 		iter->walker->tbl = rht_dereference_rcu(ht->tbl, ht);
@@ -723,9 +722,6 @@ int rhashtable_init(struct rhashtable *h
 	if (params->nulls_base && params->nulls_base < (1U << RHT_BASE_SHIFT))
 		return -EINVAL;
 
-	if (params->nelem_hint)
-		size = rounded_hashtable_size(params);
-
 	memset(ht, 0, sizeof(*ht));
 	mutex_init(&ht->mutex);
 	spin_lock_init(&ht->lock);
@@ -745,6 +741,9 @@ int rhashtable_init(struct rhashtable *h
 
 	ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);
 
+	if (params->nelem_hint)
+		size = rounded_hashtable_size(&ht->p);
+
 	/* The maximum (not average) chain length grows with the
 	 * size of the hash table, at a rate of (log N)/(log log N).
 	 * The value of 16 is selected so that even if the hash
diff -druNp --no-dereference linux-libre-4.3-gnu/Makefile linux-libre-4.3.4-gnu/Makefile
--- linux-libre-4.3-gnu/Makefile	2015-11-01 23:19:53.000000000 -0500
+++ linux-libre-4.3.4-gnu/Makefile	2016-01-23 08:02:54.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 3
-SUBLEVEL = 0
+SUBLEVEL = 4
 EXTRAVERSION = -gnu
 NAME = Blurry Fish Butt
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ax25/af_ax25.c linux-libre-4.3.4-gnu/net/ax25/af_ax25.c
--- linux-libre-4.3-gnu/net/ax25/af_ax25.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ax25/af_ax25.c	2016-01-22 23:59:37.000000000 -0500
@@ -805,6 +805,9 @@ static int ax25_create(struct net *net,
 	struct sock *sk;
 	ax25_cb *ax25;
 
+	if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+		return -EINVAL;
+
 	if (!net_eq(net, &init_net))
 		return -EAFNOSUPPORT;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/bluetooth/hci_conn.c linux-libre-4.3.4-gnu/net/bluetooth/hci_conn.c
--- linux-libre-4.3-gnu/net/bluetooth/hci_conn.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/bluetooth/hci_conn.c	2016-01-22 23:59:37.000000000 -0500
@@ -137,18 +137,51 @@ static void hci_conn_cleanup(struct hci_
 	hci_conn_put(conn);
 }
 
-/* This function requires the caller holds hdev->lock */
+static void le_scan_cleanup(struct work_struct *work)
+{
+	struct hci_conn *conn = container_of(work, struct hci_conn,
+					     le_scan_cleanup);
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_conn *c = NULL;
+
+	BT_DBG("%s hcon %p", hdev->name, conn);
+
+	hci_dev_lock(hdev);
+
+	/* Check that the hci_conn is still around */
+	rcu_read_lock();
+	list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) {
+		if (c == conn)
+			break;
+	}
+	rcu_read_unlock();
+
+	if (c == conn) {
+		hci_connect_le_scan_cleanup(conn);
+		hci_conn_cleanup(conn);
+	}
+
+	hci_dev_unlock(hdev);
+	hci_dev_put(hdev);
+	hci_conn_put(conn);
+}
+
 static void hci_connect_le_scan_remove(struct hci_conn *conn)
 {
-	hci_connect_le_scan_cleanup(conn);
+	BT_DBG("%s hcon %p", conn->hdev->name, conn);
 
-	/* We can't call hci_conn_del here since that would deadlock
-	 * with trying to call cancel_delayed_work_sync(&conn->disc_work).
-	 * Instead, call just hci_conn_cleanup() which contains the bare
-	 * minimum cleanup operations needed for a connection in this
-	 * state.
+	/* We can't call hci_conn_del/hci_conn_cleanup here since that
+	 * could deadlock with another hci_conn_del() call that's holding
+	 * hci_dev_lock and doing cancel_delayed_work_sync(&conn->disc_work).
+	 * Instead, grab temporary extra references to the hci_dev and
+	 * hci_conn and perform the necessary cleanup in a separate work
+	 * callback.
 	 */
-	hci_conn_cleanup(conn);
+
+	hci_dev_hold(conn->hdev);
+	hci_conn_get(conn);
+
+	schedule_work(&conn->le_scan_cleanup);
 }
 
 static void hci_acl_create_connection(struct hci_conn *conn)
@@ -580,6 +613,7 @@ struct hci_conn *hci_conn_add(struct hci
 	INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
 	INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
 	INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
+	INIT_WORK(&conn->le_scan_cleanup, le_scan_cleanup);
 
 	atomic_set(&conn->refcnt, 0);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/bluetooth/hidp/core.c linux-libre-4.3.4-gnu/net/bluetooth/hidp/core.c
--- linux-libre-4.3-gnu/net/bluetooth/hidp/core.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/bluetooth/hidp/core.c	2016-01-22 23:59:37.000000000 -0500
@@ -401,6 +401,20 @@ static void hidp_idle_timeout(unsigned l
 {
 	struct hidp_session *session = (struct hidp_session *) arg;
 
+	/* The HIDP user-space API only contains calls to add and remove
+	 * devices. There is no way to forward events of any kind. Therefore,
+	 * we have to forcefully disconnect a device on idle-timeouts. This is
+	 * unfortunate and weird API design, but it is spec-compliant and
+	 * required for backwards-compatibility. Hence, on idle-timeout, we
+	 * signal driver-detach events, so poll() will be woken up with an
+	 * error-condition on both sockets.
+	 */
+
+	session->intr_sock->sk->sk_err = EUNATCH;
+	session->ctrl_sock->sk->sk_err = EUNATCH;
+	wake_up_interruptible(sk_sleep(session->intr_sock->sk));
+	wake_up_interruptible(sk_sleep(session->ctrl_sock->sk));
+
 	hidp_session_terminate(session);
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/bluetooth/mgmt.c linux-libre-4.3.4-gnu/net/bluetooth/mgmt.c
--- linux-libre-4.3-gnu/net/bluetooth/mgmt.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/bluetooth/mgmt.c	2016-01-22 23:59:37.000000000 -0500
@@ -3090,6 +3090,11 @@ static int unpair_device(struct sock *sk
 	} else {
 		u8 addr_type;
 
+		if (cp->addr.type == BDADDR_LE_PUBLIC)
+			addr_type = ADDR_LE_DEV_PUBLIC;
+		else
+			addr_type = ADDR_LE_DEV_RANDOM;
+
 		conn = hci_conn_hash_lookup_ba(hdev, LE_LINK,
 					       &cp->addr.bdaddr);
 		if (conn) {
@@ -3105,13 +3110,10 @@ static int unpair_device(struct sock *sk
 			 */
 			if (!cp->disconnect)
 				conn = NULL;
+		} else {
+			hci_conn_params_del(hdev, &cp->addr.bdaddr, addr_type);
 		}
 
-		if (cp->addr.type == BDADDR_LE_PUBLIC)
-			addr_type = ADDR_LE_DEV_PUBLIC;
-		else
-			addr_type = ADDR_LE_DEV_RANDOM;
-
 		hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type);
 
 		err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
diff -druNp --no-dereference linux-libre-4.3-gnu/net/bluetooth/sco.c linux-libre-4.3.4-gnu/net/bluetooth/sco.c
--- linux-libre-4.3-gnu/net/bluetooth/sco.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/bluetooth/sco.c	2016-01-22 23:59:37.000000000 -0500
@@ -519,6 +519,9 @@ static int sco_sock_bind(struct socket *
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
 
+	if (addr_len < sizeof(struct sockaddr_sco))
+		return -EINVAL;
+
 	lock_sock(sk);
 
 	if (sk->sk_state != BT_OPEN) {
diff -druNp --no-dereference linux-libre-4.3-gnu/net/core/dst.c linux-libre-4.3.4-gnu/net/core/dst.c
--- linux-libre-4.3-gnu/net/core/dst.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/core/dst.c	2016-01-22 23:59:37.000000000 -0500
@@ -306,7 +306,7 @@ void dst_release(struct dst_entry *dst)
 		if (unlikely(newrefcnt < 0))
 			net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
 					     __func__, dst, newrefcnt);
-		if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt)
+		if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
 			call_rcu(&dst->rcu_head, dst_destroy_rcu);
 	}
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/net/core/neighbour.c linux-libre-4.3.4-gnu/net/core/neighbour.c
--- linux-libre-4.3-gnu/net/core/neighbour.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/core/neighbour.c	2016-01-22 23:59:37.000000000 -0500
@@ -2215,7 +2215,7 @@ static int pneigh_fill_info(struct sk_bu
 	ndm->ndm_pad2    = 0;
 	ndm->ndm_flags	 = pn->flags | NTF_PROXY;
 	ndm->ndm_type	 = RTN_UNICAST;
-	ndm->ndm_ifindex = pn->dev->ifindex;
+	ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0;
 	ndm->ndm_state	 = NUD_NONE;
 
 	if (nla_put(skb, NDA_DST, tbl->key_len, pn->key))
@@ -2290,7 +2290,7 @@ static int pneigh_dump_table(struct neig
 		if (h > s_h)
 			s_idx = 0;
 		for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) {
-			if (dev_net(n->dev) != net)
+			if (pneigh_net(n) != net)
 				continue;
 			if (idx < s_idx)
 				goto next;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/core/scm.c linux-libre-4.3.4-gnu/net/core/scm.c
--- linux-libre-4.3-gnu/net/core/scm.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/core/scm.c	2016-01-22 23:59:37.000000000 -0500
@@ -305,6 +305,8 @@ void scm_detach_fds(struct msghdr *msg,
 			err = put_user(cmlen, &cm->cmsg_len);
 		if (!err) {
 			cmlen = CMSG_SPACE(i*sizeof(int));
+			if (msg->msg_controllen < cmlen)
+				cmlen = msg->msg_controllen;
 			msg->msg_control += cmlen;
 			msg->msg_controllen -= cmlen;
 		}
diff -druNp --no-dereference linux-libre-4.3-gnu/net/core/skbuff.c linux-libre-4.3.4-gnu/net/core/skbuff.c
--- linux-libre-4.3-gnu/net/core/skbuff.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/core/skbuff.c	2016-01-22 23:59:37.000000000 -0500
@@ -3643,7 +3643,8 @@ static void __skb_complete_tx_timestamp(
 	serr->ee.ee_info = tstype;
 	if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
 		serr->ee.ee_data = skb_shinfo(skb)->tskey;
-		if (sk->sk_protocol == IPPROTO_TCP)
+		if (sk->sk_protocol == IPPROTO_TCP &&
+		    sk->sk_type == SOCK_STREAM)
 			serr->ee.ee_data -= sk->sk_tskey;
 	}
 
@@ -4268,7 +4269,8 @@ static struct sk_buff *skb_reorder_vlan_
 		return NULL;
 	}
 
-	memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
+	memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN,
+		2 * ETH_ALEN);
 	skb->mac_header += VLAN_HLEN;
 	return skb;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/net/core/sock.c linux-libre-4.3.4-gnu/net/core/sock.c
--- linux-libre-4.3-gnu/net/core/sock.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/core/sock.c	2016-01-22 23:59:37.000000000 -0500
@@ -422,8 +422,6 @@ static void sock_warn_obsolete_bsdism(co
 	}
 }
 
-#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
-
 static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
 {
 	if (sk->sk_flags & flags) {
@@ -862,7 +860,8 @@ set_rcvbuf:
 
 		if (val & SOF_TIMESTAMPING_OPT_ID &&
 		    !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
-			if (sk->sk_protocol == IPPROTO_TCP) {
+			if (sk->sk_protocol == IPPROTO_TCP &&
+			    sk->sk_type == SOCK_STREAM) {
 				if (sk->sk_state != TCP_ESTABLISHED) {
 					ret = -EINVAL;
 					break;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/dccp/ipv6.c linux-libre-4.3.4-gnu/net/dccp/ipv6.c
--- linux-libre-4.3-gnu/net/dccp/ipv6.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/dccp/ipv6.c	2016-01-22 23:59:37.000000000 -0500
@@ -202,7 +202,9 @@ static int dccp_v6_send_response(struct
 	security_req_classify_flow(req, flowi6_to_flowi(&fl6));
 
 
-	final_p = fl6_update_dst(&fl6, np->opt, &final);
+	rcu_read_lock();
+	final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+	rcu_read_unlock();
 
 	dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
 	if (IS_ERR(dst)) {
@@ -219,7 +221,10 @@ static int dccp_v6_send_response(struct
 							 &ireq->ir_v6_loc_addr,
 							 &ireq->ir_v6_rmt_addr);
 		fl6.daddr = ireq->ir_v6_rmt_addr;
-		err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+		rcu_read_lock();
+		err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+			       np->tclass);
+		rcu_read_unlock();
 		err = net_xmit_eval(err);
 	}
 
@@ -415,6 +420,7 @@ static struct sock *dccp_v6_request_recv
 {
 	struct inet_request_sock *ireq = inet_rsk(req);
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+	struct ipv6_txoptions *opt;
 	struct inet_sock *newinet;
 	struct dccp6_sock *newdp6;
 	struct sock *newsk;
@@ -534,13 +540,15 @@ static struct sock *dccp_v6_request_recv
 	 * Yes, keeping reference count would be much more clever, but we make
 	 * one more one thing there: reattach optmem to newsk.
 	 */
-	if (np->opt != NULL)
-		newnp->opt = ipv6_dup_options(newsk, np->opt);
-
+	opt = rcu_dereference(np->opt);
+	if (opt) {
+		opt = ipv6_dup_options(newsk, opt);
+		RCU_INIT_POINTER(newnp->opt, opt);
+	}
 	inet_csk(newsk)->icsk_ext_hdr_len = 0;
-	if (newnp->opt != NULL)
-		inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
-						     newnp->opt->opt_flen);
+	if (opt)
+		inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+						    opt->opt_flen;
 
 	dccp_sync_mss(newsk, dst_mtu(dst));
 
@@ -793,6 +801,7 @@ static int dccp_v6_connect(struct sock *
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct in6_addr *saddr = NULL, *final_p, final;
+	struct ipv6_txoptions *opt;
 	struct flowi6 fl6;
 	struct dst_entry *dst;
 	int addr_type;
@@ -892,7 +901,8 @@ static int dccp_v6_connect(struct sock *
 	fl6.fl6_sport = inet->inet_sport;
 	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-	final_p = fl6_update_dst(&fl6, np->opt, &final);
+	opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+	final_p = fl6_update_dst(&fl6, opt, &final);
 
 	dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
 	if (IS_ERR(dst)) {
@@ -912,9 +922,8 @@ static int dccp_v6_connect(struct sock *
 	__ip6_dst_store(sk, dst, NULL, NULL);
 
 	icsk->icsk_ext_hdr_len = 0;
-	if (np->opt != NULL)
-		icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
-					  np->opt->opt_nflen);
+	if (opt)
+		icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
 
 	inet->inet_dport = usin->sin6_port;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/decnet/af_decnet.c linux-libre-4.3.4-gnu/net/decnet/af_decnet.c
--- linux-libre-4.3-gnu/net/decnet/af_decnet.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/decnet/af_decnet.c	2016-01-22 23:59:37.000000000 -0500
@@ -678,6 +678,9 @@ static int dn_create(struct net *net, st
 {
 	struct sock *sk;
 
+	if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+		return -EINVAL;
+
 	if (!net_eq(net, &init_net))
 		return -EAFNOSUPPORT;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/af_inet.c linux-libre-4.3.4-gnu/net/ipv4/af_inet.c
--- linux-libre-4.3-gnu/net/ipv4/af_inet.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/af_inet.c	2016-01-22 23:59:37.000000000 -0500
@@ -261,6 +261,9 @@ static int inet_create(struct net *net,
 	int try_loading_module = 0;
 	int err;
 
+	if (protocol < 0 || protocol >= IPPROTO_MAX)
+		return -EINVAL;
+
 	sock->state = SS_UNCONNECTED;
 
 	/* Look for the requested type/protocol pair. */
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/fib_frontend.c linux-libre-4.3.4-gnu/net/ipv4/fib_frontend.c
--- linux-libre-4.3-gnu/net/ipv4/fib_frontend.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/fib_frontend.c	2016-01-22 23:59:37.000000000 -0500
@@ -1110,9 +1110,10 @@ static void nl_fib_lookup_exit(struct ne
 	net->ipv4.fibnl = NULL;
 }
 
-static void fib_disable_ip(struct net_device *dev, unsigned long event)
+static void fib_disable_ip(struct net_device *dev, unsigned long event,
+			   bool force)
 {
-	if (fib_sync_down_dev(dev, event))
+	if (fib_sync_down_dev(dev, event, force))
 		fib_flush(dev_net(dev));
 	rt_cache_flush(dev_net(dev));
 	arp_ifdown(dev);
@@ -1140,7 +1141,7 @@ static int fib_inetaddr_event(struct not
 			/* Last address was deleted from this interface.
 			 * Disable IP.
 			 */
-			fib_disable_ip(dev, event);
+			fib_disable_ip(dev, event, true);
 		} else {
 			rt_cache_flush(dev_net(dev));
 		}
@@ -1157,7 +1158,7 @@ static int fib_netdev_event(struct notif
 	unsigned int flags;
 
 	if (event == NETDEV_UNREGISTER) {
-		fib_disable_ip(dev, event);
+		fib_disable_ip(dev, event, true);
 		rt_flush_dev(dev);
 		return NOTIFY_DONE;
 	}
@@ -1178,14 +1179,14 @@ static int fib_netdev_event(struct notif
 		rt_cache_flush(net);
 		break;
 	case NETDEV_DOWN:
-		fib_disable_ip(dev, event);
+		fib_disable_ip(dev, event, false);
 		break;
 	case NETDEV_CHANGE:
 		flags = dev_get_flags(dev);
 		if (flags & (IFF_RUNNING | IFF_LOWER_UP))
 			fib_sync_up(dev, RTNH_F_LINKDOWN);
 		else
-			fib_sync_down_dev(dev, event);
+			fib_sync_down_dev(dev, event, false);
 		/* fall through */
 	case NETDEV_CHANGEMTU:
 		rt_cache_flush(net);
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/fib_semantics.c linux-libre-4.3.4-gnu/net/ipv4/fib_semantics.c
--- linux-libre-4.3-gnu/net/ipv4/fib_semantics.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/fib_semantics.c	2016-01-22 23:59:37.000000000 -0500
@@ -864,14 +864,21 @@ static bool fib_valid_prefsrc(struct fib
 	if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
 	    fib_prefsrc != cfg->fc_dst) {
 		u32 tb_id = cfg->fc_table;
+		int rc;
 
 		if (tb_id == RT_TABLE_MAIN)
 			tb_id = RT_TABLE_LOCAL;
 
-		if (inet_addr_type_table(cfg->fc_nlinfo.nl_net,
-					 fib_prefsrc, tb_id) != RTN_LOCAL) {
-			return false;
+		rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net,
+					  fib_prefsrc, tb_id);
+
+		if (rc != RTN_LOCAL && tb_id != RT_TABLE_LOCAL) {
+			rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net,
+						  fib_prefsrc, RT_TABLE_LOCAL);
 		}
+
+		if (rc != RTN_LOCAL)
+			return false;
 	}
 	return true;
 }
@@ -1281,7 +1288,13 @@ int fib_sync_down_addr(struct net *net,
 	return ret;
 }
 
-int fib_sync_down_dev(struct net_device *dev, unsigned long event)
+/* Event              force Flags           Description
+ * NETDEV_CHANGE      0     LINKDOWN        Carrier OFF, not for scope host
+ * NETDEV_DOWN        0     LINKDOWN|DEAD   Link down, not for scope host
+ * NETDEV_DOWN        1     LINKDOWN|DEAD   Last address removed
+ * NETDEV_UNREGISTER  1     LINKDOWN|DEAD   Device removed
+ */
+int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
 {
 	int ret = 0;
 	int scope = RT_SCOPE_NOWHERE;
@@ -1290,8 +1303,7 @@ int fib_sync_down_dev(struct net_device
 	struct hlist_head *head = &fib_info_devhash[hash];
 	struct fib_nh *nh;
 
-	if (event == NETDEV_UNREGISTER ||
-	    event == NETDEV_DOWN)
+	if (force)
 		scope = -1;
 
 	hlist_for_each_entry(nh, head, nh_hash) {
@@ -1440,6 +1452,13 @@ int fib_sync_up(struct net_device *dev,
 	if (!(dev->flags & IFF_UP))
 		return 0;
 
+	if (nh_flags & RTNH_F_DEAD) {
+		unsigned int flags = dev_get_flags(dev);
+
+		if (flags & (IFF_RUNNING | IFF_LOWER_UP))
+			nh_flags |= RTNH_F_LINKDOWN;
+	}
+
 	prev_fi = NULL;
 	hash = fib_devindex_hashfn(dev->ifindex);
 	head = &fib_info_devhash[hash];
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/fou.c linux-libre-4.3.4-gnu/net/ipv4/fou.c
--- linux-libre-4.3-gnu/net/ipv4/fou.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/fou.c	2016-01-22 23:59:37.000000000 -0500
@@ -24,6 +24,7 @@ struct fou {
 	u16 type;
 	struct udp_offload udp_offloads;
 	struct list_head list;
+	struct rcu_head rcu;
 };
 
 #define FOU_F_REMCSUM_NOPARTIAL BIT(0)
@@ -417,7 +418,7 @@ static void fou_release(struct fou *fou)
 	list_del(&fou->list);
 	udp_tunnel_sock_release(sock);
 
-	kfree(fou);
+	kfree_rcu(fou, rcu);
 }
 
 static int fou_encap_init(struct sock *sk, struct fou *fou, struct fou_cfg *cfg)
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/ipmr.c linux-libre-4.3.4-gnu/net/ipv4/ipmr.c
--- linux-libre-4.3-gnu/net/ipv4/ipmr.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/ipmr.c	2016-01-22 23:59:37.000000000 -0500
@@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_
 			      struct mfc_cache *c, struct rtmsg *rtm);
 static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
 				 int cmd);
-static void mroute_clean_tables(struct mr_table *mrt);
+static void mroute_clean_tables(struct mr_table *mrt, bool all);
 static void ipmr_expire_process(unsigned long arg);
 
 #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
@@ -350,7 +350,7 @@ static struct mr_table *ipmr_new_table(s
 static void ipmr_free_table(struct mr_table *mrt)
 {
 	del_timer_sync(&mrt->ipmr_expire_timer);
-	mroute_clean_tables(mrt);
+	mroute_clean_tables(mrt, true);
 	kfree(mrt);
 }
 
@@ -1208,7 +1208,7 @@ static int ipmr_mfc_add(struct net *net,
  *	Close the multicast socket, and clear the vif tables etc
  */
 
-static void mroute_clean_tables(struct mr_table *mrt)
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
 {
 	int i;
 	LIST_HEAD(list);
@@ -1217,8 +1217,9 @@ static void mroute_clean_tables(struct m
 	/* Shut down all active vif entries */
 
 	for (i = 0; i < mrt->maxvif; i++) {
-		if (!(mrt->vif_table[i].flags & VIFF_STATIC))
-			vif_delete(mrt, i, 0, &list);
+		if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
+			continue;
+		vif_delete(mrt, i, 0, &list);
 	}
 	unregister_netdevice_many(&list);
 
@@ -1226,7 +1227,7 @@ static void mroute_clean_tables(struct m
 
 	for (i = 0; i < MFC_LINES; i++) {
 		list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
-			if (c->mfc_flags & MFC_STATIC)
+			if (!all && (c->mfc_flags & MFC_STATIC))
 				continue;
 			list_del_rcu(&c->list);
 			mroute_netlink_event(mrt, c, RTM_DELROUTE);
@@ -1261,7 +1262,7 @@ static void mrtsock_destruct(struct sock
 						    NETCONFA_IFINDEX_ALL,
 						    net->ipv4.devconf_all);
 			RCU_INIT_POINTER(mrt->mroute_sk, NULL);
-			mroute_clean_tables(mrt);
+			mroute_clean_tables(mrt, false);
 		}
 	}
 	rtnl_unlock();
@@ -1682,8 +1683,8 @@ static inline int ipmr_forward_finish(st
 {
 	struct ip_options *opt = &(IPCB(skb)->opt);
 
-	IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
-	IP_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, skb->len);
+	IP_INC_STATS(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
+	IP_ADD_STATS(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, skb->len);
 
 	if (unlikely(opt->optlen))
 		ip_forward_options(skb);
@@ -1745,7 +1746,7 @@ static void ipmr_queue_xmit(struct net *
 		 * to blackhole.
 		 */
 
-		IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
+		IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
 		ip_rt_put(rt);
 		goto out_free;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/sysctl_net_ipv4.c linux-libre-4.3.4-gnu/net/ipv4/sysctl_net_ipv4.c
--- linux-libre-4.3-gnu/net/ipv4/sysctl_net_ipv4.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/sysctl_net_ipv4.c	2016-01-22 23:59:37.000000000 -0500
@@ -48,14 +48,14 @@ static void set_local_port_range(struct
 {
 	bool same_parity = !((range[0] ^ range[1]) & 1);
 
-	write_seqlock(&net->ipv4.ip_local_ports.lock);
+	write_seqlock_bh(&net->ipv4.ip_local_ports.lock);
 	if (same_parity && !net->ipv4.ip_local_ports.warned) {
 		net->ipv4.ip_local_ports.warned = true;
 		pr_err_ratelimited("ip_local_port_range: prefer different parity for start/end values.\n");
 	}
 	net->ipv4.ip_local_ports.range[0] = range[0];
 	net->ipv4.ip_local_ports.range[1] = range[1];
-	write_sequnlock(&net->ipv4.ip_local_ports.lock);
+	write_sequnlock_bh(&net->ipv4.ip_local_ports.lock);
 }
 
 /* Validate changes from /proc interface. */
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/tcp_input.c linux-libre-4.3.4-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.3-gnu/net/ipv4/tcp_input.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/tcp_input.c	2016-01-22 23:59:37.000000000 -0500
@@ -4457,19 +4457,34 @@ static int __must_check tcp_queue_rcv(st
 int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
 {
 	struct sk_buff *skb;
+	int err = -ENOMEM;
+	int data_len = 0;
 	bool fragstolen;
 
 	if (size == 0)
 		return 0;
 
-	skb = alloc_skb(size, sk->sk_allocation);
+	if (size > PAGE_SIZE) {
+		int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS);
+
+		data_len = npages << PAGE_SHIFT;
+		size = data_len + (size & ~PAGE_MASK);
+	}
+	skb = alloc_skb_with_frags(size - data_len, data_len,
+				   PAGE_ALLOC_COSTLY_ORDER,
+				   &err, sk->sk_allocation);
 	if (!skb)
 		goto err;
 
+	skb_put(skb, size - data_len);
+	skb->data_len = data_len;
+	skb->len = size;
+
 	if (tcp_try_rmem_schedule(sk, skb, skb->truesize))
 		goto err_free;
 
-	if (memcpy_from_msg(skb_put(skb, size), msg, size))
+	err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
+	if (err)
 		goto err_free;
 
 	TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
@@ -4485,7 +4500,8 @@ int tcp_send_rcvq(struct sock *sk, struc
 err_free:
 	kfree_skb(skb);
 err:
-	return -ENOMEM;
+	return err;
+
 }
 
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
@@ -5643,6 +5659,7 @@ discard:
 		}
 
 		tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
+		tp->copied_seq = tp->rcv_nxt;
 		tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1;
 
 		/* RFC1323: The window in SYN & SYN/ACK segments is
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/tcp_ipv4.c linux-libre-4.3.4-gnu/net/ipv4/tcp_ipv4.c
--- linux-libre-4.3-gnu/net/ipv4/tcp_ipv4.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/tcp_ipv4.c	2016-01-22 23:59:37.000000000 -0500
@@ -922,7 +922,8 @@ int tcp_md5_do_add(struct sock *sk, cons
 	}
 
 	md5sig = rcu_dereference_protected(tp->md5sig_info,
-					   sock_owned_by_user(sk));
+					   sock_owned_by_user(sk) ||
+					   lockdep_is_held(&sk->sk_lock.slock));
 	if (!md5sig) {
 		md5sig = kmalloc(sizeof(*md5sig), gfp);
 		if (!md5sig)
@@ -1508,7 +1509,7 @@ bool tcp_prequeue(struct sock *sk, struc
 	if (likely(sk->sk_rx_dst))
 		skb_dst_drop(skb);
 	else
-		skb_dst_force(skb);
+		skb_dst_force_safe(skb);
 
 	__skb_queue_tail(&tp->ucopy.prequeue, skb);
 	tp->ucopy.memory += skb->truesize;
@@ -1709,8 +1710,7 @@ void inet_sk_rx_dst_set(struct sock *sk,
 {
 	struct dst_entry *dst = skb_dst(skb);
 
-	if (dst) {
-		dst_hold(dst);
+	if (dst && dst_hold_safe(dst)) {
 		sk->sk_rx_dst = dst;
 		inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/tcp_output.c linux-libre-4.3.4-gnu/net/ipv4/tcp_output.c
--- linux-libre-4.3-gnu/net/ipv4/tcp_output.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/tcp_output.c	2016-01-22 23:59:37.000000000 -0500
@@ -3147,7 +3147,7 @@ static int tcp_send_syn_data(struct sock
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_fastopen_request *fo = tp->fastopen_req;
-	int syn_loss = 0, space, err = 0, copied;
+	int syn_loss = 0, space, err = 0;
 	unsigned long last_syn_loss = 0;
 	struct sk_buff *syn_data;
 
@@ -3185,17 +3185,18 @@ static int tcp_send_syn_data(struct sock
 		goto fallback;
 	syn_data->ip_summed = CHECKSUM_PARTIAL;
 	memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
-	copied = copy_from_iter(skb_put(syn_data, space), space,
-				&fo->data->msg_iter);
-	if (unlikely(!copied)) {
-		kfree_skb(syn_data);
-		goto fallback;
-	}
-	if (copied != space) {
-		skb_trim(syn_data, copied);
-		space = copied;
+	if (space) {
+		int copied = copy_from_iter(skb_put(syn_data, space), space,
+					    &fo->data->msg_iter);
+		if (unlikely(!copied)) {
+			kfree_skb(syn_data);
+			goto fallback;
+		}
+		if (copied != space) {
+			skb_trim(syn_data, copied);
+			space = copied;
+		}
 	}
-
 	/* No more data pending in inet_wait_for_connect() */
 	if (space == fo->size)
 		fo->data = NULL;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv4/tcp_timer.c linux-libre-4.3.4-gnu/net/ipv4/tcp_timer.c
--- linux-libre-4.3-gnu/net/ipv4/tcp_timer.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv4/tcp_timer.c	2016-01-22 23:59:37.000000000 -0500
@@ -176,6 +176,18 @@ static int tcp_write_timeout(struct sock
 		syn_set = true;
 	} else {
 		if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) {
+			/* Some middle-boxes may black-hole Fast Open _after_
+			 * the handshake. Therefore we conservatively disable
+			 * Fast Open on this path on recurring timeouts with
+			 * few or zero bytes acked after Fast Open.
+			 */
+			if (tp->syn_data_acked &&
+			    tp->bytes_acked <= tp->rx_opt.mss_clamp) {
+				tcp_fastopen_cache_set(sk, 0, NULL, true, 0);
+				if (icsk->icsk_retransmits == sysctl_tcp_retries1)
+					NET_INC_STATS_BH(sock_net(sk),
+							 LINUX_MIB_TCPFASTOPENACTIVEFAIL);
+			}
 			/* Black hole detection */
 			tcp_mtu_probing(icsk, sk);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/addrconf.c linux-libre-4.3.4-gnu/net/ipv6/addrconf.c
--- linux-libre-4.3-gnu/net/ipv6/addrconf.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/addrconf.c	2016-01-22 23:59:37.000000000 -0500
@@ -349,6 +349,12 @@ static struct inet6_dev *ipv6_add_dev(st
 	setup_timer(&ndev->rs_timer, addrconf_rs_timer,
 		    (unsigned long)ndev);
 	memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
+
+	if (ndev->cnf.stable_secret.initialized)
+		ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
+	else
+		ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64;
+
 	ndev->cnf.mtu6 = dev->mtu;
 	ndev->cnf.sysctl = NULL;
 	ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
@@ -417,6 +423,7 @@ static struct inet6_dev *ipv6_add_dev(st
 	if (err) {
 		ipv6_mc_destroy_dev(ndev);
 		del_timer(&ndev->regen_timer);
+		snmp6_unregister_dev(ndev);
 		goto err_release;
 	}
 	/* protected by rtnl_lock */
@@ -2452,7 +2459,7 @@ ok:
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
 			if (in6_dev->cnf.optimistic_dad &&
 			    !net->ipv6.devconf_all->forwarding && sllao)
-				addr_flags = IFA_F_OPTIMISTIC;
+				addr_flags |= IFA_F_OPTIMISTIC;
 #endif
 
 			/* Do not allow to create too much of autoconfigured
@@ -3627,7 +3634,7 @@ static void addrconf_dad_work(struct wor
 
 	/* send a neighbour solicitation for our addr */
 	addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
-	ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any, NULL);
+	ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
 out:
 	in6_ifa_put(ifp);
 	rtnl_unlock();
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/af_inet6.c linux-libre-4.3.4-gnu/net/ipv6/af_inet6.c
--- linux-libre-4.3-gnu/net/ipv6/af_inet6.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/af_inet6.c	2016-01-22 23:59:37.000000000 -0500
@@ -109,6 +109,9 @@ static int inet6_create(struct net *net,
 	int try_loading_module = 0;
 	int err;
 
+	if (protocol < 0 || protocol >= IPPROTO_MAX)
+		return -EINVAL;
+
 	/* Look for the requested type/protocol pair. */
 lookup_protocol:
 	err = -ESOCKTNOSUPPORT;
@@ -428,9 +431,11 @@ void inet6_destroy_sock(struct sock *sk)
 
 	/* Free tx options */
 
-	opt = xchg(&np->opt, NULL);
-	if (opt)
-		sock_kfree_s(sk, opt, opt->tot_len);
+	opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL);
+	if (opt) {
+		atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+		txopt_put(opt);
+	}
 }
 EXPORT_SYMBOL_GPL(inet6_destroy_sock);
 
@@ -659,7 +664,10 @@ int inet6_sk_rebuild_header(struct sock
 		fl6.fl6_sport = inet->inet_sport;
 		security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-		final_p = fl6_update_dst(&fl6, np->opt, &final);
+		rcu_read_lock();
+		final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt),
+					 &final);
+		rcu_read_unlock();
 
 		dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
 		if (IS_ERR(dst)) {
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/datagram.c linux-libre-4.3.4-gnu/net/ipv6/datagram.c
--- linux-libre-4.3-gnu/net/ipv6/datagram.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/datagram.c	2016-01-22 23:59:37.000000000 -0500
@@ -167,8 +167,10 @@ ipv4_connected:
 
 	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-	opt = flowlabel ? flowlabel->opt : np->opt;
+	rcu_read_lock();
+	opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
 	final_p = fl6_update_dst(&fl6, opt, &final);
+	rcu_read_unlock();
 
 	dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
 	err = 0;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/exthdrs.c linux-libre-4.3.4-gnu/net/ipv6/exthdrs.c
--- linux-libre-4.3-gnu/net/ipv6/exthdrs.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/exthdrs.c	2016-01-22 23:59:37.000000000 -0500
@@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct
 			*((char **)&opt2->dst1opt) += dif;
 		if (opt2->srcrt)
 			*((char **)&opt2->srcrt) += dif;
+		atomic_set(&opt2->refcnt, 1);
 	}
 	return opt2;
 }
@@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, stru
 		return ERR_PTR(-ENOBUFS);
 
 	memset(opt2, 0, tot_len);
-
+	atomic_set(&opt2->refcnt, 1);
 	opt2->tot_len = tot_len;
 	p = (char *)(opt2 + 1);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/inet6_connection_sock.c linux-libre-4.3.4-gnu/net/ipv6/inet6_connection_sock.c
--- linux-libre-4.3-gnu/net/ipv6/inet6_connection_sock.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/inet6_connection_sock.c	2016-01-22 23:59:37.000000000 -0500
@@ -77,7 +77,9 @@ struct dst_entry *inet6_csk_route_req(st
 	memset(fl6, 0, sizeof(*fl6));
 	fl6->flowi6_proto = IPPROTO_TCP;
 	fl6->daddr = ireq->ir_v6_rmt_addr;
-	final_p = fl6_update_dst(fl6, np->opt, &final);
+	rcu_read_lock();
+	final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
+	rcu_read_unlock();
 	fl6->saddr = ireq->ir_v6_loc_addr;
 	fl6->flowi6_oif = ireq->ir_iif;
 	fl6->flowi6_mark = ireq->ir_mark;
@@ -207,7 +209,9 @@ static struct dst_entry *inet6_csk_route
 	fl6->fl6_dport = inet->inet_dport;
 	security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
 
-	final_p = fl6_update_dst(fl6, np->opt, &final);
+	rcu_read_lock();
+	final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
+	rcu_read_unlock();
 
 	dst = __inet6_csk_dst_check(sk, np->dst_cookie);
 	if (!dst) {
@@ -240,7 +244,8 @@ int inet6_csk_xmit(struct sock *sk, stru
 	/* Restore final destination back after routing done */
 	fl6.daddr = sk->sk_v6_daddr;
 
-	res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+	res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+		       np->tclass);
 	rcu_read_unlock();
 	return res;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/ip6_gre.c linux-libre-4.3.4-gnu/net/ipv6/ip6_gre.c
--- linux-libre-4.3-gnu/net/ipv6/ip6_gre.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/ip6_gre.c	2016-01-22 23:59:37.000000000 -0500
@@ -1571,13 +1571,11 @@ static int ip6gre_changelink(struct net_
 			return -EEXIST;
 	} else {
 		t = nt;
-
-		ip6gre_tunnel_unlink(ign, t);
-		ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
-		ip6gre_tunnel_link(ign, t);
-		netdev_state_change(dev);
 	}
 
+	ip6gre_tunnel_unlink(ign, t);
+	ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
+	ip6gre_tunnel_link(ign, t);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/ip6mr.c linux-libre-4.3.4-gnu/net/ipv6/ip6mr.c
--- linux-libre-4.3-gnu/net/ipv6/ip6mr.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/ip6mr.c	2016-01-22 23:59:37.000000000 -0500
@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6
 			      int cmd);
 static int ip6mr_rtm_dumproute(struct sk_buff *skb,
 			       struct netlink_callback *cb);
-static void mroute_clean_tables(struct mr6_table *mrt);
+static void mroute_clean_tables(struct mr6_table *mrt, bool all);
 static void ipmr_expire_process(unsigned long arg);
 
 #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table
 static void ip6mr_free_table(struct mr6_table *mrt)
 {
 	del_timer_sync(&mrt->ipmr_expire_timer);
-	mroute_clean_tables(mrt);
+	mroute_clean_tables(mrt, true);
 	kfree(mrt);
 }
 
@@ -1542,7 +1542,7 @@ static int ip6mr_mfc_add(struct net *net
  *	Close the multicast socket, and clear the vif tables etc
  */
 
-static void mroute_clean_tables(struct mr6_table *mrt)
+static void mroute_clean_tables(struct mr6_table *mrt, bool all)
 {
 	int i;
 	LIST_HEAD(list);
@@ -1552,8 +1552,9 @@ static void mroute_clean_tables(struct m
 	 *	Shut down all active vif entries
 	 */
 	for (i = 0; i < mrt->maxvif; i++) {
-		if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
-			mif6_delete(mrt, i, &list);
+		if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
+			continue;
+		mif6_delete(mrt, i, &list);
 	}
 	unregister_netdevice_many(&list);
 
@@ -1562,7 +1563,7 @@ static void mroute_clean_tables(struct m
 	 */
 	for (i = 0; i < MFC6_LINES; i++) {
 		list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
-			if (c->mfc_flags & MFC_STATIC)
+			if (!all && (c->mfc_flags & MFC_STATIC))
 				continue;
 			write_lock_bh(&mrt_lock);
 			list_del(&c->list);
@@ -1625,7 +1626,7 @@ int ip6mr_sk_done(struct sock *sk)
 						     net->ipv6.devconf_all);
 			write_unlock_bh(&mrt_lock);
 
-			mroute_clean_tables(mrt);
+			mroute_clean_tables(mrt, false);
 			err = 0;
 			break;
 		}
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/ip6_tunnel.c linux-libre-4.3.4-gnu/net/ipv6/ip6_tunnel.c
--- linux-libre-4.3-gnu/net/ipv6/ip6_tunnel.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/ip6_tunnel.c	2016-01-22 23:59:37.000000000 -0500
@@ -177,7 +177,7 @@ void ip6_tnl_dst_reset(struct ip6_tnl *t
 	int i;
 
 	for_each_possible_cpu(i)
-		ip6_tnl_per_cpu_dst_set(raw_cpu_ptr(t->dst_cache), NULL);
+		ip6_tnl_per_cpu_dst_set(per_cpu_ptr(t->dst_cache, i), NULL);
 }
 EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/ipv6_sockglue.c linux-libre-4.3.4-gnu/net/ipv6/ipv6_sockglue.c
--- linux-libre-4.3-gnu/net/ipv6/ipv6_sockglue.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/ipv6_sockglue.c	2016-01-22 23:59:37.000000000 -0500
@@ -111,7 +111,8 @@ struct ipv6_txoptions *ipv6_update_optio
 			icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 		}
 	}
-	opt = xchg(&inet6_sk(sk)->opt, opt);
+	opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+		   opt);
 	sk_dst_reset(sk);
 
 	return opt;
@@ -231,9 +232,12 @@ static int do_ipv6_setsockopt(struct soc
 				sk->sk_socket->ops = &inet_dgram_ops;
 				sk->sk_family = PF_INET;
 			}
-			opt = xchg(&np->opt, NULL);
-			if (opt)
-				sock_kfree_s(sk, opt, opt->tot_len);
+			opt = xchg((__force struct ipv6_txoptions **)&np->opt,
+				   NULL);
+			if (opt) {
+				atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+				txopt_put(opt);
+			}
 			pktopt = xchg(&np->pktoptions, NULL);
 			kfree_skb(pktopt);
 
@@ -403,7 +407,8 @@ static int do_ipv6_setsockopt(struct soc
 		if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
 			break;
 
-		opt = ipv6_renew_options(sk, np->opt, optname,
+		opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+		opt = ipv6_renew_options(sk, opt, optname,
 					 (struct ipv6_opt_hdr __user *)optval,
 					 optlen);
 		if (IS_ERR(opt)) {
@@ -432,8 +437,10 @@ static int do_ipv6_setsockopt(struct soc
 		retv = 0;
 		opt = ipv6_update_options(sk, opt);
 sticky_done:
-		if (opt)
-			sock_kfree_s(sk, opt, opt->tot_len);
+		if (opt) {
+			atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+			txopt_put(opt);
+		}
 		break;
 	}
 
@@ -486,6 +493,7 @@ sticky_done:
 			break;
 
 		memset(opt, 0, sizeof(*opt));
+		atomic_set(&opt->refcnt, 1);
 		opt->tot_len = sizeof(*opt) + optlen;
 		retv = -EFAULT;
 		if (copy_from_user(opt+1, optval, optlen))
@@ -502,8 +510,10 @@ update:
 		retv = 0;
 		opt = ipv6_update_options(sk, opt);
 done:
-		if (opt)
-			sock_kfree_s(sk, opt, opt->tot_len);
+		if (opt) {
+			atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+			txopt_put(opt);
+		}
 		break;
 	}
 	case IPV6_UNICAST_HOPS:
@@ -1110,10 +1120,11 @@ static int do_ipv6_getsockopt(struct soc
 	case IPV6_RTHDR:
 	case IPV6_DSTOPTS:
 	{
+		struct ipv6_txoptions *opt;
 
 		lock_sock(sk);
-		len = ipv6_getsockopt_sticky(sk, np->opt,
-					     optname, optval, len);
+		opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+		len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
 		release_sock(sk);
 		/* check if ipv6_getsockopt_sticky() returns err code */
 		if (len < 0)
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/mcast.c linux-libre-4.3.4-gnu/net/ipv6/mcast.c
--- linux-libre-4.3-gnu/net/ipv6/mcast.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/mcast.c	2016-01-22 23:59:37.000000000 -0500
@@ -1651,7 +1651,6 @@ out:
 	if (!err) {
 		ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
 		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
-		IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
 	} else {
 		IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
 	}
@@ -2014,7 +2013,6 @@ out:
 	if (!err) {
 		ICMP6MSGOUT_INC_STATS(net, idev, type);
 		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
-		IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
 	} else
 		IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/ndisc.c linux-libre-4.3.4-gnu/net/ipv6/ndisc.c
--- linux-libre-4.3-gnu/net/ipv6/ndisc.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/ndisc.c	2016-01-22 23:59:37.000000000 -0500
@@ -553,8 +553,7 @@ static void ndisc_send_unsol_na(struct n
 
 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 		   const struct in6_addr *solicit,
-		   const struct in6_addr *daddr, const struct in6_addr *saddr,
-		   struct sk_buff *oskb)
+		   const struct in6_addr *daddr, const struct in6_addr *saddr)
 {
 	struct sk_buff *skb;
 	struct in6_addr addr_buf;
@@ -590,9 +589,6 @@ void ndisc_send_ns(struct net_device *de
 		ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
 				       dev->dev_addr);
 
-	if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE) && oskb)
-		skb_dst_copy(skb, oskb);
-
 	ndisc_send_skb(skb, daddr, saddr);
 }
 
@@ -679,12 +675,12 @@ static void ndisc_solicit(struct neighbo
 				  "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
 				  __func__, target);
 		}
-		ndisc_send_ns(dev, neigh, target, target, saddr, skb);
+		ndisc_send_ns(dev, neigh, target, target, saddr);
 	} else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) {
 		neigh_app_ns(neigh);
 	} else {
 		addrconf_addr_solict_mult(target, &mcaddr);
-		ndisc_send_ns(dev, NULL, target, &mcaddr, saddr, skb);
+		ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c linux-libre-4.3.4-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c
--- linux-libre-4.3-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c	2016-01-22 23:59:37.000000000 -0500
@@ -190,7 +190,7 @@ static void nf_ct_frag6_expire(unsigned
 /* Creation primitives. */
 static inline struct frag_queue *fq_find(struct net *net, __be32 id,
 					 u32 user, struct in6_addr *src,
-					 struct in6_addr *dst, u8 ecn)
+					 struct in6_addr *dst, int iif, u8 ecn)
 {
 	struct inet_frag_queue *q;
 	struct ip6_create_arg arg;
@@ -200,6 +200,7 @@ static inline struct frag_queue *fq_find
 	arg.user = user;
 	arg.src = src;
 	arg.dst = dst;
+	arg.iif = iif;
 	arg.ecn = ecn;
 
 	local_bh_disable();
@@ -603,7 +604,7 @@ struct sk_buff *nf_ct_frag6_gather(struc
 	fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
 	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
-		     ip6_frag_ecn(hdr));
+		     skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
 	if (fq == NULL) {
 		pr_debug("Can't find and can't create new queue\n");
 		goto ret_orig;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/raw.c linux-libre-4.3.4-gnu/net/ipv6/raw.c
--- linux-libre-4.3-gnu/net/ipv6/raw.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/raw.c	2016-01-22 23:59:37.000000000 -0500
@@ -732,6 +732,7 @@ static int raw6_getfrag(void *from, char
 
 static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
+	struct ipv6_txoptions *opt_to_free = NULL;
 	struct ipv6_txoptions opt_space;
 	DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
 	struct in6_addr *daddr, *final_p, final;
@@ -838,8 +839,10 @@ static int rawv6_sendmsg(struct sock *sk
 		if (!(opt->opt_nflen|opt->opt_flen))
 			opt = NULL;
 	}
-	if (!opt)
-		opt = np->opt;
+	if (!opt) {
+		opt = txopt_get(np);
+		opt_to_free = opt;
+		}
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
@@ -905,6 +908,7 @@ done:
 	dst_release(dst);
 out:
 	fl6_sock_release(flowlabel);
+	txopt_put(opt_to_free);
 	return err < 0 ? err : len;
 do_confirm:
 	dst_confirm(dst);
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/reassembly.c linux-libre-4.3.4-gnu/net/ipv6/reassembly.c
--- linux-libre-4.3-gnu/net/ipv6/reassembly.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/reassembly.c	2016-01-22 23:59:37.000000000 -0500
@@ -108,7 +108,10 @@ bool ip6_frag_match(const struct inet_fr
 	return	fq->id == arg->id &&
 		fq->user == arg->user &&
 		ipv6_addr_equal(&fq->saddr, arg->src) &&
-		ipv6_addr_equal(&fq->daddr, arg->dst);
+		ipv6_addr_equal(&fq->daddr, arg->dst) &&
+		(arg->iif == fq->iif ||
+		 !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST |
+					       IPV6_ADDR_LINKLOCAL)));
 }
 EXPORT_SYMBOL(ip6_frag_match);
 
@@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned lon
 
 static struct frag_queue *
 fq_find(struct net *net, __be32 id, const struct in6_addr *src,
-	const struct in6_addr *dst, u8 ecn)
+	const struct in6_addr *dst, int iif, u8 ecn)
 {
 	struct inet_frag_queue *q;
 	struct ip6_create_arg arg;
@@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, cons
 	arg.user = IP6_DEFRAG_LOCAL_DELIVER;
 	arg.src = src;
 	arg.dst = dst;
+	arg.iif = iif;
 	arg.ecn = ecn;
 
 	hash = inet6_hash_frag(id, src, dst);
@@ -551,7 +555,7 @@ static int ipv6_frag_rcv(struct sk_buff
 	}
 
 	fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
-		     ip6_frag_ecn(hdr));
+		     skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
 	if (fq) {
 		int ret;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/route.c linux-libre-4.3.4-gnu/net/ipv6/route.c
--- linux-libre-4.3-gnu/net/ipv6/route.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/route.c	2016-01-22 23:59:37.000000000 -0500
@@ -403,6 +403,14 @@ static void ip6_dst_ifdown(struct dst_en
 	}
 }
 
+static bool __rt6_check_expired(const struct rt6_info *rt)
+{
+	if (rt->rt6i_flags & RTF_EXPIRES)
+		return time_after(jiffies, rt->dst.expires);
+	else
+		return false;
+}
+
 static bool rt6_check_expired(const struct rt6_info *rt)
 {
 	if (rt->rt6i_flags & RTF_EXPIRES) {
@@ -538,7 +546,7 @@ static void rt6_probe_deferred(struct wo
 		container_of(w, struct __rt6_probe_work, work);
 
 	addrconf_addr_solict_mult(&work->target, &mcaddr);
-	ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL, NULL);
+	ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL);
 	dev_put(work->dev);
 	kfree(work);
 }
@@ -1270,7 +1278,8 @@ static struct dst_entry *rt6_check(struc
 
 static struct dst_entry *rt6_dst_from_check(struct rt6_info *rt, u32 cookie)
 {
-	if (rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
+	if (!__rt6_check_expired(rt) &&
+	    rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
 	    rt6_check((struct rt6_info *)(rt->dst.from), cookie))
 		return &rt->dst;
 	else
@@ -1290,7 +1299,8 @@ static struct dst_entry *ip6_dst_check(s
 
 	rt6_dst_from_metrics_check(rt);
 
-	if ((rt->rt6i_flags & RTF_PCPU) || unlikely(dst->flags & DST_NOCACHE))
+	if (rt->rt6i_flags & RTF_PCPU ||
+	    (unlikely(dst->flags & DST_NOCACHE) && rt->dst.from))
 		return rt6_dst_from_check(rt, cookie);
 	else
 		return rt6_check(rt, cookie);
@@ -1340,6 +1350,12 @@ static void rt6_do_update_pmtu(struct rt
 	rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires);
 }
 
+static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt)
+{
+	return !(rt->rt6i_flags & RTF_CACHE) &&
+		(rt->rt6i_flags & RTF_PCPU || rt->rt6i_node);
+}
+
 static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
 				 const struct ipv6hdr *iph, u32 mtu)
 {
@@ -1353,7 +1369,7 @@ static void __ip6_rt_update_pmtu(struct
 	if (mtu >= dst_mtu(dst))
 		return;
 
-	if (rt6->rt6i_flags & RTF_CACHE) {
+	if (!rt6_cache_allowed_for_pmtu(rt6)) {
 		rt6_do_update_pmtu(rt6, mtu);
 	} else {
 		const struct in6_addr *daddr, *saddr;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/sit.c linux-libre-4.3.4-gnu/net/ipv6/sit.c
--- linux-libre-4.3-gnu/net/ipv6/sit.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/sit.c	2016-01-22 23:59:37.000000000 -0500
@@ -1394,34 +1394,20 @@ static int ipip6_tunnel_init(struct net_
 	return 0;
 }
 
-static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
+static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct iphdr *iph = &tunnel->parms.iph;
 	struct net *net = dev_net(dev);
 	struct sit_net *sitn = net_generic(net, sit_net_id);
 
-	tunnel->dev = dev;
-	tunnel->net = dev_net(dev);
-
 	iph->version		= 4;
 	iph->protocol		= IPPROTO_IPV6;
 	iph->ihl		= 5;
 	iph->ttl		= 64;
 
-	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
-	if (!dev->tstats)
-		return -ENOMEM;
-
-	tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
-	if (!tunnel->dst_cache) {
-		free_percpu(dev->tstats);
-		return -ENOMEM;
-	}
-
 	dev_hold(dev);
 	rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
-	return 0;
 }
 
 static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -1831,23 +1817,19 @@ static int __net_init sit_init_net(struc
 	 */
 	sitn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
 
-	err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
-	if (err)
-		goto err_dev_free;
-
-	ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
 	err = register_netdev(sitn->fb_tunnel_dev);
 	if (err)
 		goto err_reg_dev;
 
+	ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
+	ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
+
 	t = netdev_priv(sitn->fb_tunnel_dev);
 
 	strcpy(t->parms.name, sitn->fb_tunnel_dev->name);
 	return 0;
 
 err_reg_dev:
-	dev_put(sitn->fb_tunnel_dev);
-err_dev_free:
 	ipip6_dev_free(sitn->fb_tunnel_dev);
 err_alloc_dev:
 	return err;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/syncookies.c linux-libre-4.3.4-gnu/net/ipv6/syncookies.c
--- linux-libre-4.3-gnu/net/ipv6/syncookies.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/syncookies.c	2016-01-22 23:59:37.000000000 -0500
@@ -225,7 +225,7 @@ struct sock *cookie_v6_check(struct sock
 		memset(&fl6, 0, sizeof(fl6));
 		fl6.flowi6_proto = IPPROTO_TCP;
 		fl6.daddr = ireq->ir_v6_rmt_addr;
-		final_p = fl6_update_dst(&fl6, np->opt, &final);
+		final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
 		fl6.saddr = ireq->ir_v6_loc_addr;
 		fl6.flowi6_oif = sk->sk_bound_dev_if;
 		fl6.flowi6_mark = ireq->ir_mark;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/tcp_ipv6.c linux-libre-4.3.4-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-4.3-gnu/net/ipv6/tcp_ipv6.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/tcp_ipv6.c	2016-01-22 23:59:37.000000000 -0500
@@ -93,10 +93,9 @@ static void inet6_sk_rx_dst_set(struct s
 {
 	struct dst_entry *dst = skb_dst(skb);
 
-	if (dst) {
+	if (dst && dst_hold_safe(dst)) {
 		const struct rt6_info *rt = (const struct rt6_info *)dst;
 
-		dst_hold(dst);
 		sk->sk_rx_dst = dst;
 		inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
 		inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
@@ -120,6 +119,7 @@ static int tcp_v6_connect(struct sock *s
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct in6_addr *saddr = NULL, *final_p, final;
+	struct ipv6_txoptions *opt;
 	struct flowi6 fl6;
 	struct dst_entry *dst;
 	int addr_type;
@@ -235,7 +235,8 @@ static int tcp_v6_connect(struct sock *s
 	fl6.fl6_dport = usin->sin6_port;
 	fl6.fl6_sport = inet->inet_sport;
 
-	final_p = fl6_update_dst(&fl6, np->opt, &final);
+	opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+	final_p = fl6_update_dst(&fl6, opt, &final);
 
 	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
@@ -263,9 +264,9 @@ static int tcp_v6_connect(struct sock *s
 		tcp_fetch_timewait_stamp(sk, dst);
 
 	icsk->icsk_ext_hdr_len = 0;
-	if (np->opt)
-		icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
-					  np->opt->opt_nflen);
+	if (opt)
+		icsk->icsk_ext_hdr_len = opt->opt_flen +
+					 opt->opt_nflen;
 
 	tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
@@ -461,7 +462,8 @@ static int tcp_v6_send_synack(struct soc
 			fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
 
 		skb_set_queue_mapping(skb, queue_mapping);
-		err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
+		err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
+			       np->tclass);
 		err = net_xmit_eval(err);
 	}
 
@@ -991,6 +993,7 @@ static struct sock *tcp_v6_syn_recv_sock
 	struct inet_request_sock *ireq;
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct tcp6_sock *newtcp6sk;
+	struct ipv6_txoptions *opt;
 	struct inet_sock *newinet;
 	struct tcp_sock *newtp;
 	struct sock *newsk;
@@ -1126,13 +1129,15 @@ static struct sock *tcp_v6_syn_recv_sock
 	   but we make one more one thing there: reattach optmem
 	   to newsk.
 	 */
-	if (np->opt)
-		newnp->opt = ipv6_dup_options(newsk, np->opt);
-
+	opt = rcu_dereference(np->opt);
+	if (opt) {
+		opt = ipv6_dup_options(newsk, opt);
+		RCU_INIT_POINTER(newnp->opt, opt);
+	}
 	inet_csk(newsk)->icsk_ext_hdr_len = 0;
-	if (newnp->opt)
-		inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
-						     newnp->opt->opt_flen);
+	if (opt)
+		inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+						    opt->opt_flen;
 
 	tcp_ca_openreq_child(newsk, dst);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/ipv6/udp.c linux-libre-4.3.4-gnu/net/ipv6/udp.c
--- linux-libre-4.3-gnu/net/ipv6/udp.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/ipv6/udp.c	2016-01-22 23:59:37.000000000 -0500
@@ -1107,6 +1107,7 @@ int udpv6_sendmsg(struct sock *sk, struc
 	DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
 	struct in6_addr *daddr, *final_p, final;
 	struct ipv6_txoptions *opt = NULL;
+	struct ipv6_txoptions *opt_to_free = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
 	struct flowi6 fl6;
 	struct dst_entry *dst;
@@ -1260,8 +1261,10 @@ do_udp_sendmsg:
 			opt = NULL;
 		connected = 0;
 	}
-	if (!opt)
-		opt = np->opt;
+	if (!opt) {
+		opt = txopt_get(np);
+		opt_to_free = opt;
+	}
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
@@ -1370,6 +1373,7 @@ release_dst:
 out:
 	dst_release(dst);
 	fl6_sock_release(flowlabel);
+	txopt_put(opt_to_free);
 	if (!err)
 		return len;
 	/*
diff -druNp --no-dereference linux-libre-4.3-gnu/net/irda/af_irda.c linux-libre-4.3.4-gnu/net/irda/af_irda.c
--- linux-libre-4.3-gnu/net/irda/af_irda.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/irda/af_irda.c	2016-01-22 23:59:37.000000000 -0500
@@ -1086,6 +1086,9 @@ static int irda_create(struct net *net,
 	struct sock *sk;
 	struct irda_sock *self;
 
+	if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+		return -EINVAL;
+
 	if (net != &init_net)
 		return -EAFNOSUPPORT;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/l2tp/l2tp_ip6.c linux-libre-4.3.4-gnu/net/l2tp/l2tp_ip6.c
--- linux-libre-4.3-gnu/net/l2tp/l2tp_ip6.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/l2tp/l2tp_ip6.c	2016-01-22 23:59:37.000000000 -0500
@@ -486,6 +486,7 @@ static int l2tp_ip6_sendmsg(struct sock
 	DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
 	struct in6_addr *daddr, *final_p, final;
 	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct ipv6_txoptions *opt_to_free = NULL;
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
 	struct dst_entry *dst = NULL;
@@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct sock
 			opt = NULL;
 	}
 
-	if (opt == NULL)
-		opt = np->opt;
+	if (!opt) {
+		opt = txopt_get(np);
+		opt_to_free = opt;
+	}
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
@@ -631,6 +634,7 @@ done:
 	dst_release(dst);
 out:
 	fl6_sock_release(flowlabel);
+	txopt_put(opt_to_free);
 
 	return err < 0 ? err : len;
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/mac80211/mlme.c linux-libre-4.3.4-gnu/net/mac80211/mlme.c
--- linux-libre-4.3-gnu/net/mac80211/mlme.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/mac80211/mlme.c	2016-01-22 23:59:37.000000000 -0500
@@ -3391,7 +3391,7 @@ static void ieee80211_rx_mgmt_beacon(str
 
 	if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
 	    ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
-		int sig = ifmgd->ave_beacon_signal;
+		int sig = ifmgd->ave_beacon_signal / 16;
 		int last_sig = ifmgd->last_ave_beacon_signal;
 		struct ieee80211_event event = {
 			.type = RSSI_EVENT,
@@ -5028,6 +5028,25 @@ int ieee80211_mgd_deauth(struct ieee8021
 		return 0;
 	}
 
+	if (ifmgd->assoc_data &&
+	    ether_addr_equal(ifmgd->assoc_data->bss->bssid, req->bssid)) {
+		sdata_info(sdata,
+			   "aborting association with %pM by local choice (Reason: %u=%s)\n",
+			   req->bssid, req->reason_code,
+			   ieee80211_get_reason_code_string(req->reason_code));
+
+		drv_mgd_prepare_tx(sdata->local, sdata);
+		ieee80211_send_deauth_disassoc(sdata, req->bssid,
+					       IEEE80211_STYPE_DEAUTH,
+					       req->reason_code, tx,
+					       frame_buf);
+		ieee80211_destroy_assoc_data(sdata, false);
+		ieee80211_report_disconnect(sdata, frame_buf,
+					    sizeof(frame_buf), true,
+					    req->reason_code);
+		return 0;
+	}
+
 	if (ifmgd->associated &&
 	    ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
 		sdata_info(sdata,
diff -druNp --no-dereference linux-libre-4.3-gnu/net/mac80211/trace.h linux-libre-4.3.4-gnu/net/mac80211/trace.h
--- linux-libre-4.3-gnu/net/mac80211/trace.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/mac80211/trace.h	2016-01-22 23:59:37.000000000 -0500
@@ -33,11 +33,11 @@
 			__field(u32, chan_width)					\
 			__field(u32, center_freq1)					\
 			__field(u32, center_freq2)
-#define CHANDEF_ASSIGN(c)								\
-			__entry->control_freq = (c)->chan ? (c)->chan->center_freq : 0;	\
-			__entry->chan_width = (c)->width;				\
-			__entry->center_freq1 = (c)->center_freq1;			\
-			__entry->center_freq2 = (c)->center_freq2;
+#define CHANDEF_ASSIGN(c)							\
+			__entry->control_freq = (c) ? ((c)->chan ? (c)->chan->center_freq : 0) : 0;	\
+			__entry->chan_width = (c) ? (c)->width : 0;			\
+			__entry->center_freq1 = (c) ? (c)->center_freq1 : 0;		\
+			__entry->center_freq2 = (c) ? (c)->center_freq2 : 0;
 #define CHANDEF_PR_FMT	" control:%d MHz width:%d center: %d/%d MHz"
 #define CHANDEF_PR_ARG	__entry->control_freq, __entry->chan_width,			\
 			__entry->center_freq1, __entry->center_freq2
diff -druNp --no-dereference linux-libre-4.3-gnu/net/mac80211/util.c linux-libre-4.3.4-gnu/net/mac80211/util.c
--- linux-libre-4.3-gnu/net/mac80211/util.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/mac80211/util.c	2016-01-22 23:59:37.000000000 -0500
@@ -2951,6 +2951,13 @@ ieee80211_extend_noa_desc(struct ieee802
 	if (end > 0)
 		return false;
 
+	/* One shot NOA  */
+	if (data->count[i] == 1)
+		return false;
+
+	if (data->desc[i].interval == 0)
+		return false;
+
 	/* End time is in the past, check for repetitions */
 	skip = DIV_ROUND_UP(-end, data->desc[i].interval);
 	if (data->count[i] < 255) {
diff -druNp --no-dereference linux-libre-4.3-gnu/net/nfc/nci/hci.c linux-libre-4.3.4-gnu/net/nfc/nci/hci.c
--- linux-libre-4.3-gnu/net/nfc/nci/hci.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/nfc/nci/hci.c	2016-01-22 23:59:37.000000000 -0500
@@ -101,6 +101,20 @@ struct nci_hcp_packet {
 #define NCI_HCP_MSG_GET_CMD(header)  (header & 0x3f)
 #define NCI_HCP_MSG_GET_PIPE(header) (header & 0x7f)
 
+static int nci_hci_result_to_errno(u8 result)
+{
+	switch (result) {
+	case NCI_HCI_ANY_OK:
+		return 0;
+	case NCI_HCI_ANY_E_REG_PAR_UNKNOWN:
+		return -EOPNOTSUPP;
+	case NCI_HCI_ANY_E_TIMEOUT:
+		return -ETIME;
+	default:
+		return -1;
+	}
+}
+
 /* HCI core */
 static void nci_hci_reset_pipes(struct nci_hci_dev *hdev)
 {
@@ -146,18 +160,18 @@ static int nci_hci_send_data(struct nci_
 	if (!conn_info)
 		return -EPROTO;
 
-	skb = nci_skb_alloc(ndev, 2 + conn_info->max_pkt_payload_len +
+	i = 0;
+	skb = nci_skb_alloc(ndev, conn_info->max_pkt_payload_len +
 			    NCI_DATA_HDR_SIZE, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 
-	skb_reserve(skb, 2 + NCI_DATA_HDR_SIZE);
+	skb_reserve(skb, NCI_DATA_HDR_SIZE + 2);
 	*skb_push(skb, 1) = data_type;
 
-	i = 0;
-	len = conn_info->max_pkt_payload_len;
-
 	do {
+		len = conn_info->max_pkt_payload_len;
+
 		/* If last packet add NCI_HFP_NO_CHAINING */
 		if (i + conn_info->max_pkt_payload_len -
 		    (skb->len + 1) >= data_len) {
@@ -177,9 +191,15 @@ static int nci_hci_send_data(struct nci_
 			return r;
 
 		i += len;
+
 		if (i < data_len) {
-			skb_trim(skb, 0);
-			skb_pull(skb, len);
+			skb = nci_skb_alloc(ndev,
+					    conn_info->max_pkt_payload_len +
+					    NCI_DATA_HDR_SIZE, GFP_KERNEL);
+			if (!skb)
+				return -ENOMEM;
+
+			skb_reserve(skb, NCI_DATA_HDR_SIZE + 1);
 		}
 	} while (i < data_len);
 
@@ -212,7 +232,8 @@ int nci_hci_send_cmd(struct nci_dev *nde
 		     const u8 *param, size_t param_len,
 		     struct sk_buff **skb)
 {
-	struct nci_conn_info    *conn_info;
+	struct nci_hcp_message *message;
+	struct nci_conn_info   *conn_info;
 	struct nci_data data;
 	int r;
 	u8 pipe = ndev->hci_dev->gate2pipe[gate];
@@ -232,9 +253,15 @@ int nci_hci_send_cmd(struct nci_dev *nde
 
 	r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
+	if (r == NCI_STATUS_OK) {
+		message = (struct nci_hcp_message *)conn_info->rx_skb->data;
+		r = nci_hci_result_to_errno(
+			NCI_HCP_MSG_GET_CMD(message->header));
+		skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 
-	if (r == NCI_STATUS_OK && skb)
-		*skb = conn_info->rx_skb;
+		if (!r && skb)
+			*skb = conn_info->rx_skb;
+	}
 
 	return r;
 }
@@ -328,9 +355,6 @@ static void nci_hci_resp_received(struct
 	struct nci_conn_info    *conn_info;
 	u8 status = result;
 
-	if (result != NCI_HCI_ANY_OK)
-		goto exit;
-
 	conn_info = ndev->hci_dev->conn_info;
 	if (!conn_info) {
 		status = NCI_STATUS_REJECTED;
@@ -340,7 +364,7 @@ static void nci_hci_resp_received(struct
 	conn_info->rx_skb = skb;
 
 exit:
-	nci_req_complete(ndev, status);
+	nci_req_complete(ndev, NCI_STATUS_OK);
 }
 
 /* Receive hcp message for pipe, with type and cmd.
@@ -378,7 +402,7 @@ static void nci_hci_msg_rx_work(struct w
 	u8 pipe, type, instruction;
 
 	while ((skb = skb_dequeue(&hdev->msg_rx_queue)) != NULL) {
-		pipe = skb->data[0];
+		pipe = NCI_HCP_MSG_GET_PIPE(skb->data[0]);
 		skb_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
 		message = (struct nci_hcp_message *)skb->data;
 		type = NCI_HCP_MSG_GET_TYPE(message->header);
@@ -395,7 +419,7 @@ void nci_hci_data_received_cb(void *cont
 {
 	struct nci_dev *ndev = (struct nci_dev *)context;
 	struct nci_hcp_packet *packet;
-	u8 pipe, type, instruction;
+	u8 pipe, type;
 	struct sk_buff *hcp_skb;
 	struct sk_buff *frag_skb;
 	int msg_len;
@@ -415,7 +439,7 @@ void nci_hci_data_received_cb(void *cont
 
 	/* it's the last fragment. Does it need re-aggregation? */
 	if (skb_queue_len(&ndev->hci_dev->rx_hcp_frags)) {
-		pipe = packet->header & NCI_HCI_FRAGMENT;
+		pipe = NCI_HCP_MSG_GET_PIPE(packet->header);
 		skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
 
 		msg_len = 0;
@@ -434,7 +458,7 @@ void nci_hci_data_received_cb(void *cont
 		*skb_put(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN) = pipe;
 
 		skb_queue_walk(&ndev->hci_dev->rx_hcp_frags, frag_skb) {
-		       msg_len = frag_skb->len - NCI_HCI_HCP_PACKET_HEADER_LEN;
+			msg_len = frag_skb->len - NCI_HCI_HCP_PACKET_HEADER_LEN;
 			memcpy(skb_put(hcp_skb, msg_len), frag_skb->data +
 			       NCI_HCI_HCP_PACKET_HEADER_LEN, msg_len);
 		}
@@ -452,11 +476,10 @@ void nci_hci_data_received_cb(void *cont
 	packet = (struct nci_hcp_packet *)hcp_skb->data;
 	type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
 	if (type == NCI_HCI_HCP_RESPONSE) {
-		pipe = packet->header;
-		instruction = NCI_HCP_MSG_GET_CMD(packet->message.header);
-		skb_pull(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN +
-			 NCI_HCI_HCP_MESSAGE_HEADER_LEN);
-		nci_hci_hcp_message_rx(ndev, pipe, type, instruction, hcp_skb);
+		pipe = NCI_HCP_MSG_GET_PIPE(packet->header);
+		skb_pull(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
+		nci_hci_hcp_message_rx(ndev, pipe, type,
+				       NCI_STATUS_OK, hcp_skb);
 	} else {
 		skb_queue_tail(&ndev->hci_dev->msg_rx_queue, hcp_skb);
 		schedule_work(&ndev->hci_dev->msg_rx_work);
@@ -488,6 +511,7 @@ EXPORT_SYMBOL(nci_hci_open_pipe);
 int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
 		      const u8 *param, size_t param_len)
 {
+	struct nci_hcp_message *message;
 	struct nci_conn_info *conn_info;
 	struct nci_data data;
 	int r;
@@ -520,6 +544,12 @@ int nci_hci_set_param(struct nci_dev *nd
 	r = nci_request(ndev, nci_hci_send_data_req,
 			(unsigned long)&data,
 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
+	if (r == NCI_STATUS_OK) {
+		message = (struct nci_hcp_message *)conn_info->rx_skb->data;
+		r = nci_hci_result_to_errno(
+			NCI_HCP_MSG_GET_CMD(message->header));
+		skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
+	}
 
 	kfree(tmp);
 	return r;
@@ -529,6 +559,7 @@ EXPORT_SYMBOL(nci_hci_set_param);
 int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx,
 		      struct sk_buff **skb)
 {
+	struct nci_hcp_message *message;
 	struct nci_conn_info    *conn_info;
 	struct nci_data data;
 	int r;
@@ -553,8 +584,15 @@ int nci_hci_get_param(struct nci_dev *nd
 	r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
 
-	if (r == NCI_STATUS_OK)
-		*skb = conn_info->rx_skb;
+	if (r == NCI_STATUS_OK) {
+		message = (struct nci_hcp_message *)conn_info->rx_skb->data;
+		r = nci_hci_result_to_errno(
+			NCI_HCP_MSG_GET_CMD(message->header));
+		skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
+
+		if (!r && skb)
+			*skb = conn_info->rx_skb;
+	}
 
 	return r;
 }
diff -druNp --no-dereference linux-libre-4.3-gnu/net/openvswitch/conntrack.c linux-libre-4.3.4-gnu/net/openvswitch/conntrack.c
--- linux-libre-4.3-gnu/net/openvswitch/conntrack.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/openvswitch/conntrack.c	2016-01-22 23:59:37.000000000 -0500
@@ -53,6 +53,8 @@ struct ovs_conntrack_info {
 	struct md_labels labels;
 };
 
+static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info);
+
 static u16 key_to_nfproto(const struct sw_flow_key *key)
 {
 	switch (ntohs(key->eth.type)) {
@@ -141,6 +143,7 @@ static void __ovs_ct_update_key(struct s
  * previously sent the packet to conntrack via the ct action.
  */
 static void ovs_ct_update_key(const struct sk_buff *skb,
+			      const struct ovs_conntrack_info *info,
 			      struct sw_flow_key *key, bool post_ct)
 {
 	const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;
@@ -158,13 +161,15 @@ static void ovs_ct_update_key(const stru
 		zone = nf_ct_zone(ct);
 	} else if (post_ct) {
 		state = OVS_CS_F_TRACKED | OVS_CS_F_INVALID;
+		if (info)
+			zone = &info->zone;
 	}
 	__ovs_ct_update_key(key, state, zone, ct);
 }
 
 void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
 {
-	ovs_ct_update_key(skb, key, false);
+	ovs_ct_update_key(skb, NULL, key, false);
 }
 
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
@@ -418,7 +423,7 @@ static int __ovs_ct_lookup(struct net *n
 		}
 	}
 
-	ovs_ct_update_key(skb, key, true);
+	ovs_ct_update_key(skb, info, key, true);
 
 	return 0;
 }
@@ -708,7 +713,7 @@ int ovs_ct_copy_action(struct net *net,
 	nf_conntrack_get(&ct_info.ct->ct_general);
 	return 0;
 err_free_ct:
-	nf_conntrack_free(ct_info.ct);
+	__ovs_ct_free_action(&ct_info);
 	return err;
 }
 
@@ -750,6 +755,11 @@ void ovs_ct_free_action(const struct nla
 {
 	struct ovs_conntrack_info *ct_info = nla_data(a);
 
+	__ovs_ct_free_action(ct_info);
+}
+
+static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
+{
 	if (ct_info->helper)
 		module_put(ct_info->helper->me);
 	if (ct_info->ct)
diff -druNp --no-dereference linux-libre-4.3-gnu/net/openvswitch/dp_notify.c linux-libre-4.3.4-gnu/net/openvswitch/dp_notify.c
--- linux-libre-4.3-gnu/net/openvswitch/dp_notify.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/openvswitch/dp_notify.c	2016-01-22 23:59:37.000000000 -0500
@@ -58,7 +58,7 @@ void ovs_dp_notify_wq(struct work_struct
 			struct hlist_node *n;
 
 			hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) {
-				if (vport->ops->type != OVS_VPORT_TYPE_NETDEV)
+				if (vport->ops->type == OVS_VPORT_TYPE_INTERNAL)
 					continue;
 
 				if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH))
diff -druNp --no-dereference linux-libre-4.3-gnu/net/openvswitch/vport-netdev.c linux-libre-4.3.4-gnu/net/openvswitch/vport-netdev.c
--- linux-libre-4.3-gnu/net/openvswitch/vport-netdev.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/openvswitch/vport-netdev.c	2016-01-22 23:59:37.000000000 -0500
@@ -180,9 +180,13 @@ void ovs_netdev_tunnel_destroy(struct vp
 	if (vport->dev->priv_flags & IFF_OVS_DATAPATH)
 		ovs_netdev_detach_dev(vport);
 
-	/* Early release so we can unregister the device */
+	/* We can be invoked by both explicit vport deletion and
+	 * underlying netdev deregistration; delete the link only
+	 * if it's not already shutting down.
+	 */
+	if (vport->dev->reg_state == NETREG_REGISTERED)
+		rtnl_delete_link(vport->dev);
 	dev_put(vport->dev);
-	rtnl_delete_link(vport->dev);
 	vport->dev = NULL;
 	rtnl_unlock();
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/packet/af_packet.c linux-libre-4.3.4-gnu/net/packet/af_packet.c
--- linux-libre-4.3-gnu/net/packet/af_packet.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/packet/af_packet.c	2016-01-22 23:59:37.000000000 -0500
@@ -1741,6 +1741,20 @@ static void fanout_release(struct sock *
 		kfree_rcu(po->rollover, rcu);
 }
 
+static bool packet_extra_vlan_len_allowed(const struct net_device *dev,
+					  struct sk_buff *skb)
+{
+	/* Earlier code assumed this would be a VLAN pkt, double-check
+	 * this now that we have the actual packet in hand. We can only
+	 * do this check on Ethernet devices.
+	 */
+	if (unlikely(dev->type != ARPHRD_ETHER))
+		return false;
+
+	skb_reset_mac_header(skb);
+	return likely(eth_hdr(skb)->h_proto == htons(ETH_P_8021Q));
+}
+
 static const struct proto_ops packet_ops;
 
 static const struct proto_ops packet_ops_spkt;
@@ -1902,18 +1916,10 @@ retry:
 		goto retry;
 	}
 
-	if (len > (dev->mtu + dev->hard_header_len + extra_len)) {
-		/* Earlier code assumed this would be a VLAN pkt,
-		 * double-check this now that we have the actual
-		 * packet in hand.
-		 */
-		struct ethhdr *ehdr;
-		skb_reset_mac_header(skb);
-		ehdr = eth_hdr(skb);
-		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
-			err = -EMSGSIZE;
-			goto out_unlock;
-		}
+	if (len > (dev->mtu + dev->hard_header_len + extra_len) &&
+	    !packet_extra_vlan_len_allowed(dev, skb)) {
+		err = -EMSGSIZE;
+		goto out_unlock;
 	}
 
 	skb->protocol = proto;
@@ -2332,6 +2338,15 @@ static bool ll_header_truncated(const st
 	return false;
 }
 
+static void tpacket_set_protocol(const struct net_device *dev,
+				 struct sk_buff *skb)
+{
+	if (dev->type == ARPHRD_ETHER) {
+		skb_reset_mac_header(skb);
+		skb->protocol = eth_hdr(skb)->h_proto;
+	}
+}
+
 static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		void *frame, struct net_device *dev, int size_max,
 		__be16 proto, unsigned char *addr, int hlen)
@@ -2368,8 +2383,6 @@ static int tpacket_fill_skb(struct packe
 	skb_reserve(skb, hlen);
 	skb_reset_network_header(skb);
 
-	if (!packet_use_direct_xmit(po))
-		skb_probe_transport_header(skb, 0);
 	if (unlikely(po->tp_tx_has_off)) {
 		int off_min, off_max, off;
 		off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll);
@@ -2415,6 +2428,8 @@ static int tpacket_fill_skb(struct packe
 				dev->hard_header_len);
 		if (unlikely(err))
 			return err;
+		if (!skb->protocol)
+			tpacket_set_protocol(dev, skb);
 
 		data += dev->hard_header_len;
 		to_write -= dev->hard_header_len;
@@ -2449,6 +2464,8 @@ static int tpacket_fill_skb(struct packe
 		len = ((to_write > len_max) ? len_max : to_write);
 	}
 
+	skb_probe_transport_header(skb, 0);
+
 	return tp_len;
 }
 
@@ -2493,12 +2510,13 @@ static int tpacket_snd(struct packet_soc
 	if (unlikely(!(dev->flags & IFF_UP)))
 		goto out_put;
 
-	reserve = dev->hard_header_len + VLAN_HLEN;
+	if (po->sk.sk_socket->type == SOCK_RAW)
+		reserve = dev->hard_header_len;
 	size_max = po->tx_ring.frame_size
 		- (po->tp_hdrlen - sizeof(struct sockaddr_ll));
 
-	if (size_max > dev->mtu + reserve)
-		size_max = dev->mtu + reserve;
+	if (size_max > dev->mtu + reserve + VLAN_HLEN)
+		size_max = dev->mtu + reserve + VLAN_HLEN;
 
 	do {
 		ph = packet_current_frame(po, &po->tx_ring,
@@ -2525,18 +2543,10 @@ static int tpacket_snd(struct packet_soc
 		tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto,
 					  addr, hlen);
 		if (likely(tp_len >= 0) &&
-		    tp_len > dev->mtu + dev->hard_header_len) {
-			struct ethhdr *ehdr;
-			/* Earlier code assumed this would be a VLAN pkt,
-			 * double-check this now that we have the actual
-			 * packet in hand.
-			 */
+		    tp_len > dev->mtu + reserve &&
+		    !packet_extra_vlan_len_allowed(dev, skb))
+			tp_len = -EMSGSIZE;
 
-			skb_reset_mac_header(skb);
-			ehdr = eth_hdr(skb);
-			if (ehdr->h_proto != htons(ETH_P_8021Q))
-				tp_len = -EMSGSIZE;
-		}
 		if (unlikely(tp_len < 0)) {
 			if (po->tp_loss) {
 				__packet_set_status(po, ph,
@@ -2757,18 +2767,10 @@ static int packet_snd(struct socket *soc
 
 	sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 
-	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
-		/* Earlier code assumed this would be a VLAN pkt,
-		 * double-check this now that we have the actual
-		 * packet in hand.
-		 */
-		struct ethhdr *ehdr;
-		skb_reset_mac_header(skb);
-		ehdr = eth_hdr(skb);
-		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
-			err = -EMSGSIZE;
-			goto out_free;
-		}
+	if (!gso_type && (len > dev->mtu + reserve + extra_len) &&
+	    !packet_extra_vlan_len_allowed(dev, skb)) {
+		err = -EMSGSIZE;
+		goto out_free;
 	}
 
 	skb->protocol = proto;
@@ -2799,8 +2801,8 @@ static int packet_snd(struct socket *soc
 		len += vnet_hdr_len;
 	}
 
-	if (!packet_use_direct_xmit(po))
-		skb_probe_transport_header(skb, reserve);
+	skb_probe_transport_header(skb, reserve);
+
 	if (unlikely(extra_len == 4))
 		skb->no_fcs = 1;
 
@@ -2903,22 +2905,40 @@ static int packet_release(struct socket
  *	Attach a packet hook.
  */
 
-static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
+static int packet_do_bind(struct sock *sk, const char *name, int ifindex,
+			  __be16 proto)
 {
 	struct packet_sock *po = pkt_sk(sk);
 	struct net_device *dev_curr;
 	__be16 proto_curr;
 	bool need_rehook;
+	struct net_device *dev = NULL;
+	int ret = 0;
+	bool unlisted = false;
 
-	if (po->fanout) {
-		if (dev)
-			dev_put(dev);
-
+	if (po->fanout)
 		return -EINVAL;
-	}
 
 	lock_sock(sk);
 	spin_lock(&po->bind_lock);
+	rcu_read_lock();
+
+	if (name) {
+		dev = dev_get_by_name_rcu(sock_net(sk), name);
+		if (!dev) {
+			ret = -ENODEV;
+			goto out_unlock;
+		}
+	} else if (ifindex) {
+		dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
+		if (!dev) {
+			ret = -ENODEV;
+			goto out_unlock;
+		}
+	}
+
+	if (dev)
+		dev_hold(dev);
 
 	proto_curr = po->prot_hook.type;
 	dev_curr = po->prot_hook.dev;
@@ -2926,14 +2946,29 @@ static int packet_do_bind(struct sock *s
 	need_rehook = proto_curr != proto || dev_curr != dev;
 
 	if (need_rehook) {
-		unregister_prot_hook(sk, true);
+		if (po->running) {
+			rcu_read_unlock();
+			__unregister_prot_hook(sk, true);
+			rcu_read_lock();
+			dev_curr = po->prot_hook.dev;
+			if (dev)
+				unlisted = !dev_get_by_index_rcu(sock_net(sk),
+								 dev->ifindex);
+		}
 
 		po->num = proto;
 		po->prot_hook.type = proto;
-		po->prot_hook.dev = dev;
 
-		po->ifindex = dev ? dev->ifindex : 0;
-		packet_cached_dev_assign(po, dev);
+		if (unlikely(unlisted)) {
+			dev_put(dev);
+			po->prot_hook.dev = NULL;
+			po->ifindex = -1;
+			packet_cached_dev_reset(po);
+		} else {
+			po->prot_hook.dev = dev;
+			po->ifindex = dev ? dev->ifindex : 0;
+			packet_cached_dev_assign(po, dev);
+		}
 	}
 	if (dev_curr)
 		dev_put(dev_curr);
@@ -2941,7 +2976,7 @@ static int packet_do_bind(struct sock *s
 	if (proto == 0 || !need_rehook)
 		goto out_unlock;
 
-	if (!dev || (dev->flags & IFF_UP)) {
+	if (!unlisted && (!dev || (dev->flags & IFF_UP))) {
 		register_prot_hook(sk);
 	} else {
 		sk->sk_err = ENETDOWN;
@@ -2950,9 +2985,10 @@ static int packet_do_bind(struct sock *s
 	}
 
 out_unlock:
+	rcu_read_unlock();
 	spin_unlock(&po->bind_lock);
 	release_sock(sk);
-	return 0;
+	return ret;
 }
 
 /*
@@ -2964,8 +3000,6 @@ static int packet_bind_spkt(struct socke
 {
 	struct sock *sk = sock->sk;
 	char name[15];
-	struct net_device *dev;
-	int err = -ENODEV;
 
 	/*
 	 *	Check legality
@@ -2975,19 +3009,13 @@ static int packet_bind_spkt(struct socke
 		return -EINVAL;
 	strlcpy(name, uaddr->sa_data, sizeof(name));
 
-	dev = dev_get_by_name(sock_net(sk), name);
-	if (dev)
-		err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
-	return err;
+	return packet_do_bind(sk, name, 0, pkt_sk(sk)->num);
 }
 
 static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
 	struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr;
 	struct sock *sk = sock->sk;
-	struct net_device *dev = NULL;
-	int err;
-
 
 	/*
 	 *	Check legality
@@ -2998,16 +3026,8 @@ static int packet_bind(struct socket *so
 	if (sll->sll_family != AF_PACKET)
 		return -EINVAL;
 
-	if (sll->sll_ifindex) {
-		err = -ENODEV;
-		dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex);
-		if (dev == NULL)
-			goto out;
-	}
-	err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num);
-
-out:
-	return err;
+	return packet_do_bind(sk, NULL, sll->sll_ifindex,
+			      sll->sll_protocol ? : pkt_sk(sk)->num);
 }
 
 static struct proto packet_proto = {
diff -druNp --no-dereference linux-libre-4.3-gnu/net/rds/connection.c linux-libre-4.3.4-gnu/net/rds/connection.c
--- linux-libre-4.3-gnu/net/rds/connection.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/rds/connection.c	2016-01-22 23:59:37.000000000 -0500
@@ -190,12 +190,6 @@ new_conn:
 		}
 	}
 
-	if (trans == NULL) {
-		kmem_cache_free(rds_conn_slab, conn);
-		conn = ERR_PTR(-ENODEV);
-		goto out;
-	}
-
 	conn->c_trans = trans;
 
 	ret = trans->conn_alloc(conn, gfp);
diff -druNp --no-dereference linux-libre-4.3-gnu/net/rds/send.c linux-libre-4.3.4-gnu/net/rds/send.c
--- linux-libre-4.3-gnu/net/rds/send.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/rds/send.c	2016-01-22 23:59:37.000000000 -0500
@@ -1009,11 +1009,13 @@ int rds_sendmsg(struct socket *sock, str
 		release_sock(sk);
 	}
 
-	/* racing with another thread binding seems ok here */
+	lock_sock(sk);
 	if (daddr == 0 || rs->rs_bound_addr == 0) {
+		release_sock(sk);
 		ret = -ENOTCONN; /* XXX not a great errno */
 		goto out;
 	}
+	release_sock(sk);
 
 	if (payload_len > rds_sk_sndbuf(rs)) {
 		ret = -EMSGSIZE;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sched/sch_api.c linux-libre-4.3.4-gnu/net/sched/sch_api.c
--- linux-libre-4.3-gnu/net/sched/sch_api.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sched/sch_api.c	2016-01-22 23:59:37.000000000 -0500
@@ -253,7 +253,8 @@ int qdisc_set_default(const char *name)
 }
 
 /* We know handle. Find qdisc among all qdisc's attached to device
-   (root qdisc, all its children, children of children etc.)
+ * (root qdisc, all its children, children of children etc.)
+ * Note: caller either uses rtnl or rcu_read_lock()
  */
 
 static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
@@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_ro
 	    root->handle == handle)
 		return root;
 
-	list_for_each_entry(q, &root->list, list) {
+	list_for_each_entry_rcu(q, &root->list, list) {
 		if (q->handle == handle)
 			return q;
 	}
@@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q)
 		struct Qdisc *root = qdisc_dev(q)->qdisc;
 
 		WARN_ON_ONCE(root == &noop_qdisc);
-		list_add_tail(&q->list, &root->list);
+		ASSERT_RTNL();
+		list_add_tail_rcu(&q->list, &root->list);
 	}
 }
 EXPORT_SYMBOL(qdisc_list_add);
 
 void qdisc_list_del(struct Qdisc *q)
 {
-	if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS))
-		list_del(&q->list);
+	if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
+		ASSERT_RTNL();
+		list_del_rcu(&q->list);
+	}
 }
 EXPORT_SYMBOL(qdisc_list_del);
 
@@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdi
 	if (n == 0)
 		return;
 	drops = max_t(int, n, 0);
+	rcu_read_lock();
 	while ((parentid = sch->parent)) {
 		if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
-			return;
+			break;
 
+		if (sch->flags & TCQ_F_NOPARENT)
+			break;
+		/* TODO: perform the search on a per txq basis */
 		sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
 		if (sch == NULL) {
-			WARN_ON(parentid != TC_H_ROOT);
-			return;
+			WARN_ON_ONCE(parentid != TC_H_ROOT);
+			break;
 		}
 		cops = sch->ops->cl_ops;
 		if (cops->qlen_notify) {
@@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdi
 		sch->q.qlen -= n;
 		__qdisc_qstats_drop(sch, drops);
 	}
+	rcu_read_unlock();
 }
 EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sched/sch_generic.c linux-libre-4.3.4-gnu/net/sched/sch_generic.c
--- linux-libre-4.3-gnu/net/sched/sch_generic.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sched/sch_generic.c	2016-01-22 23:59:37.000000000 -0500
@@ -737,7 +737,7 @@ static void attach_one_default_qdisc(str
 		return;
 	}
 	if (!netif_is_multiqueue(dev))
-		qdisc->flags |= TCQ_F_ONETXQUEUE;
+		qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 	dev_queue->qdisc_sleeping = qdisc;
 }
 
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sched/sch_mq.c linux-libre-4.3.4-gnu/net/sched/sch_mq.c
--- linux-libre-4.3-gnu/net/sched/sch_mq.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sched/sch_mq.c	2016-01-22 23:59:37.000000000 -0500
@@ -63,7 +63,7 @@ static int mq_init(struct Qdisc *sch, st
 		if (qdisc == NULL)
 			goto err;
 		priv->qdiscs[ntx] = qdisc;
-		qdisc->flags |= TCQ_F_ONETXQUEUE;
+		qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 	}
 
 	sch->flags |= TCQ_F_MQROOT;
@@ -156,7 +156,7 @@ static int mq_graft(struct Qdisc *sch, u
 
 	*old = dev_graft_qdisc(dev_queue, new);
 	if (new)
-		new->flags |= TCQ_F_ONETXQUEUE;
+		new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 	if (dev->flags & IFF_UP)
 		dev_activate(dev);
 	return 0;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sched/sch_mqprio.c linux-libre-4.3.4-gnu/net/sched/sch_mqprio.c
--- linux-libre-4.3-gnu/net/sched/sch_mqprio.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sched/sch_mqprio.c	2016-01-22 23:59:37.000000000 -0500
@@ -132,7 +132,7 @@ static int mqprio_init(struct Qdisc *sch
 			goto err;
 		}
 		priv->qdiscs[i] = qdisc;
-		qdisc->flags |= TCQ_F_ONETXQUEUE;
+		qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 	}
 
 	/* If the mqprio options indicate that hardware should own
@@ -209,7 +209,7 @@ static int mqprio_graft(struct Qdisc *sc
 	*old = dev_graft_qdisc(dev_queue, new);
 
 	if (new)
-		new->flags |= TCQ_F_ONETXQUEUE;
+		new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 
 	if (dev->flags & IFF_UP)
 		dev_activate(dev);
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sctp/auth.c linux-libre-4.3.4-gnu/net/sctp/auth.c
--- linux-libre-4.3-gnu/net/sctp/auth.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sctp/auth.c	2016-01-22 23:59:37.000000000 -0500
@@ -809,8 +809,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_e
 	if (!has_sha1)
 		return -EINVAL;
 
-	memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0],
-		hmacs->shmac_num_idents * sizeof(__u16));
+	for (i = 0; i < hmacs->shmac_num_idents; i++)
+		ep->auth_hmacs_list->hmac_ids[i] = htons(hmacs->shmac_idents[i]);
 	ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) +
 				hmacs->shmac_num_idents * sizeof(__u16));
 	return 0;
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sctp/ipv6.c linux-libre-4.3.4-gnu/net/sctp/ipv6.c
--- linux-libre-4.3-gnu/net/sctp/ipv6.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sctp/ipv6.c	2016-01-22 23:59:37.000000000 -0500
@@ -635,6 +635,7 @@ static struct sock *sctp_v6_create_accep
 	struct sock *newsk;
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct sctp6_sock *newsctp6sk;
+	struct ipv6_txoptions *opt;
 
 	newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, 0);
 	if (!newsk)
@@ -654,6 +655,13 @@ static struct sock *sctp_v6_create_accep
 
 	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
+	rcu_read_lock();
+	opt = rcu_dereference(np->opt);
+	if (opt)
+		opt = ipv6_dup_options(newsk, opt);
+	RCU_INIT_POINTER(newnp->opt, opt);
+	rcu_read_unlock();
+
 	/* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
 	 * and getpeername().
 	 */
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sctp/sm_make_chunk.c linux-libre-4.3.4-gnu/net/sctp/sm_make_chunk.c
--- linux-libre-4.3-gnu/net/sctp/sm_make_chunk.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sctp/sm_make_chunk.c	2016-01-22 23:59:37.000000000 -0500
@@ -1652,7 +1652,7 @@ static sctp_cookie_param_t *sctp_pack_co
 
 	/* Set an expiration time for the cookie.  */
 	cookie->c.expiration = ktime_add(asoc->cookie_life,
-					 ktime_get());
+					 ktime_get_real());
 
 	/* Copy the peer's init packet.  */
 	memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
@@ -1780,7 +1780,7 @@ no_hmac:
 	if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
 		kt = skb_get_ktime(skb);
 	else
-		kt = ktime_get();
+		kt = ktime_get_real();
 
 	if (!asoc && ktime_before(bear_cookie->expiration, kt)) {
 		/*
diff -druNp --no-dereference linux-libre-4.3-gnu/net/sctp/socket.c linux-libre-4.3.4-gnu/net/sctp/socket.c
--- linux-libre-4.3-gnu/net/sctp/socket.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/sctp/socket.c	2016-01-22 23:59:37.000000000 -0500
@@ -7163,6 +7163,7 @@ void sctp_copy_sock(struct sock *newsk,
 	newsk->sk_type = sk->sk_type;
 	newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
 	newsk->sk_flags = sk->sk_flags;
+	newsk->sk_tsflags = sk->sk_tsflags;
 	newsk->sk_no_check_tx = sk->sk_no_check_tx;
 	newsk->sk_no_check_rx = sk->sk_no_check_rx;
 	newsk->sk_reuse = sk->sk_reuse;
@@ -7195,6 +7196,9 @@ void sctp_copy_sock(struct sock *newsk,
 	newinet->mc_ttl = 1;
 	newinet->mc_index = 0;
 	newinet->mc_list = NULL;
+
+	if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
+		net_enable_timestamp();
 }
 
 static inline void sctp_copy_descendant(struct sock *sk_to,
@@ -7375,6 +7379,13 @@ struct proto sctp_prot = {
 
 #if IS_ENABLED(CONFIG_IPV6)
 
+#include <net/transp_v6.h>
+static void sctp_v6_destroy_sock(struct sock *sk)
+{
+	sctp_destroy_sock(sk);
+	inet6_destroy_sock(sk);
+}
+
 struct proto sctpv6_prot = {
 	.name		= "SCTPv6",
 	.owner		= THIS_MODULE,
@@ -7384,7 +7395,7 @@ struct proto sctpv6_prot = {
 	.accept		= sctp_accept,
 	.ioctl		= sctp_ioctl,
 	.init		= sctp_init_sock,
-	.destroy	= sctp_destroy_sock,
+	.destroy	= sctp_v6_destroy_sock,
 	.shutdown	= sctp_shutdown,
 	.setsockopt	= sctp_setsockopt,
 	.getsockopt	= sctp_getsockopt,
diff -druNp --no-dereference linux-libre-4.3-gnu/net/socket.c linux-libre-4.3.4-gnu/net/socket.c
--- linux-libre-4.3-gnu/net/socket.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/socket.c	2016-01-22 23:59:37.000000000 -0500
@@ -1702,6 +1702,7 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void
 	msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
 	/* We assume all kernel code knows the size of sockaddr_storage */
 	msg.msg_namelen = 0;
+	msg.msg_iocb = NULL;
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	err = sock_recvmsg(sock, &msg, iov_iter_count(&msg.msg_iter), flags);
diff -druNp --no-dereference linux-libre-4.3-gnu/net/tipc/udp_media.c linux-libre-4.3.4-gnu/net/tipc/udp_media.c
--- linux-libre-4.3-gnu/net/tipc/udp_media.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/tipc/udp_media.c	2016-01-22 23:59:37.000000000 -0500
@@ -48,6 +48,7 @@
 #include <linux/tipc_netlink.h>
 #include "core.h"
 #include "bearer.h"
+#include "msg.h"
 
 /* IANA assigned UDP port */
 #define UDP_PORT_DEFAULT	6118
@@ -158,8 +159,11 @@ static int tipc_udp_send_msg(struct net
 	struct sk_buff *clone;
 	struct rtable *rt;
 
-	if (skb_headroom(skb) < UDP_MIN_HEADROOM)
-		pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+	if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
+		err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+		if (err)
+			return err;
+	}
 
 	clone = skb_clone(skb, GFP_ATOMIC);
 	skb_set_inner_protocol(clone, htons(ETH_P_TIPC));
@@ -222,6 +226,10 @@ static int tipc_udp_recv(struct sock *sk
 {
 	struct udp_bearer *ub;
 	struct tipc_bearer *b;
+	int usr = msg_user(buf_msg(skb));
+
+	if ((usr == LINK_PROTOCOL) || (usr == NAME_DISTRIBUTOR))
+		skb_linearize(skb);
 
 	ub = rcu_dereference_sk_user_data(sk);
 	if (!ub) {
diff -druNp --no-dereference linux-libre-4.3-gnu/net/unix/af_unix.c linux-libre-4.3.4-gnu/net/unix/af_unix.c
--- linux-libre-4.3-gnu/net/unix/af_unix.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/unix/af_unix.c	2016-01-22 23:59:37.000000000 -0500
@@ -326,6 +326,118 @@ found:
 	return s;
 }
 
+/* Support code for asymmetrically connected dgram sockets
+ *
+ * If a datagram socket is connected to a socket not itself connected
+ * to the first socket (eg, /dev/log), clients may only enqueue more
+ * messages if the present receive queue of the server socket is not
+ * "too large". This means there's a second writeability condition
+ * poll and sendmsg need to test. The dgram recv code will do a wake
+ * up on the peer_wait wait queue of a socket upon reception of a
+ * datagram which needs to be propagated to sleeping would-be writers
+ * since these might not have sent anything so far. This can't be
+ * accomplished via poll_wait because the lifetime of the server
+ * socket might be less than that of its clients if these break their
+ * association with it or if the server socket is closed while clients
+ * are still connected to it and there's no way to inform "a polling
+ * implementation" that it should let go of a certain wait queue
+ *
+ * In order to propagate a wake up, a wait_queue_t of the client
+ * socket is enqueued on the peer_wait queue of the server socket
+ * whose wake function does a wake_up on the ordinary client socket
+ * wait queue. This connection is established whenever a write (or
+ * poll for write) hit the flow control condition and broken when the
+ * association to the server socket is dissolved or after a wake up
+ * was relayed.
+ */
+
+static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags,
+				      void *key)
+{
+	struct unix_sock *u;
+	wait_queue_head_t *u_sleep;
+
+	u = container_of(q, struct unix_sock, peer_wake);
+
+	__remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
+			    q);
+	u->peer_wake.private = NULL;
+
+	/* relaying can only happen while the wq still exists */
+	u_sleep = sk_sleep(&u->sk);
+	if (u_sleep)
+		wake_up_interruptible_poll(u_sleep, key);
+
+	return 0;
+}
+
+static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
+{
+	struct unix_sock *u, *u_other;
+	int rc;
+
+	u = unix_sk(sk);
+	u_other = unix_sk(other);
+	rc = 0;
+	spin_lock(&u_other->peer_wait.lock);
+
+	if (!u->peer_wake.private) {
+		u->peer_wake.private = other;
+		__add_wait_queue(&u_other->peer_wait, &u->peer_wake);
+
+		rc = 1;
+	}
+
+	spin_unlock(&u_other->peer_wait.lock);
+	return rc;
+}
+
+static void unix_dgram_peer_wake_disconnect(struct sock *sk,
+					    struct sock *other)
+{
+	struct unix_sock *u, *u_other;
+
+	u = unix_sk(sk);
+	u_other = unix_sk(other);
+	spin_lock(&u_other->peer_wait.lock);
+
+	if (u->peer_wake.private == other) {
+		__remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
+		u->peer_wake.private = NULL;
+	}
+
+	spin_unlock(&u_other->peer_wait.lock);
+}
+
+static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
+						   struct sock *other)
+{
+	unix_dgram_peer_wake_disconnect(sk, other);
+	wake_up_interruptible_poll(sk_sleep(sk),
+				   POLLOUT |
+				   POLLWRNORM |
+				   POLLWRBAND);
+}
+
+/* preconditions:
+ *	- unix_peer(sk) == other
+ *	- association is stable
+ */
+static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
+{
+	int connected;
+
+	connected = unix_dgram_peer_wake_connect(sk, other);
+
+	if (unix_recvq_full(other))
+		return 1;
+
+	if (connected)
+		unix_dgram_peer_wake_disconnect(sk, other);
+
+	return 0;
+}
+
 static inline int unix_writable(struct sock *sk)
 {
 	return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
@@ -430,6 +542,8 @@ static void unix_release_sock(struct soc
 			skpair->sk_state_change(skpair);
 			sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
 		}
+
+		unix_dgram_peer_wake_disconnect(sk, skpair);
 		sock_put(skpair); /* It may now die */
 		unix_peer(sk) = NULL;
 	}
@@ -440,6 +554,7 @@ static void unix_release_sock(struct soc
 		if (state == TCP_LISTEN)
 			unix_release_sock(skb->sk, 1);
 		/* passed fds are erased in the kfree_skb hook	      */
+		UNIXCB(skb).consumed = skb->len;
 		kfree_skb(skb);
 	}
 
@@ -664,6 +779,7 @@ static struct sock *unix_create1(struct
 	INIT_LIST_HEAD(&u->link);
 	mutex_init(&u->readlock); /* single task reading lock */
 	init_waitqueue_head(&u->peer_wait);
+	init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
 	unix_insert_socket(unix_sockets_unbound(sk), sk);
 out:
 	if (sk == NULL)
@@ -1031,6 +1147,8 @@ restart:
 	if (unix_peer(sk)) {
 		struct sock *old_peer = unix_peer(sk);
 		unix_peer(sk) = other;
+		unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
+
 		unix_state_double_unlock(sk, other);
 
 		if (other != old_peer)
@@ -1432,6 +1550,14 @@ static int unix_scm_to_skb(struct scm_co
 	return err;
 }
 
+static bool unix_passcred_enabled(const struct socket *sock,
+				  const struct sock *other)
+{
+	return test_bit(SOCK_PASSCRED, &sock->flags) ||
+	       !other->sk_socket ||
+	       test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
+}
+
 /*
  * Some apps rely on write() giving SCM_CREDENTIALS
  * We include credentials if source or destination socket
@@ -1442,14 +1568,41 @@ static void maybe_add_creds(struct sk_bu
 {
 	if (UNIXCB(skb).pid)
 		return;
-	if (test_bit(SOCK_PASSCRED, &sock->flags) ||
-	    !other->sk_socket ||
-	    test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
+	if (unix_passcred_enabled(sock, other)) {
 		UNIXCB(skb).pid  = get_pid(task_tgid(current));
 		current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
 	}
 }
 
+static int maybe_init_creds(struct scm_cookie *scm,
+			    struct socket *socket,
+			    const struct sock *other)
+{
+	int err;
+	struct msghdr msg = { .msg_controllen = 0 };
+
+	err = scm_send(socket, &msg, scm, false);
+	if (err)
+		return err;
+
+	if (unix_passcred_enabled(socket, other)) {
+		scm->pid = get_pid(task_tgid(current));
+		current_uid_gid(&scm->creds.uid, &scm->creds.gid);
+	}
+	return err;
+}
+
+static bool unix_skb_scm_eq(struct sk_buff *skb,
+			    struct scm_cookie *scm)
+{
+	const struct unix_skb_parms *u = &UNIXCB(skb);
+
+	return u->pid == scm->pid &&
+	       uid_eq(u->uid, scm->creds.uid) &&
+	       gid_eq(u->gid, scm->creds.gid) &&
+	       unix_secdata_eq(scm, skb);
+}
+
 /*
  *	Send AF_UNIX data.
  */
@@ -1470,6 +1623,7 @@ static int unix_dgram_sendmsg(struct soc
 	struct scm_cookie scm;
 	int max_level;
 	int data_len = 0;
+	int sk_locked;
 
 	wait_for_unix_gc();
 	err = scm_send(sock, msg, &scm, false);
@@ -1548,12 +1702,14 @@ restart:
 		goto out_free;
 	}
 
+	sk_locked = 0;
 	unix_state_lock(other);
+restart_locked:
 	err = -EPERM;
 	if (!unix_may_send(sk, other))
 		goto out_unlock;
 
-	if (sock_flag(other, SOCK_DEAD)) {
+	if (unlikely(sock_flag(other, SOCK_DEAD))) {
 		/*
 		 *	Check with 1003.1g - what should
 		 *	datagram error
@@ -1561,10 +1717,14 @@ restart:
 		unix_state_unlock(other);
 		sock_put(other);
 
+		if (!sk_locked)
+			unix_state_lock(sk);
+
 		err = 0;
-		unix_state_lock(sk);
 		if (unix_peer(sk) == other) {
 			unix_peer(sk) = NULL;
+			unix_dgram_peer_wake_disconnect_wakeup(sk, other);
+
 			unix_state_unlock(sk);
 
 			unix_dgram_disconnected(sk, other);
@@ -1590,21 +1750,38 @@ restart:
 			goto out_unlock;
 	}
 
-	if (unix_peer(other) != sk && unix_recvq_full(other)) {
-		if (!timeo) {
-			err = -EAGAIN;
-			goto out_unlock;
+	if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+		if (timeo) {
+			timeo = unix_wait_for_peer(other, timeo);
+
+			err = sock_intr_errno(timeo);
+			if (signal_pending(current))
+				goto out_free;
+
+			goto restart;
 		}
 
-		timeo = unix_wait_for_peer(other, timeo);
+		if (!sk_locked) {
+			unix_state_unlock(other);
+			unix_state_double_lock(sk, other);
+		}
 
-		err = sock_intr_errno(timeo);
-		if (signal_pending(current))
-			goto out_free;
+		if (unix_peer(sk) != other ||
+		    unix_dgram_peer_wake_me(sk, other)) {
+			err = -EAGAIN;
+			sk_locked = 1;
+			goto out_unlock;
+		}
 
-		goto restart;
+		if (!sk_locked) {
+			sk_locked = 1;
+			goto restart_locked;
+		}
 	}
 
+	if (unlikely(sk_locked))
+		unix_state_unlock(sk);
+
 	if (sock_flag(other, SOCK_RCVTSTAMP))
 		__net_timestamp(skb);
 	maybe_add_creds(skb, sock, other);
@@ -1618,6 +1795,8 @@ restart:
 	return len;
 
 out_unlock:
+	if (sk_locked)
+		unix_state_unlock(sk);
 	unix_state_unlock(other);
 out_free:
 	kfree_skb(skb);
@@ -1739,8 +1918,10 @@ out_err:
 static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
 				    int offset, size_t size, int flags)
 {
-	int err = 0;
-	bool send_sigpipe = true;
+	int err;
+	bool send_sigpipe = false;
+	bool init_scm = true;
+	struct scm_cookie scm;
 	struct sock *other, *sk = socket->sk;
 	struct sk_buff *skb, *newskb = NULL, *tail = NULL;
 
@@ -1758,7 +1939,7 @@ alloc_skb:
 		newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
 					      &err, 0);
 		if (!newskb)
-			return err;
+			goto err;
 	}
 
 	/* we must acquire readlock as we modify already present
@@ -1767,12 +1948,12 @@ alloc_skb:
 	err = mutex_lock_interruptible(&unix_sk(other)->readlock);
 	if (err) {
 		err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
-		send_sigpipe = false;
 		goto err;
 	}
 
 	if (sk->sk_shutdown & SEND_SHUTDOWN) {
 		err = -EPIPE;
+		send_sigpipe = true;
 		goto err_unlock;
 	}
 
@@ -1781,23 +1962,34 @@ alloc_skb:
 	if (sock_flag(other, SOCK_DEAD) ||
 	    other->sk_shutdown & RCV_SHUTDOWN) {
 		err = -EPIPE;
+		send_sigpipe = true;
 		goto err_state_unlock;
 	}
 
+	if (init_scm) {
+		err = maybe_init_creds(&scm, socket, other);
+		if (err)
+			goto err_state_unlock;
+		init_scm = false;
+	}
+
 	skb = skb_peek_tail(&other->sk_receive_queue);
 	if (tail && tail == skb) {
 		skb = newskb;
-	} else if (!skb) {
-		if (newskb)
+	} else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
+		if (newskb) {
 			skb = newskb;
-		else
+		} else {
+			tail = skb;
 			goto alloc_skb;
+		}
 	} else if (newskb) {
 		/* this is fast path, we don't necessarily need to
 		 * call to kfree_skb even though with newskb == NULL
 		 * this - does no harm
 		 */
 		consume_skb(newskb);
+		newskb = NULL;
 	}
 
 	if (skb_append_pagefrags(skb, page, offset, size)) {
@@ -1810,14 +2002,20 @@ alloc_skb:
 	skb->truesize += size;
 	atomic_add(size, &sk->sk_wmem_alloc);
 
-	if (newskb)
+	if (newskb) {
+		err = unix_scm_to_skb(&scm, skb, false);
+		if (err)
+			goto err_state_unlock;
+		spin_lock(&other->sk_receive_queue.lock);
 		__skb_queue_tail(&other->sk_receive_queue, newskb);
+		spin_unlock(&other->sk_receive_queue.lock);
+	}
 
 	unix_state_unlock(other);
 	mutex_unlock(&unix_sk(other)->readlock);
 
 	other->sk_data_ready(other);
-
+	scm_destroy(&scm);
 	return size;
 
 err_state_unlock:
@@ -1828,6 +2026,8 @@ err:
 	kfree_skb(newskb);
 	if (send_sigpipe && !(flags & MSG_NOSIGNAL))
 		send_sig(SIGPIPE, current, 0);
+	if (!init_scm)
+		scm_destroy(&scm);
 	return err;
 }
 
@@ -2055,14 +2255,7 @@ static int unix_stream_read_generic(stru
 	/* Lock the socket to prevent queue disordering
 	 * while sleeps in memcpy_tomsg
 	 */
-	err = mutex_lock_interruptible(&u->readlock);
-	if (unlikely(err)) {
-		/* recvmsg() in non blocking mode is supposed to return -EAGAIN
-		 * sk_rcvtimeo is not honored by mutex_lock_interruptible()
-		 */
-		err = noblock ? -EAGAIN : -ERESTARTSYS;
-		goto out;
-	}
+	mutex_lock(&u->readlock);
 
 	if (flags & MSG_PEEK)
 		skip = sk_peek_offset(sk, flags);
@@ -2071,6 +2264,7 @@ static int unix_stream_read_generic(stru
 
 	do {
 		int chunk;
+		bool drop_skb;
 		struct sk_buff *skb, *last;
 
 		unix_state_lock(sk);
@@ -2105,12 +2299,12 @@ again:
 			timeo = unix_stream_data_wait(sk, timeo, last,
 						      last_len);
 
-			if (signal_pending(current) ||
-			    mutex_lock_interruptible(&u->readlock)) {
+			if (signal_pending(current)) {
 				err = sock_intr_errno(timeo);
 				goto out;
 			}
 
+			mutex_lock(&u->readlock);
 			continue;
 unlock:
 			unix_state_unlock(sk);
@@ -2130,10 +2324,7 @@ unlock:
 
 		if (check_creds) {
 			/* Never glue messages from different writers */
-			if ((UNIXCB(skb).pid  != scm.pid) ||
-			    !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
-			    !gid_eq(UNIXCB(skb).gid, scm.creds.gid) ||
-			    !unix_secdata_eq(&scm, skb))
+			if (!unix_skb_scm_eq(skb, &scm))
 				break;
 		} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
 			/* Copy credentials */
@@ -2151,7 +2342,11 @@ unlock:
 		}
 
 		chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
+		skb_get(skb);
 		chunk = state->recv_actor(skb, skip, chunk, state);
+		drop_skb = !unix_skb_len(skb);
+		/* skb is only safe to use if !drop_skb */
+		consume_skb(skb);
 		if (chunk < 0) {
 			if (copied == 0)
 				copied = -EFAULT;
@@ -2160,6 +2355,18 @@ unlock:
 		copied += chunk;
 		size -= chunk;
 
+		if (drop_skb) {
+			/* the skb was touched by a concurrent reader;
+			 * we should not expect anything from this skb
+			 * anymore and assume it invalid - we can be
+			 * sure it was dropped from the socket queue
+			 *
+			 * let's report a short read
+			 */
+			err = 0;
+			break;
+		}
+
 		/* Mark read part of skb as used */
 		if (!(flags & MSG_PEEK)) {
 			UNIXCB(skb).consumed += chunk;
@@ -2453,14 +2660,16 @@ static unsigned int unix_dgram_poll(stru
 		return mask;
 
 	writable = unix_writable(sk);
-	other = unix_peer_get(sk);
-	if (other) {
-		if (unix_peer(other) != sk) {
-			sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
-			if (unix_recvq_full(other))
-				writable = 0;
-		}
-		sock_put(other);
+	if (writable) {
+		unix_state_lock(sk);
+
+		other = unix_peer(sk);
+		if (other && unix_peer(other) != sk &&
+		    unix_recvq_full(other) &&
+		    unix_dgram_peer_wake_me(sk, other))
+			writable = 0;
+
+		unix_state_unlock(sk);
 	}
 
 	if (writable)
diff -druNp --no-dereference linux-libre-4.3-gnu/net/wireless/nl80211.c linux-libre-4.3.4-gnu/net/wireless/nl80211.c
--- linux-libre-4.3-gnu/net/wireless/nl80211.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/net/wireless/nl80211.c	2016-01-22 23:59:37.000000000 -0500
@@ -3409,12 +3409,6 @@ static int nl80211_start_ap(struct sk_bu
 					   wdev->iftype))
 		return -EINVAL;
 
-	if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
-		params.acl = parse_acl_data(&rdev->wiphy, info);
-		if (IS_ERR(params.acl))
-			return PTR_ERR(params.acl);
-	}
-
 	if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
 		params.smps_mode =
 			nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
@@ -3438,6 +3432,12 @@ static int nl80211_start_ap(struct sk_bu
 		params.smps_mode = NL80211_SMPS_OFF;
 	}
 
+	if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
+		params.acl = parse_acl_data(&rdev->wiphy, info);
+		if (IS_ERR(params.acl))
+			return PTR_ERR(params.acl);
+	}
+
 	wdev_lock(wdev);
 	err = rdev_start_ap(rdev, dev, &params);
 	if (!err) {
diff -druNp --no-dereference linux-libre-4.3-gnu/security/keys/keyctl.c linux-libre-4.3.4-gnu/security/keys/keyctl.c
--- linux-libre-4.3-gnu/security/keys/keyctl.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/security/keys/keyctl.c	2016-01-22 23:59:37.000000000 -0500
@@ -757,16 +757,16 @@ long keyctl_read_key(key_serial_t keyid,
 
 	/* the key is probably readable - now try to read it */
 can_read_key:
-	ret = key_validate(key);
-	if (ret == 0) {
-		ret = -EOPNOTSUPP;
-		if (key->type->read) {
-			/* read the data with the semaphore held (since we
-			 * might sleep) */
-			down_read(&key->sem);
+	ret = -EOPNOTSUPP;
+	if (key->type->read) {
+		/* Read the data with the semaphore held (since we might sleep)
+		 * to protect against the key being updated or revoked.
+		 */
+		down_read(&key->sem);
+		ret = key_validate(key);
+		if (ret == 0)
 			ret = key->type->read(key, buffer, buflen);
-			up_read(&key->sem);
-		}
+		up_read(&key->sem);
 	}
 
 error2:
diff -druNp --no-dereference linux-libre-4.3-gnu/security/keys/process_keys.c linux-libre-4.3.4-gnu/security/keys/process_keys.c
--- linux-libre-4.3-gnu/security/keys/process_keys.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/security/keys/process_keys.c	2016-01-22 23:59:37.000000000 -0500
@@ -794,6 +794,7 @@ long join_session_keyring(const char *na
 		ret = PTR_ERR(keyring);
 		goto error2;
 	} else if (keyring == new->session_keyring) {
+		key_put(keyring);
 		ret = 0;
 		goto error2;
 	}
diff -druNp --no-dereference linux-libre-4.3-gnu/sound/pci/hda/patch_hdmi.c linux-libre-4.3.4-gnu/sound/pci/hda/patch_hdmi.c
--- linux-libre-4.3-gnu/sound/pci/hda/patch_hdmi.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/sound/pci/hda/patch_hdmi.c	2016-01-22 23:59:37.000000000 -0500
@@ -50,8 +50,9 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't
 #define is_haswell(codec)  ((codec)->core.vendor_id == 0x80862807)
 #define is_broadwell(codec)    ((codec)->core.vendor_id == 0x80862808)
 #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
+#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
 #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
-					|| is_skylake(codec))
+				|| is_skylake(codec) || is_broxton(codec))
 
 #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
 #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
diff -druNp --no-dereference linux-libre-4.3-gnu/sound/pci/Kconfig linux-libre-4.3.4-gnu/sound/pci/Kconfig
--- linux-libre-4.3-gnu/sound/pci/Kconfig	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/sound/pci/Kconfig	2016-01-22 23:59:37.000000000 -0500
@@ -25,7 +25,7 @@ config SND_ALS300
 	select SND_PCM
 	select SND_AC97_CODEC
 	select SND_OPL3_LIB
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
 
@@ -50,7 +50,7 @@ config SND_ALI5451
 	tristate "ALi M5451 PCI Audio Controller"
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for the integrated AC97 sound
 	  device on motherboards using the ALi M5451 Audio Controller
@@ -155,7 +155,7 @@ config SND_AZT3328
 	select SND_PCM
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for Aztech AZF3328 (PCI168)
 	  soundcards.
@@ -463,7 +463,7 @@ config SND_EMU10K1
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y to include support for Sound Blaster PCI 512, Live!,
 	  Audigy and E-mu APS (partially supported) soundcards.
@@ -479,7 +479,7 @@ config SND_EMU10K1X
 	tristate "Emu10k1X (Dell OEM Version)"
 	select SND_AC97_CODEC
 	select SND_RAWMIDI
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for the Dell OEM version of the
 	  Sound Blaster Live!.
@@ -513,7 +513,7 @@ config SND_ES1938
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on ESS Solo-1
 	  (ES1938, ES1946, ES1969) chips.
@@ -525,7 +525,7 @@ config SND_ES1968
 	tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on ESS Maestro
 	  1/2/2E chips.
@@ -612,7 +612,7 @@ config SND_ICE1712
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	select BITREVERSE
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on the
 	  ICE1712 (Envy24) chip.
@@ -700,7 +700,7 @@ config SND_LX6464ES
 config SND_MAESTRO3
 	tristate "ESS Allegro/Maestro3"
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on ESS Maestro 3
 	  (Allegro) chips.
@@ -806,7 +806,7 @@ config SND_SIS7019
 	tristate "SiS 7019 Audio Accelerator"
 	depends on X86_32
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for the SiS 7019 Audio Accelerator.
 
@@ -818,7 +818,7 @@ config SND_SONICVIBES
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on the S3
 	  SonicVibes chip.
@@ -830,7 +830,7 @@ config SND_TRIDENT
 	tristate "Trident 4D-Wave DX/NX; SiS 7018"
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
-	select ZONE_DMA
+	depends on ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on Trident
 	  4D-Wave DX/NX or SiS 7018 chips.
diff -druNp --no-dereference linux-libre-4.3-gnu/sound/usb/midi.c linux-libre-4.3.4-gnu/sound/usb/midi.c
--- linux-libre-4.3-gnu/sound/usb/midi.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/sound/usb/midi.c	2016-01-22 23:59:37.000000000 -0500
@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
 		u8 running_status_length;
 	} ports[0x10];
 	u8 seen_f5;
+	bool in_sysex;
+	u8 last_cin;
 	u8 error_resubmit;
 	int current_port;
 };
@@ -468,6 +470,39 @@ static void snd_usbmidi_maudio_broken_ru
 }
 
 /*
+ * QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4
+ * but the previously seen CIN, but still with three data bytes.
+ */
+static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
+				     uint8_t *buffer, int buffer_length)
+{
+	unsigned int i, cin, length;
+
+	for (i = 0; i + 3 < buffer_length; i += 4) {
+		if (buffer[i] == 0 && i > 0)
+			break;
+		cin = buffer[i] & 0x0f;
+		if (ep->in_sysex &&
+		    cin == ep->last_cin &&
+		    (buffer[i + 1 + (cin == 0x6)] & 0x80) == 0)
+			cin = 0x4;
+#if 0
+		if (buffer[i + 1] == 0x90) {
+			/*
+			 * Either a corrupted running status or a real note-on
+			 * message; impossible to detect reliably.
+			 */
+		}
+#endif
+		length = snd_usbmidi_cin_length[cin];
+		snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length);
+		ep->in_sysex = cin == 0x4;
+		if (!ep->in_sysex)
+			ep->last_cin = cin;
+	}
+}
+
+/*
  * CME protocol: like the standard protocol, but SysEx commands are sent as a
  * single USB packet preceded by a 0x0F byte.
  */
@@ -660,6 +695,12 @@ static struct usb_protocol_ops snd_usbmi
 	.output_packet = snd_usbmidi_output_standard_packet,
 };
 
+static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
+	.input = ch345_broken_sysex_input,
+	.output = snd_usbmidi_standard_output,
+	.output_packet = snd_usbmidi_output_standard_packet,
+};
+
 /*
  * AKAI MPD16 protocol:
  *
@@ -1341,6 +1382,7 @@ static int snd_usbmidi_out_endpoint_crea
 		 * Various chips declare a packet size larger than 4 bytes, but
 		 * do not actually work with larger packets:
 		 */
+	case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
 	case USB_ID(0x0a92, 0x1020): /* ESI M4U */
 	case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
 	case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
@@ -2375,6 +2417,10 @@ int snd_usbmidi_create(struct snd_card *
 
 		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
 		break;
+	case QUIRK_MIDI_CH345:
+		umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops;
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
 	default:
 		dev_err(&umidi->dev->dev, "invalid quirk type %d\n",
 			quirk->type);
diff -druNp --no-dereference linux-libre-4.3-gnu/sound/usb/quirks.c linux-libre-4.3.4-gnu/sound/usb/quirks.c
--- linux-libre-4.3-gnu/sound/usb/quirks.c	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/sound/usb/quirks.c	2016-01-22 23:59:37.000000000 -0500
@@ -535,6 +535,7 @@ int snd_usb_create_quirk(struct snd_usb_
 		[QUIRK_MIDI_CME] = create_any_midi_quirk,
 		[QUIRK_MIDI_AKAI] = create_any_midi_quirk,
 		[QUIRK_MIDI_FTDI] = create_any_midi_quirk,
+		[QUIRK_MIDI_CH345] = create_any_midi_quirk,
 		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
 		[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
 		[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
@@ -1271,6 +1272,7 @@ u64 snd_usb_interface_dsd_format_quirks(
 	case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */
 	case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */
 	case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */
+	case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */
 		if (fp->altsetting == 3)
 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
 		break;
diff -druNp --no-dereference linux-libre-4.3-gnu/sound/usb/quirks-table.h linux-libre-4.3.4-gnu/sound/usb/quirks-table.h
--- linux-libre-4.3-gnu/sound/usb/quirks-table.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/sound/usb/quirks-table.h	2016-01-22 23:59:37.000000000 -0500
@@ -2820,6 +2820,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.idProduct = 0x1020,
 },
 
+/* QinHeng devices */
+{
+	USB_DEVICE(0x1a86, 0x752d),
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.vendor_name = "QinHeng",
+		.product_name = "CH345",
+		.ifnum = 1,
+		.type = QUIRK_MIDI_CH345
+	}
+},
+
 /* KeithMcMillen Stringport */
 {
 	USB_DEVICE(0x1f38, 0x0001),
diff -druNp --no-dereference linux-libre-4.3-gnu/sound/usb/usbaudio.h linux-libre-4.3.4-gnu/sound/usb/usbaudio.h
--- linux-libre-4.3-gnu/sound/usb/usbaudio.h	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/sound/usb/usbaudio.h	2016-01-22 23:59:37.000000000 -0500
@@ -94,6 +94,7 @@ enum quirk_type {
 	QUIRK_MIDI_AKAI,
 	QUIRK_MIDI_US122L,
 	QUIRK_MIDI_FTDI,
+	QUIRK_MIDI_CH345,
 	QUIRK_AUDIO_STANDARD_INTERFACE,
 	QUIRK_AUDIO_FIXED_ENDPOINT,
 	QUIRK_AUDIO_EDIROL_UAXX,
diff -druNp --no-dereference linux-libre-4.3-gnu/tools/net/Makefile linux-libre-4.3.4-gnu/tools/net/Makefile
--- linux-libre-4.3-gnu/tools/net/Makefile	2015-11-01 19:05:25.000000000 -0500
+++ linux-libre-4.3.4-gnu/tools/net/Makefile	2016-01-22 23:59:37.000000000 -0500
@@ -4,6 +4,9 @@ CC = gcc
 LEX = flex
 YACC = bison
 
+CFLAGS += -Wall -O2
+CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
+
 %.yacc.c: %.y
 	$(YACC) -o $@ -d $<
 
@@ -12,15 +15,13 @@ YACC = bison
 
 all : bpf_jit_disasm bpf_dbg bpf_asm
 
-bpf_jit_disasm : CFLAGS = -Wall -O2 -DPACKAGE='bpf_jit_disasm'
+bpf_jit_disasm : CFLAGS += -DPACKAGE='bpf_jit_disasm'
 bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl
 bpf_jit_disasm : bpf_jit_disasm.o
 
-bpf_dbg : CFLAGS = -Wall -O2
 bpf_dbg : LDLIBS = -lreadline
 bpf_dbg : bpf_dbg.o
 
-bpf_asm : CFLAGS = -Wall -O2 -I.
 bpf_asm : LDLIBS =
 bpf_asm : bpf_asm.o bpf_exp.yacc.o bpf_exp.lex.o
 bpf_exp.lex.o : bpf_exp.yacc.c
