diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/alpha/kernel/console.c linux-libre-4.1.52-gnu/arch/alpha/kernel/console.c
--- linux-libre-4.1.51-gnu/arch/alpha/kernel/console.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/alpha/kernel/console.c	2018-05-27 22:26:45.000000000 -0400
@@ -20,6 +20,7 @@
 struct pci_controller *pci_vga_hose;
 static struct resource alpha_vga = {
 	.name	= "alpha-vga+",
+	.flags	= IORESOURCE_IO,
 	.start	= 0x3C0,
 	.end	= 0x3DF
 };
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/am335x-pepper.dts linux-libre-4.1.52-gnu/arch/arm/boot/dts/am335x-pepper.dts
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/am335x-pepper.dts	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/am335x-pepper.dts	2018-05-27 22:26:45.000000000 -0400
@@ -138,7 +138,7 @@
 &audio_codec {
 	status = "okay";
 
-	gpio-reset = <&gpio1 16 GPIO_ACTIVE_LOW>;
+	reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
 	AVDD-supply = <&ldo3_reg>;
 	IOVDD-supply = <&ldo3_reg>;
 	DRVDD-supply = <&ldo3_reg>;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/am57xx-beagle-x15.dts linux-libre-4.1.52-gnu/arch/arm/boot/dts/am57xx-beagle-x15.dts
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/am57xx-beagle-x15.dts	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/am57xx-beagle-x15.dts	2018-05-27 22:26:45.000000000 -0400
@@ -299,6 +299,7 @@
 		interrupt-controller;
 
 		ti,system-power-controller;
+		ti,palmas-override-powerhold;
 
 		tps659038_pmic {
 			compatible = "ti,tps659038-pmic";
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/at91sam9g25.dtsi linux-libre-4.1.52-gnu/arch/arm/boot/dts/at91sam9g25.dtsi
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/at91sam9g25.dtsi	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/at91sam9g25.dtsi	2018-05-27 22:26:45.000000000 -0400
@@ -21,7 +21,7 @@
 				atmel,mux-mask = <
 				      /*    A         B          C     */
 				       0xffffffff 0xffe0399f 0xc000001c  /* pioA */
-				       0x0007ffff 0x8000fe3f 0x00000000  /* pioB */
+				       0x0007ffff 0x00047e3f 0x00000000  /* pioB */
 				       0x80000000 0x07c0ffff 0xb83fffff  /* pioC */
 				       0x003fffff 0x003f8000 0x00000000  /* pioD */
 				      >;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/dra7-evm.dts linux-libre-4.1.52-gnu/arch/arm/boot/dts/dra7-evm.dts
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/dra7-evm.dts	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/dra7-evm.dts	2018-05-27 22:26:45.000000000 -0400
@@ -285,6 +285,8 @@
 	tps659038: tps659038@58 {
 		compatible = "ti,tps659038";
 		reg = <0x58>;
+		ti,palmas-override-powerhold;
+		ti,system-power-controller;
 
 		tps659038_pmic {
 			compatible = "ti,tps659038-pmic";
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/imx6qdl-wandboard.dtsi linux-libre-4.1.52-gnu/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/imx6qdl-wandboard.dtsi	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/imx6qdl-wandboard.dtsi	2018-05-27 22:26:45.000000000 -0400
@@ -88,6 +88,7 @@
 		clocks = <&clks 201>;
 		VDDA-supply = <&reg_2p5v>;
 		VDDIO-supply = <&reg_3p3v>;
+		lrclk-strength = <3>;
 	};
 };
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/ls1021a.dtsi linux-libre-4.1.52-gnu/arch/arm/boot/dts/ls1021a.dtsi
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/ls1021a.dtsi	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/ls1021a.dtsi	2018-05-27 22:26:45.000000000 -0400
@@ -128,7 +128,7 @@
 		};
 
 		esdhc: esdhc@1560000 {
-			compatible = "fsl,esdhc";
+			compatible = "fsl,ls1021a-esdhc", "fsl,esdhc";
 			reg = <0x0 0x1560000 0x0 0x10000>;
 			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
 			clock-frequency = <0>;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/moxart.dtsi linux-libre-4.1.52-gnu/arch/arm/boot/dts/moxart.dtsi
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/moxart.dtsi	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/moxart.dtsi	2018-05-27 22:26:45.000000000 -0400
@@ -6,6 +6,7 @@
  */
 
 /include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	compatible = "moxa,moxart";
@@ -36,8 +37,8 @@
 		ranges;
 
 		intc: interrupt-controller@98800000 {
-			compatible = "moxa,moxart-ic";
-			reg = <0x98800000 0x38>;
+			compatible = "moxa,moxart-ic", "faraday,ftintc010";
+			reg = <0x98800000 0x100>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			interrupt-mask = <0x00080000>;
@@ -59,7 +60,7 @@
 		timer: timer@98400000 {
 			compatible = "moxa,moxart-timer";
 			reg = <0x98400000 0x42>;
-			interrupts = <19 1>;
+			interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
 			clocks = <&clk_apb>;
 		};
 
@@ -80,7 +81,7 @@
 		dma: dma@90500000 {
 			compatible = "moxa,moxart-dma";
 			reg = <0x90500080 0x40>;
-			interrupts = <24 0>;
+			interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
 			#dma-cells = <1>;
 		};
 
@@ -93,7 +94,7 @@
 		sdhci: sdhci@98e00000 {
 			compatible = "moxa,moxart-sdhci";
 			reg = <0x98e00000 0x5C>;
-			interrupts = <5 0>;
+			interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clk_apb>;
 			dmas =  <&dma 5>,
 				<&dma 5>;
@@ -120,7 +121,7 @@
 		mac0: mac@90900000 {
 			compatible = "moxa,moxart-mac";
 			reg = <0x90900000 0x90>;
-			interrupts = <25 0>;
+			interrupts = <25 IRQ_TYPE_LEVEL_HIGH>;
 			phy-handle = <&ethphy0>;
 			phy-mode = "mii";
 			status = "disabled";
@@ -129,7 +130,7 @@
 		mac1: mac@92000000 {
 			compatible = "moxa,moxart-mac";
 			reg = <0x92000000 0x90>;
-			interrupts = <27 0>;
+			interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
 			phy-handle = <&ethphy1>;
 			phy-mode = "mii";
 			status = "disabled";
@@ -138,7 +139,7 @@
 		uart0: uart@98200000 {
 			compatible = "ns16550a";
 			reg = <0x98200000 0x20>;
-			interrupts = <31 8>;
+			interrupts = <31 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
 			clock-frequency = <14745600>;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/moxart-uc7112lx.dts linux-libre-4.1.52-gnu/arch/arm/boot/dts/moxart-uc7112lx.dts
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/moxart-uc7112lx.dts	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/moxart-uc7112lx.dts	2018-05-27 22:26:45.000000000 -0400
@@ -6,7 +6,7 @@
  */
 
 /dts-v1/;
-/include/ "moxart.dtsi"
+#include "moxart.dtsi"
 
 / {
 	model = "MOXA UC-7112-LX";
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/omap3-n900.dts linux-libre-4.1.52-gnu/arch/arm/boot/dts/omap3-n900.dts
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/omap3-n900.dts	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/omap3-n900.dts	2018-05-27 22:26:45.000000000 -0400
@@ -488,7 +488,7 @@
 	tlv320aic3x: tlv320aic3x@18 {
 		compatible = "ti,tlv320aic3x";
 		reg = <0x18>;
-		gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */
+		reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* 60 */
 		ai3x-gpio-func = <
 			0 /* AIC3X_GPIO1_FUNC_DISABLED */
 			5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */
@@ -505,7 +505,7 @@
 	tlv320aic3x_aux: tlv320aic3x@19 {
 		compatible = "ti,tlv320aic3x";
 		reg = <0x19>;
-		gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */
+		reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* 60 */
 
 		AVDD-supply = <&vmmc2>;
 		DRVDD-supply = <&vmmc2>;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/r8a7790.dtsi linux-libre-4.1.52-gnu/arch/arm/boot/dts/r8a7790.dtsi
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/r8a7790.dtsi	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/r8a7790.dtsi	2018-05-27 22:26:45.000000000 -0400
@@ -1227,8 +1227,11 @@
 			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
 			reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>;
 			clocks = <&p_clk>,
-				<&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
-				<&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+				<&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>,
 				<&p_clk>,
 				<&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
 				<&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/r8a7791.dtsi linux-libre-4.1.52-gnu/arch/arm/boot/dts/r8a7791.dtsi
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/r8a7791.dtsi	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/r8a7791.dtsi	2018-05-27 22:26:45.000000000 -0400
@@ -1232,8 +1232,11 @@
 			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
 			reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>;
 			clocks = <&p_clk>,
-				<&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
-				<&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+				<&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>,
+				<&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>,
 				<&p_clk>,
 				<&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
 				<&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/boot/dts/r8a7791-koelsch.dts linux-libre-4.1.52-gnu/arch/arm/boot/dts/r8a7791-koelsch.dts
--- linux-libre-4.1.51-gnu/arch/arm/boot/dts/r8a7791-koelsch.dts	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/boot/dts/r8a7791-koelsch.dts	2018-05-27 22:26:45.000000000 -0400
@@ -273,7 +273,7 @@
 	x2_clk: x2-clock {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <148500000>;
+		clock-frequency = <74250000>;
 	};
 
 	x13_clk: x13-clock {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/include/asm/xen/events.h linux-libre-4.1.52-gnu/arch/arm/include/asm/xen/events.h
--- linux-libre-4.1.51-gnu/arch/arm/include/asm/xen/events.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/include/asm/xen/events.h	2018-05-27 22:26:45.000000000 -0400
@@ -16,7 +16,7 @@ static inline int xen_irqs_disabled(stru
 	return raw_irqs_disabled_flags(regs->ARM_cpsr);
 }
 
-#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr),	\
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((long long*)(ptr),\
 							    atomic64_t,	\
 							    counter), (val))
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/kernel/ftrace.c linux-libre-4.1.52-gnu/arch/arm/kernel/ftrace.c
--- linux-libre-4.1.51-gnu/arch/arm/kernel/ftrace.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/kernel/ftrace.c	2018-05-27 22:26:45.000000000 -0400
@@ -29,11 +29,6 @@
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-#ifdef CONFIG_OLD_MCOUNT
-#define OLD_MCOUNT_ADDR	((unsigned long) mcount)
-#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
-
-#define	OLD_NOP		0xe1a00000	/* mov r0, r0 */
 
 static int __ftrace_modify_code(void *data)
 {
@@ -51,6 +46,12 @@ void arch_ftrace_update_code(int command
 	stop_machine(__ftrace_modify_code, &command, NULL);
 }
 
+#ifdef CONFIG_OLD_MCOUNT
+#define OLD_MCOUNT_ADDR	((unsigned long) mcount)
+#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
+
+#define	OLD_NOP		0xe1a00000	/* mov r0, r0 */
+
 static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
 {
 	return rec->arch.old_mcount ? OLD_NOP : NOP;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/kernel/perf_event.c linux-libre-4.1.52-gnu/arch/arm/kernel/perf_event.c
--- linux-libre-4.1.51-gnu/arch/arm/kernel/perf_event.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/kernel/perf_event.c	2018-05-27 22:26:45.000000000 -0400
@@ -311,10 +311,16 @@ validate_group(struct perf_event *event)
 	return 0;
 }
 
+static struct arm_pmu_platdata *armpmu_get_platdata(struct arm_pmu *armpmu)
+{
+	struct platform_device *pdev = armpmu->plat_device;
+
+	return pdev ? dev_get_platdata(&pdev->dev) : NULL;
+}
+
 static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
 {
 	struct arm_pmu *armpmu;
-	struct platform_device *plat_device;
 	struct arm_pmu_platdata *plat;
 	int ret;
 	u64 start_clock, finish_clock;
@@ -326,8 +332,8 @@ static irqreturn_t armpmu_dispatch_irq(i
 	 * dereference.
 	 */
 	armpmu = *(void **)dev;
-	plat_device = armpmu->plat_device;
-	plat = dev_get_platdata(&plat_device->dev);
+
+	plat = armpmu_get_platdata(armpmu);
 
 	start_clock = sched_clock();
 	if (plat && plat->handle_irq)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/mach-davinci/devices-da8xx.c linux-libre-4.1.52-gnu/arch/arm/mach-davinci/devices-da8xx.c
--- linux-libre-4.1.51-gnu/arch/arm/mach-davinci/devices-da8xx.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/mach-davinci/devices-da8xx.c	2018-05-27 22:26:45.000000000 -0400
@@ -827,6 +827,8 @@ static struct platform_device da8xx_dsp
 	.resource	= da8xx_rproc_resources,
 };
 
+static bool rproc_mem_inited __initdata;
+
 #if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC)
 
 static phys_addr_t rproc_base __initdata;
@@ -865,6 +867,8 @@ void __init da8xx_rproc_reserve_cma(void
 	ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0);
 	if (ret)
 		pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret);
+	else
+		rproc_mem_inited = true;
 }
 
 #else
@@ -879,6 +883,12 @@ int __init da8xx_register_rproc(void)
 {
 	int ret;
 
+	if (!rproc_mem_inited) {
+		pr_warn("%s: memory not reserved for DSP, not registering DSP device\n",
+			__func__);
+		return -ENOMEM;
+	}
+
 	ret = platform_device_register(&da8xx_dsp);
 	if (ret)
 		pr_err("%s: can't register DSP device: %d\n", __func__, ret);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/mach-imx/clk-imx6q.c linux-libre-4.1.52-gnu/arch/arm/mach-imx/clk-imx6q.c
--- linux-libre-4.1.51-gnu/arch/arm/mach-imx/clk-imx6q.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/mach-imx/clk-imx6q.c	2018-05-27 22:26:45.000000000 -0400
@@ -402,7 +402,7 @@ static void __init imx6q_clocks_init(str
 		clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
 	clk[IMX6QDL_CLK_GPU3D_CORE]   = imx_clk_gate2("gpu3d_core",    "gpu3d_core_podf",   base + 0x6c, 26);
 	clk[IMX6QDL_CLK_HDMI_IAHB]    = imx_clk_gate2("hdmi_iahb",     "ahb",               base + 0x70, 0);
-	clk[IMX6QDL_CLK_HDMI_ISFR]    = imx_clk_gate2("hdmi_isfr",     "video_27m",         base + 0x70, 4);
+	clk[IMX6QDL_CLK_HDMI_ISFR]    = imx_clk_gate2("hdmi_isfr",     "mipi_core_cfg",     base + 0x70, 4);
 	clk[IMX6QDL_CLK_I2C1]         = imx_clk_gate2("i2c1",          "ipg_per",           base + 0x70, 6);
 	clk[IMX6QDL_CLK_I2C2]         = imx_clk_gate2("i2c2",          "ipg_per",           base + 0x70, 8);
 	clk[IMX6QDL_CLK_I2C3]         = imx_clk_gate2("i2c3",          "ipg_per",           base + 0x70, 10);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c linux-libre-4.1.52-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c
--- linux-libre-4.1.51-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm/mach-omap2/clockdomains7xx_data.c	2018-05-27 22:26:45.000000000 -0400
@@ -524,7 +524,7 @@ static struct clockdomain pcie_7xx_clkdm
 	.dep_bit	  = DRA7XX_PCIE_STATDEP_SHIFT,
 	.wkdep_srcs	  = pcie_wkup_sleep_deps,
 	.sleepdep_srcs	  = pcie_wkup_sleep_deps,
-	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.flags		  = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain atl_7xx_clkdm = {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/arm64/include/asm/futex.h linux-libre-4.1.52-gnu/arch/arm64/include/asm/futex.h
--- linux-libre-4.1.51-gnu/arch/arm64/include/asm/futex.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/arm64/include/asm/futex.h	2018-05-27 22:26:45.000000000 -0400
@@ -44,16 +44,16 @@
 	: "memory")
 
 static inline int
-futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
+futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)
 {
 	int op = (encoded_op >> 28) & 7;
 	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
+	int oparg = (int)(encoded_op << 8) >> 20;
+	int cmparg = (int)(encoded_op << 20) >> 20;
 	int oldval = 0, ret, tmp;
 
 	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
+		oparg = 1U << (oparg & 0x1f);
 
 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
 		return -EFAULT;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/frv/include/asm/timex.h linux-libre-4.1.52-gnu/arch/frv/include/asm/timex.h
--- linux-libre-4.1.51-gnu/arch/frv/include/asm/timex.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/frv/include/asm/timex.h	2018-05-27 22:26:45.000000000 -0400
@@ -16,5 +16,11 @@ static inline cycles_t get_cycles(void)
 #define vxtime_lock()		do {} while (0)
 #define vxtime_unlock()		do {} while (0)
 
+/* This attribute is used in include/linux/jiffies.h alongside with
+ * __cacheline_aligned_in_smp. It is assumed that __cacheline_aligned_in_smp
+ * for frv does not contain another section specification.
+ */
+#define __jiffy_arch_data	__attribute__((__section__(".data")))
+
 #endif
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/ia64/kernel/module.c linux-libre-4.1.52-gnu/arch/ia64/kernel/module.c
--- linux-libre-4.1.51-gnu/arch/ia64/kernel/module.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/ia64/kernel/module.c	2018-05-27 22:26:45.000000000 -0400
@@ -153,7 +153,7 @@ slot (const struct insn *insn)
 static int
 apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
 {
-	if (slot(insn) != 2) {
+	if (slot(insn) != 1 && slot(insn) != 2) {
 		printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
 		       mod->name, slot(insn));
 		return 0;
@@ -165,7 +165,7 @@ apply_imm64 (struct module *mod, struct
 static int
 apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
 {
-	if (slot(insn) != 2) {
+	if (slot(insn) != 1 && slot(insn) != 2) {
 		printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
 		       mod->name, slot(insn));
 		return 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/mips/include/asm/kprobes.h linux-libre-4.1.52-gnu/arch/mips/include/asm/kprobes.h
--- linux-libre-4.1.51-gnu/arch/mips/include/asm/kprobes.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/mips/include/asm/kprobes.h	2018-05-27 22:26:45.000000000 -0400
@@ -40,7 +40,8 @@ typedef union mips_instruction kprobe_op
 
 #define flush_insn_slot(p)						\
 do {									\
-	flush_icache_range((unsigned long)p->addr,			\
+	if (p->addr)							\
+		flush_icache_range((unsigned long)p->addr,		\
 			   (unsigned long)p->addr +			\
 			   (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));	\
 } while (0)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c linux-libre-4.1.52-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c
--- linux-libre-4.1.51-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/mips/kernel/mips-r2-to-r6-emul.c	2018-05-27 22:26:45.000000000 -0400
@@ -1096,10 +1096,20 @@ repeat:
 		}
 		break;
 
-	case beql_op:
-	case bnel_op:
 	case blezl_op:
 	case bgtzl_op:
+		/*
+		 * For BLEZL and BGTZL, rt field must be set to 0. If this
+		 * is not the case, this may be an encoding of a MIPS R6
+		 * instruction, so return to CPU execution if this occurs
+		 */
+		if (MIPSInst_RT(inst)) {
+			err = SIGILL;
+			break;
+		}
+		/* fall through */
+	case beql_op:
+	case bnel_op:
 		if (delay_slot(regs)) {
 			err = SIGILL;
 			break;
@@ -2329,6 +2339,8 @@ static int mipsr2_stats_clear_show(struc
 	__this_cpu_write((mipsr2bremustats).bgezl, 0);
 	__this_cpu_write((mipsr2bremustats).bltzll, 0);
 	__this_cpu_write((mipsr2bremustats).bgezll, 0);
+	__this_cpu_write((mipsr2bremustats).bltzall, 0);
+	__this_cpu_write((mipsr2bremustats).bgezall, 0);
 	__this_cpu_write((mipsr2bremustats).bltzal, 0);
 	__this_cpu_write((mipsr2bremustats).bgezal, 0);
 	__this_cpu_write((mipsr2bremustats).beql, 0);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/mips/lib/memset.S linux-libre-4.1.52-gnu/arch/mips/lib/memset.S
--- linux-libre-4.1.51-gnu/arch/mips/lib/memset.S	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/mips/lib/memset.S	2018-05-27 22:26:45.000000000 -0400
@@ -218,7 +218,7 @@
 1:	PTR_ADDIU	a0, 1			/* fill bytewise */
 	R10KCBARRIER(0(ra))
 	bne		t1, a0, 1b
-	sb		a1, -1(a0)
+	 EX(sb, a1, -1(a0), .Lsmall_fixup\@)
 
 2:	jr		ra			/* done */
 	move		a2, zero
@@ -249,13 +249,18 @@
 	PTR_L		t0, TI_TASK($28)
 	andi		a2, STORMASK
 	LONG_L		t0, THREAD_BUADDR(t0)
-	LONG_ADDU	a2, t1
+	LONG_ADDU	a2, a0
 	jr		ra
 	LONG_SUBU	a2, t0
 
 .Llast_fixup\@:
 	jr		ra
-	andi		v1, a2, STORMASK
+	 nop
+
+.Lsmall_fixup\@:
+	PTR_SUBU	a2, t1, a0
+	jr		ra
+	 PTR_ADDIU	a2, 1
 
 	.endm
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/mips/mm/pgtable-32.c linux-libre-4.1.52-gnu/arch/mips/mm/pgtable-32.c
--- linux-libre-4.1.51-gnu/arch/mips/mm/pgtable-32.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/mips/mm/pgtable-32.c	2018-05-27 22:26:45.000000000 -0400
@@ -51,15 +51,15 @@ void __init pagetable_init(void)
 	/*
 	 * Fixed mappings:
 	 */
-	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
+	fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
 
 #ifdef CONFIG_HIGHMEM
 	/*
 	 * Permanent kmaps:
 	 */
 	vaddr = PKMAP_BASE;
-	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+	fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
 
 	pgd = swapper_pg_dir + __pgd_offset(vaddr);
 	pud = pud_offset(pgd, vaddr);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/mips/net/bpf_jit.c linux-libre-4.1.52-gnu/arch/mips/net/bpf_jit.c
--- linux-libre-4.1.51-gnu/arch/mips/net/bpf_jit.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/mips/net/bpf_jit.c	2018-05-27 22:26:45.000000000 -0400
@@ -562,7 +562,8 @@ static void save_bpf_jit_regs(struct jit
 	u32 sflags, tmp_flags;
 
 	/* Adjust the stack pointer */
-	emit_stack_offset(-align_sp(offset), ctx);
+	if (offset)
+		emit_stack_offset(-align_sp(offset), ctx);
 
 	if (ctx->flags & SEEN_CALL) {
 		/* Argument save area */
@@ -641,7 +642,8 @@ static void restore_bpf_jit_regs(struct
 		emit_load_stack_reg(r_ra, r_sp, real_off, ctx);
 
 	/* Restore the sp and discard the scrach memory */
-	emit_stack_offset(align_sp(offset), ctx);
+	if (offset)
+		emit_stack_offset(align_sp(offset), ctx);
 }
 
 static unsigned int get_stack_depth(struct jit_ctx *ctx)
@@ -685,8 +687,14 @@ static void build_prologue(struct jit_ct
 	if (ctx->flags & SEEN_X)
 		emit_jit_reg_move(r_X, r_zero, ctx);
 
-	/* Do not leak kernel data to userspace */
-	if (bpf_needs_clear_a(&ctx->skf->insns[0]))
+	/*
+	 * Do not leak kernel data to userspace, we only need to clear
+	 * r_A if it is ever used.  In fact if it is never used, we
+	 * will not save/restore it, so clearing it in this case would
+	 * corrupt the state of the caller.
+	 */
+	if (bpf_needs_clear_a(&ctx->skf->insns[0]) &&
+	    (ctx->flags & SEEN_A))
 		emit_jit_reg_move(r_A, r_zero, ctx);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/parisc/kernel/drivers.c linux-libre-4.1.52-gnu/arch/parisc/kernel/drivers.c
--- linux-libre-4.1.51-gnu/arch/parisc/kernel/drivers.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/parisc/kernel/drivers.c	2018-05-27 22:26:45.000000000 -0400
@@ -648,6 +648,10 @@ static int match_pci_device(struct devic
 					(modpath->mod == PCI_FUNC(devfn)));
 	}
 
+	/* index might be out of bounds for bc[] */
+	if (index >= 6)
+		return 0;
+
 	id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5);
 	return (modpath->bc[index] == id);
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/include/asm/barrier.h linux-libre-4.1.52-gnu/arch/powerpc/include/asm/barrier.h
--- linux-libre-4.1.51-gnu/arch/powerpc/include/asm/barrier.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/include/asm/barrier.h	2018-05-27 22:26:45.000000000 -0400
@@ -36,7 +36,8 @@
 
 #define set_mb(var, value)	do { var = value; mb(); } while (0)
 
-#ifdef __SUBARCH_HAS_LWSYNC
+/* The sub-arch has lwsync */
+#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
 #    define SMPWMB      LWSYNC
 #else
 #    define SMPWMB      eieio
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/include/asm/opal.h linux-libre-4.1.52-gnu/arch/powerpc/include/asm/opal.h
--- linux-libre-4.1.51-gnu/arch/powerpc/include/asm/opal.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/include/asm/opal.h	2018-05-27 22:26:45.000000000 -0400
@@ -21,6 +21,9 @@
 /* We calculate number of sg entries based on PAGE_SIZE */
 #define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry))
 
+/* Default time to sleep or delay between OPAL_BUSY/OPAL_BUSY_EVENT loops */
+#define OPAL_BUSY_DELAY_MS	10
+
 /* /sys/firmware/opal */
 extern struct kobject *opal_kobj;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/include/asm/synch.h linux-libre-4.1.52-gnu/arch/powerpc/include/asm/synch.h
--- linux-libre-4.1.51-gnu/arch/powerpc/include/asm/synch.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/include/asm/synch.h	2018-05-27 22:26:45.000000000 -0400
@@ -5,10 +5,6 @@
 #include <linux/stringify.h>
 #include <asm/feature-fixups.h>
 
-#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
-#define __SUBARCH_HAS_LWSYNC
-#endif
-
 #ifndef __ASSEMBLY__
 extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
 extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/kernel/eeh_pe.c linux-libre-4.1.52-gnu/arch/powerpc/kernel/eeh_pe.c
--- linux-libre-4.1.51-gnu/arch/powerpc/kernel/eeh_pe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/kernel/eeh_pe.c	2018-05-27 22:26:45.000000000 -0400
@@ -766,7 +766,8 @@ static void eeh_restore_bridge_bars(stru
 	eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]);
 
 	/* PCI Command: 0x4 */
-	eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]);
+	eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1] |
+			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 
 	/* Check the PCIe link is ready */
 	eeh_bridge_check_link(edev);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/kernel/time.c linux-libre-4.1.52-gnu/arch/powerpc/kernel/time.c
--- linux-libre-4.1.51-gnu/arch/powerpc/kernel/time.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/kernel/time.c	2018-05-27 22:26:45.000000000 -0400
@@ -685,12 +685,20 @@ static int __init get_freq(char *name, i
 static void start_cpu_decrementer(void)
 {
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+	unsigned int tcr;
+
 	/* Clear any pending timer interrupts */
 	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
 
-	/* Enable decrementer interrupt */
-	mtspr(SPRN_TCR, TCR_DIE);
-#endif /* defined(CONFIG_BOOKE) || defined(CONFIG_40x) */
+	tcr = mfspr(SPRN_TCR);
+	/*
+	 * The watchdog may have already been enabled by u-boot. So leave
+	 * TRC[WP] (Watchdog Period) alone.
+	 */
+	tcr &= TCR_WP_MASK;	/* Clear all bits except for TCR[WP] */
+	tcr |= TCR_DIE;		/* Enable decrementer */
+	mtspr(SPRN_TCR, tcr);
+#endif
 }
 
 void __init generic_calibrate_decr(void)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c linux-libre-4.1.52-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c
--- linux-libre-4.1.51-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c	2018-05-27 22:26:45.000000000 -0400
@@ -176,12 +176,15 @@ map_again:
 	ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
 				 hpsize, hpsize, MMU_SEGSIZE_256M);
 
-	if (ret < 0) {
+	if (ret == -1) {
 		/* If we couldn't map a primary PTE, try a secondary */
 		hash = ~hash;
 		vflags ^= HPTE_V_SECONDARY;
 		attempt++;
 		goto map_again;
+	} else if (ret < 0) {
+		r = -EIO;
+		goto out_unlock;
 	} else {
 		trace_kvm_book3s_64_mmu_map(rflags, hpteg,
 					    vpn, hpaddr, orig_pte);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/kvm/book3s_pr.c linux-libre-4.1.52-gnu/arch/powerpc/kvm/book3s_pr.c
--- linux-libre-4.1.51-gnu/arch/powerpc/kvm/book3s_pr.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/kvm/book3s_pr.c	2018-05-27 22:26:45.000000000 -0400
@@ -625,7 +625,11 @@ int kvmppc_handle_pagefault(struct kvm_r
 			kvmppc_mmu_unmap_page(vcpu, &pte);
 		}
 		/* The guest's PTE is not mapped yet. Map on the host */
-		kvmppc_mmu_map_page(vcpu, &pte, iswrite);
+		if (kvmppc_mmu_map_page(vcpu, &pte, iswrite) == -EIO) {
+			/* Exit KVM if mapping failed */
+			run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+			return RESUME_HOST;
+		}
 		if (data)
 			vcpu->stat.sp_storage++;
 		else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/kvm/book3s_pr_papr.c linux-libre-4.1.52-gnu/arch/powerpc/kvm/book3s_pr_papr.c
--- linux-libre-4.1.51-gnu/arch/powerpc/kvm/book3s_pr_papr.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/kvm/book3s_pr_papr.c	2018-05-27 22:26:45.000000000 -0400
@@ -50,7 +50,9 @@ static int kvmppc_h_pr_enter(struct kvm_
 	pteg_addr = get_pteg_addr(vcpu, pte_index);
 
 	mutex_lock(&vcpu->kvm->arch.hpt_mutex);
-	copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg));
+	ret = H_FUNCTION;
+	if (copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg)))
+		goto done;
 	hpte = pteg;
 
 	ret = H_PTEG_FULL;
@@ -71,7 +73,9 @@ static int kvmppc_h_pr_enter(struct kvm_
 	hpte[0] = cpu_to_be64(kvmppc_get_gpr(vcpu, 6));
 	hpte[1] = cpu_to_be64(kvmppc_get_gpr(vcpu, 7));
 	pteg_addr += i * HPTE_SIZE;
-	copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE);
+	ret = H_FUNCTION;
+	if (copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE))
+		goto done;
 	kvmppc_set_gpr(vcpu, 4, pte_index | i);
 	ret = H_SUCCESS;
 
@@ -93,7 +97,9 @@ static int kvmppc_h_pr_remove(struct kvm
 
 	pteg = get_pteg_addr(vcpu, pte_index);
 	mutex_lock(&vcpu->kvm->arch.hpt_mutex);
-	copy_from_user(pte, (void __user *)pteg, sizeof(pte));
+	ret = H_FUNCTION;
+	if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
+		goto done;
 	pte[0] = be64_to_cpu((__force __be64)pte[0]);
 	pte[1] = be64_to_cpu((__force __be64)pte[1]);
 
@@ -103,7 +109,9 @@ static int kvmppc_h_pr_remove(struct kvm
 	    ((flags & H_ANDCOND) && (pte[0] & avpn) != 0))
 		goto done;
 
-	copy_to_user((void __user *)pteg, &v, sizeof(v));
+	ret = H_FUNCTION;
+	if (copy_to_user((void __user *)pteg, &v, sizeof(v)))
+		goto done;
 
 	rb = compute_tlbie_rb(pte[0], pte[1], pte_index);
 	vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
@@ -171,7 +179,10 @@ static int kvmppc_h_pr_bulk_remove(struc
 		}
 
 		pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX);
-		copy_from_user(pte, (void __user *)pteg, sizeof(pte));
+		if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) {
+			ret = H_FUNCTION;
+			break;
+		}
 		pte[0] = be64_to_cpu((__force __be64)pte[0]);
 		pte[1] = be64_to_cpu((__force __be64)pte[1]);
 
@@ -184,7 +195,10 @@ static int kvmppc_h_pr_bulk_remove(struc
 			tsh |= H_BULK_REMOVE_NOT_FOUND;
 		} else {
 			/* Splat the pteg in (userland) hpt */
-			copy_to_user((void __user *)pteg, &v, sizeof(v));
+			if (copy_to_user((void __user *)pteg, &v, sizeof(v))) {
+				ret = H_FUNCTION;
+				break;
+			}
 
 			rb = compute_tlbie_rb(pte[0], pte[1],
 					      tsh & H_BULK_REMOVE_PTEX);
@@ -211,7 +225,9 @@ static int kvmppc_h_pr_protect(struct kv
 
 	pteg = get_pteg_addr(vcpu, pte_index);
 	mutex_lock(&vcpu->kvm->arch.hpt_mutex);
-	copy_from_user(pte, (void __user *)pteg, sizeof(pte));
+	ret = H_FUNCTION;
+	if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
+		goto done;
 	pte[0] = be64_to_cpu((__force __be64)pte[0]);
 	pte[1] = be64_to_cpu((__force __be64)pte[1]);
 
@@ -234,7 +250,9 @@ static int kvmppc_h_pr_protect(struct kv
 	vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
 	pte[0] = (__force u64)cpu_to_be64(pte[0]);
 	pte[1] = (__force u64)cpu_to_be64(pte[1]);
-	copy_to_user((void __user *)pteg, pte, sizeof(pte));
+	ret = H_FUNCTION;
+	if (copy_to_user((void __user *)pteg, pte, sizeof(pte)))
+		goto done;
 	ret = H_SUCCESS;
 
  done:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/mm/fault.c linux-libre-4.1.52-gnu/arch/powerpc/mm/fault.c
--- linux-libre-4.1.51-gnu/arch/powerpc/mm/fault.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/mm/fault.c	2018-05-27 22:26:45.000000000 -0400
@@ -293,7 +293,7 @@ int __kprobes do_page_fault(struct pt_re
 	 * can result in fault, which will cause a deadlock when called with
 	 * mmap_sem held
 	 */
-	if (user_mode(regs))
+	if (!is_exec && user_mode(regs))
 		store_update_sp = store_updates_sp(regs);
 
 	if (user_mode(regs))
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/platforms/cell/spufs/coredump.c linux-libre-4.1.52-gnu/arch/powerpc/platforms/cell/spufs/coredump.c
--- linux-libre-4.1.51-gnu/arch/powerpc/platforms/cell/spufs/coredump.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/platforms/cell/spufs/coredump.c	2018-05-27 22:26:45.000000000 -0400
@@ -174,6 +174,8 @@ static int spufs_arch_write_note(struct
 	if (!dump_skip(cprm,
 		       roundup(cprm->written - total + sz, 4) - cprm->written))
 		goto Eio;
+
+	rc = 0;
 out:
 	free_page((unsigned long)buf);
 	return rc;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/powerpc/platforms/powernv/opal-nvram.c linux-libre-4.1.52-gnu/arch/powerpc/platforms/powernv/opal-nvram.c
--- linux-libre-4.1.51-gnu/arch/powerpc/platforms/powernv/opal-nvram.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/powerpc/platforms/powernv/opal-nvram.c	2018-05-27 22:26:45.000000000 -0400
@@ -11,6 +11,7 @@
 
 #define DEBUG
 
+#include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/of.h>
@@ -56,9 +57,17 @@ static ssize_t opal_nvram_write(char *bu
 
 	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
 		rc = opal_write_nvram(__pa(buf), count, off);
-		if (rc == OPAL_BUSY_EVENT)
+		if (rc == OPAL_BUSY_EVENT) {
+			msleep(OPAL_BUSY_DELAY_MS);
 			opal_poll_events(NULL);
+		} else if (rc == OPAL_BUSY) {
+			msleep(OPAL_BUSY_DELAY_MS);
+		}
 	}
+
+	if (rc)
+		return -EIO;
+
 	*index += count;
 	return count;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/s390/hypfs/inode.c linux-libre-4.1.52-gnu/arch/s390/hypfs/inode.c
--- linux-libre-4.1.51-gnu/arch/s390/hypfs/inode.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/s390/hypfs/inode.c	2018-05-27 22:26:45.000000000 -0400
@@ -323,7 +323,7 @@ static void hypfs_kill_super(struct supe
 
 	if (sb->s_root)
 		hypfs_delete_tree(sb->s_root);
-	if (sb_info->update_file)
+	if (sb_info && sb_info->update_file)
 		hypfs_remove(sb_info->update_file);
 	kfree(sb->s_fs_info);
 	sb->s_fs_info = NULL;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/s390/kernel/ipl.c linux-libre-4.1.52-gnu/arch/s390/kernel/ipl.c
--- linux-libre-4.1.51-gnu/arch/s390/kernel/ipl.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/s390/kernel/ipl.c	2018-05-27 22:26:45.000000000 -0400
@@ -770,6 +770,7 @@ static ssize_t reipl_generic_loadparm_st
 	/* copy and convert to ebcdic */
 	memcpy(ipb->hdr.loadparm, buf, lp_len);
 	ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
+	ipb->hdr.flags |= DIAG308_FLAGS_LP_VALID;
 	return len;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/s390/kernel/vmlinux.lds.S linux-libre-4.1.52-gnu/arch/s390/kernel/vmlinux.lds.S
--- linux-libre-4.1.51-gnu/arch/s390/kernel/vmlinux.lds.S	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/s390/kernel/vmlinux.lds.S	2018-05-27 22:26:45.000000000 -0400
@@ -21,8 +21,14 @@ SECTIONS
 {
 	. = 0x00000000;
 	.text : {
-	_text = .;		/* Text and read-only data */
+		/* Text and read-only data */
 		HEAD_TEXT
+		/*
+		 * E.g. perf doesn't like symbols starting at address zero,
+		 * therefore skip the initial PSW and channel program located
+		 * at address zero and let _text start at 0x200.
+		 */
+	_text = 0x200;
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/sparc/kernel/ldc.c linux-libre-4.1.52-gnu/arch/sparc/kernel/ldc.c
--- linux-libre-4.1.51-gnu/arch/sparc/kernel/ldc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/sparc/kernel/ldc.c	2018-05-27 22:26:45.000000000 -0400
@@ -1733,9 +1733,14 @@ static int read_nonraw(struct ldc_channe
 
 		lp->rcv_nxt = p->seqid;
 
+		/*
+		 * If this is a control-only packet, there is nothing
+		 * else to do but advance the rx queue since the packet
+		 * was already processed above.
+		 */
 		if (!(p->type & LDC_DATA)) {
 			new = rx_advance(lp, new);
-			goto no_data;
+			break;
 		}
 		if (p->stype & (LDC_ACK | LDC_NACK)) {
 			err = data_ack_nack(lp, p);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/um/os-Linux/signal.c linux-libre-4.1.52-gnu/arch/um/os-Linux/signal.c
--- linux-libre-4.1.51-gnu/arch/um/os-Linux/signal.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/um/os-Linux/signal.c	2018-05-27 22:26:45.000000000 -0400
@@ -135,7 +135,7 @@ static void (*handlers[_NSIG])(int sig,
 
 static void hard_handler(int sig, siginfo_t *si, void *p)
 {
-	struct ucontext *uc = p;
+	ucontext_t *uc = p;
 	mcontext_t *mc = &uc->uc_mcontext;
 	unsigned long pending = 1UL << sig;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/boot/compressed/misc.c linux-libre-4.1.52-gnu/arch/x86/boot/compressed/misc.c
--- linux-libre-4.1.51-gnu/arch/x86/boot/compressed/misc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/boot/compressed/misc.c	2018-05-27 22:26:45.000000000 -0400
@@ -349,6 +349,10 @@ static void parse_elf(void *output)
 
 		switch (phdr->p_type) {
 		case PT_LOAD:
+#ifdef CONFIG_X86_64
+			if ((phdr->p_align % 0x200000) != 0)
+				error("Alignment of LOAD segment isn't multiple of 2MB");
+#endif
 #ifdef CONFIG_RELOCATABLE
 			dest = output;
 			dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/crypto/cast5_avx_glue.c linux-libre-4.1.52-gnu/arch/x86/crypto/cast5_avx_glue.c
--- linux-libre-4.1.51-gnu/arch/x86/crypto/cast5_avx_glue.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/crypto/cast5_avx_glue.c	2018-05-27 22:26:45.000000000 -0400
@@ -67,8 +67,6 @@ static int ecb_crypt(struct blkcipher_de
 	void (*fn)(struct cast5_ctx *ctx, u8 *dst, const u8 *src);
 	int err;
 
-	fn = (enc) ? cast5_ecb_enc_16way : cast5_ecb_dec_16way;
-
 	err = blkcipher_walk_virt(desc, walk);
 	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
@@ -80,6 +78,7 @@ static int ecb_crypt(struct blkcipher_de
 
 		/* Process multi-block batch */
 		if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) {
+			fn = (enc) ? cast5_ecb_enc_16way : cast5_ecb_dec_16way;
 			do {
 				fn(ctx, wdst, wsrc);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/include/asm/vmx.h linux-libre-4.1.52-gnu/arch/x86/include/asm/vmx.h
--- linux-libre-4.1.51-gnu/arch/x86/include/asm/vmx.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/include/asm/vmx.h	2018-05-27 22:26:45.000000000 -0400
@@ -306,6 +306,7 @@ enum vmcs_field {
 #define INTR_TYPE_NMI_INTR		(2 << 8) /* NMI */
 #define INTR_TYPE_HARD_EXCEPTION	(3 << 8) /* processor exception */
 #define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */
+#define INTR_TYPE_PRIV_SW_EXCEPTION	(5 << 8) /* ICE breakpoint - undocumented */
 #define INTR_TYPE_SOFT_EXCEPTION	(6 << 8) /* software exception */
 
 /* GUEST_INTERRUPTIBILITY_INFO flags. */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/include/uapi/asm/msr-index.h linux-libre-4.1.52-gnu/arch/x86/include/uapi/asm/msr-index.h
--- linux-libre-4.1.51-gnu/arch/x86/include/uapi/asm/msr-index.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/include/uapi/asm/msr-index.h	2018-05-27 22:26:45.000000000 -0400
@@ -307,6 +307,9 @@
 #define FAM10H_MMIO_CONF_BASE_MASK	0xfffffffULL
 #define FAM10H_MMIO_CONF_BASE_SHIFT	20
 #define MSR_FAM10H_NODE_ID		0xc001100c
+#define MSR_F10H_DECFG			0xc0011029
+#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT	1
+#define MSR_F10H_DECFG_LFENCE_SERIALIZE		BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT)
 
 /* K8 MSRs */
 #define MSR_K8_TOP_MEM1			0xc001001a
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/cpu/amd.c linux-libre-4.1.52-gnu/arch/x86/kernel/cpu/amd.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/cpu/amd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/cpu/amd.c	2018-05-27 22:26:45.000000000 -0400
@@ -712,8 +712,32 @@ static void init_amd(struct cpuinfo_x86
 		set_cpu_cap(c, X86_FEATURE_K8);
 
 	if (cpu_has_xmm2) {
-		/* MFENCE stops RDTSC speculation */
-		set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
+		unsigned long long val;
+		int ret;
+
+		/*
+		 * A serializing LFENCE has less overhead than MFENCE, so
+		 * use it for execution serialization.  On families which
+		 * don't have that MSR, LFENCE is already serializing.
+		 * msr_set_bit() uses the safe accessors, too, even if the MSR
+		 * is not present.
+		 */
+		msr_set_bit(MSR_F10H_DECFG,
+			    MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
+
+		/*
+		 * Verify that the MSR write was successful (could be running
+		 * under a hypervisor) and only then assume that LFENCE is
+		 * serializing.
+		 */
+		ret = rdmsrl_safe(MSR_F10H_DECFG, &val);
+		if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) {
+			/* A serializing LFENCE stops RDTSC speculation */
+			set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+		} else {
+			/* MFENCE stops RDTSC speculation */
+			set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
+		}
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/cpu/perf_event_intel.c linux-libre-4.1.52-gnu/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/cpu/perf_event_intel.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/cpu/perf_event_intel.c	2018-05-27 22:26:45.000000000 -0400
@@ -2493,7 +2493,7 @@ static unsigned bdw_limit_period(struct
 			X86_CONFIG(.event=0xc0, .umask=0x01)) {
 		if (left < 128)
 			left = 128;
-		left &= ~0x3fu;
+		left &= ~0x3fULL;
 	}
 	return left;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/i8259.c linux-libre-4.1.52-gnu/arch/x86/kernel/i8259.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/i8259.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/i8259.c	2018-05-27 22:26:45.000000000 -0400
@@ -405,6 +405,7 @@ struct legacy_pic default_legacy_pic = {
 };
 
 struct legacy_pic *legacy_pic = &default_legacy_pic;
+EXPORT_SYMBOL(legacy_pic);
 
 static int __init i8259A_init_ops(void)
 {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/kprobes/core.c linux-libre-4.1.52-gnu/arch/x86/kernel/kprobes/core.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/kprobes/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/kprobes/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/kdebug.h>
 #include <linux/kallsyms.h>
 #include <linux/ftrace.h>
+#include <linux/moduleloader.h>
 
 #include <asm/cacheflush.h>
 #include <asm/desc.h>
@@ -196,6 +197,8 @@ retry:
 		return (opcode != 0x62 && opcode != 0x67);
 	case 0x70:
 		return 0; /* can't boost conditional jump */
+	case 0x90:
+		return opcode != 0x9a;	/* can't boost call far */
 	case 0xc0:
 		/* can't boost software-interruptions */
 		return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf;
@@ -400,10 +403,20 @@ int __copy_instruction(u8 *dest, u8 *src
 	return length;
 }
 
+/* Recover page to RW mode before releasing it */
+void free_insn_page(void *page)
+{
+	set_memory_nx((unsigned long)page & PAGE_MASK, 1);
+	set_memory_rw((unsigned long)page & PAGE_MASK, 1);
+	module_memfree(page);
+}
+
 static int arch_copy_kprobe(struct kprobe *p)
 {
 	int ret;
 
+	set_memory_rw((unsigned long)p->ainsn.insn & PAGE_MASK, 1);
+
 	/* Copy an instruction with recovering if other optprobe modifies it.*/
 	ret = __copy_instruction(p->ainsn.insn, p->addr);
 	if (!ret)
@@ -418,6 +431,8 @@ static int arch_copy_kprobe(struct kprob
 	else
 		p->ainsn.boostable = -1;
 
+	set_memory_ro((unsigned long)p->ainsn.insn & PAGE_MASK, 1);
+
 	/* Check whether the instruction modifies Interrupt Flag or not */
 	p->ainsn.if_modifier = is_IF_modifier(p->ainsn.insn);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/kprobes/opt.c linux-libre-4.1.52-gnu/arch/x86/kernel/kprobes/opt.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/kprobes/opt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/kprobes/opt.c	2018-05-27 22:26:45.000000000 -0400
@@ -349,6 +349,7 @@ int arch_prepare_optimized_kprobe(struct
 	}
 
 	buf = (u8 *)op->optinsn.insn;
+	set_memory_rw((unsigned long)buf & PAGE_MASK, 1);
 
 	/* Copy instructions into the out-of-line buffer */
 	ret = copy_optimized_instructions(buf + TMPL_END_IDX, op->kp.addr);
@@ -371,6 +372,8 @@ int arch_prepare_optimized_kprobe(struct
 	synthesize_reljump(buf + TMPL_END_IDX + op->optinsn.size,
 			   (u8 *)op->kp.addr + op->optinsn.size);
 
+	set_memory_ro((unsigned long)buf & PAGE_MASK, 1);
+
 	flush_icache_range((unsigned long) buf,
 			   (unsigned long) buf + TMPL_END_IDX +
 			   op->optinsn.size + RELATIVEJUMP_SIZE);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/smpboot.c linux-libre-4.1.52-gnu/arch/x86/kernel/smpboot.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/smpboot.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/smpboot.c	2018-05-27 22:26:45.000000000 -0400
@@ -1400,6 +1400,8 @@ static inline void mwait_play_dead(void)
 	void *mwait_ptr;
 	int i;
 
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+		return;
 	if (!this_cpu_has(X86_FEATURE_MWAIT))
 		return;
 	if (!this_cpu_has(X86_FEATURE_CLFLUSH))
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kernel/tsc.c linux-libre-4.1.52-gnu/arch/x86/kernel/tsc.c
--- linux-libre-4.1.51-gnu/arch/x86/kernel/tsc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kernel/tsc.c	2018-05-27 22:26:45.000000000 -0400
@@ -356,6 +356,8 @@ static int __init tsc_setup(char *str)
 		tsc_clocksource_reliable = 1;
 	if (!strncmp(str, "noirqtime", 9))
 		no_sched_irq_time = 1;
+	if (!strcmp(str, "unstable"))
+		mark_tsc_unstable("boot parameter");
 	return 1;
 }
 
@@ -397,7 +399,7 @@ static unsigned long calc_hpet_ref(u64 d
 	hpet2 -= hpet1;
 	tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
 	do_div(tmp, 1000000);
-	do_div(deltatsc, tmp);
+	deltatsc = div64_u64(deltatsc, tmp);
 
 	return (unsigned long) deltatsc;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kvm/svm.c linux-libre-4.1.52-gnu/arch/x86/kvm/svm.c
--- linux-libre-4.1.51-gnu/arch/x86/kvm/svm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kvm/svm.c	2018-05-27 22:26:45.000000000 -0400
@@ -1470,6 +1470,7 @@ static void svm_get_segment(struct kvm_v
 		 */
 		if (var->unusable)
 			var->db = 0;
+		/* This is symmetric with svm_set_segment() */
 		var->dpl = to_svm(vcpu)->vmcb->save.cpl;
 		break;
 	}
@@ -1614,18 +1615,14 @@ static void svm_set_segment(struct kvm_v
 	s->base = var->base;
 	s->limit = var->limit;
 	s->selector = var->selector;
-	if (var->unusable)
-		s->attrib = 0;
-	else {
-		s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK);
-		s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT;
-		s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT;
-		s->attrib |= (var->present & 1) << SVM_SELECTOR_P_SHIFT;
-		s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT;
-		s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT;
-		s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT;
-		s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT;
-	}
+	s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK);
+	s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT;
+	s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT;
+	s->attrib |= ((var->present & 1) && !var->unusable) << SVM_SELECTOR_P_SHIFT;
+	s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT;
+	s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT;
+	s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT;
+	s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT;
 
 	/*
 	 * This is always accurate, except if SYSRET returned to a segment
@@ -1634,7 +1631,8 @@ static void svm_set_segment(struct kvm_v
 	 * would entail passing the CPL to userspace and back.
 	 */
 	if (seg == VCPU_SREG_SS)
-		svm->vmcb->save.cpl = (s->attrib >> SVM_SELECTOR_DPL_SHIFT) & 3;
+		/* This is symmetric with svm_get_segment() */
+		svm->vmcb->save.cpl = (var->dpl & 3);
 
 	mark_dirty(svm->vmcb, VMCB_SEG);
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/kvm/vmx.c linux-libre-4.1.52-gnu/arch/x86/kvm/vmx.c
--- linux-libre-4.1.51-gnu/arch/x86/kvm/vmx.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/kvm/vmx.c	2018-05-27 22:26:45.000000000 -0400
@@ -942,6 +942,13 @@ static inline bool is_machine_check(u32
 		(INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK);
 }
 
+/* Undocumented: icebp/int1 */
+static inline bool is_icebp(u32 intr_info)
+{
+	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
+		== (INTR_TYPE_PRIV_SW_EXCEPTION | INTR_INFO_VALID_MASK);
+}
+
 static inline bool cpu_has_vmx_msr_bitmap(void)
 {
 	return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
@@ -5151,7 +5158,7 @@ static int handle_exception(struct kvm_v
 		      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
 			vcpu->arch.dr6 &= ~15;
 			vcpu->arch.dr6 |= dr6 | DR6_RTM;
-			if (!(dr6 & ~DR6_RESERVED)) /* icebp */
+			if (is_icebp(intr_info))
 				skip_emulated_instruction(vcpu);
 
 			kvm_queue_exception(vcpu, DB_VECTOR);
@@ -7417,11 +7424,13 @@ static bool nested_vmx_exit_handled_cr(s
 {
 	unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 	int cr = exit_qualification & 15;
-	int reg = (exit_qualification >> 8) & 15;
-	unsigned long val = kvm_register_readl(vcpu, reg);
+	int reg;
+	unsigned long val;
 
 	switch ((exit_qualification >> 4) & 3) {
 	case 0: /* mov to cr */
+		reg = (exit_qualification >> 8) & 15;
+		val = kvm_register_readl(vcpu, reg);
 		switch (cr) {
 		case 0:
 			if (vmcs12->cr0_guest_host_mask &
@@ -7476,6 +7485,7 @@ static bool nested_vmx_exit_handled_cr(s
 		 * lmsw can change bits 1..3 of cr0, and only set bit 0 of
 		 * cr0. Other attempted changes are ignored, with no exit.
 		 */
+		val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f;
 		if (vmcs12->cr0_guest_host_mask & 0xe &
 		    (val ^ vmcs12->cr0_read_shadow))
 			return true;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/Makefile linux-libre-4.1.52-gnu/arch/x86/Makefile
--- linux-libre-4.1.51-gnu/arch/x86/Makefile	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/Makefile	2018-05-27 22:26:45.000000000 -0400
@@ -158,6 +158,15 @@ KBUILD_CFLAGS += $(cfi) $(cfi-sigframe)
 
 LDFLAGS := -m elf_$(UTS_MACHINE)
 
+#
+# The 64-bit kernel must be aligned to 2MB.  Pass -z max-page-size=0x200000 to
+# the linker to force 2MB page size regardless of the default page size used
+# by the linker.
+#
+ifdef CONFIG_X86_64
+LDFLAGS += $(call ld-option, -z max-page-size=0x200000)
+endif
+
 # Speed up the build
 KBUILD_CFLAGS += -pipe
 # Workaround for a gcc prelease that unfortunately was shipped in a suse release
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/mm/fault.c linux-libre-4.1.52-gnu/arch/x86/mm/fault.c
--- linux-libre-4.1.51-gnu/arch/x86/mm/fault.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/mm/fault.c	2018-05-27 22:26:45.000000000 -0400
@@ -285,7 +285,7 @@ static noinline int vmalloc_fault(unsign
 	if (!pmd_k)
 		return -1;
 
-	if (pmd_huge(*pmd_k))
+	if (pmd_large(*pmd_k))
 		return 0;
 
 	pte_k = pte_offset_kernel(pmd_k, address);
@@ -403,7 +403,7 @@ static noinline int vmalloc_fault(unsign
 	if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
 		BUG();
 
-	if (pud_huge(*pud))
+	if (pud_large(*pud))
 		return 0;
 
 	pmd = pmd_offset(pud, address);
@@ -414,7 +414,7 @@ static noinline int vmalloc_fault(unsign
 	if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
 		BUG();
 
-	if (pmd_huge(*pmd))
+	if (pmd_large(*pmd))
 		return 0;
 
 	pte_ref = pte_offset_kernel(pmd_ref, address);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/net/bpf_jit_comp.c linux-libre-4.1.52-gnu/arch/x86/net/bpf_jit_comp.c
--- linux-libre-4.1.51-gnu/arch/x86/net/bpf_jit_comp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/net/bpf_jit_comp.c	2018-05-27 22:26:45.000000000 -0400
@@ -971,7 +971,7 @@ void bpf_int_jit_compile(struct bpf_prog
 	 * may converge on the last pass. In such case do one more
 	 * pass to emit the final image
 	 */
-	for (pass = 0; pass < 10 || image; pass++) {
+	for (pass = 0; pass < 20 || image; pass++) {
 		proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
 		if (proglen <= 0) {
 			image = NULL;
@@ -994,6 +994,7 @@ void bpf_int_jit_compile(struct bpf_prog
 				goto out;
 		}
 		oldproglen = proglen;
+		cond_resched();
 	}
 
 	if (bpf_jit_enable > 1)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/arch/x86/um/stub_segv.c linux-libre-4.1.52-gnu/arch/x86/um/stub_segv.c
--- linux-libre-4.1.51-gnu/arch/x86/um/stub_segv.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/arch/x86/um/stub_segv.c	2018-05-27 22:26:45.000000000 -0400
@@ -10,7 +10,7 @@
 void __attribute__ ((__section__ (".__syscall_stub")))
 stub_segv_handler(int sig, siginfo_t *info, void *p)
 {
-	struct ucontext *uc = p;
+	ucontext_t *uc = p;
 
 	GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA),
 			      &uc->uc_mcontext);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/block/bio-integrity.c linux-libre-4.1.52-gnu/block/bio-integrity.c
--- linux-libre-4.1.51-gnu/block/bio-integrity.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/block/bio-integrity.c	2018-05-27 22:26:45.000000000 -0400
@@ -165,6 +165,9 @@ bool bio_integrity_enabled(struct bio *b
 	if (!bio_is_rw(bio))
 		return false;
 
+	if (!bio_sectors(bio))
+		return false;
+
 	/* Already protected? */
 	if (bio_integrity(bio))
 		return false;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/block/blk-mq.c linux-libre-4.1.52-gnu/block/blk-mq.c
--- linux-libre-4.1.51-gnu/block/blk-mq.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/block/blk-mq.c	2018-05-27 22:26:45.000000000 -0400
@@ -1607,7 +1607,8 @@ static void blk_mq_exit_hctx(struct requ
 {
 	unsigned flush_start_tag = set->queue_depth;
 
-	blk_mq_tag_idle(hctx);
+	if (blk_mq_hw_queue_mapped(hctx))
+		blk_mq_tag_idle(hctx);
 
 	if (set->ops->exit_request)
 		set->ops->exit_request(set->driver_data,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/block/blk-throttle.c linux-libre-4.1.52-gnu/block/blk-throttle.c
--- linux-libre-4.1.51-gnu/block/blk-throttle.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/block/blk-throttle.c	2018-05-27 22:26:45.000000000 -0400
@@ -648,6 +648,17 @@ static void throtl_dequeue_tg(struct thr
 static void throtl_schedule_pending_timer(struct throtl_service_queue *sq,
 					  unsigned long expires)
 {
+	unsigned long max_expire = jiffies + 8 * throtl_slice;
+
+	/*
+	 * Since we are adjusting the throttle limit dynamically, the sleep
+	 * time calculated according to previous limit might be invalid. It's
+	 * possible the cgroup sleep time is very long and no other cgroups
+	 * have IO running so notify the limit changes. Make sure the cgroup
+	 * doesn't sleep too long to avoid the missed notification.
+	 */
+	if (time_after(expires, max_expire))
+		expires = max_expire;
 	mod_timer(&sq->pending_timer, expires);
 	throtl_log(sq, "schedule timer. delay=%lu jiffies=%lu",
 		   expires - jiffies, jiffies);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/block/partition-generic.c linux-libre-4.1.52-gnu/block/partition-generic.c
--- linux-libre-4.1.51-gnu/block/partition-generic.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/block/partition-generic.c	2018-05-27 22:26:45.000000000 -0400
@@ -309,8 +309,10 @@ struct hd_struct *add_partition(struct g
 
 	if (info) {
 		struct partition_meta_info *pinfo = alloc_part_info(disk);
-		if (!pinfo)
+		if (!pinfo) {
+			err = -ENOMEM;
 			goto out_free_stats;
+		}
 		memcpy(pinfo, info, sizeof(*info));
 		p->info = pinfo;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/block/partitions/msdos.c linux-libre-4.1.52-gnu/block/partitions/msdos.c
--- linux-libre-4.1.51-gnu/block/partitions/msdos.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/block/partitions/msdos.c	2018-05-27 22:26:45.000000000 -0400
@@ -300,7 +300,9 @@ static void parse_bsd(struct parsed_part
 			continue;
 		bsd_start = le32_to_cpu(p->p_offset);
 		bsd_size = le32_to_cpu(p->p_size);
-		if (memcmp(flavour, "bsd\0", 4) == 0)
+		/* FreeBSD has relative offset if C partition offset is zero */
+		if (memcmp(flavour, "bsd\0", 4) == 0 &&
+		    le32_to_cpu(l->d_partitions[2].p_offset) == 0)
 			bsd_start += offset;
 		if (offset == bsd_start && size == bsd_size)
 			/* full parent partition, we have it already */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/crypto/ahash.c linux-libre-4.1.52-gnu/crypto/ahash.c
--- linux-libre-4.1.51-gnu/crypto/ahash.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/crypto/ahash.c	2018-05-27 22:26:45.000000000 -0400
@@ -91,13 +91,14 @@ int crypto_hash_walk_done(struct crypto_
 
 	if (nbytes && walk->offset & alignmask && !err) {
 		walk->offset = ALIGN(walk->offset, alignmask + 1);
-		walk->data += walk->offset;
-
 		nbytes = min(nbytes,
 			     ((unsigned int)(PAGE_SIZE)) - walk->offset);
 		walk->entrylen -= nbytes;
 
-		return nbytes;
+		if (nbytes) {
+			walk->data += walk->offset;
+			return nbytes;
+		}
 	}
 
 	if (walk->flags & CRYPTO_ALG_ASYNC)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/crypto/async_tx/async_pq.c linux-libre-4.1.52-gnu/crypto/async_tx/async_pq.c
--- linux-libre-4.1.51-gnu/crypto/async_tx/async_pq.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/crypto/async_tx/async_pq.c	2018-05-27 22:26:45.000000000 -0400
@@ -62,9 +62,6 @@ do_async_gen_syndrome(struct dma_chan *c
 	dma_addr_t dma_dest[2];
 	int src_off = 0;
 
-	if (submit->flags & ASYNC_TX_FENCE)
-		dma_flags |= DMA_PREP_FENCE;
-
 	while (src_cnt > 0) {
 		submit->flags = flags_orig;
 		pq_src_cnt = min(src_cnt, dma_maxpq(dma, dma_flags));
@@ -83,6 +80,8 @@ do_async_gen_syndrome(struct dma_chan *c
 			if (cb_fn_orig)
 				dma_flags |= DMA_PREP_INTERRUPT;
 		}
+		if (submit->flags & ASYNC_TX_FENCE)
+			dma_flags |= DMA_PREP_FENCE;
 
 		/* Drivers force forward progress in case they can not provide
 		 * a descriptor
diff -druNp --no-dereference linux-libre-4.1.51-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt linux-libre-4.1.52-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
--- linux-libre-4.1.51-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt	2018-05-27 22:26:45.000000000 -0400
@@ -35,6 +35,15 @@ Optional properties:
 - ti,palmas-enable-dvfs2: Enable DVFS2. Configure pins for DVFS2 mode.
 	Selection primary or secondary function associated to GPADC_START
 	and SYSEN2 pin/pad for DVFS2 interface
+- ti,palmas-override-powerhold: This is applicable for PMICs for which
+	GPIO7 is configured in POWERHOLD mode which has higher priority
+	over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON
+	bit is turned off. This property enables driver to over ride the
+	POWERHOLD value to GPIO7 so as to turn off the PMIC in power off
+	scenarios. So for GPIO7 if ti,palmas-override-powerhold is set
+	then the GPIO_7 field should never be muxed to anything else.
+	It should be set to POWERHOLD by default and only in case of
+	power off scenarios the driver will over ride the mux value.
 
 This binding uses the following generic properties as defined in
 pinctrl-bindings.txt:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/acpi/acpica/evxfevnt.c linux-libre-4.1.52-gnu/drivers/acpi/acpica/evxfevnt.c
--- linux-libre-4.1.51-gnu/drivers/acpi/acpica/evxfevnt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/acpi/acpica/evxfevnt.c	2018-05-27 22:26:45.000000000 -0400
@@ -180,6 +180,12 @@ acpi_status acpi_enable_event(u32 event,
 
 	ACPI_FUNCTION_TRACE(acpi_enable_event);
 
+	/* If Hardware Reduced flag is set, there are no fixed events */
+
+	if (acpi_gbl_reduced_hardware) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
 	/* Decode the Fixed Event */
 
 	if (event > ACPI_EVENT_MAX) {
@@ -237,6 +243,12 @@ acpi_status acpi_disable_event(u32 event
 
 	ACPI_FUNCTION_TRACE(acpi_disable_event);
 
+	/* If Hardware Reduced flag is set, there are no fixed events */
+
+	if (acpi_gbl_reduced_hardware) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
 	/* Decode the Fixed Event */
 
 	if (event > ACPI_EVENT_MAX) {
@@ -290,6 +302,12 @@ acpi_status acpi_clear_event(u32 event)
 
 	ACPI_FUNCTION_TRACE(acpi_clear_event);
 
+	/* If Hardware Reduced flag is set, there are no fixed events */
+
+	if (acpi_gbl_reduced_hardware) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
 	/* Decode the Fixed Event */
 
 	if (event > ACPI_EVENT_MAX) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/acpi/acpica/psobject.c linux-libre-4.1.52-gnu/drivers/acpi/acpica/psobject.c
--- linux-libre-4.1.51-gnu/drivers/acpi/acpica/psobject.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/acpi/acpica/psobject.c	2018-05-27 22:26:45.000000000 -0400
@@ -118,6 +118,9 @@ static acpi_status acpi_ps_get_aml_opcod
 			     (u32)(walk_state->aml_offset +
 				   sizeof(struct acpi_table_header)));
 
+			ACPI_ERROR((AE_INFO,
+				    "Aborting disassembly, AML byte code is corrupt"));
+
 			/* Dump the context surrounding the invalid opcode */
 
 			acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
@@ -126,6 +129,14 @@ static acpi_status acpi_ps_get_aml_opcod
 					     sizeof(struct acpi_table_header) -
 					     16));
 			acpi_os_printf(" */\n");
+
+			/*
+			 * Just abort the disassembly, cannot continue because the
+			 * parser is essentially lost. The disassembler can then
+			 * randomly fail because an ill-constructed parse tree
+			 * can result.
+			 */
+			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 #endif
 		}
 
@@ -290,6 +301,9 @@ acpi_ps_create_op(struct acpi_walk_state
 	if (status == AE_CTRL_PARSE_CONTINUE) {
 		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 	}
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
 	/* Create Op structure and append to parent's argument list */
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/acpi/pci_irq.c linux-libre-4.1.52-gnu/drivers/acpi/pci_irq.c
--- linux-libre-4.1.51-gnu/drivers/acpi/pci_irq.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/acpi/pci_irq.c	2018-05-27 22:26:45.000000000 -0400
@@ -136,9 +136,6 @@ static void do_prt_fixups(struct acpi_pr
 		quirk = &prt_quirks[i];
 
 		/* All current quirks involve link devices, not GSIs */
-		if (!prt->source)
-			continue;
-
 		if (dmi_check_system(quirk->system) &&
 		    entry->id.segment == quirk->segment &&
 		    entry->id.bus == quirk->bus &&
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/acpi/pmic/intel_pmic_xpower.c linux-libre-4.1.52-gnu/drivers/acpi/pmic/intel_pmic_xpower.c
--- linux-libre-4.1.51-gnu/drivers/acpi/pmic/intel_pmic_xpower.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/acpi/pmic/intel_pmic_xpower.c	2018-05-27 22:26:45.000000000 -0400
@@ -28,97 +28,97 @@ static struct pmic_table power_table[] =
 		.address = 0x00,
 		.reg = 0x13,
 		.bit = 0x05,
-	},
+	}, /* ALD1 */
 	{
 		.address = 0x04,
 		.reg = 0x13,
 		.bit = 0x06,
-	},
+	}, /* ALD2 */
 	{
 		.address = 0x08,
 		.reg = 0x13,
 		.bit = 0x07,
-	},
+	}, /* ALD3 */
 	{
 		.address = 0x0c,
 		.reg = 0x12,
 		.bit = 0x03,
-	},
+	}, /* DLD1 */
 	{
 		.address = 0x10,
 		.reg = 0x12,
 		.bit = 0x04,
-	},
+	}, /* DLD2 */
 	{
 		.address = 0x14,
 		.reg = 0x12,
 		.bit = 0x05,
-	},
+	}, /* DLD3 */
 	{
 		.address = 0x18,
 		.reg = 0x12,
 		.bit = 0x06,
-	},
+	}, /* DLD4 */
 	{
 		.address = 0x1c,
 		.reg = 0x12,
 		.bit = 0x00,
-	},
+	}, /* ELD1 */
 	{
 		.address = 0x20,
 		.reg = 0x12,
 		.bit = 0x01,
-	},
+	}, /* ELD2 */
 	{
 		.address = 0x24,
 		.reg = 0x12,
 		.bit = 0x02,
-	},
+	}, /* ELD3 */
 	{
 		.address = 0x28,
 		.reg = 0x13,
 		.bit = 0x02,
-	},
+	}, /* FLD1 */
 	{
 		.address = 0x2c,
 		.reg = 0x13,
 		.bit = 0x03,
-	},
+	}, /* FLD2 */
 	{
 		.address = 0x30,
 		.reg = 0x13,
 		.bit = 0x04,
-	},
+	}, /* FLD3 */
 	{
-		.address = 0x38,
+		.address = 0x34,
 		.reg = 0x10,
 		.bit = 0x03,
-	},
+	}, /* BUC1 */
 	{
-		.address = 0x3c,
+		.address = 0x38,
 		.reg = 0x10,
 		.bit = 0x06,
-	},
+	}, /* BUC2 */
 	{
-		.address = 0x40,
+		.address = 0x3c,
 		.reg = 0x10,
 		.bit = 0x05,
-	},
+	}, /* BUC3 */
 	{
-		.address = 0x44,
+		.address = 0x40,
 		.reg = 0x10,
 		.bit = 0x04,
-	},
+	}, /* BUC4 */
 	{
-		.address = 0x48,
+		.address = 0x44,
 		.reg = 0x10,
 		.bit = 0x01,
-	},
+	}, /* BUC5 */
 	{
-		.address = 0x4c,
+		.address = 0x48,
 		.reg = 0x10,
 		.bit = 0x00
-	},
+	}, /* BUC6 */
 };
 
 /* TMP0 - TMP5 are the same, all from GPADC */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/acpi/processor_driver.c linux-libre-4.1.52-gnu/drivers/acpi/processor_driver.c
--- linux-libre-4.1.51-gnu/drivers/acpi/processor_driver.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/acpi/processor_driver.c	2018-05-27 22:26:45.000000000 -0400
@@ -231,11 +231,16 @@ static int __acpi_processor_start(struct
 static int acpi_processor_start(struct device *dev)
 {
 	struct acpi_device *device = ACPI_COMPANION(dev);
+	int ret;
 
 	if (!device)
 		return -ENODEV;
 
-	return __acpi_processor_start(device);
+	/* Protect against concurrent CPU hotplug operations */
+	get_online_cpus();
+	ret = __acpi_processor_start(device);
+	put_online_cpus();
+	return ret;
 }
 
 static int acpi_processor_stop(struct device *dev)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/acpi/processor_throttling.c linux-libre-4.1.52-gnu/drivers/acpi/processor_throttling.c
--- linux-libre-4.1.51-gnu/drivers/acpi/processor_throttling.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/acpi/processor_throttling.c	2018-05-27 22:26:45.000000000 -0400
@@ -66,8 +66,8 @@ struct acpi_processor_throttling_arg {
 #define THROTTLING_POSTCHANGE      (2)
 
 static int acpi_processor_get_throttling(struct acpi_processor *pr);
-int acpi_processor_set_throttling(struct acpi_processor *pr,
-						int state, bool force);
+static int __acpi_processor_set_throttling(struct acpi_processor *pr,
+					   int state, bool force, bool direct);
 
 static int acpi_processor_update_tsd_coord(void)
 {
@@ -895,7 +895,8 @@ static int acpi_processor_get_throttling
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				"Invalid throttling state, reset\n"));
 			state = 0;
-			ret = acpi_processor_set_throttling(pr, state, true);
+			ret = __acpi_processor_set_throttling(pr, state, true,
+							      true);
 			if (ret)
 				return ret;
 		}
@@ -905,36 +906,31 @@ static int acpi_processor_get_throttling
 	return 0;
 }
 
-static int acpi_processor_get_throttling(struct acpi_processor *pr)
+static long __acpi_processor_get_throttling(void *data)
 {
-	cpumask_var_t saved_mask;
-	int ret;
+	struct acpi_processor *pr = data;
 
+	return pr->throttling.acpi_processor_get_throttling(pr);
+}
+
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
+{
 	if (!pr)
 		return -EINVAL;
 
 	if (!pr->flags.throttling)
 		return -ENODEV;
 
-	if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
-		return -ENOMEM;
-
 	/*
-	 * Migrate task to the cpu pointed by pr.
+	 * This is either called from the CPU hotplug callback of
+	 * processor_driver or via the ACPI probe function. In the latter
+	 * case the CPU is not guaranteed to be online. Both call sites are
+	 * protected against CPU hotplug.
 	 */
-	cpumask_copy(saved_mask, &current->cpus_allowed);
-	/* FIXME: use work_on_cpu() */
-	if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
-		/* Can't migrate to the target pr->id CPU. Exit */
-		free_cpumask_var(saved_mask);
+	if (!cpu_online(pr->id))
 		return -ENODEV;
-	}
-	ret = pr->throttling.acpi_processor_get_throttling(pr);
-	/* restore the previous state */
-	set_cpus_allowed_ptr(current, saved_mask);
-	free_cpumask_var(saved_mask);
 
-	return ret;
+	return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr);
 }
 
 static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
@@ -1084,8 +1080,15 @@ static long acpi_processor_throttling_fn
 			arg->target_state, arg->force);
 }
 
-int acpi_processor_set_throttling(struct acpi_processor *pr,
-						int state, bool force)
+static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct)
+{
+	if (direct)
+		return fn(arg);
+	return work_on_cpu(cpu, fn, arg);
+}
+
+static int __acpi_processor_set_throttling(struct acpi_processor *pr,
+					   int state, bool force, bool direct)
 {
 	int ret = 0;
 	unsigned int i;
@@ -1134,7 +1137,8 @@ int acpi_processor_set_throttling(struct
 		arg.pr = pr;
 		arg.target_state = state;
 		arg.force = force;
-		ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg);
+		ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, &arg,
+				  direct);
 	} else {
 		/*
 		 * When the T-state coordination is SW_ALL or HW_ALL,
@@ -1167,8 +1171,8 @@ int acpi_processor_set_throttling(struct
 			arg.pr = match_pr;
 			arg.target_state = state;
 			arg.force = force;
-			ret = work_on_cpu(pr->id, acpi_processor_throttling_fn,
-				&arg);
+			ret = call_on_cpu(pr->id, acpi_processor_throttling_fn,
+					  &arg, direct);
 		}
 	}
 	/*
@@ -1186,6 +1190,12 @@ int acpi_processor_set_throttling(struct
 	return ret;
 }
 
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state,
+				  bool force)
+{
+	return __acpi_processor_set_throttling(pr, state, force, false);
+}
+
 int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 {
 	int result = 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/amba/bus.c linux-libre-4.1.52-gnu/drivers/amba/bus.c
--- linux-libre-4.1.51-gnu/drivers/amba/bus.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/amba/bus.c	2018-05-27 22:26:45.000000000 -0400
@@ -68,11 +68,12 @@ static ssize_t driver_override_show(stru
 				    struct device_attribute *attr, char *buf)
 {
 	struct amba_device *dev = to_amba_device(_dev);
+	ssize_t len;
 
-	if (!dev->driver_override)
-		return 0;
-
-	return sprintf(buf, "%s\n", dev->driver_override);
+	device_lock(_dev);
+	len = sprintf(buf, "%s\n", dev->driver_override);
+	device_unlock(_dev);
+	return len;
 }
 
 static ssize_t driver_override_store(struct device *_dev,
@@ -80,9 +81,10 @@ static ssize_t driver_override_store(str
 				     const char *buf, size_t count)
 {
 	struct amba_device *dev = to_amba_device(_dev);
-	char *driver_override, *old = dev->driver_override, *cp;
+	char *driver_override, *old, *cp;
 
-	if (count > PATH_MAX)
+	/* We need to keep extra room for a newline */
+	if (count >= (PAGE_SIZE - 1))
 		return -EINVAL;
 
 	driver_override = kstrndup(buf, count, GFP_KERNEL);
@@ -93,12 +95,15 @@ static ssize_t driver_override_store(str
 	if (cp)
 		*cp = '\0';
 
+	device_lock(_dev);
+	old = dev->driver_override;
 	if (strlen(driver_override)) {
 		dev->driver_override = driver_override;
 	} else {
 	       kfree(driver_override);
 	       dev->driver_override = NULL;
 	}
+	device_unlock(_dev);
 
 	kfree(old);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/ata/ahci.c linux-libre-4.1.52-gnu/drivers/ata/ahci.c
--- linux-libre-4.1.51-gnu/drivers/ata/ahci.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/ata/ahci.c	2018-05-27 22:26:45.000000000 -0400
@@ -542,7 +542,9 @@ static const struct pci_device_id ahci_p
 	  .driver_data = board_ahci_yes_fbs },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
 	  .driver_data = board_ahci_yes_fbs },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
+	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */
+	  .driver_data = board_ahci_yes_fbs },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */
 	  .driver_data = board_ahci_yes_fbs },
 
 	/* Promise */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/ata/libahci_platform.c linux-libre-4.1.52-gnu/drivers/ata/libahci_platform.c
--- linux-libre-4.1.51-gnu/drivers/ata/libahci_platform.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/ata/libahci_platform.c	2018-05-27 22:26:45.000000000 -0400
@@ -514,8 +514,9 @@ int ahci_platform_init_host(struct platf
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq <= 0) {
-		dev_err(dev, "no irq\n");
-		return -EINVAL;
+		if (irq != -EPROBE_DEFER)
+			dev_err(dev, "no irq\n");
+		return irq;
 	}
 
 	/* prepare host */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/ata/libata-core.c linux-libre-4.1.52-gnu/drivers/ata/libata-core.c
--- linux-libre-4.1.51-gnu/drivers/ata/libata-core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/ata/libata-core.c	2018-05-27 22:26:45.000000000 -0400
@@ -4226,6 +4226,28 @@ static const struct ata_blacklist_entry
 	{ "PIONEER DVD-RW  DVR-212D",	NULL,	ATA_HORKAGE_NOSETXFER },
 	{ "PIONEER DVD-RW  DVR-216D",	NULL,	ATA_HORKAGE_NOSETXFER },
 
+	/* Crucial BX100 SSD 500GB has broken LPM support */
+	{ "CT500BX100SSD1",		NULL,	ATA_HORKAGE_NOLPM },
+
+	/* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */
+	{ "Crucial_CT512MX100*",	"MU01",	ATA_HORKAGE_NO_NCQ_TRIM |
+						ATA_HORKAGE_ZERO_AFTER_TRIM |
+						ATA_HORKAGE_NOLPM, },
+	/* 512GB MX100 with newer firmware has only LPM issues */
+	{ "Crucial_CT512MX100*",	NULL,	ATA_HORKAGE_ZERO_AFTER_TRIM |
+						ATA_HORKAGE_NOLPM, },
+
+	/* 480GB+ M500 SSDs have both queued TRIM and LPM issues */
+	{ "Crucial_CT480M500*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
+						ATA_HORKAGE_ZERO_AFTER_TRIM |
+						ATA_HORKAGE_NOLPM, },
+	{ "Crucial_CT960M500*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
+						ATA_HORKAGE_ZERO_AFTER_TRIM |
+						ATA_HORKAGE_NOLPM, },
+
+	/* Sandisk devices which are known to not handle LPM well */
+	{ "SanDisk SD7UB3Q*G1001",	NULL,	ATA_HORKAGE_NOLPM, },
+
 	/* devices that don't properly handle queued TRIM commands */
 	{ "Micron_M500_*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
@@ -4237,7 +4259,9 @@ static const struct ata_blacklist_entry
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
 	{ "Crucial_CT*MX100*",		"MU01",	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
-	{ "Samsung SSD 8*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
+	{ "Samsung SSD 840*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
+						ATA_HORKAGE_ZERO_AFTER_TRIM, },
+	{ "Samsung SSD 850*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
 	{ "FCCT*M500*",			NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
@@ -5078,8 +5102,7 @@ void ata_qc_issue(struct ata_queued_cmd
 	 * We guarantee to LLDs that they will have at least one
 	 * non-zero sg if the command is a data command.
 	 */
-	if (WARN_ON_ONCE(ata_is_data(prot) &&
-			 (!qc->sg || !qc->n_elem || !qc->nbytes)))
+	if (ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes))
 		goto sys_err;
 
 	if (ata_is_dma(prot) || (ata_is_pio(prot) &&
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/ata/libata-scsi.c linux-libre-4.1.52-gnu/drivers/ata/libata-scsi.c
--- linux-libre-4.1.51-gnu/drivers/ata/libata-scsi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/ata/libata-scsi.c	2018-05-27 22:26:45.000000000 -0400
@@ -3465,7 +3465,9 @@ static inline int __ata_scsi_queuecmd(st
 		if (likely((scsi_op != ATA_16) || !atapi_passthru16)) {
 			/* relay SCSI command to ATAPI device */
 			int len = COMMAND_SIZE(scsi_op);
-			if (unlikely(len > scmd->cmd_len || len > dev->cdb_len))
+			if (unlikely(len > scmd->cmd_len ||
+				     len > dev->cdb_len ||
+				     scmd->cmd_len > ATAPI_CDB_LEN))
 				goto bad_cdb_len;
 
 			xlat_func = atapi_xlat;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/block/loop.c linux-libre-4.1.52-gnu/drivers/block/loop.c
--- linux-libre-4.1.51-gnu/drivers/block/loop.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/block/loop.c	2018-05-27 22:26:45.000000000 -0400
@@ -471,6 +471,9 @@ static int loop_switch(struct loop_devic
  */
 static int loop_flush(struct loop_device *lo)
 {
+	/* loop not yet configured, no running thread, nothing to flush */
+	if (lo->lo_state != Lo_bound)
+		return 0;
 	return loop_switch(lo, NULL);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/bluetooth/btusb.c linux-libre-4.1.52-gnu/drivers/bluetooth/btusb.c
--- linux-libre-4.1.51-gnu/drivers/bluetooth/btusb.c	2018-03-28 09:57:35.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/bluetooth/btusb.c	2018-05-29 04:44:31.000000000 -0400
@@ -203,7 +203,6 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
@@ -236,6 +235,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
 
 	/* QCA ROME chipset */
+	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME },
 	{ USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME },
 	{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
 	{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/bus/brcmstb_gisb.c linux-libre-4.1.52-gnu/drivers/bus/brcmstb_gisb.c
--- linux-libre-4.1.51-gnu/drivers/bus/brcmstb_gisb.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/bus/brcmstb_gisb.c	2018-05-27 22:26:45.000000000 -0400
@@ -33,8 +33,6 @@
 #define  ARB_ERR_CAP_CLEAR		(1 << 0)
 #define  ARB_ERR_CAP_STATUS_TIMEOUT	(1 << 12)
 #define  ARB_ERR_CAP_STATUS_TEA		(1 << 11)
-#define  ARB_ERR_CAP_STATUS_BS_SHIFT	(1 << 2)
-#define  ARB_ERR_CAP_STATUS_BS_MASK	0x3c
 #define  ARB_ERR_CAP_STATUS_WRITE	(1 << 1)
 #define  ARB_ERR_CAP_STATUS_VALID	(1 << 0)
 
@@ -43,7 +41,6 @@ enum {
 	ARB_ERR_CAP_CLR,
 	ARB_ERR_CAP_HI_ADDR,
 	ARB_ERR_CAP_ADDR,
-	ARB_ERR_CAP_DATA,
 	ARB_ERR_CAP_STATUS,
 	ARB_ERR_CAP_MASTER,
 };
@@ -53,7 +50,6 @@ static const int gisb_offsets_bcm7038[]
 	[ARB_ERR_CAP_CLR]	= 0x0c4,
 	[ARB_ERR_CAP_HI_ADDR]	= -1,
 	[ARB_ERR_CAP_ADDR]	= 0x0c8,
-	[ARB_ERR_CAP_DATA]	= 0x0cc,
 	[ARB_ERR_CAP_STATUS]	= 0x0d0,
 	[ARB_ERR_CAP_MASTER]	= -1,
 };
@@ -63,7 +59,6 @@ static const int gisb_offsets_bcm7400[]
 	[ARB_ERR_CAP_CLR]	= 0x0c8,
 	[ARB_ERR_CAP_HI_ADDR]	= -1,
 	[ARB_ERR_CAP_ADDR]	= 0x0cc,
-	[ARB_ERR_CAP_DATA]	= 0x0d0,
 	[ARB_ERR_CAP_STATUS]	= 0x0d4,
 	[ARB_ERR_CAP_MASTER]	= 0x0d8,
 };
@@ -73,7 +68,6 @@ static const int gisb_offsets_bcm7435[]
 	[ARB_ERR_CAP_CLR]	= 0x168,
 	[ARB_ERR_CAP_HI_ADDR]	= -1,
 	[ARB_ERR_CAP_ADDR]	= 0x16c,
-	[ARB_ERR_CAP_DATA]	= 0x170,
 	[ARB_ERR_CAP_STATUS]	= 0x174,
 	[ARB_ERR_CAP_MASTER]	= 0x178,
 };
@@ -83,7 +77,6 @@ static const int gisb_offsets_bcm7445[]
 	[ARB_ERR_CAP_CLR]	= 0x7e4,
 	[ARB_ERR_CAP_HI_ADDR]	= 0x7e8,
 	[ARB_ERR_CAP_ADDR]	= 0x7ec,
-	[ARB_ERR_CAP_DATA]	= 0x7f0,
 	[ARB_ERR_CAP_STATUS]	= 0x7f4,
 	[ARB_ERR_CAP_MASTER]	= 0x7f8,
 };
@@ -104,13 +97,27 @@ static u32 gisb_read(struct brcmstb_gisb
 {
 	int offset = gdev->gisb_offsets[reg];
 
-	/* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
-	if (offset == -1)
-		return 1;
+	if (offset < 0) {
+		/* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
+		if (reg == ARB_ERR_CAP_MASTER)
+			return 1;
+		else
+			return 0;
+	}
 
 	return ioread32(gdev->base + offset);
 }
 
+static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev)
+{
+	u64 value;
+
+	value = gisb_read(gdev, ARB_ERR_CAP_ADDR);
+	value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
+
+	return value;
+}
+
 static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
 {
 	int offset = gdev->gisb_offsets[reg];
@@ -173,7 +180,7 @@ static int brcmstb_gisb_arb_decode_addr(
 					const char *reason)
 {
 	u32 cap_status;
-	unsigned long arb_addr;
+	u64 arb_addr;
 	u32 master;
 	const char *m_name;
 	char m_fmt[11];
@@ -185,10 +192,7 @@ static int brcmstb_gisb_arb_decode_addr(
 		return 1;
 
 	/* Read the address and master */
-	arb_addr = gisb_read(gdev, ARB_ERR_CAP_ADDR) & 0xffffffff;
-#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
-	arb_addr |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
-#endif
+	arb_addr = gisb_read_address(gdev);
 	master = gisb_read(gdev, ARB_ERR_CAP_MASTER);
 
 	m_name = brcmstb_gisb_master_to_str(gdev, master);
@@ -197,7 +201,7 @@ static int brcmstb_gisb_arb_decode_addr(
 		m_name = m_fmt;
 	}
 
-	pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n",
+	pr_crit("%s: %s at 0x%llx [%c %s], core: %s\n",
 		__func__, reason, arb_addr,
 		cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
 		cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/cdrom/cdrom.c linux-libre-4.1.52-gnu/drivers/cdrom/cdrom.c
--- linux-libre-4.1.51-gnu/drivers/cdrom/cdrom.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/cdrom/cdrom.c	2018-05-27 22:26:45.000000000 -0400
@@ -2357,7 +2357,7 @@ static int cdrom_ioctl_media_changed(str
 	if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
 		return media_changed(cdi, 1);
 
-	if ((unsigned int)arg >= cdi->capacity)
+	if (arg >= cdi->capacity)
 		return -EINVAL;
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/char/agp/intel-gtt.c linux-libre-4.1.52-gnu/drivers/char/agp/intel-gtt.c
--- linux-libre-4.1.51-gnu/drivers/char/agp/intel-gtt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/char/agp/intel-gtt.c	2018-05-27 22:26:45.000000000 -0400
@@ -859,6 +859,8 @@ void intel_gtt_insert_sg_entries(struct
 		}
 	}
 	wmb();
+	if (intel_private.driver->chipset_flush)
+		intel_private.driver->chipset_flush();
 }
 EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/char/ipmi/ipmi_ssif.c linux-libre-4.1.52-gnu/drivers/char/ipmi/ipmi_ssif.c
--- linux-libre-4.1.51-gnu/drivers/char/ipmi/ipmi_ssif.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/char/ipmi/ipmi_ssif.c	2018-05-27 22:26:45.000000000 -0400
@@ -408,6 +408,7 @@ static void start_event_fetch(struct ssi
 	msg = ipmi_alloc_smi_msg();
 	if (!msg) {
 		ssif_info->ssif_state = SSIF_NORMAL;
+		ipmi_ssif_unlock_cond(ssif_info, flags);
 		return;
 	}
 
@@ -430,6 +431,7 @@ static void start_recv_msg_fetch(struct
 	msg = ipmi_alloc_smi_msg();
 	if (!msg) {
 		ssif_info->ssif_state = SSIF_NORMAL;
+		ipmi_ssif_unlock_cond(ssif_info, flags);
 		return;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/char/ipmi/ipmi_watchdog.c linux-libre-4.1.52-gnu/drivers/char/ipmi/ipmi_watchdog.c
--- linux-libre-4.1.51-gnu/drivers/char/ipmi/ipmi_watchdog.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/char/ipmi/ipmi_watchdog.c	2018-05-27 22:26:45.000000000 -0400
@@ -509,7 +509,7 @@ static void panic_halt_ipmi_heartbeat(vo
 	msg.cmd = IPMI_WDOG_RESET_TIMER;
 	msg.data = NULL;
 	msg.data_len = 0;
-	atomic_add(2, &panic_done_count);
+	atomic_add(1, &panic_done_count);
 	rv = ipmi_request_supply_msgs(watchdog_user,
 				      (struct ipmi_addr *) &addr,
 				      0,
@@ -519,7 +519,7 @@ static void panic_halt_ipmi_heartbeat(vo
 				      &panic_halt_heartbeat_recv_msg,
 				      1);
 	if (rv)
-		atomic_sub(2, &panic_done_count);
+		atomic_sub(1, &panic_done_count);
 }
 
 static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -543,12 +543,12 @@ static void panic_halt_ipmi_set_timeout(
 	/* Wait for the messages to be free. */
 	while (atomic_read(&panic_done_count) != 0)
 		ipmi_poll_interface(watchdog_user);
-	atomic_add(2, &panic_done_count);
+	atomic_add(1, &panic_done_count);
 	rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
 				&panic_halt_recv_msg,
 				&send_heartbeat_now);
 	if (rv) {
-		atomic_sub(2, &panic_done_count);
+		atomic_sub(1, &panic_done_count);
 		printk(KERN_WARNING PFX
 		       "Unable to extend the watchdog timeout.");
 	} else {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/char/random.c linux-libre-4.1.52-gnu/drivers/char/random.c
--- linux-libre-4.1.51-gnu/drivers/char/random.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/char/random.c	2018-05-27 22:26:45.000000000 -0400
@@ -704,7 +704,7 @@ retry:
 
 static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
 {
-	const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
+	const int nbits_max = r->poolinfo->poolwords * 32;
 
 	/* Cap the value to avoid overflows */
 	nbits = min(nbits,  nbits_max);
@@ -863,12 +863,16 @@ static void add_interrupt_bench(cycles_t
 static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
 {
 	__u32 *ptr = (__u32 *) regs;
+	unsigned int idx;
 
 	if (regs == NULL)
 		return 0;
-	if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32))
-		f->reg_idx = 0;
-	return *(ptr + f->reg_idx++);
+	idx = READ_ONCE(f->reg_idx);
+	if (idx >= sizeof(struct pt_regs) / sizeof(__u32))
+		idx = 0;
+	ptr += idx++;
+	WRITE_ONCE(f->reg_idx, idx);
+	return *ptr;
 }
 
 void add_interrupt_randomness(int irq, int irq_flags)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/char/tpm/tpm_tis.c linux-libre-4.1.52-gnu/drivers/char/tpm/tpm_tis.c
--- linux-libre-4.1.51-gnu/drivers/char/tpm/tpm_tis.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/char/tpm/tpm_tis.c	2018-05-27 22:26:45.000000000 -0400
@@ -283,7 +283,8 @@ static int recv_data(struct tpm_chip *ch
 static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	int size = 0;
-	int expected, status;
+	int status;
+	u32 expected;
 
 	if (count < TPM_HEADER_SIZE) {
 		size = -EIO;
@@ -298,7 +299,7 @@ static int tpm_tis_recv(struct tpm_chip
 	}
 
 	expected = be32_to_cpu(*(__be32 *) (buf + 2));
-	if (expected > count) {
+	if (expected > count || expected < TPM_HEADER_SIZE) {
 		size = -EIO;
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/char/virtio_console.c linux-libre-4.1.52-gnu/drivers/char/virtio_console.c
--- linux-libre-4.1.51-gnu/drivers/char/virtio_console.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/char/virtio_console.c	2018-05-27 22:26:45.000000000 -0400
@@ -1399,7 +1399,6 @@ static int add_port(struct ports_device
 {
 	char debugfs_name[16];
 	struct port *port;
-	struct port_buffer *buf;
 	dev_t devt;
 	unsigned int nr_added_bufs;
 	int err;
@@ -1510,8 +1509,6 @@ static int add_port(struct ports_device
 	return 0;
 
 free_inbufs:
-	while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
-		free_buf(buf, true);
 free_device:
 	device_destroy(pdrvdata.class, port->dev->devt);
 free_cdev:
@@ -1536,34 +1533,14 @@ static void remove_port(struct kref *kre
 
 static void remove_port_data(struct port *port)
 {
-	struct port_buffer *buf;
-
 	spin_lock_irq(&port->inbuf_lock);
 	/* Remove unused data this port might have received. */
 	discard_port_data(port);
 	spin_unlock_irq(&port->inbuf_lock);
 
-	/* Remove buffers we queued up for the Host to send us data in. */
-	do {
-		spin_lock_irq(&port->inbuf_lock);
-		buf = virtqueue_detach_unused_buf(port->in_vq);
-		spin_unlock_irq(&port->inbuf_lock);
-		if (buf)
-			free_buf(buf, true);
-	} while (buf);
-
 	spin_lock_irq(&port->outvq_lock);
 	reclaim_consumed_buffers(port);
 	spin_unlock_irq(&port->outvq_lock);
-
-	/* Free pending buffers from the out-queue. */
-	do {
-		spin_lock_irq(&port->outvq_lock);
-		buf = virtqueue_detach_unused_buf(port->out_vq);
-		spin_unlock_irq(&port->outvq_lock);
-		if (buf)
-			free_buf(buf, true);
-	} while (buf);
 }
 
 /*
@@ -1788,13 +1765,24 @@ static void control_work_handler(struct
 	spin_unlock(&portdev->c_ivq_lock);
 }
 
+static void flush_bufs(struct virtqueue *vq, bool can_sleep)
+{
+	struct port_buffer *buf;
+	unsigned int len;
+
+	while ((buf = virtqueue_get_buf(vq, &len)))
+		free_buf(buf, can_sleep);
+}
+
 static void out_intr(struct virtqueue *vq)
 {
 	struct port *port;
 
 	port = find_port_by_vq(vq->vdev->priv, vq);
-	if (!port)
+	if (!port) {
+		flush_bufs(vq, false);
 		return;
+	}
 
 	wake_up_interruptible(&port->waitqueue);
 }
@@ -1805,8 +1793,10 @@ static void in_intr(struct virtqueue *vq
 	unsigned long flags;
 
 	port = find_port_by_vq(vq->vdev->priv, vq);
-	if (!port)
+	if (!port) {
+		flush_bufs(vq, false);
 		return;
+	}
 
 	spin_lock_irqsave(&port->inbuf_lock, flags);
 	port->inbuf = get_inbuf(port);
@@ -1981,6 +1971,15 @@ static const struct file_operations port
 
 static void remove_vqs(struct ports_device *portdev)
 {
+	struct virtqueue *vq;
+
+	virtio_device_for_each_vq(portdev->vdev, vq) {
+		struct port_buffer *buf;
+
+		flush_bufs(vq, true);
+		while ((buf = virtqueue_detach_unused_buf(vq)))
+			free_buf(buf, true);
+	}
 	portdev->vdev->config->del_vqs(portdev->vdev);
 	kfree(portdev->in_vqs);
 	kfree(portdev->out_vqs);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/clk/clk-si5351.c linux-libre-4.1.52-gnu/drivers/clk/clk-si5351.c
--- linux-libre-4.1.51-gnu/drivers/clk/clk-si5351.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/clk/clk-si5351.c	2018-05-27 22:26:45.000000000 -0400
@@ -72,7 +72,7 @@ static const char * const si5351_input_n
 	"xtal", "clkin"
 };
 static const char * const si5351_pll_names[] = {
-	"plla", "pllb", "vxco"
+	"si5351_plla", "si5351_pllb", "si5351_vxco"
 };
 static const char * const si5351_msynth_names[] = {
 	"ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/clk/mvebu/armada-38x.c linux-libre-4.1.52-gnu/drivers/clk/mvebu/armada-38x.c
--- linux-libre-4.1.51-gnu/drivers/clk/mvebu/armada-38x.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/clk/mvebu/armada-38x.c	2018-05-27 22:26:45.000000000 -0400
@@ -46,10 +46,11 @@ static u32 __init armada_38x_get_tclk_fr
 }
 
 static const u32 armada_38x_cpu_frequencies[] __initconst = {
-	0, 0, 0, 0,
-	1066 * 1000 * 1000, 0, 0, 0,
+	666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
+	1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
 	1332 * 1000 * 1000, 0, 0, 0,
-	1600 * 1000 * 1000,
+	1600 * 1000 * 1000, 0, 0, 0,
+	1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -75,11 +76,11 @@ static const struct coreclk_ratio armada
 };
 
 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
-	{0, 1}, {0, 1}, {0, 1}, {0, 1},
-	{1, 2}, {0, 1}, {0, 1}, {0, 1},
+	{1, 2}, {0, 1}, {1, 2}, {0, 1},
+	{1, 2}, {0, 1}, {1, 2}, {0, 1},
 	{1, 2}, {0, 1}, {0, 1}, {0, 1},
 	{1, 2}, {0, 1}, {0, 1}, {0, 1},
-	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+	{1, 2}, {0, 1}, {0, 1}, {1, 2},
 	{0, 1}, {0, 1}, {0, 1}, {0, 1},
 	{0, 1}, {0, 1}, {0, 1}, {0, 1},
 	{0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -90,7 +91,7 @@ static const int armada_38x_cpu_ddr_rati
 	{1, 2}, {0, 1}, {0, 1}, {0, 1},
 	{1, 2}, {0, 1}, {0, 1}, {0, 1},
 	{1, 2}, {0, 1}, {0, 1}, {0, 1},
-	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+	{1, 2}, {0, 1}, {0, 1}, {7, 15},
 	{0, 1}, {0, 1}, {0, 1}, {0, 1},
 	{0, 1}, {0, 1}, {0, 1}, {0, 1},
 	{0, 1}, {0, 1}, {0, 1}, {0, 1},
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/cpufreq/sh-cpufreq.c linux-libre-4.1.52-gnu/drivers/cpufreq/sh-cpufreq.c
--- linux-libre-4.1.51-gnu/drivers/cpufreq/sh-cpufreq.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/cpufreq/sh-cpufreq.c	2018-05-27 22:26:45.000000000 -0400
@@ -30,54 +30,63 @@
 
 static DEFINE_PER_CPU(struct clk, sh_cpuclk);
 
+struct cpufreq_target {
+	struct cpufreq_policy	*policy;
+	unsigned int		freq;
+};
+
 static unsigned int sh_cpufreq_get(unsigned int cpu)
 {
 	return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000;
 }
 
-/*
- * Here we notify other drivers of the proposed change and the final change.
- */
-static int sh_cpufreq_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
+static long __sh_cpufreq_target(void *arg)
 {
-	unsigned int cpu = policy->cpu;
+	struct cpufreq_target *target = arg;
+	struct cpufreq_policy *policy = target->policy;
+	int cpu = policy->cpu;
 	struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu);
-	cpumask_t cpus_allowed;
 	struct cpufreq_freqs freqs;
 	struct device *dev;
 	long freq;
 
-	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
-	BUG_ON(smp_processor_id() != cpu);
+	if (smp_processor_id() != cpu)
+		return -ENODEV;
 
 	dev = get_cpu_device(cpu);
 
 	/* Convert target_freq from kHz to Hz */
-	freq = clk_round_rate(cpuclk, target_freq * 1000);
+	freq = clk_round_rate(cpuclk, target->freq * 1000);
 
 	if (freq < (policy->min * 1000) || freq > (policy->max * 1000))
 		return -EINVAL;
 
-	dev_dbg(dev, "requested frequency %u Hz\n", target_freq * 1000);
+	dev_dbg(dev, "requested frequency %u Hz\n", target->freq * 1000);
 
 	freqs.old	= sh_cpufreq_get(cpu);
 	freqs.new	= (freq + 500) / 1000;
 	freqs.flags	= 0;
 
-	cpufreq_freq_transition_begin(policy, &freqs);
-	set_cpus_allowed_ptr(current, &cpus_allowed);
+	cpufreq_freq_transition_begin(target->policy, &freqs);
 	clk_set_rate(cpuclk, freq);
-	cpufreq_freq_transition_end(policy, &freqs, 0);
+	cpufreq_freq_transition_end(target->policy, &freqs, 0);
 
 	dev_dbg(dev, "set frequency %lu Hz\n", freq);
-
 	return 0;
 }
 
+/*
+ * Here we notify other drivers of the proposed change and the final change.
+ */
+static int sh_cpufreq_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
+{
+	struct cpufreq_target data = { .policy = policy, .freq = target_freq };
+
+	return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data);
+}
+
 static int sh_cpufreq_verify(struct cpufreq_policy *policy)
 {
 	struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/cpuidle/dt_idle_states.c linux-libre-4.1.52-gnu/drivers/cpuidle/dt_idle_states.c
--- linux-libre-4.1.51-gnu/drivers/cpuidle/dt_idle_states.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/cpuidle/dt_idle_states.c	2018-05-27 22:26:45.000000000 -0400
@@ -174,8 +174,10 @@ int dt_init_idle_driver(struct cpuidle_d
 		if (!state_node)
 			break;
 
-		if (!of_device_is_available(state_node))
+		if (!of_device_is_available(state_node)) {
+			of_node_put(state_node);
 			continue;
+		}
 
 		if (!idle_state_valid(state_node, i, cpumask)) {
 			pr_warn("%s idle state not valid, bailing out\n",
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/dma/at_xdmac.c linux-libre-4.1.52-gnu/drivers/dma/at_xdmac.c
--- linux-libre-4.1.51-gnu/drivers/dma/at_xdmac.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/dma/at_xdmac.c	2018-05-27 22:26:45.000000000 -0400
@@ -1003,10 +1003,10 @@ at_xdmac_tx_status(struct dma_chan *chan
 	for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) {
 		check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
 		rmb();
-		initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD);
-		rmb();
 		cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
 		rmb();
+		initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD);
+		rmb();
 		cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
 		rmb();
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/dma/imx-sdma.c linux-libre-4.1.52-gnu/drivers/dma/imx-sdma.c
--- linux-libre-4.1.51-gnu/drivers/dma/imx-sdma.c	2018-03-28 09:45:27.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/dma/imx-sdma.c	2018-05-29 04:32:48.000000000 -0400
@@ -1503,17 +1503,24 @@ static int sdma_probe(struct platform_de
 	if (IS_ERR(sdma->clk_ahb))
 		return PTR_ERR(sdma->clk_ahb);
 
-	clk_prepare(sdma->clk_ipg);
-	clk_prepare(sdma->clk_ahb);
+	ret = clk_prepare(sdma->clk_ipg);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare(sdma->clk_ahb);
+	if (ret)
+		goto err_clk;
 
 	ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma",
 			       sdma);
 	if (ret)
-		return ret;
+		goto err_irq;
 
 	sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL);
-	if (!sdma->script_addrs)
-		return -ENOMEM;
+	if (!sdma->script_addrs) {
+		ret = -ENOMEM;
+		goto err_irq;
+	}
 
 	/* initially no scripts available */
 	saddr_arr = (s32 *)sdma->script_addrs;
@@ -1618,6 +1625,10 @@ err_register:
 	dma_async_device_unregister(&sdma->dma_device);
 err_init:
 	kfree(sdma->script_addrs);
+err_irq:
+	clk_unprepare(sdma->clk_ahb);
+err_clk:
+	clk_unprepare(sdma->clk_ipg);
 	return ret;
 }
 
@@ -1628,6 +1639,8 @@ static int sdma_remove(struct platform_d
 
 	dma_async_device_unregister(&sdma->dma_device);
 	kfree(sdma->script_addrs);
+	clk_unprepare(sdma->clk_ahb);
+	clk_unprepare(sdma->clk_ipg);
 	/* Kill the tasklet */
 	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
 		struct sdma_channel *sdmac = &sdma->channel[i];
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/edac/mv64x60_edac.c linux-libre-4.1.52-gnu/drivers/edac/mv64x60_edac.c
--- linux-libre-4.1.51-gnu/drivers/edac/mv64x60_edac.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/edac/mv64x60_edac.c	2018-05-27 22:26:45.000000000 -0400
@@ -763,7 +763,7 @@ static int mv64x60_mc_err_probe(struct p
 		/* Non-ECC RAM? */
 		printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
 		res = -ENODEV;
-		goto err2;
+		goto err;
 	}
 
 	edac_dbg(3, "init mci\n");
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpio/gpiolib.c linux-libre-4.1.52-gnu/drivers/gpio/gpiolib.c
--- linux-libre-4.1.51-gnu/drivers/gpio/gpiolib.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpio/gpiolib.c	2018-05-27 22:26:45.000000000 -0400
@@ -1998,7 +1998,8 @@ struct gpio_desc *__must_check __gpiod_g
 		return desc;
 	}
 
-	status = gpiod_request(desc, con_id);
+	/* If a connection label was passed use that, else use the device name as label */
+	status = gpiod_request(desc, con_id ? con_id : dev_name(dev));
 	if (status < 0)
 		return ERR_PTR(status);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/amd/amdkfd/kfd_topology.c linux-libre-4.1.52-gnu/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/amd/amdkfd/kfd_topology.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/amd/amdkfd/kfd_topology.c	2018-05-27 22:26:45.000000000 -0400
@@ -519,11 +519,17 @@ static ssize_t sysprops_show(struct kobj
 	return ret;
 }
 
+static void kfd_topology_kobj_release(struct kobject *kobj)
+{
+	kfree(kobj);
+}
+
 static const struct sysfs_ops sysprops_ops = {
 	.show = sysprops_show,
 };
 
 static struct kobj_type sysprops_type = {
+	.release = kfd_topology_kobj_release,
 	.sysfs_ops = &sysprops_ops,
 };
 
@@ -559,6 +565,7 @@ static const struct sysfs_ops iolink_ops
 };
 
 static struct kobj_type iolink_type = {
+	.release = kfd_topology_kobj_release,
 	.sysfs_ops = &iolink_ops,
 };
 
@@ -586,6 +593,7 @@ static const struct sysfs_ops mem_ops =
 };
 
 static struct kobj_type mem_type = {
+	.release = kfd_topology_kobj_release,
 	.sysfs_ops = &mem_ops,
 };
 
@@ -625,6 +633,7 @@ static const struct sysfs_ops cache_ops
 };
 
 static struct kobj_type cache_type = {
+	.release = kfd_topology_kobj_release,
 	.sysfs_ops = &cache_ops,
 };
 
@@ -747,6 +756,7 @@ static const struct sysfs_ops node_ops =
 };
 
 static struct kobj_type node_type = {
+	.release = kfd_topology_kobj_release,
 	.sysfs_ops = &node_ops,
 };
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/drm_edid.c linux-libre-4.1.52-gnu/drivers/gpu/drm/drm_edid.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/drm_edid.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/drm_edid.c	2018-05-27 22:26:45.000000000 -0400
@@ -3103,8 +3103,7 @@ monitor_name(struct detailed_timing *t,
  * @edid: EDID to parse
  *
  * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
- * Conn_Type, HDCP and Port_ID ELD fields are left for the graphics driver to
- * fill in.
+ * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
  */
 void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 {
@@ -3177,6 +3176,12 @@ void drm_edid_to_eld(struct drm_connecto
 	}
 	eld[5] |= sad_count << 4;
 
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+		eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_DP;
+	else
+		eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_HDMI;
+
 	eld[DRM_ELD_BASELINE_ELD_LEN] =
 		DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/drm_irq.c linux-libre-4.1.52-gnu/drivers/gpu/drm/drm_irq.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/drm_irq.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/drm_irq.c	2018-05-27 22:26:45.000000000 -0400
@@ -1090,9 +1090,9 @@ void drm_vblank_put(struct drm_device *d
 	if (atomic_dec_and_test(&vblank->refcount)) {
 		if (drm_vblank_offdelay == 0)
 			return;
-		else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
+		else if (drm_vblank_offdelay < 0)
 			vblank_disable_fn((unsigned long)vblank);
-		else
+		else if (!dev->vblank_disable_immediate)
 			mod_timer(&vblank->disable_timer,
 				  jiffies + ((drm_vblank_offdelay * HZ)/1000));
 	}
@@ -1750,6 +1750,16 @@ bool drm_handle_vblank(struct drm_device
 	wake_up(&vblank->queue);
 	drm_handle_vblank_events(dev, crtc);
 
+	/* With instant-off, we defer disabling the interrupt until after
+	 * we finish processing the following vblank. The disable has to
+	 * be last (after drm_handle_vblank_events) so that the timestamp
+	 * is always accurate.
+	 */
+	if (dev->vblank_disable_immediate &&
+	    drm_vblank_offdelay > 0 &&
+	    !atomic_read(&vblank->refcount))
+		vblank_disable_fn((unsigned long)vblank);
+
 	spin_unlock_irqrestore(&dev->event_lock, irqflags);
 
 	return true;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c linux-libre-4.1.52-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c	2018-05-27 22:26:45.000000000 -0400
@@ -241,6 +241,15 @@ struct exynos_drm_gem_obj *exynos_drm_ge
 
 	exynos_gem_obj->buffer = buf;
 
+	if (!is_drm_iommu_supported(dev) && (flags & EXYNOS_BO_NONCONTIG)) {
+		/*
+		 * when no IOMMU is available, all allocated buffers are
+		 * contiguous anyway, so drop EXYNOS_BO_NONCONTIG flag
+		 */
+		flags &= ~EXYNOS_BO_NONCONTIG;
+		DRM_WARN("Non-contiguous allocation is not supported without IOMMU, falling back to contiguous buffer\n");
+	}
+
 	/* set memory type and cache attribute from user side. */
 	exynos_gem_obj->flags = flags;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/msm/msm_gem.c linux-libre-4.1.52-gnu/drivers/gpu/drm/msm/msm_gem.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/msm/msm_gem.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/msm/msm_gem.c	2018-05-27 22:26:45.000000000 -0400
@@ -89,14 +89,17 @@ static struct page **get_pages(struct dr
 			return p;
 		}
 
+		msm_obj->pages = p;
+
 		msm_obj->sgt = drm_prime_pages_to_sg(p, npages);
 		if (IS_ERR(msm_obj->sgt)) {
+			void *ptr = ERR_CAST(msm_obj->sgt);
+
 			dev_err(dev->dev, "failed to allocate sgt\n");
-			return ERR_CAST(msm_obj->sgt);
+			msm_obj->sgt = NULL;
+			return ptr;
 		}
 
-		msm_obj->pages = p;
-
 		/* For non-cached buffers, ensure the new pages are clean
 		 * because display controller, GPU, etc. are not coherent:
 		 */
@@ -119,7 +122,10 @@ static void put_pages(struct drm_gem_obj
 		if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
 			dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
 					msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
-		sg_free_table(msm_obj->sgt);
+
+		if (msm_obj->sgt)
+			sg_free_table(msm_obj->sgt);
+
 		kfree(msm_obj->sgt);
 
 		if (use_pages(obj))
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c linux-libre-4.1.52-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c	2018-05-27 22:26:45.000000000 -0400
@@ -287,7 +287,12 @@ static int dmm_txn_commit(struct dmm_txn
 				msecs_to_jiffies(1))) {
 			dev_err(dmm->dev, "timed out waiting for done\n");
 			ret = -ETIMEDOUT;
+			goto cleanup;
 		}
+
+		/* Check the engine status before continue */
+		ret = wait_status(engine, DMM_PATSTATUS_READY |
+				  DMM_PATSTATUS_VALID | DMM_PATSTATUS_DONE);
 	}
 
 cleanup:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/omapdrm/omap_gem.c linux-libre-4.1.52-gnu/drivers/gpu/drm/omapdrm/omap_gem.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/omapdrm/omap_gem.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/omapdrm/omap_gem.c	2018-05-27 22:26:45.000000000 -0400
@@ -158,7 +158,7 @@ static void evict_entry(struct drm_gem_o
 	size_t size = PAGE_SIZE * n;
 	loff_t off = mmap_offset(obj) +
 			(entry->obj_pgoff << PAGE_SHIFT);
-	const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE);
+	const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE);
 
 	if (m > 1) {
 		int i;
@@ -415,7 +415,7 @@ static int fault_2d(struct drm_gem_objec
 	 * into account in some of the math, so figure out virtual stride
 	 * in pages
 	 */
-	const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE);
+	const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE);
 
 	/* We don't use vmf->pgoff since that has the fake offset: */
 	pgoff = ((unsigned long)vmf->virtual_address -
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/radeon_connectors.c linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/radeon_connectors.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/radeon_connectors.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/radeon_connectors.c	2018-05-27 22:26:45.000000000 -0400
@@ -89,25 +89,18 @@ void radeon_connector_hotplug(struct drm
 		/* don't do anything if sink is not display port, i.e.,
 		 * passive dp->(dvi|hdmi) adaptor
 		 */
-		if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
-			int saved_dpms = connector->dpms;
-			/* Only turn off the display if it's physically disconnected */
-			if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
-				drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
-			} else if (radeon_dp_needs_link_train(radeon_connector)) {
-				/* Don't try to start link training before we
-				 * have the dpcd */
-				if (!radeon_dp_getdpcd(radeon_connector))
-					return;
+		if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
+		    radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
+		    radeon_dp_needs_link_train(radeon_connector)) {
+			/* Don't start link training before we have the DPCD */
+			if (!radeon_dp_getdpcd(radeon_connector))
+				return;
 
-				/* set it to OFF so that drm_helper_connector_dpms()
-				 * won't return immediately since the current state
-				 * is ON at this point.
-				 */
-				connector->dpms = DRM_MODE_DPMS_OFF;
-				drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
-			}
-			connector->dpms = saved_dpms;
+			/* Turn the connector off and back on immediately, which
+			 * will trigger link training
+			 */
+			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
 		}
 	}
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/radeon_display.c linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/radeon_display.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/radeon_display.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/radeon_display.c	2018-05-27 22:26:45.000000000 -0400
@@ -1321,6 +1321,12 @@ radeon_user_framebuffer_create(struct dr
 		return ERR_PTR(-ENOENT);
 	}
 
+	/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
+	if (obj->import_attach) {
+		DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n");
+		return ERR_PTR(-EINVAL);
+	}
+
 	radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
 	if (radeon_fb == NULL) {
 		drm_gem_object_unreference_unlocked(obj);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/radeon_object.c linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/radeon_object.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/radeon_object.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/radeon_object.c	2018-05-27 22:26:45.000000000 -0400
@@ -232,9 +232,10 @@ int radeon_bo_create(struct radeon_devic
 	 * may be slow
 	 * See https://bugs.freedesktop.org/show_bug.cgi?id=88758
 	 */
-
+#ifndef CONFIG_COMPILE_TEST
 #warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
 	 thanks to write-combining
+#endif
 
 	DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
 		      "better performance thanks to write-combining\n");
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/si_dpm.c linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/si_dpm.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/radeon/si_dpm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/radeon/si_dpm.c	2018-05-27 22:26:45.000000000 -0400
@@ -5895,9 +5895,9 @@ static void si_set_pcie_lane_width_in_sm
 {
 	u32 lane_width;
 	u32 new_lane_width =
-		(radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT;
+		((radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
 	u32 current_lane_width =
-		(radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT;
+		((radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
 
 	if (new_lane_width != current_lane_width) {
 		radeon_set_pcie_lanes(rdev, new_lane_width);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/gpu/drm/udl/udl_fb.c linux-libre-4.1.52-gnu/drivers/gpu/drm/udl/udl_fb.c
--- linux-libre-4.1.51-gnu/drivers/gpu/drm/udl/udl_fb.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/gpu/drm/udl/udl_fb.c	2018-05-27 22:26:45.000000000 -0400
@@ -256,10 +256,15 @@ static int udl_fb_mmap(struct fb_info *i
 {
 	unsigned long start = vma->vm_start;
 	unsigned long size = vma->vm_end - vma->vm_start;
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long offset;
 	unsigned long page, pos;
 
-	if (offset + size > info->fix.smem_len)
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+
+	offset = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (offset > info->fix.smem_len || size > info->fix.smem_len - offset)
 		return -EINVAL;
 
 	pos = (unsigned long)info->fix.smem_start + offset;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hid/hid-core.c linux-libre-4.1.52-gnu/drivers/hid/hid-core.c
--- linux-libre-4.1.51-gnu/drivers/hid/hid-core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hid/hid-core.c	2018-05-27 22:26:45.000000000 -0400
@@ -1308,7 +1308,7 @@ u8 *hid_alloc_report_buf(struct hid_repo
 	 * of implement() working on 8 byte chunks
 	 */
 
-	int len = hid_report_len(report) + 7;
+	u32 len = hid_report_len(report) + 7;
 
 	return kmalloc(len, flags);
 }
@@ -1373,7 +1373,7 @@ void __hid_request(struct hid_device *hi
 {
 	char *buf;
 	int ret;
-	int len;
+	u32 len;
 
 	buf = hid_alloc_report_buf(report, GFP_KERNEL);
 	if (!buf)
@@ -1399,14 +1399,14 @@ out:
 }
 EXPORT_SYMBOL_GPL(__hid_request);
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 		int interrupt)
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
 	struct hid_driver *hdrv;
 	unsigned int a;
-	int rsize, csize = size;
+	u32 rsize, csize = size;
 	u8 *cdata = data;
 	int ret = 0;
 
@@ -1464,7 +1464,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
  *
  * This is data entry for lower layers.
  */
-int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt)
+int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt)
 {
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hid/hid-elo.c linux-libre-4.1.52-gnu/drivers/hid/hid-elo.c
--- linux-libre-4.1.51-gnu/drivers/hid/hid-elo.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hid/hid-elo.c	2018-05-27 22:26:45.000000000 -0400
@@ -42,6 +42,12 @@ static void elo_input_configured(struct
 {
 	struct input_dev *input = hidinput->input;
 
+	/*
+	 * ELO devices have one Button usage in GenDesk field, which makes
+	 * hid-input map it to BTN_LEFT; that confuses userspace, which then
+	 * considers the device to be a mouse/touchpad instead of touchscreen.
+	 */
+	clear_bit(BTN_LEFT, input->keybit);
 	set_bit(BTN_TOUCH, input->keybit);
 	set_bit(ABS_PRESSURE, input->absbit);
 	input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hid/hid-input.c linux-libre-4.1.52-gnu/drivers/hid/hid-input.c
--- linux-libre-4.1.51-gnu/drivers/hid/hid-input.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hid/hid-input.c	2018-05-27 22:26:45.000000000 -0400
@@ -1128,18 +1128,26 @@ void hidinput_hid_event(struct hid_devic
 
 	/*
 	 * Ignore out-of-range values as per HID specification,
-	 * section 5.10 and 6.2.25.
+	 * section 5.10 and 6.2.25, when NULL state bit is present.
+	 * When it's not, clamp the value to match Microsoft's input
+	 * driver as mentioned in "Required HID usages for digitizers":
+	 * https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp
 	 *
 	 * The logical_minimum < logical_maximum check is done so that we
 	 * don't unintentionally discard values sent by devices which
 	 * don't specify logical min and max.
 	 */
 	if ((field->flags & HID_MAIN_ITEM_VARIABLE) &&
-	    (field->logical_minimum < field->logical_maximum) &&
-	    (value < field->logical_minimum ||
-	     value > field->logical_maximum)) {
-		dbg_hid("Ignoring out-of-range value %x\n", value);
-		return;
+	    (field->logical_minimum < field->logical_maximum)) {
+		if (field->flags & HID_MAIN_ITEM_NULL_STATE &&
+		    (value < field->logical_minimum ||
+		     value > field->logical_maximum)) {
+			dbg_hid("Ignoring out-of-range value %x\n", value);
+			return;
+		}
+		value = clamp(value,
+			      field->logical_minimum,
+			      field->logical_maximum);
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hid/hidraw.c linux-libre-4.1.52-gnu/drivers/hid/hidraw.c
--- linux-libre-4.1.51-gnu/drivers/hid/hidraw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hid/hidraw.c	2018-05-27 22:26:45.000000000 -0400
@@ -197,6 +197,11 @@ static ssize_t hidraw_get_report(struct
 	int ret = 0, len;
 	unsigned char report_number;
 
+	if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+		ret = -ENODEV;
+		goto out;
+	}
+
 	dev = hidraw_table[minor]->hid;
 
 	if (!dev->ll_driver->raw_request) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hid/i2c-hid/i2c-hid.c linux-libre-4.1.52-gnu/drivers/hid/i2c-hid/i2c-hid.c
--- linux-libre-4.1.51-gnu/drivers/hid/i2c-hid/i2c-hid.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hid/i2c-hid/i2c-hid.c	2018-05-27 22:26:45.000000000 -0400
@@ -137,10 +137,10 @@ struct i2c_hid {
 						   * register of the HID
 						   * descriptor. */
 	unsigned int		bufsize;	/* i2c buffer size */
-	char			*inbuf;		/* Input buffer */
-	char			*rawbuf;	/* Raw Input buffer */
-	char			*cmdbuf;	/* Command buffer */
-	char			*argsbuf;	/* Command arguments buffer */
+	u8			*inbuf;		/* Input buffer */
+	u8			*rawbuf;	/* Raw Input buffer */
+	u8			*cmdbuf;	/* Command buffer */
+	u8			*argsbuf;	/* Command arguments buffer */
 
 	unsigned long		flags;		/* device flags */
 
@@ -385,7 +385,8 @@ static int i2c_hid_hwreset(struct i2c_cl
 
 static void i2c_hid_get_input(struct i2c_hid *ihid)
 {
-	int ret, ret_size;
+	int ret;
+	u32 ret_size;
 	int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
 
 	if (size > ihid->bufsize)
@@ -410,7 +411,7 @@ static void i2c_hid_get_input(struct i2c
 		return;
 	}
 
-	if (ret_size > size) {
+	if ((ret_size > size) || (ret_size <= 2)) {
 		dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
 			__func__, size, ret_size);
 		return;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hsi/clients/ssi_protocol.c linux-libre-4.1.52-gnu/drivers/hsi/clients/ssi_protocol.c
--- linux-libre-4.1.51-gnu/drivers/hsi/clients/ssi_protocol.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hsi/clients/ssi_protocol.c	2018-05-27 22:26:45.000000000 -0400
@@ -976,7 +976,7 @@ static int ssip_pn_xmit(struct sk_buff *
 		goto drop;
 	/* Pad to 32-bits - FIXME: Revisit*/
 	if ((skb->len & 3) && skb_pad(skb, 4 - (skb->len & 3)))
-		goto drop;
+		goto inc_dropped;
 
 	/*
 	 * Modem sends Phonet messages over SSI with its own endianess...
@@ -1028,8 +1028,9 @@ static int ssip_pn_xmit(struct sk_buff *
 drop2:
 	hsi_free_msg(msg);
 drop:
-	dev->stats.tx_dropped++;
 	dev_kfree_skb(skb);
+inc_dropped:
+	dev->stats.tx_dropped++;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hwtracing/coresight/coresight-tpiu.c linux-libre-4.1.52-gnu/drivers/hwtracing/coresight/coresight-tpiu.c
--- linux-libre-4.1.51-gnu/drivers/hwtracing/coresight/coresight-tpiu.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hwtracing/coresight/coresight-tpiu.c	2018-05-27 22:26:45.000000000 -0400
@@ -44,8 +44,11 @@
 #define TPIU_ITATBCTR0		0xef8
 
 /** register definition **/
+/* FFSR - 0x300 */
+#define FFSR_FT_STOPPED		BIT(1)
 /* FFCR - 0x304 */
 #define FFCR_FON_MAN		BIT(6)
+#define FFCR_STOP_FI		BIT(12)
 
 /**
  * @base:	memory mapped base address for this component.
@@ -88,10 +91,14 @@ static void tpiu_disable_hw(struct tpiu_
 {
 	CS_UNLOCK(drvdata->base);
 
-	/* Clear formatter controle reg. */
-	writel_relaxed(0x0, drvdata->base + TPIU_FFCR);
+	/* Clear formatter and stop on flush */
+	writel_relaxed(FFCR_STOP_FI, drvdata->base + TPIU_FFCR);
 	/* Generate manual flush */
-	writel_relaxed(FFCR_FON_MAN, drvdata->base + TPIU_FFCR);
+	writel_relaxed(FFCR_STOP_FI | FFCR_FON_MAN, drvdata->base + TPIU_FFCR);
+	/* Wait for flush to complete */
+	coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN, 0);
+	/* Wait for formatter to stop */
+	coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED, 1);
 
 	CS_LOCK(drvdata->base);
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/hwtracing/coresight/of_coresight.c linux-libre-4.1.52-gnu/drivers/hwtracing/coresight/of_coresight.c
--- linux-libre-4.1.51-gnu/drivers/hwtracing/coresight/of_coresight.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/hwtracing/coresight/of_coresight.c	2018-05-27 22:26:45.000000000 -0400
@@ -150,7 +150,7 @@ struct coresight_platform_data *of_get_c
 				continue;
 
 			/* The local out port number */
-			pdata->outports[i] = endpoint.id;
+			pdata->outports[i] = endpoint.port;
 
 			/*
 			 * Get a handle on the remote port and parent
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/i2c/busses/i2c-scmi.c linux-libre-4.1.52-gnu/drivers/i2c/busses/i2c-scmi.c
--- linux-libre-4.1.51-gnu/drivers/i2c/busses/i2c-scmi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/i2c/busses/i2c-scmi.c	2018-05-27 22:26:45.000000000 -0400
@@ -18,6 +18,9 @@
 #define ACPI_SMBUS_HC_CLASS		"smbus"
 #define ACPI_SMBUS_HC_DEVICE_NAME	"cmi"
 
+/* SMBUS HID definition as supported by Microsoft Windows */
+#define ACPI_SMBUS_MS_HID		"SMB0001"
+
 ACPI_MODULE_NAME("smbus_cmi");
 
 struct smbus_methods_t {
@@ -51,6 +54,7 @@ static const struct smbus_methods_t ibm_
 static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
 	{"SMBUS01", (kernel_ulong_t)&smbus_methods},
 	{ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
+	{ACPI_SMBUS_MS_HID, (kernel_ulong_t)&smbus_methods},
 	{"", 0}
 };
 MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/iio/accel/st_accel_core.c linux-libre-4.1.52-gnu/drivers/iio/accel/st_accel_core.c
--- linux-libre-4.1.51-gnu/drivers/iio/accel/st_accel_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/iio/accel/st_accel_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -535,6 +535,8 @@ static const struct iio_trigger_ops st_a
 int st_accel_common_probe(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *adata = iio_priv(indio_dev);
+	struct st_sensors_platform_data *pdata =
+		(struct st_sensors_platform_data *)adata->dev->platform_data;
 	int irq = adata->get_irq_data_ready(indio_dev);
 	int err;
 
@@ -559,11 +561,10 @@ int st_accel_common_probe(struct iio_dev
 					&adata->sensor_settings->fs.fs_avl[0];
 	adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
 
-	if (!adata->dev->platform_data)
-		adata->dev->platform_data =
-			(struct st_sensors_platform_data *)&default_accel_pdata;
+	if (!pdata)
+		pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
 
-	err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
+	err = st_sensors_init_sensor(indio_dev, pdata);
 	if (err < 0)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/iio/magnetometer/st_magn_spi.c linux-libre-4.1.52-gnu/drivers/iio/magnetometer/st_magn_spi.c
--- linux-libre-4.1.51-gnu/drivers/iio/magnetometer/st_magn_spi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/iio/magnetometer/st_magn_spi.c	2018-05-27 22:26:45.000000000 -0400
@@ -48,8 +48,6 @@ static int st_magn_spi_remove(struct spi
 }
 
 static const struct spi_device_id st_magn_id_table[] = {
-	{ LSM303DLHC_MAGN_DEV_NAME },
-	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
 	{},
 };
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/iio/pressure/st_pressure_core.c linux-libre-4.1.52-gnu/drivers/iio/pressure/st_pressure_core.c
--- linux-libre-4.1.51-gnu/drivers/iio/pressure/st_pressure_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/iio/pressure/st_pressure_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -432,6 +432,8 @@ static const struct iio_trigger_ops st_p
 int st_press_common_probe(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *press_data = iio_priv(indio_dev);
+	struct st_sensors_platform_data *pdata =
+		(struct st_sensors_platform_data *)press_data->dev->platform_data;
 	int irq = press_data->get_irq_data_ready(indio_dev);
 	int err;
 
@@ -460,12 +462,10 @@ int st_press_common_probe(struct iio_dev
 	press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
 
 	/* Some devices don't support a data ready pin. */
-	if (!press_data->dev->platform_data &&
-				press_data->sensor_settings->drdy_irq.addr)
-		press_data->dev->platform_data =
-			(struct st_sensors_platform_data *)&default_press_pdata;
+	if (!pdata && press_data->sensor_settings->drdy_irq.addr)
+		pdata =	(struct st_sensors_platform_data *)&default_press_pdata;
 
-	err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
+	err = st_sensors_init_sensor(indio_dev, pdata);
 	if (err < 0)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/core/addr.c linux-libre-4.1.52-gnu/drivers/infiniband/core/addr.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/core/addr.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/core/addr.c	2018-05-27 22:26:45.000000000 -0400
@@ -86,6 +86,22 @@ int rdma_addr_size(struct sockaddr *addr
 }
 EXPORT_SYMBOL(rdma_addr_size);
 
+int rdma_addr_size_in6(struct sockaddr_in6 *addr)
+{
+	int ret = rdma_addr_size((struct sockaddr *) addr);
+
+	return ret <= sizeof(*addr) ? ret : 0;
+}
+EXPORT_SYMBOL(rdma_addr_size_in6);
+
+int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
+{
+	int ret = rdma_addr_size((struct sockaddr *) addr);
+
+	return ret <= sizeof(*addr) ? ret : 0;
+}
+EXPORT_SYMBOL(rdma_addr_size_kss);
+
 static struct rdma_addr_client self;
 
 void rdma_addr_register_client(struct rdma_addr_client *client)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/core/cma.c linux-libre-4.1.52-gnu/drivers/infiniband/core/cma.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/core/cma.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/core/cma.c	2018-05-27 22:26:45.000000000 -0400
@@ -3363,6 +3363,9 @@ int rdma_join_multicast(struct rdma_cm_i
 	struct cma_multicast *mc;
 	int ret;
 
+	if (!id->device)
+		return -EINVAL;
+
 	id_priv = container_of(id, struct rdma_id_private, id);
 	if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) &&
 	    !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED))
@@ -3645,7 +3648,7 @@ static int cma_get_id_stats(struct sk_bu
 					  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR))
 				goto out;
 			if (ibnl_put_attr(skb, nlh,
-					  rdma_addr_size(cma_src_addr(id_priv)),
+					  rdma_addr_size(cma_dst_addr(id_priv)),
 					  cma_dst_addr(id_priv),
 					  RDMA_NL_RDMA_CM_ATTR_DST_ADDR))
 				goto out;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/core/iwpm_util.c linux-libre-4.1.52-gnu/drivers/infiniband/core/iwpm_util.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/core/iwpm_util.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/core/iwpm_util.c	2018-05-27 22:26:45.000000000 -0400
@@ -654,6 +654,7 @@ int iwpm_send_mapinfo(u8 nl_client, int
 	}
 	skb_num++;
 	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
+	ret = -EINVAL;
 	for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
 		hlist_for_each_entry(map_info, &iwpm_hash_bucket[i],
 				     hlist_node) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/core/ucma.c linux-libre-4.1.52-gnu/drivers/infiniband/core/ucma.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/core/ucma.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/core/ucma.c	2018-05-27 22:26:45.000000000 -0400
@@ -411,6 +411,9 @@ err1:
 	mutex_lock(&mut);
 	idr_remove(&ctx_idr, ctx->id);
 	mutex_unlock(&mut);
+	mutex_lock(&file->mut);
+	list_del(&ctx->list);
+	mutex_unlock(&file->mut);
 	kfree(ctx);
 	return ret;
 }
@@ -522,6 +525,9 @@ static ssize_t ucma_bind_ip(struct ucma_
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	if (!rdma_addr_size_in6(&cmd.addr))
+		return -EINVAL;
+
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
@@ -535,22 +541,21 @@ static ssize_t ucma_bind(struct ucma_fil
 			 int in_len, int out_len)
 {
 	struct rdma_ucm_bind cmd;
-	struct sockaddr *addr;
 	struct ucma_context *ctx;
 	int ret;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	addr = (struct sockaddr *) &cmd.addr;
-	if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr)))
+	if (cmd.reserved || !cmd.addr_size ||
+	    cmd.addr_size != rdma_addr_size_kss(&cmd.addr))
 		return -EINVAL;
 
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_bind_addr(ctx->cm_id, addr);
+	ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -566,13 +571,16 @@ static ssize_t ucma_resolve_ip(struct uc
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	if ((cmd.src_addr.sin6_family && !rdma_addr_size_in6(&cmd.src_addr)) ||
+	    !rdma_addr_size_in6(&cmd.dst_addr))
+		return -EINVAL;
+
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
 	ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
-				(struct sockaddr *) &cmd.dst_addr,
-				cmd.timeout_ms);
+				(struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -582,24 +590,23 @@ static ssize_t ucma_resolve_addr(struct
 				 int in_len, int out_len)
 {
 	struct rdma_ucm_resolve_addr cmd;
-	struct sockaddr *src, *dst;
 	struct ucma_context *ctx;
 	int ret;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	src = (struct sockaddr *) &cmd.src_addr;
-	dst = (struct sockaddr *) &cmd.dst_addr;
-	if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) ||
-	    !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
+	if (cmd.reserved ||
+	    (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) ||
+	    !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr)))
 		return -EINVAL;
 
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+	ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+				(struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -1057,6 +1064,11 @@ static ssize_t ucma_init_qp_attr(struct
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
+	if (!ctx->cm_id->device) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	resp.qp_attr_mask = 0;
 	memset(&qp_attr, 0, sizeof qp_attr);
 	qp_attr.qp_state = cmd.qp_state;
@@ -1127,6 +1139,9 @@ static int ucma_set_ib_path(struct ucma_
 	if (!optlen)
 		return -EINVAL;
 
+	if (!ctx->cm_id->device)
+		return -EINVAL;
+
 	memset(&sa_path, 0, sizeof(sa_path));
 	sa_path.vlan_id = 0xffff;
 
@@ -1214,7 +1229,7 @@ static ssize_t ucma_notify(struct ucma_f
 {
 	struct rdma_ucm_notify cmd;
 	struct ucma_context *ctx;
-	int ret;
+	int ret = -EINVAL;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
@@ -1223,7 +1238,9 @@ static ssize_t ucma_notify(struct ucma_f
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event);
+	if (ctx->cm_id->device)
+		ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event);
+
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -1241,7 +1258,7 @@ static ssize_t ucma_process_join(struct
 		return -ENOSPC;
 
 	addr = (struct sockaddr *) &cmd->addr;
-	if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
+	if (cmd->reserved || (cmd->addr_size != rdma_addr_size(addr)))
 		return -EINVAL;
 
 	ctx = ucma_get_ctx(file, cmd->id);
@@ -1300,7 +1317,10 @@ static ssize_t ucma_join_ip_multicast(st
 	join_cmd.response = cmd.response;
 	join_cmd.uid = cmd.uid;
 	join_cmd.id = cmd.id;
-	join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+	join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr);
+	if (!join_cmd.addr_size)
+		return -EINVAL;
+
 	join_cmd.reserved = 0;
 	memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
 
@@ -1316,6 +1336,9 @@ static ssize_t ucma_join_multicast(struc
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	if (!rdma_addr_size_kss(&cmd.addr))
+		return -EINVAL;
+
 	return ucma_process_join(file, &cmd, out_len);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/core/umem.c linux-libre-4.1.52-gnu/drivers/infiniband/core/umem.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/core/umem.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/core/umem.c	2018-05-27 22:26:45.000000000 -0400
@@ -352,7 +352,7 @@ int ib_umem_copy_from(void *dst, struct
 		return -EINVAL;
 	}
 
-	ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length,
+	ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->npages, dst, length,
 				 offset + ib_umem_offset(umem));
 
 	if (ret < 0)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/hw/mlx5/qp.c linux-libre-4.1.52-gnu/drivers/infiniband/hw/mlx5/qp.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/hw/mlx5/qp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/hw/mlx5/qp.c	2018-05-27 22:26:45.000000000 -0400
@@ -236,7 +236,11 @@ static int set_rq_size(struct mlx5_ib_de
 	} else {
 		if (ucmd) {
 			qp->rq.wqe_cnt = ucmd->rq_wqe_count;
+			if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift))
+				return -EINVAL;
 			qp->rq.wqe_shift = ucmd->rq_wqe_shift;
+			if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig)
+				return -EINVAL;
 			qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig;
 			qp->rq.max_post = qp->rq.wqe_cnt;
 		} else {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c linux-libre-4.1.52-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/hw/ocrdma/ocrdma_stats.c	2018-05-27 22:26:45.000000000 -0400
@@ -819,7 +819,7 @@ void ocrdma_add_port_stats(struct ocrdma
 
 	dev->reset_stats.type = OCRDMA_RESET_STATS;
 	dev->reset_stats.dev = dev;
-	if (!debugfs_create_file("reset_stats", S_IRUSR, dev->dir,
+	if (!debugfs_create_file("reset_stats", 0200, dev->dir,
 				&dev->reset_stats, &ocrdma_dbg_ops))
 		goto err;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-4.1.52-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2018-05-27 22:26:45.000000000 -0400
@@ -963,6 +963,19 @@ static inline int update_parent_pkey(str
 		 */
 		priv->dev->broadcast[8] = priv->pkey >> 8;
 		priv->dev->broadcast[9] = priv->pkey & 0xff;
+
+		/*
+		 * Update the broadcast address in the priv->broadcast object,
+		 * in case it already exists, otherwise no one will do that.
+		 */
+		if (priv->broadcast) {
+			spin_lock_irq(&priv->lock);
+			memcpy(priv->broadcast->mcmember.mgid.raw,
+			       priv->dev->broadcast + 4,
+			sizeof(union ib_gid));
+			spin_unlock_irq(&priv->lock);
+		}
+
 		return 0;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-libre-4.1.52-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -488,6 +488,22 @@ static void path_rec_completion(int stat
 	spin_lock_irqsave(&priv->lock, flags);
 
 	if (!IS_ERR_OR_NULL(ah)) {
+		/*
+		 * pathrec.dgid is used as the database key from the LLADDR,
+		 * it must remain unchanged even if the SA returns a different
+		 * GID to use in the AH.
+		 */
+		if (memcmp(pathrec->dgid.raw, path->pathrec.dgid.raw,
+			   sizeof(union ib_gid))) {
+			ipoib_dbg(
+				priv,
+				"%s got PathRec for gid %pI6 while asked for %pI6\n",
+				dev->name, pathrec->dgid.raw,
+				path->pathrec.dgid.raw);
+			memcpy(pathrec->dgid.raw, path->pathrec.dgid.raw,
+			       sizeof(union ib_gid));
+		}
+
 		path->pathrec = *pathrec;
 
 		old_ah   = path->ah;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/ulp/srp/ib_srp.c linux-libre-4.1.52-gnu/drivers/infiniband/ulp/srp/ib_srp.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/ulp/srp/ib_srp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/ulp/srp/ib_srp.c	2018-05-27 22:26:45.000000000 -0400
@@ -2510,9 +2510,11 @@ static int srp_abort(struct scsi_cmnd *s
 		ret = FAST_IO_FAIL;
 	else
 		ret = FAILED;
-	srp_free_req(ch, req, scmnd, 0);
-	scmnd->result = DID_ABORT << 16;
-	scmnd->scsi_done(scmnd);
+	if (ret == SUCCESS) {
+		srp_free_req(ch, req, scmnd, 0);
+		scmnd->result = DID_ABORT << 16;
+		scmnd->scsi_done(scmnd);
+	}
 
 	return ret;
 }
@@ -3245,12 +3247,10 @@ static ssize_t srp_create_target(struct
 				      num_online_nodes());
 		const int ch_end = ((node_idx + 1) * target->ch_count /
 				    num_online_nodes());
-		const int cv_start = (node_idx * ibdev->num_comp_vectors /
-				      num_online_nodes() + target->comp_vector)
-				     % ibdev->num_comp_vectors;
-		const int cv_end = ((node_idx + 1) * ibdev->num_comp_vectors /
-				    num_online_nodes() + target->comp_vector)
-				   % ibdev->num_comp_vectors;
+		const int cv_start = node_idx * ibdev->num_comp_vectors /
+				     num_online_nodes();
+		const int cv_end = (node_idx + 1) * ibdev->num_comp_vectors /
+				   num_online_nodes();
 		int cpu_idx = 0;
 
 		for_each_online_cpu(cpu) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c linux-libre-4.1.52-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c
--- linux-libre-4.1.51-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c	2018-05-27 22:26:45.000000000 -0400
@@ -2981,12 +2981,8 @@ static void srpt_queue_response(struct s
 	}
 	spin_unlock_irqrestore(&ioctx->spinlock, flags);
 
-	if (unlikely(transport_check_aborted_status(&ioctx->cmd, false)
-		     || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) {
-		atomic_inc(&ch->req_lim_delta);
-		srpt_abort_cmd(ioctx);
+	if (unlikely(WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT)))
 		return;
-	}
 
 	dir = ioctx->cmd.data_direction;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/misc/drv260x.c linux-libre-4.1.52-gnu/drivers/input/misc/drv260x.c
--- linux-libre-4.1.51-gnu/drivers/input/misc/drv260x.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/misc/drv260x.c	2018-05-27 22:26:45.000000000 -0400
@@ -521,7 +521,7 @@ static int drv260x_probe(struct i2c_clie
 	if (!haptics)
 		return -ENOMEM;
 
-	haptics->rated_voltage = DRV260X_DEF_OD_CLAMP_VOLT;
+	haptics->overdrive_voltage = DRV260X_DEF_OD_CLAMP_VOLT;
 	haptics->rated_voltage = DRV260X_DEF_RATED_VOLT;
 
 	if (pdata) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/mouse/elan_i2c_core.c linux-libre-4.1.52-gnu/drivers/input/mouse/elan_i2c_core.c
--- linux-libre-4.1.51-gnu/drivers/input/mouse/elan_i2c_core.c	2018-03-28 09:58:19.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/mouse/elan_i2c_core.c	2018-05-29 04:45:15.000000000 -0400
@@ -972,6 +972,13 @@ static int elan_probe(struct i2c_client
 		return error;
 	}
 
+	/* Make sure there is something at this address */
+	error = i2c_smbus_read_byte(client);
+	if (error < 0) {
+		dev_dbg(&client->dev, "nothing at this address: %d\n", error);
+		return -ENXIO;
+	}
+
 	/* Initialize the touchpad. */
 	error = elan_initialize(data);
 	if (error)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/mouse/elan_i2c_i2c.c linux-libre-4.1.52-gnu/drivers/input/mouse/elan_i2c_i2c.c
--- linux-libre-4.1.51-gnu/drivers/input/mouse/elan_i2c_i2c.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/mouse/elan_i2c_i2c.c	2018-05-27 22:26:45.000000000 -0400
@@ -555,7 +555,14 @@ static int elan_i2c_finish_fw_update(str
 	long ret;
 	int error;
 	int len;
-	u8 buffer[ETP_I2C_INF_LENGTH];
+	u8 buffer[ETP_I2C_REPORT_LEN];
+
+	len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_LEN);
+	if (len != ETP_I2C_REPORT_LEN) {
+		error = len < 0 ? len : -EIO;
+		dev_warn(dev, "failed to read I2C data after FW WDT reset: %d (%d)\n",
+			error, len);
+	}
 
 	reinit_completion(completion);
 	enable_irq(client->irq);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/mousedev.c linux-libre-4.1.52-gnu/drivers/input/mousedev.c
--- linux-libre-4.1.51-gnu/drivers/input/mousedev.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/mousedev.c	2018-05-27 22:26:45.000000000 -0400
@@ -15,6 +15,7 @@
 #define MOUSEDEV_MINORS		31
 #define MOUSEDEV_MIX		63
 
+#include <linux/bitops.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
@@ -103,7 +104,7 @@ struct mousedev_client {
 	spinlock_t packet_lock;
 	int pos_x, pos_y;
 
-	signed char ps2[6];
+	u8 ps2[6];
 	unsigned char ready, buffer, bufsiz;
 	unsigned char imexseq, impsseq;
 	enum mousedev_emul mode;
@@ -291,11 +292,10 @@ static void mousedev_notify_readers(stru
 		}
 
 		client->pos_x += packet->dx;
-		client->pos_x = client->pos_x < 0 ?
-			0 : (client->pos_x >= xres ? xres : client->pos_x);
+		client->pos_x = clamp_val(client->pos_x, 0, xres);
+
 		client->pos_y += packet->dy;
-		client->pos_y = client->pos_y < 0 ?
-			0 : (client->pos_y >= yres ? yres : client->pos_y);
+		client->pos_y = clamp_val(client->pos_y, 0, yres);
 
 		p->dx += packet->dx;
 		p->dy += packet->dy;
@@ -571,44 +571,50 @@ static int mousedev_open(struct inode *i
 	return error;
 }
 
-static inline int mousedev_limit_delta(int delta, int limit)
-{
-	return delta > limit ? limit : (delta < -limit ? -limit : delta);
-}
-
-static void mousedev_packet(struct mousedev_client *client,
-			    signed char *ps2_data)
+static void mousedev_packet(struct mousedev_client *client, u8 *ps2_data)
 {
 	struct mousedev_motion *p = &client->packets[client->tail];
+	s8 dx, dy, dz;
 
-	ps2_data[0] = 0x08 |
-		((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
-	ps2_data[1] = mousedev_limit_delta(p->dx, 127);
-	ps2_data[2] = mousedev_limit_delta(p->dy, 127);
-	p->dx -= ps2_data[1];
-	p->dy -= ps2_data[2];
+	dx = clamp_val(p->dx, -127, 127);
+	p->dx -= dx;
+
+	dy = clamp_val(p->dy, -127, 127);
+	p->dy -= dy;
+
+	ps2_data[0] = BIT(3);
+	ps2_data[0] |= ((dx & BIT(7)) >> 3) | ((dy & BIT(7)) >> 2);
+	ps2_data[0] |= p->buttons & 0x07;
+	ps2_data[1] = dx;
+	ps2_data[2] = dy;
 
 	switch (client->mode) {
 	case MOUSEDEV_EMUL_EXPS:
-		ps2_data[3] = mousedev_limit_delta(p->dz, 7);
-		p->dz -= ps2_data[3];
-		ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
+		dz = clamp_val(p->dz, -7, 7);
+		p->dz -= dz;
+
+		ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1);
 		client->bufsiz = 4;
 		break;
 
 	case MOUSEDEV_EMUL_IMPS:
-		ps2_data[0] |=
-			((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
-		ps2_data[3] = mousedev_limit_delta(p->dz, 127);
-		p->dz -= ps2_data[3];
+		dz = clamp_val(p->dz, -127, 127);
+		p->dz -= dz;
+
+		ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
+			       ((p->buttons & 0x08) >> 1);
+		ps2_data[3] = dz;
+
 		client->bufsiz = 4;
 		break;
 
 	case MOUSEDEV_EMUL_PS2:
 	default:
-		ps2_data[0] |=
-			((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
 		p->dz = 0;
+
+		ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
+			       ((p->buttons & 0x08) >> 1);
+
 		client->bufsiz = 3;
 		break;
 	}
@@ -714,7 +720,7 @@ static ssize_t mousedev_read(struct file
 {
 	struct mousedev_client *client = file->private_data;
 	struct mousedev *mousedev = client->mousedev;
-	signed char data[sizeof(client->ps2)];
+	u8 data[sizeof(client->ps2)];
 	int retval = 0;
 
 	if (!client->ready && !client->buffer && mousedev->exist &&
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/serio/i8042-x86ia64io.h linux-libre-4.1.52-gnu/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-4.1.51-gnu/drivers/input/serio/i8042-x86ia64io.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/serio/i8042-x86ia64io.h	2018-05-27 22:26:45.000000000 -0400
@@ -603,6 +603,13 @@ static const struct dmi_system_id __init
 		},
 	},
 	{
+		/* Lenovo ThinkPad L460 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
+		},
+	},
+	{
 		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/touchscreen/ar1021_i2c.c linux-libre-4.1.52-gnu/drivers/input/touchscreen/ar1021_i2c.c
--- linux-libre-4.1.51-gnu/drivers/input/touchscreen/ar1021_i2c.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/touchscreen/ar1021_i2c.c	2018-05-27 22:26:45.000000000 -0400
@@ -152,7 +152,7 @@ static int __maybe_unused ar1021_i2c_res
 static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume);
 
 static const struct i2c_device_id ar1021_i2c_id[] = {
-	{ "MICROCHIP_AR1021_I2C", 0 },
+	{ "ar1021", 0 },
 	{ },
 };
 MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/input/touchscreen/tsc2007.c linux-libre-4.1.52-gnu/drivers/input/touchscreen/tsc2007.c
--- linux-libre-4.1.51-gnu/drivers/input/touchscreen/tsc2007.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/input/touchscreen/tsc2007.c	2018-05-27 22:26:45.000000000 -0400
@@ -455,6 +455,14 @@ static int tsc2007_probe(struct i2c_clie
 
 	tsc2007_stop(ts);
 
+	/* power down the chip (TSC2007_SETUP does not ACK on I2C) */
+	err = tsc2007_xfer(ts, PWRDOWN);
+	if (err < 0) {
+		dev_err(&client->dev,
+			"Failed to setup chip: %d\n", err);
+		return err;	/* usually, chip does not respond */
+	}
+
 	err = input_register_device(input_dev);
 	if (err) {
 		dev_err(&client->dev,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/iommu/iova.c linux-libre-4.1.52-gnu/drivers/iommu/iova.c
--- linux-libre-4.1.51-gnu/drivers/iommu/iova.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/iommu/iova.c	2018-05-27 22:26:45.000000000 -0400
@@ -163,7 +163,7 @@ static int __alloc_and_insert_iova_range
 				break;	/* found a free slot */
 		}
 adjust_limit_pfn:
-		limit_pfn = curr_iova->pfn_lo - 1;
+		limit_pfn = curr_iova->pfn_lo ? (curr_iova->pfn_lo - 1) : 0;
 move_left:
 		prev = curr;
 		curr = rb_prev(curr);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/iommu/omap-iommu.c linux-libre-4.1.52-gnu/drivers/iommu/omap-iommu.c
--- linux-libre-4.1.51-gnu/drivers/iommu/omap-iommu.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/iommu/omap-iommu.c	2018-05-27 22:26:45.000000000 -0400
@@ -1386,6 +1386,7 @@ static int __init omap_iommu_init(void)
 	const unsigned long flags = SLAB_HWCACHE_ALIGN;
 	size_t align = 1 << 10; /* L2 pagetable alignement */
 	struct device_node *np;
+	int ret;
 
 	np = of_find_matching_node(NULL, omap_iommu_of_match);
 	if (!np)
@@ -1399,11 +1400,25 @@ static int __init omap_iommu_init(void)
 		return -ENOMEM;
 	iopte_cachep = p;
 
-	bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
-
 	omap_iommu_debugfs_init();
 
-	return platform_driver_register(&omap_iommu_driver);
+	ret = platform_driver_register(&omap_iommu_driver);
+	if (ret) {
+		pr_err("%s: failed to register driver\n", __func__);
+		goto fail_driver;
+	}
+
+	ret = bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
+	if (ret)
+		goto fail_bus;
+
+	return 0;
+
+fail_bus:
+	platform_driver_unregister(&omap_iommu_driver);
+fail_driver:
+	kmem_cache_destroy(iopte_cachep);
+	return ret;
 }
 /* must be ready before omap3isp is probed */
 subsys_initcall(omap_iommu_init);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/irqchip/irq-gic-v3-its.c linux-libre-4.1.52-gnu/drivers/irqchip/irq-gic-v3-its.c
--- linux-libre-4.1.51-gnu/drivers/irqchip/irq-gic-v3-its.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/irqchip/irq-gic-v3-its.c	2018-05-27 22:26:45.000000000 -0400
@@ -674,7 +674,7 @@ static struct irq_chip its_msi_irq_chip
  * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations.
  */
 #define IRQS_PER_CHUNK_SHIFT	5
-#define IRQS_PER_CHUNK		(1 << IRQS_PER_CHUNK_SHIFT)
+#define IRQS_PER_CHUNK		(1UL << IRQS_PER_CHUNK_SHIFT)
 
 static unsigned long *lpi_bitmap;
 static u32 lpi_chunks;
@@ -1145,11 +1145,10 @@ static struct its_device *its_create_dev
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	/*
-	 * At least one bit of EventID is being used, hence a minimum
-	 * of two entries. No, the architecture doesn't let you
-	 * express an ITT with a single entry.
+	 * We allocate at least one chunk worth of LPIs bet device,
+	 * and thus that many ITEs. The device may require less though.
 	 */
-	nr_ites = max(2UL, roundup_pow_of_two(nvecs));
+	nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs));
 	sz = nr_ites * its->ite_size;
 	sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
 	itt = kzalloc(sz, GFP_KERNEL);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/isdn/mISDN/stack.c linux-libre-4.1.52-gnu/drivers/isdn/mISDN/stack.c
--- linux-libre-4.1.51-gnu/drivers/isdn/mISDN/stack.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/isdn/mISDN/stack.c	2018-05-27 22:26:45.000000000 -0400
@@ -72,7 +72,7 @@ send_socklist(struct mISDN_sock_list *sl
 		if (sk->sk_state != MISDN_BOUND)
 			continue;
 		if (!cskb)
-			cskb = skb_copy(skb, GFP_KERNEL);
+			cskb = skb_copy(skb, GFP_ATOMIC);
 		if (!cskb) {
 			printk(KERN_WARNING "%s no skb\n", __func__);
 			break;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/leds/leds-pca955x.c linux-libre-4.1.52-gnu/drivers/leds/leds-pca955x.c
--- linux-libre-4.1.51-gnu/drivers/leds/leds-pca955x.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/leds/leds-pca955x.c	2018-05-27 22:26:45.000000000 -0400
@@ -281,7 +281,7 @@ static int pca955x_probe(struct i2c_clie
 			"slave address 0x%02x\n",
 			id->name, chip->bits, client->addr);
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
 	if (pdata) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/md/bcache/alloc.c linux-libre-4.1.52-gnu/drivers/md/bcache/alloc.c
--- linux-libre-4.1.51-gnu/drivers/md/bcache/alloc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/md/bcache/alloc.c	2018-05-27 22:26:45.000000000 -0400
@@ -514,15 +514,21 @@ struct open_bucket {
 
 /*
  * We keep multiple buckets open for writes, and try to segregate different
- * write streams for better cache utilization: first we look for a bucket where
- * the last write to it was sequential with the current write, and failing that
- * we look for a bucket that was last used by the same task.
+ * write streams for better cache utilization: first we try to segregate flash
+ * only volume write streams from cached devices, secondly we look for a bucket
+ * where the last write to it was sequential with the current write, and
+ * failing that we look for a bucket that was last used by the same task.
  *
  * The ideas is if you've got multiple tasks pulling data into the cache at the
  * same time, you'll get better cache utilization if you try to segregate their
  * data and preserve locality.
  *
- * For example, say you've starting Firefox at the same time you're copying a
+ * For example, dirty sectors of flash only volume is not reclaimable, if their
+ * dirty sectors mixed with dirty sectors of cached device, such buckets will
+ * be marked as dirty and won't be reclaimed, though the dirty data of cached
+ * device have been written back to backend device.
+ *
+ * And say you've starting Firefox at the same time you're copying a
  * bunch of files. Firefox will likely end up being fairly hot and stay in the
  * cache awhile, but the data you copied might not be; if you wrote all that
  * data to the same buckets it'd get invalidated at the same time.
@@ -539,7 +545,10 @@ static struct open_bucket *pick_data_buc
 	struct open_bucket *ret, *ret_task = NULL;
 
 	list_for_each_entry_reverse(ret, &c->data_buckets, list)
-		if (!bkey_cmp(&ret->key, search))
+		if (UUID_FLASH_ONLY(&c->uuids[KEY_INODE(&ret->key)]) !=
+		    UUID_FLASH_ONLY(&c->uuids[KEY_INODE(search)]))
+			continue;
+		else if (!bkey_cmp(&ret->key, search))
 			goto found;
 		else if (ret->last_write_point == write_point)
 			ret_task = ret;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/md/bcache/super.c linux-libre-4.1.52-gnu/drivers/md/bcache/super.c
--- linux-libre-4.1.51-gnu/drivers/md/bcache/super.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/md/bcache/super.c	2018-05-27 22:26:45.000000000 -0400
@@ -921,6 +921,12 @@ static void cached_dev_detach_finish(str
 
 	mutex_lock(&bch_register_lock);
 
+	cancel_delayed_work_sync(&dc->writeback_rate_update);
+	if (!IS_ERR_OR_NULL(dc->writeback_thread)) {
+		kthread_stop(dc->writeback_thread);
+		dc->writeback_thread = NULL;
+	}
+
 	memset(&dc->sb.set_uuid, 0, 16);
 	SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/md/dm-ioctl.c linux-libre-4.1.52-gnu/drivers/md/dm-ioctl.c
--- linux-libre-4.1.51-gnu/drivers/md/dm-ioctl.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/md/dm-ioctl.c	2018-05-27 22:26:45.000000000 -0400
@@ -1773,12 +1773,12 @@ static int validate_params(uint cmd, str
 	    cmd == DM_LIST_VERSIONS_CMD)
 		return 0;
 
-	if ((cmd == DM_DEV_CREATE_CMD)) {
+	if (cmd == DM_DEV_CREATE_CMD) {
 		if (!*param->name) {
 			DMWARN("name not supplied when creating device");
 			return -EINVAL;
 		}
-	} else if ((*param->uuid && *param->name)) {
+	} else if (*param->uuid && *param->name) {
 		DMWARN("only supply one of name or uuid, cmd(%u)", cmd);
 		return -EINVAL;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/md/md-cluster.c linux-libre-4.1.52-gnu/drivers/md/md-cluster.c
--- linux-libre-4.1.51-gnu/drivers/md/md-cluster.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/md/md-cluster.c	2018-05-27 22:26:45.000000000 -0400
@@ -850,8 +850,10 @@ static int add_new_disk_start(struct mdd
 	cmsg.raid_slot = rdev->desc_nr;
 	lock_comm(cinfo);
 	ret = __sendmsg(cinfo, &cmsg);
-	if (ret)
+	if (ret) {
+		unlock_comm(cinfo);
 		return ret;
+	}
 	cinfo->no_new_dev_lockres->flags |= DLM_LKF_NOQUEUE;
 	ret = dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_EX);
 	cinfo->no_new_dev_lockres->flags &= ~DLM_LKF_NOQUEUE;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/md/raid10.c linux-libre-4.1.52-gnu/drivers/md/raid10.c
--- linux-libre-4.1.51-gnu/drivers/md/raid10.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/md/raid10.c	2018-05-27 22:26:45.000000000 -0400
@@ -3702,6 +3702,7 @@ static int run(struct mddev *mddev)
 
 		if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
 			discard_supported = true;
+		first = 0;
 	}
 
 	if (mddev->queue) {
@@ -4110,6 +4111,7 @@ static int raid10_start_reshape(struct m
 				diff = 0;
 			if (first || diff < min_offset_diff)
 				min_offset_diff = diff;
+			first = 0;
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/md/raid5.c linux-libre-4.1.52-gnu/drivers/md/raid5.c
--- linux-libre-4.1.51-gnu/drivers/md/raid5.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/md/raid5.c	2018-05-27 22:26:45.000000000 -0400
@@ -110,8 +110,7 @@ static inline void unlock_device_hash_lo
 static inline void lock_all_device_hash_locks_irq(struct r5conf *conf)
 {
 	int i;
-	local_irq_disable();
-	spin_lock(conf->hash_locks);
+	spin_lock_irq(conf->hash_locks);
 	for (i = 1; i < NR_STRIPE_HASH_LOCKS; i++)
 		spin_lock_nest_lock(conf->hash_locks + i, conf->hash_locks);
 	spin_lock(&conf->device_lock);
@@ -121,9 +120,9 @@ static inline void unlock_all_device_has
 {
 	int i;
 	spin_unlock(&conf->device_lock);
-	for (i = NR_STRIPE_HASH_LOCKS; i; i--)
-		spin_unlock(conf->hash_locks + i - 1);
-	local_irq_enable();
+	for (i = NR_STRIPE_HASH_LOCKS - 1; i; i--)
+		spin_unlock(conf->hash_locks + i);
+	spin_unlock_irq(conf->hash_locks);
 }
 
 /* bio's attached to a stripe+device for I/O are linked together in bi_sector
@@ -728,12 +727,11 @@ static bool is_full_stripe_write(struct
 
 static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
 {
-	local_irq_disable();
 	if (sh1 > sh2) {
-		spin_lock(&sh2->stripe_lock);
+		spin_lock_irq(&sh2->stripe_lock);
 		spin_lock_nested(&sh1->stripe_lock, 1);
 	} else {
-		spin_lock(&sh1->stripe_lock);
+		spin_lock_irq(&sh1->stripe_lock);
 		spin_lock_nested(&sh2->stripe_lock, 1);
 	}
 }
@@ -741,8 +739,7 @@ static void lock_two_stripes(struct stri
 static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
 {
 	spin_unlock(&sh1->stripe_lock);
-	spin_unlock(&sh2->stripe_lock);
-	local_irq_enable();
+	spin_unlock_irq(&sh2->stripe_lock);
 }
 
 /* Only freshly new full stripe normal write stripe can be added to a batch list */
@@ -3368,9 +3365,20 @@ static int fetch_block(struct stripe_hea
 		BUG_ON(test_bit(R5_Wantcompute, &dev->flags));
 		BUG_ON(test_bit(R5_Wantread, &dev->flags));
 		BUG_ON(sh->batch_head);
+
+		/*
+		 * In the raid6 case if the only non-uptodate disk is P
+		 * then we already trusted P to compute the other failed
+		 * drives. It is safe to compute rather than re-read P.
+		 * In other cases we only compute blocks from failed
+		 * devices, otherwise check/repair might fail to detect
+		 * a real inconsistency.
+		 */
+
 		if ((s->uptodate == disks - 1) &&
+		    ((sh->qd_idx >= 0 && sh->pd_idx == disk_idx) ||
 		    (s->failed && (disk_idx == s->failed_num[0] ||
-				   disk_idx == s->failed_num[1]))) {
+				   disk_idx == s->failed_num[1])))) {
 			/* have disk failed, and we're requested to fetch it;
 			 * do compute it
 			 */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/dvb-core/dvb_ca_en50221.c linux-libre-4.1.52-gnu/drivers/media/dvb-core/dvb_ca_en50221.c
--- linux-libre-4.1.51-gnu/drivers/media/dvb-core/dvb_ca_en50221.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/dvb-core/dvb_ca_en50221.c	2018-05-27 22:26:45.000000000 -0400
@@ -749,6 +749,29 @@ static int dvb_ca_en50221_write_data(str
 		goto exit;
 	}
 
+	/*
+	 * It may need some time for the CAM to settle down, or there might
+	 * be a race condition between the CAM, writing HC and our last
+	 * check for DA. This happens, if the CAM asserts DA, just after
+	 * checking DA before we are setting HC. In this case it might be
+	 * a bug in the CAM to keep the FR bit, the lower layer/HW
+	 * communication requires a longer timeout or the CAM needs more
+	 * time internally. But this happens in reality!
+	 * We need to read the status from the HW again and do the same
+	 * we did for the previous check for DA
+	 */
+	status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
+	if (status < 0)
+		goto exit;
+
+	if (status & (STATUSREG_DA | STATUSREG_RE)) {
+		if (status & STATUSREG_DA)
+			dvb_ca_en50221_thread_wakeup(ca);
+
+		status = -EAGAIN;
+		goto exit;
+	}
+
 	/* send the amount of data */
 	if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
 		goto exit;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/dvb-frontends/si2168.c linux-libre-4.1.52-gnu/drivers/media/dvb-frontends/si2168.c
--- linux-libre-4.1.51-gnu/drivers/media/dvb-frontends/si2168.c	2018-03-28 09:48:13.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/dvb-frontends/si2168.c	2018-05-29 04:35:32.000000000 -0400
@@ -14,6 +14,8 @@
  *    GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
+
 #include "si2168_priv.h"
 
 static const struct dvb_frontend_ops si2168_ops;
@@ -375,6 +377,7 @@ static int si2168_init(struct dvb_fronte
 		if (ret)
 			goto err;
 
+		udelay(100);
 		memcpy(cmd.args, "\x85", 1);
 		cmd.wlen = 1;
 		cmd.rlen = 1;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/i2c/cx25840/cx25840-core.c linux-libre-4.1.52-gnu/drivers/media/i2c/cx25840/cx25840-core.c
--- linux-libre-4.1.51-gnu/drivers/media/i2c/cx25840/cx25840-core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/i2c/cx25840/cx25840-core.c	2018-05-27 22:26:45.000000000 -0400
@@ -420,11 +420,13 @@ static void cx25840_initialize(struct i2
 	INIT_WORK(&state->fw_work, cx25840_work_handler);
 	init_waitqueue_head(&state->fw_wait);
 	q = create_singlethread_workqueue("cx25840_fw");
-	prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
-	queue_work(q, &state->fw_work);
-	schedule();
-	finish_wait(&state->fw_wait, &wait);
-	destroy_workqueue(q);
+	if (q) {
+		prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
+		queue_work(q, &state->fw_work);
+		schedule();
+		finish_wait(&state->fw_wait, &wait);
+		destroy_workqueue(q);
+	}
 
 	/* 6. */
 	cx25840_write(client, 0x115, 0x8c);
@@ -631,11 +633,13 @@ static void cx23885_initialize(struct i2
 	INIT_WORK(&state->fw_work, cx25840_work_handler);
 	init_waitqueue_head(&state->fw_wait);
 	q = create_singlethread_workqueue("cx25840_fw");
-	prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
-	queue_work(q, &state->fw_work);
-	schedule();
-	finish_wait(&state->fw_wait, &wait);
-	destroy_workqueue(q);
+	if (q) {
+		prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
+		queue_work(q, &state->fw_work);
+		schedule();
+		finish_wait(&state->fw_wait, &wait);
+		destroy_workqueue(q);
+	}
 
 	/* Call the cx23888 specific std setup func, we no longer rely on
 	 * the generic cx24840 func.
@@ -746,11 +750,13 @@ static void cx231xx_initialize(struct i2
 	INIT_WORK(&state->fw_work, cx25840_work_handler);
 	init_waitqueue_head(&state->fw_wait);
 	q = create_singlethread_workqueue("cx25840_fw");
-	prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
-	queue_work(q, &state->fw_work);
-	schedule();
-	finish_wait(&state->fw_wait, &wait);
-	destroy_workqueue(q);
+	if (q) {
+		prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
+		queue_work(q, &state->fw_work);
+		schedule();
+		finish_wait(&state->fw_wait, &wait);
+		destroy_workqueue(q);
+	}
 
 	cx25840_std_setup(client);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/i2c/soc_camera/ov6650.c linux-libre-4.1.52-gnu/drivers/media/i2c/soc_camera/ov6650.c
--- linux-libre-4.1.51-gnu/drivers/media/i2c/soc_camera/ov6650.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/i2c/soc_camera/ov6650.c	2018-05-27 22:26:45.000000000 -0400
@@ -1016,7 +1016,7 @@ static int ov6650_probe(struct i2c_clien
 	priv->code	  = MEDIA_BUS_FMT_YUYV8_2X8;
 	priv->colorspace  = V4L2_COLORSPACE_JPEG;
 
-	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	priv->clk = v4l2_clk_get(&client->dev, NULL);
 	if (IS_ERR(priv->clk)) {
 		ret = PTR_ERR(priv->clk);
 		goto eclkget;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/pci/bt8xx/bt878.c linux-libre-4.1.52-gnu/drivers/media/pci/bt8xx/bt878.c
--- linux-libre-4.1.51-gnu/drivers/media/pci/bt8xx/bt878.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/pci/bt8xx/bt878.c	2018-05-27 22:26:45.000000000 -0400
@@ -422,8 +422,7 @@ static int bt878_probe(struct pci_dev *d
 	       bt878_num);
 	if (bt878_num >= BT878_MAX) {
 		printk(KERN_ERR "bt878: Too many devices inserted\n");
-		result = -ENOMEM;
-		goto fail0;
+		return -ENOMEM;
 	}
 	if (pci_enable_device(dev))
 		return -EIO;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/rc/mceusb.c linux-libre-4.1.52-gnu/drivers/media/rc/mceusb.c
--- linux-libre-4.1.51-gnu/drivers/media/rc/mceusb.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/rc/mceusb.c	2018-05-27 22:26:45.000000000 -0400
@@ -1370,8 +1370,13 @@ static int mceusb_dev_probe(struct usb_i
 		goto rc_dev_fail;
 
 	/* wire up inbound data handler */
-	usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
-				mceusb_dev_recv, ir, ep_in->bInterval);
+	if (usb_endpoint_xfer_int(ep_in))
+		usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
+				 mceusb_dev_recv, ir, ep_in->bInterval);
+	else
+		usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
+				  mceusb_dev_recv, ir);
+
 	ir->urb_in->transfer_dma = ir->dma_in;
 	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/usb/cpia2/cpia2_v4l.c linux-libre-4.1.52-gnu/drivers/media/usb/cpia2/cpia2_v4l.c
--- linux-libre-4.1.51-gnu/drivers/media/usb/cpia2/cpia2_v4l.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/usb/cpia2/cpia2_v4l.c	2018-05-27 22:26:45.000000000 -0400
@@ -812,7 +812,7 @@ static int cpia2_querybuf(struct file *f
 	struct camera_data *cam = video_drvdata(file);
 
 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-	   buf->index > cam->num_frames)
+	   buf->index >= cam->num_frames)
 		return -EINVAL;
 
 	buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
@@ -863,7 +863,7 @@ static int cpia2_qbuf(struct file *file,
 
 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
 	   buf->memory != V4L2_MEMORY_MMAP ||
-	   buf->index > cam->num_frames)
+	   buf->index >= cam->num_frames)
 		return -EINVAL;
 
 	DBG("QBUF #%d\n", buf->index);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/usb/usbtv/usbtv-core.c linux-libre-4.1.52-gnu/drivers/media/usb/usbtv/usbtv-core.c
--- linux-libre-4.1.51-gnu/drivers/media/usb/usbtv/usbtv-core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/usb/usbtv/usbtv-core.c	2018-05-27 22:26:45.000000000 -0400
@@ -95,6 +95,8 @@ static int usbtv_probe(struct usb_interf
 	return 0;
 
 usbtv_audio_fail:
+	/* we must not free at this point */
+	usb_get_dev(usbtv->udev);
 	usbtv_video_free(usbtv);
 
 usbtv_video_fail:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c linux-libre-4.1.52-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
--- linux-libre-4.1.51-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c	2018-05-27 22:26:45.000000000 -0400
@@ -101,7 +101,7 @@ static int get_v4l2_window32(struct v4l2
 static int put_v4l2_window32(struct v4l2_window __user *kp,
 			     struct v4l2_window32 __user *up)
 {
-	struct v4l2_clip __user *kclips = kp->clips;
+	struct v4l2_clip __user *kclips;
 	struct v4l2_clip32 __user *uclips;
 	compat_caddr_t p;
 	u32 clipcount;
@@ -116,6 +116,8 @@ static int put_v4l2_window32(struct v4l2
 	if (!clipcount)
 		return 0;
 
+	if (get_user(kclips, &kp->clips))
+		return -EFAULT;
 	if (get_user(p, &up->clips))
 		return -EFAULT;
 	uclips = compat_ptr(p);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mfd/palmas.c linux-libre-4.1.52-gnu/drivers/mfd/palmas.c
--- linux-libre-4.1.51-gnu/drivers/mfd/palmas.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mfd/palmas.c	2018-05-27 22:26:45.000000000 -0400
@@ -430,6 +430,20 @@ static void palmas_power_off(void)
 {
 	unsigned int addr;
 	int ret, slave;
+	struct device_node *np = palmas_dev->dev->of_node;
+
+	if (of_property_read_bool(np, "ti,palmas-override-powerhold")) {
+		addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
+					  PALMAS_PRIMARY_SECONDARY_PAD2);
+		slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
+
+		ret = regmap_update_bits(palmas_dev->regmap[slave], addr,
+				PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK, 0);
+		if (ret)
+			dev_err(palmas_dev->dev,
+				"Unable to write PRIMARY_SECONDARY_PAD2 %d\n",
+				ret);
+	}
 
 	if (!palmas_dev)
 		return;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/misc/enclosure.c linux-libre-4.1.52-gnu/drivers/misc/enclosure.c
--- linux-libre-4.1.51-gnu/drivers/misc/enclosure.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/misc/enclosure.c	2018-05-27 22:26:45.000000000 -0400
@@ -148,7 +148,7 @@ enclosure_register(struct device *dev, c
 	for (i = 0; i < components; i++) {
 		edev->component[i].number = -1;
 		edev->component[i].slot = -1;
-		edev->component[i].power_status = 1;
+		edev->component[i].power_status = -1;
 	}
 
 	mutex_lock(&container_list_lock);
@@ -600,6 +600,11 @@ static ssize_t get_component_power_statu
 
 	if (edev->cb->get_power_status)
 		edev->cb->get_power_status(edev, ecomp);
+
+	/* If still uninitialized, the callback failed or does not exist. */
+	if (ecomp->power_status == -1)
+		return (edev->cb->get_power_status) ? -EIO : -ENOTTY;
+
 	return snprintf(buf, 40, "%s\n", ecomp->power_status ? "on" : "off");
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/misc/mei/main.c linux-libre-4.1.52-gnu/drivers/misc/mei/main.c
--- linux-libre-4.1.51-gnu/drivers/misc/mei/main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/misc/mei/main.c	2018-05-27 22:26:45.000000000 -0400
@@ -503,7 +503,6 @@ static long mei_ioctl(struct file *file,
 		break;
 
 	default:
-		dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd);
 		rets = -ENOIOCTLCMD;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/misc/vmw_vmci/vmci_queue_pair.c linux-libre-4.1.52-gnu/drivers/misc/vmw_vmci/vmci_queue_pair.c
--- linux-libre-4.1.51-gnu/drivers/misc/vmw_vmci/vmci_queue_pair.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/misc/vmw_vmci/vmci_queue_pair.c	2018-05-27 22:26:45.000000000 -0400
@@ -298,8 +298,11 @@ static void *qp_alloc_queue(u64 size, u3
 	size_t pas_size;
 	size_t vas_size;
 	size_t queue_size = sizeof(*queue) + sizeof(*queue->kernel_if);
-	const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
+	u64 num_pages;
 
+	if (size > SIZE_MAX - PAGE_SIZE)
+		return NULL;
+	num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
 	if (num_pages >
 		 (SIZE_MAX - queue_size) /
 		 (sizeof(*queue->kernel_if->u.g.pas) +
@@ -624,9 +627,12 @@ static struct vmci_queue *qp_host_alloc_
 {
 	struct vmci_queue *queue;
 	size_t queue_page_size;
-	const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
+	u64 num_pages;
 	const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if));
 
+	if (size > SIZE_MAX - PAGE_SIZE)
+		return NULL;
+	num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
 	if (num_pages > (SIZE_MAX - queue_size) /
 		 sizeof(*queue->kernel_if->u.h.page))
 		return NULL;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mmc/core/core.c linux-libre-4.1.52-gnu/drivers/mmc/core/core.c
--- linux-libre-4.1.51-gnu/drivers/mmc/core/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mmc/core/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -2668,6 +2668,14 @@ int mmc_pm_notify(struct notifier_block
 		if (!err)
 			break;
 
+		if (!mmc_card_is_removable(host)) {
+			dev_warn(mmc_dev(host),
+				 "pre_suspend failed for non-removable host: "
+				 "%d\n", err);
+			/* Avoid removing non-removable hosts */
+			break;
+		}
+
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
 		host->bus_ops->remove(host);
 		mmc_claim_host(host);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mmc/host/jz4740_mmc.c linux-libre-4.1.52-gnu/drivers/mmc/host/jz4740_mmc.c
--- linux-libre-4.1.51-gnu/drivers/mmc/host/jz4740_mmc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mmc/host/jz4740_mmc.c	2018-05-27 22:26:45.000000000 -0400
@@ -368,9 +368,9 @@ static void jz4740_mmc_set_irq_enabled(s
 		host->irq_mask &= ~irq;
 	else
 		host->irq_mask |= irq;
-	spin_unlock_irqrestore(&host->lock, flags);
 
 	writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mmc/host/omap_hsmmc.c linux-libre-4.1.52-gnu/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-4.1.51-gnu/drivers/mmc/host/omap_hsmmc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mmc/host/omap_hsmmc.c	2018-05-27 22:26:45.000000000 -0400
@@ -1693,8 +1693,8 @@ static int omap_hsmmc_configure_wake_irq
 	 */
 	if (host->pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) {
 		struct pinctrl *p = devm_pinctrl_get(host->dev);
-		if (!p) {
-			ret = -ENODEV;
+		if (IS_ERR(p)) {
+			ret = PTR_ERR(p);
 			goto err_free_irq;
 		}
 		if (IS_ERR(pinctrl_lookup_state(p, PINCTRL_STATE_DEFAULT))) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/chips/cfi_cmdset_0001.c linux-libre-4.1.52-gnu/drivers/mtd/chips/cfi_cmdset_0001.c
--- linux-libre-4.1.51-gnu/drivers/mtd/chips/cfi_cmdset_0001.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/chips/cfi_cmdset_0001.c	2018-05-27 22:26:45.000000000 -0400
@@ -45,6 +45,7 @@
 #define I82802AB	0x00ad
 #define I82802AC	0x00ac
 #define PF38F4476	0x881c
+#define M28F00AP30	0x8963
 /* STMicroelectronics chips */
 #define M50LPW080       0x002F
 #define M50FLW080A	0x0080
@@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct
 		extp->MinorVersion = '1';
 }
 
+static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
+{
+	/*
+	 * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
+	 * Erase Supend for their small Erase Blocks(0x8000)
+	 */
+	if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
+		return 1;
+	return 0;
+}
+
 static inline struct cfi_pri_intelext *
 read_pri_intelext(struct map_info *map, __u16 adr)
 {
@@ -825,21 +837,30 @@ static int chip_ready (struct map_info *
 		     (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
 			goto sleep;
 
+		/* Do not allow suspend iff read/write to EB address */
+		if ((adr & chip->in_progress_block_mask) ==
+		    chip->in_progress_block_addr)
+			goto sleep;
+
+		/* do not suspend small EBs, buggy Micron Chips */
+		if (cfi_is_micron_28F00AP30(cfi, chip) &&
+		    (chip->in_progress_block_mask == ~(0x8000-1)))
+			goto sleep;
 
 		/* Erase suspend */
-		map_write(map, CMD(0xB0), adr);
+		map_write(map, CMD(0xB0), chip->in_progress_block_addr);
 
 		/* If the flash has finished erasing, then 'erase suspend'
 		 * appears to make some (28F320) flash devices switch to
 		 * 'read' mode.  Make sure that we switch to 'read status'
 		 * mode so we get the right data. --rmk
 		 */
-		map_write(map, CMD(0x70), adr);
+		map_write(map, CMD(0x70), chip->in_progress_block_addr);
 		chip->oldstate = FL_ERASING;
 		chip->state = FL_ERASE_SUSPENDING;
 		chip->erase_suspended = 1;
 		for (;;) {
-			status = map_read(map, adr);
+			status = map_read(map, chip->in_progress_block_addr);
 			if (map_word_andequal(map, status, status_OK, status_OK))
 			        break;
 
@@ -1035,8 +1056,8 @@ static void put_chip(struct map_info *ma
 		   sending the 0x70 (Read Status) command to an erasing
 		   chip and expecting it to be ignored, that's what we
 		   do. */
-		map_write(map, CMD(0xd0), adr);
-		map_write(map, CMD(0x70), adr);
+		map_write(map, CMD(0xd0), chip->in_progress_block_addr);
+		map_write(map, CMD(0x70), chip->in_progress_block_addr);
 		chip->oldstate = FL_READY;
 		chip->state = FL_ERASING;
 		break;
@@ -1927,6 +1948,8 @@ static int __xipram do_erase_oneblock(st
 	map_write(map, CMD(0xD0), adr);
 	chip->state = FL_ERASING;
 	chip->erase_suspended = 0;
+	chip->in_progress_block_addr = adr;
+	chip->in_progress_block_mask = ~(len - 1);
 
 	ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
 				   adr, len,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/chips/cfi_cmdset_0002.c linux-libre-4.1.52-gnu/drivers/mtd/chips/cfi_cmdset_0002.c
--- linux-libre-4.1.51-gnu/drivers/mtd/chips/cfi_cmdset_0002.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/chips/cfi_cmdset_0002.c	2018-05-27 22:26:45.000000000 -0400
@@ -814,9 +814,10 @@ static int get_chip(struct map_info *map
 		    (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
 			goto sleep;
 
-		/* We could check to see if we're trying to access the sector
-		 * that is currently being erased. However, no user will try
-		 * anything like that so we just wait for the timeout. */
+		/* Do not allow suspend iff read/write to EB address */
+		if ((adr & chip->in_progress_block_mask) ==
+		    chip->in_progress_block_addr)
+			goto sleep;
 
 		/* Erase suspend */
 		/* It's harmless to issue the Erase-Suspend and Erase-Resume
@@ -2265,6 +2266,7 @@ static int __xipram do_erase_chip(struct
 	chip->state = FL_ERASING;
 	chip->erase_suspended = 0;
 	chip->in_progress_block_addr = adr;
+	chip->in_progress_block_mask = ~(map->size - 1);
 
 	INVALIDATE_CACHE_UDELAY(map, chip,
 				adr, map->size,
@@ -2354,6 +2356,7 @@ static int __xipram do_erase_oneblock(st
 	chip->state = FL_ERASING;
 	chip->erase_suspended = 0;
 	chip->in_progress_block_addr = adr;
+	chip->in_progress_block_mask = ~(len - 1);
 
 	INVALIDATE_CACHE_UDELAY(map, chip,
 				adr, len,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/chips/jedec_probe.c linux-libre-4.1.52-gnu/drivers/mtd/chips/jedec_probe.c
--- linux-libre-4.1.51-gnu/drivers/mtd/chips/jedec_probe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/chips/jedec_probe.c	2018-05-27 22:26:45.000000000 -0400
@@ -1889,6 +1889,8 @@ static inline u32 jedec_read_mfr(struct
 	do {
 		uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
 		mask = (1 << (cfi->device_type * 8)) - 1;
+		if (ofs >= map->size)
+			return 0;
 		result = map_read(map, base + ofs);
 		bank++;
 	} while ((result.x[0] & mask) == CFI_MFR_CONTINUATION);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/nand/nand_base.c linux-libre-4.1.52-gnu/drivers/mtd/nand/nand_base.c
--- linux-libre-4.1.51-gnu/drivers/mtd/nand/nand_base.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/nand/nand_base.c	2018-05-27 22:26:45.000000000 -0400
@@ -618,7 +618,8 @@ static void nand_command(struct mtd_info
 		chip->cmd_ctrl(mtd, readcmd, ctrl);
 		ctrl &= ~NAND_CTRL_CHANGE;
 	}
-	chip->cmd_ctrl(mtd, command, ctrl);
+	if (command != NAND_CMD_NONE)
+		chip->cmd_ctrl(mtd, command, ctrl);
 
 	/* Address cycle, when necessary */
 	ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
@@ -647,6 +648,7 @@ static void nand_command(struct mtd_info
 	 */
 	switch (command) {
 
+	case NAND_CMD_NONE:
 	case NAND_CMD_PAGEPROG:
 	case NAND_CMD_ERASE1:
 	case NAND_CMD_ERASE2:
@@ -709,7 +711,9 @@ static void nand_command_lp(struct mtd_i
 	}
 
 	/* Command latch cycle */
-	chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+	if (command != NAND_CMD_NONE)
+		chip->cmd_ctrl(mtd, command,
+			       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
 
 	if (column != -1 || page_addr != -1) {
 		int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
@@ -742,6 +746,7 @@ static void nand_command_lp(struct mtd_i
 	 */
 	switch (command) {
 
+	case NAND_CMD_NONE:
 	case NAND_CMD_CACHEDPROG:
 	case NAND_CMD_PAGEPROG:
 	case NAND_CMD_ERASE1:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/ubi/block.c linux-libre-4.1.52-gnu/drivers/mtd/ubi/block.c
--- linux-libre-4.1.51-gnu/drivers/mtd/ubi/block.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/ubi/block.c	2018-05-27 22:26:45.000000000 -0400
@@ -241,7 +241,7 @@ static int ubiblock_open(struct block_de
 	 * in any case.
 	 */
 	if (mode & FMODE_WRITE) {
-		ret = -EPERM;
+		ret = -EROFS;
 		goto out_unlock;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/ubi/build.c linux-libre-4.1.52-gnu/drivers/mtd/ubi/build.c
--- linux-libre-4.1.51-gnu/drivers/mtd/ubi/build.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/ubi/build.c	2018-05-27 22:26:45.000000000 -0400
@@ -907,6 +907,17 @@ int ubi_attach_mtd_dev(struct mtd_info *
 		return -EINVAL;
 	}
 
+	/*
+	 * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes.
+	 * MLC NAND is different and needs special care, otherwise UBI or UBIFS
+	 * will die soon and you will lose all your data.
+	 */
+	if (mtd->type == MTD_MLCNANDFLASH) {
+		pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n",
+			mtd->index);
+		return -EINVAL;
+	}
+
 	if (ubi_num == UBI_DEV_NUM_AUTO) {
 		/* Search for an empty slot in the @ubi_devices array */
 		for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/mtd/ubi/fastmap-wl.c linux-libre-4.1.52-gnu/drivers/mtd/ubi/fastmap-wl.c
--- linux-libre-4.1.51-gnu/drivers/mtd/ubi/fastmap-wl.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/mtd/ubi/fastmap-wl.c	2018-05-27 22:26:45.000000000 -0400
@@ -331,7 +331,6 @@ static void ubi_fastmap_close(struct ubi
 {
 	int i;
 
-	flush_work(&ubi->fm_work);
 	return_unused_pool_pebs(ubi, &ubi->fm_pool);
 	return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/bonding/bond_main.c linux-libre-4.1.52-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-4.1.51-gnu/drivers/net/bonding/bond_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/bonding/bond_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -1476,39 +1476,6 @@ int bond_enslave(struct net_device *bond
 			goto err_close;
 	}
 
-	/* If the mode uses primary, then the following is handled by
-	 * bond_change_active_slave().
-	 */
-	if (!bond_uses_primary(bond)) {
-		/* set promiscuity level to new slave */
-		if (bond_dev->flags & IFF_PROMISC) {
-			res = dev_set_promiscuity(slave_dev, 1);
-			if (res)
-				goto err_close;
-		}
-
-		/* set allmulti level to new slave */
-		if (bond_dev->flags & IFF_ALLMULTI) {
-			res = dev_set_allmulti(slave_dev, 1);
-			if (res)
-				goto err_close;
-		}
-
-		netif_addr_lock_bh(bond_dev);
-
-		dev_mc_sync_multiple(slave_dev, bond_dev);
-		dev_uc_sync_multiple(slave_dev, bond_dev);
-
-		netif_addr_unlock_bh(bond_dev);
-	}
-
-	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-		/* add lacpdu mc addr to mc list */
-		u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-
-		dev_mc_add(slave_dev, lacpdu_multicast);
-	}
-
 	res = vlan_vids_add_by_dev(slave_dev, bond_dev);
 	if (res) {
 		netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n",
@@ -1633,8 +1600,7 @@ int bond_enslave(struct net_device *bond
 	} /* switch(bond_mode) */
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-	slave_dev->npinfo = bond->dev->npinfo;
-	if (slave_dev->npinfo) {
+	if (bond->dev->npinfo) {
 		if (slave_enable_netpoll(new_slave)) {
 			netdev_info(bond_dev, "master_dev is using netpoll, but new slave device does not support netpoll\n");
 			res = -EBUSY;
@@ -1665,6 +1631,40 @@ int bond_enslave(struct net_device *bond
 		goto err_upper_unlink;
 	}
 
+	/* If the mode uses primary, then the following is handled by
+	 * bond_change_active_slave().
+	 */
+	if (!bond_uses_primary(bond)) {
+		/* set promiscuity level to new slave */
+		if (bond_dev->flags & IFF_PROMISC) {
+			res = dev_set_promiscuity(slave_dev, 1);
+			if (res)
+				goto err_sysfs_del;
+		}
+
+		/* set allmulti level to new slave */
+		if (bond_dev->flags & IFF_ALLMULTI) {
+			res = dev_set_allmulti(slave_dev, 1);
+			if (res) {
+				if (bond_dev->flags & IFF_PROMISC)
+					dev_set_promiscuity(slave_dev, -1);
+				goto err_sysfs_del;
+			}
+		}
+
+		netif_addr_lock_bh(bond_dev);
+		dev_mc_sync_multiple(slave_dev, bond_dev);
+		dev_uc_sync_multiple(slave_dev, bond_dev);
+		netif_addr_unlock_bh(bond_dev);
+
+		if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+			/* add lacpdu mc addr to mc list */
+			u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
+
+			dev_mc_add(slave_dev, lacpdu_multicast);
+		}
+	}
+
 	bond->slave_cnt++;
 	bond_compute_features(bond);
 	bond_set_carrier(bond);
@@ -1688,6 +1688,9 @@ int bond_enslave(struct net_device *bond
 	return 0;
 
 /* Undo stages on error */
+err_sysfs_del:
+	bond_sysfs_slave_del(new_slave);
+
 err_upper_unlink:
 	bond_upper_dev_unlink(bond_dev, slave_dev);
 
@@ -1695,9 +1698,6 @@ err_unregister:
 	netdev_rx_handler_unregister(slave_dev);
 
 err_detach:
-	if (!bond_uses_primary(bond))
-		bond_hw_addr_flush(bond_dev, slave_dev);
-
 	vlan_vids_del_by_dev(slave_dev, bond_dev);
 	if (rcu_access_pointer(bond->primary_slave) == new_slave)
 		RCU_INIT_POINTER(bond->primary_slave, NULL);
@@ -2533,11 +2533,13 @@ static void bond_loadbalance_arp_mon(str
 	bond_for_each_slave_rcu(bond, slave, iter) {
 		unsigned long trans_start = dev_trans_start(slave->dev);
 
+		slave->new_link = BOND_LINK_NOCHANGE;
+
 		if (slave->link != BOND_LINK_UP) {
 			if (bond_time_in_interval(bond, trans_start, 1) &&
 			    bond_time_in_interval(bond, slave->last_rx, 1)) {
 
-				slave->link  = BOND_LINK_UP;
+				slave->new_link = BOND_LINK_UP;
 				slave_state_changed = 1;
 
 				/* primary_slave has no meaning in round-robin
@@ -2564,7 +2566,7 @@ static void bond_loadbalance_arp_mon(str
 			if (!bond_time_in_interval(bond, trans_start, 2) ||
 			    !bond_time_in_interval(bond, slave->last_rx, 2)) {
 
-				slave->link  = BOND_LINK_DOWN;
+				slave->new_link = BOND_LINK_DOWN;
 				slave_state_changed = 1;
 
 				if (slave->link_failure_count < UINT_MAX)
@@ -2595,6 +2597,11 @@ static void bond_loadbalance_arp_mon(str
 		if (!rtnl_trylock())
 			goto re_arm;
 
+		bond_for_each_slave(bond, slave, iter) {
+			if (slave->new_link != BOND_LINK_NOCHANGE)
+				slave->link = slave->new_link;
+		}
+
 		if (slave_state_changed) {
 			bond_slave_state_change(bond);
 			if (BOND_MODE(bond) == BOND_MODE_XOR)
@@ -3261,12 +3268,17 @@ static void bond_fold_stats(struct rtnl_
 	for (i = 0; i < sizeof(*_res) / sizeof(u64); i++) {
 		u64 nv = new[i];
 		u64 ov = old[i];
+		s64 delta = nv - ov;
 
 		/* detects if this particular field is 32bit only */
 		if (((nv | ov) >> 32) == 0)
-			res[i] += (u32)nv - (u32)ov;
-		else
-			res[i] += nv - ov;
+			delta = (s64)(s32)((u32)nv - (u32)ov);
+
+		/* filter anomalies, some drivers reset their stats
+		 * at down/up events.
+		 */
+		if (delta > 0)
+			res[i] += delta;
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/can/cc770/cc770.c linux-libre-4.1.52-gnu/drivers/net/can/cc770/cc770.c
--- linux-libre-4.1.51-gnu/drivers/net/can/cc770/cc770.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/can/cc770/cc770.c	2018-05-27 22:26:45.000000000 -0400
@@ -390,37 +390,23 @@ static int cc770_get_berr_counter(const
 	return 0;
 }
 
-static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static void cc770_tx(struct net_device *dev, int mo)
 {
 	struct cc770_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
-	struct can_frame *cf = (struct can_frame *)skb->data;
-	unsigned int mo = obj2msgobj(CC770_OBJ_TX);
+	struct can_frame *cf = (struct can_frame *)priv->tx_skb->data;
 	u8 dlc, rtr;
 	u32 id;
 	int i;
 
-	if (can_dropped_invalid_skb(dev, skb))
-		return NETDEV_TX_OK;
-
-	if ((cc770_read_reg(priv,
-			    msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
-		netdev_err(dev, "TX register is still occupied!\n");
-		return NETDEV_TX_BUSY;
-	}
-
-	netif_stop_queue(dev);
-
 	dlc = cf->can_dlc;
 	id = cf->can_id;
-	if (cf->can_id & CAN_RTR_FLAG)
-		rtr = 0;
-	else
-		rtr = MSGCFG_DIR;
+	rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR;
+
+	cc770_write_reg(priv, msgobj[mo].ctrl0,
+			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
 	cc770_write_reg(priv, msgobj[mo].ctrl1,
 			RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES);
+
 	if (id & CAN_EFF_FLAG) {
 		id &= CAN_EFF_MASK;
 		cc770_write_reg(priv, msgobj[mo].config,
@@ -439,22 +425,30 @@ static netdev_tx_t cc770_start_xmit(stru
 	for (i = 0; i < dlc; i++)
 		cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
 
-	/* Store echo skb before starting the transfer */
-	can_put_echo_skb(skb, dev, 0);
-
 	cc770_write_reg(priv, msgobj[mo].ctrl1,
-			RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
+			RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
+	cc770_write_reg(priv, msgobj[mo].ctrl0,
+			MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC);
+}
 
-	stats->tx_bytes += dlc;
+static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	unsigned int mo = obj2msgobj(CC770_OBJ_TX);
 
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
 
-	/*
-	 * HM: We had some cases of repeated IRQs so make sure the
-	 * INT is acknowledged I know it's already further up, but
-	 * doing again fixed the issue
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+	netif_stop_queue(dev);
+
+	if ((cc770_read_reg(priv,
+			    msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
+		netdev_err(dev, "TX register is still occupied!\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	priv->tx_skb = skb;
+	cc770_tx(dev, mo);
 
 	return NETDEV_TX_OK;
 }
@@ -680,19 +674,46 @@ static void cc770_tx_interrupt(struct ne
 	struct cc770_priv *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &dev->stats;
 	unsigned int mo = obj2msgobj(o);
+	struct can_frame *cf;
+	u8 ctrl1;
+
+	ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
 
-	/* Nothing more to send, switch off interrupts */
 	cc770_write_reg(priv, msgobj[mo].ctrl0,
 			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
-	/*
-	 * We had some cases of repeated IRQ so make sure the
-	 * INT is acknowledged
+	cc770_write_reg(priv, msgobj[mo].ctrl1,
+			RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES);
+
+	if (unlikely(!priv->tx_skb)) {
+		netdev_err(dev, "missing tx skb in tx interrupt\n");
+		return;
+	}
+
+	if (unlikely(ctrl1 & MSGLST_SET)) {
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+	}
+
+	/* When the CC770 is sending an RTR message and it receives a regular
+	 * message that matches the id of the RTR message, it will overwrite the
+	 * outgoing message in the TX register. When this happens we must
+	 * process the received message and try to transmit the outgoing skb
+	 * again.
 	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+	if (unlikely(ctrl1 & NEWDAT_SET)) {
+		cc770_rx(dev, mo, ctrl1);
+		cc770_tx(dev, mo);
+		return;
+	}
 
+	cf = (struct can_frame *)priv->tx_skb->data;
+	stats->tx_bytes += cf->can_dlc;
 	stats->tx_packets++;
+
+	can_put_echo_skb(priv->tx_skb, dev, 0);
 	can_get_echo_skb(dev, 0);
+	priv->tx_skb = NULL;
+
 	netif_wake_queue(dev);
 }
 
@@ -804,6 +825,7 @@ struct net_device *alloc_cc770dev(int si
 	priv->can.do_set_bittiming = cc770_set_bittiming;
 	priv->can.do_set_mode = cc770_set_mode;
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+	priv->tx_skb = NULL;
 
 	memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/can/cc770/cc770.h linux-libre-4.1.52-gnu/drivers/net/can/cc770/cc770.h
--- linux-libre-4.1.51-gnu/drivers/net/can/cc770/cc770.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/can/cc770/cc770.h	2018-05-27 22:26:45.000000000 -0400
@@ -193,6 +193,8 @@ struct cc770_priv {
 	u8 cpu_interface;	/* CPU interface register */
 	u8 clkout;		/* Clock out register */
 	u8 bus_config;		/* Bus conffiguration register */
+
+	struct sk_buff *tx_skb;
 };
 
 struct net_device *alloc_cc770dev(int sizeof_priv);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c linux-libre-4.1.52-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c	2018-05-27 22:26:45.000000000 -0400
@@ -535,6 +535,7 @@ static void xgene_enet_cle_bypass(struct
 	xgene_enet_rd_csr(pdata, CLE_BYPASS_REG0_0_ADDR, &cb);
 	cb |= CFG_CLE_BYPASS_EN0;
 	CFG_CLE_IP_PROTOCOL0_SET(&cb, 3);
+	CFG_CLE_IP_HDR_LEN_SET(&cb, 0);
 	xgene_enet_wr_csr(pdata, CLE_BYPASS_REG0_0_ADDR, cb);
 
 	xgene_enet_rd_csr(pdata, CLE_BYPASS_REG1_0_ADDR, &cb);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h linux-libre-4.1.52-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h	2018-05-27 22:26:45.000000000 -0400
@@ -145,6 +145,7 @@ enum xgene_enet_rm {
 #define CFG_TXCLK_MUXSEL0_SET(dst, val)	xgene_set_bits(dst, val, 29, 3)
 
 #define CFG_CLE_IP_PROTOCOL0_SET(dst, val)	xgene_set_bits(dst, val, 16, 2)
+#define CFG_CLE_IP_HDR_LEN_SET(dst, val)	xgene_set_bits(dst, val, 8, 5)
 #define CFG_CLE_DSTQID0_SET(dst, val)		xgene_set_bits(dst, val, 0, 12)
 #define CFG_CLE_FPSEL0_SET(dst, val)		xgene_set_bits(dst, val, 16, 4)
 #define CFG_MACMODE_SET(dst, val)		xgene_set_bits(dst, val, 18, 2)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/arc/emac_rockchip.c linux-libre-4.1.52-gnu/drivers/net/ethernet/arc/emac_rockchip.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/arc/emac_rockchip.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/arc/emac_rockchip.c	2018-05-27 22:26:45.000000000 -0400
@@ -150,8 +150,10 @@ static int emac_rockchip_probe(struct pl
 	/* Optional regulator for PHY */
 	priv->regulator = devm_regulator_get_optional(dev, "phy");
 	if (IS_ERR(priv->regulator)) {
-		if (PTR_ERR(priv->regulator) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
+		if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) {
+			err = -EPROBE_DEFER;
+			goto out_clk_disable;
+		}
 		dev_err(dev, "no regulator found\n");
 		priv->regulator = NULL;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-libre-4.1.52-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2018-03-28 09:51:26.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2018-05-29 04:38:27.000000000 -0400
@@ -2024,6 +2024,7 @@ static void bnx2x_set_rx_buf_size(struct
 				  ETH_OVREHEAD +
 				  mtu +
 				  BNX2X_FW_RX_ALIGN_END;
+		fp->rx_buf_size = SKB_DATA_ALIGN(fp->rx_buf_size);
 		/* Note : rx_buf_size doesn't take into account NET_SKB_PAD */
 		if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE)
 			fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD;
@@ -3876,15 +3877,26 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b
 		/* when transmitting in a vf, start bd must hold the ethertype
 		 * for fw to enforce it
 		 */
+		u16 vlan_tci = 0;
 #ifndef BNX2X_STOP_ON_ERROR
-		if (IS_VF(bp))
+		if (IS_VF(bp)) {
 #endif
-			tx_start_bd->vlan_or_ethertype =
-				cpu_to_le16(ntohs(eth->h_proto));
+			/* Still need to consider inband vlan for enforced */
+			if (__vlan_get_tag(skb, &vlan_tci)) {
+				tx_start_bd->vlan_or_ethertype =
+					cpu_to_le16(ntohs(eth->h_proto));
+			} else {
+				tx_start_bd->bd_flags.as_bitfield |=
+					(X_ETH_INBAND_VLAN <<
+					 ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
+				tx_start_bd->vlan_or_ethertype =
+					cpu_to_le16(vlan_tci);
+			}
 #ifndef BNX2X_STOP_ON_ERROR
-		else
+		} else {
 			/* used by FW for packet accounting */
 			tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
+		}
 #endif
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c linux-libre-4.1.52-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c	2018-05-27 22:26:45.000000000 -0400
@@ -2861,7 +2861,7 @@ bfa_ioc_get_adapter_optrom_ver(struct bf
 static void
 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer)
 {
-	memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+	strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
 }
 
 static void
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c linux-libre-4.1.52-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c	2018-05-27 22:26:45.000000000 -0400
@@ -2573,8 +2573,8 @@ void t4vf_sge_stop(struct adapter *adapt
 int t4vf_sge_init(struct adapter *adapter)
 {
 	struct sge_params *sge_params = &adapter->params.sge;
-	u32 fl0 = sge_params->sge_fl_buffer_size[0];
-	u32 fl1 = sge_params->sge_fl_buffer_size[1];
+	u32 fl_small_pg = sge_params->sge_fl_buffer_size[0];
+	u32 fl_large_pg = sge_params->sge_fl_buffer_size[1];
 	struct sge *s = &adapter->sge;
 	unsigned int ingpadboundary, ingpackboundary;
 
@@ -2583,9 +2583,20 @@ int t4vf_sge_init(struct adapter *adapte
 	 * the Physical Function Driver.  Ideally we should be able to deal
 	 * with _any_ configuration.  Practice is different ...
 	 */
-	if (fl0 != PAGE_SIZE || (fl1 != 0 && fl1 <= fl0)) {
+
+	/* We only bother using the Large Page logic if the Large Page Buffer
+	 * is larger than our Page Size Buffer.
+	 */
+	if (fl_large_pg <= fl_small_pg)
+		fl_large_pg = 0;
+
+	/* The Page Size Buffer must be exactly equal to our Page Size and the
+	 * Large Page Size Buffer should be 0 (per above) or a power of 2.
+	 */
+	if (fl_small_pg != PAGE_SIZE ||
+	    (fl_large_pg & (fl_large_pg - 1)) != 0) {
 		dev_err(adapter->pdev_dev, "bad SGE FL buffer sizes [%d, %d]\n",
-			fl0, fl1);
+			fl_small_pg, fl_large_pg);
 		return -EINVAL;
 	}
 	if ((sge_params->sge_control & RXPKTCPLMODE_F) == 0) {
@@ -2596,8 +2607,8 @@ int t4vf_sge_init(struct adapter *adapte
 	/*
 	 * Now translate the adapter parameters into our internal forms.
 	 */
-	if (fl1)
-		s->fl_pg_order = ilog2(fl1) - PAGE_SHIFT;
+	if (fl_large_pg)
+		s->fl_pg_order = ilog2(fl_large_pg) - PAGE_SHIFT;
 	s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_F)
 			? 128 : 64);
 	s->pktshift = PKTSHIFT_G(sge_params->sge_control);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/faraday/ftgmac100.c linux-libre-4.1.52-gnu/drivers/net/ethernet/faraday/ftgmac100.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/faraday/ftgmac100.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/faraday/ftgmac100.c	2018-05-27 22:26:45.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <net/ip.h>
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/freescale/fsl_pq_mdio.c linux-libre-4.1.52-gnu/drivers/net/ethernet/freescale/fsl_pq_mdio.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/freescale/fsl_pq_mdio.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/freescale/fsl_pq_mdio.c	2018-05-27 22:26:45.000000000 -0400
@@ -370,7 +370,7 @@ static int fsl_pq_mdio_probe(struct plat
 {
 	const struct of_device_id *id =
 		of_match_device(fsl_pq_mdio_match, &pdev->dev);
-	const struct fsl_pq_mdio_data *data = id->data;
+	const struct fsl_pq_mdio_data *data;
 	struct device_node *np = pdev->dev.of_node;
 	struct resource res;
 	struct device_node *tbi;
@@ -378,6 +378,13 @@ static int fsl_pq_mdio_probe(struct plat
 	struct mii_bus *new_bus;
 	int err;
 
+	if (!id) {
+		dev_err(&pdev->dev, "Failed to match device\n");
+		return -ENODEV;
+	}
+
+	data = id->data;
+
 	dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible);
 
 	new_bus = mdiobus_alloc_size(sizeof(*priv));
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/ibm/emac/core.c linux-libre-4.1.52-gnu/drivers/net/ethernet/ibm/emac/core.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/ibm/emac/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/ibm/emac/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -342,6 +342,7 @@ static int emac_reset(struct emac_instan
 {
 	struct emac_regs __iomem *p = dev->emacp;
 	int n = 20;
+	bool __maybe_unused try_internal_clock = false;
 
 	DBG(dev, "reset" NL);
 
@@ -354,6 +355,7 @@ static int emac_reset(struct emac_instan
 	}
 
 #ifdef CONFIG_PPC_DCR_NATIVE
+do_retry:
 	/*
 	 * PPC460EX/GT Embedded Processor Advanced User's Manual
 	 * section 28.10.1 Mode Register 0 (EMACx_MR0) states:
@@ -361,10 +363,19 @@ static int emac_reset(struct emac_instan
 	 * of the EMAC. If none is present, select the internal clock
 	 * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
 	 * After a soft reset, select the external clock.
+	 *
+	 * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the
+	 * ethernet cable is not attached. This causes the reset to timeout
+	 * and the PHY detection code in emac_init_phy() is unable to
+	 * communicate and detect the AR8035-A PHY. As a result, the emac
+	 * driver bails out early and the user has no ethernet.
+	 * In order to stay compatible with existing configurations, the
+	 * driver will temporarily switch to the internal clock, after
+	 * the first reset fails.
 	 */
 	if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-		if (dev->phy_address == 0xffffffff &&
-		    dev->phy_map == 0xffffffff) {
+		if (try_internal_clock || (dev->phy_address == 0xffffffff &&
+					   dev->phy_map == 0xffffffff)) {
 			/* No PHY: select internal loop clock before reset */
 			dcri_clrset(SDR0, SDR0_ETH_CFG,
 				    0, SDR0_ETH_CFG_ECS << dev->cell_index);
@@ -382,8 +393,15 @@ static int emac_reset(struct emac_instan
 
 #ifdef CONFIG_PPC_DCR_NATIVE
 	if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-		if (dev->phy_address == 0xffffffff &&
-		    dev->phy_map == 0xffffffff) {
+		if (!n && !try_internal_clock) {
+			/* first attempt has timed out. */
+			n = 20;
+			try_internal_clock = true;
+			goto do_retry;
+		}
+
+		if (try_internal_clock || (dev->phy_address == 0xffffffff &&
+					   dev->phy_map == 0xffffffff)) {
 			/* No PHY: restore external clock source after reset */
 			dcri_clrset(SDR0, SDR0_ETH_CFG,
 				    SDR0_ETH_CFG_ECS << dev->cell_index, 0);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/intel/e1000e/netdev.c linux-libre-4.1.52-gnu/drivers/net/ethernet/intel/e1000e/netdev.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2018-05-27 22:26:45.000000000 -0400
@@ -1182,6 +1182,7 @@ static void e1000e_tx_hwtstamp_work(stru
 	struct e1000_hw *hw = &adapter->hw;
 
 	if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) {
+		struct sk_buff *skb = adapter->tx_hwtstamp_skb;
 		struct skb_shared_hwtstamps shhwtstamps;
 		u64 txstmp;
 
@@ -1190,9 +1191,14 @@ static void e1000e_tx_hwtstamp_work(stru
 
 		e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp);
 
-		skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
-		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
+		/* Clear the global tx_hwtstamp_skb pointer and force writes
+		 * prior to notifying the stack of a Tx timestamp.
+		 */
 		adapter->tx_hwtstamp_skb = NULL;
+		wmb(); /* force write prior to skb_tstamp_tx */
+
+		skb_tstamp_tx(skb, &shhwtstamps);
+		dev_kfree_skb_any(skb);
 	} else if (time_after(jiffies, adapter->tx_hwtstamp_start
 			      + adapter->tx_timeout_factor * HZ)) {
 		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
@@ -3524,6 +3530,12 @@ s32 e1000e_get_base_timinca(struct e1000
 
 	switch (hw->mac.type) {
 	case e1000_pch2lan:
+		/* Stable 96MHz frequency */
+		incperiod = INCPERIOD_96MHz;
+		incvalue = INCVALUE_96MHz;
+		shift = INCVALUE_SHIFT_96MHz;
+		adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz;
+		break;
 	case e1000_pch_lpt:
 	case e1000_pch_spt:
 		/* On I217, I218 and I219, the clock frequency is 25MHz
@@ -6375,12 +6387,17 @@ static int e1000e_pm_thaw(struct device
 static int e1000e_pm_suspend(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
+	int rc;
 
 	e1000e_flush_lpic(pdev);
 
 	e1000e_pm_freeze(dev);
 
-	return __e1000_shutdown(pdev, false);
+	rc = __e1000_shutdown(pdev, false);
+	if (rc)
+		e1000e_pm_thaw(dev);
+
+	return rc;
 }
 
 static int e1000e_pm_resume(struct device *dev)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c linux-libre-4.1.52-gnu/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c	2018-05-27 22:26:45.000000000 -0400
@@ -869,7 +869,7 @@ static void fm10k_self_test(struct net_d
 
 	memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
 
-	if (FM10K_REMOVED(hw)) {
+	if (FM10K_REMOVED(hw->hw_addr)) {
 		netif_err(interface, drv, dev,
 			  "Interface removed - test blocked\n");
 		eth_test->flags |= ETH_TEST_FL_FAILED;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/marvell/sky2.c linux-libre-4.1.52-gnu/drivers/net/ethernet/marvell/sky2.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/marvell/sky2.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/marvell/sky2.c	2018-05-27 22:26:45.000000000 -0400
@@ -5067,7 +5067,7 @@ static int sky2_probe(struct pci_dev *pd
 	INIT_WORK(&hw->restart_work, sky2_restart);
 
 	pci_set_drvdata(pdev, hw);
-	pdev->d3_delay = 150;
+	pdev->d3_delay = 200;
 
 	return 0;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c linux-libre-4.1.52-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c	2018-05-27 22:26:45.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/etherdevice.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/mlx4/qp.h>
 #include <linux/export.h>
 
 #include "mlx4.h"
@@ -985,16 +986,21 @@ int mlx4_flow_attach(struct mlx4_dev *de
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
 
+	if (!mlx4_qp_lookup(dev, rule->qpn)) {
+		mlx4_err_rule(dev, "QP doesn't exist\n", rule);
+		ret = -EINVAL;
+		goto out;
+	}
+
 	trans_rule_ctrl_to_hw(rule, mailbox->buf);
 
 	size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);
 
 	list_for_each_entry(cur, &rule->list, list) {
 		ret = parse_trans_rule(dev, cur, mailbox->buf + size);
-		if (ret < 0) {
-			mlx4_free_cmd_mailbox(dev, mailbox);
-			return ret;
-		}
+		if (ret < 0)
+			goto out;
+
 		size += ret;
 	}
 
@@ -1021,6 +1027,7 @@ int mlx4_flow_attach(struct mlx4_dev *de
 		}
 	}
 
+out:
 	mlx4_free_cmd_mailbox(dev, mailbox);
 
 	return ret;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/mellanox/mlx4/qp.c linux-libre-4.1.52-gnu/drivers/net/ethernet/mellanox/mlx4/qp.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/mellanox/mlx4/qp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/mellanox/mlx4/qp.c	2018-05-27 22:26:45.000000000 -0400
@@ -381,6 +381,19 @@ static void mlx4_qp_free_icm(struct mlx4
 		__mlx4_qp_free_icm(dev, qpn);
 }
 
+struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
+{
+	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
+	struct mlx4_qp *qp;
+
+	spin_lock(&qp_table->lock);
+
+	qp = __mlx4_qp_lookup(dev, qpn);
+
+	spin_unlock(&qp_table->lock);
+	return qp;
+}
+
 int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c	2018-05-27 22:26:45.000000000 -0400
@@ -247,7 +247,7 @@ nx_fw_cmd_set_mtu(struct netxen_adapter
 	cmd.req.arg3 = 0;
 
 	if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
-		netxen_issue_cmd(adapter, &cmd);
+		rcode = netxen_issue_cmd(adapter, &cmd);
 
 	if (rcode != NX_RCODE_SUCCESS)
 		return -EIO;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c	2018-05-27 22:26:45.000000000 -0400
@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapt
 			}
 			return -EIO;
 		}
-		usleep_range(1000, 1500);
+		udelay(1200);
 	}
 
 	if (id_reg)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c	2018-05-27 22:26:45.000000000 -0400
@@ -126,6 +126,8 @@ static int qlcnic_sriov_virtid_fn(struct
 		return 0;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+	if (!pos)
+		return 0;
 	pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
 	pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c	2018-05-27 22:26:45.000000000 -0400
@@ -765,7 +765,7 @@ int ql_core_dump(struct ql_adapter *qdev
 		sizeof(struct mpi_coredump_global_header);
 	mpi_coredump->mpi_global_header.imageSize =
 		sizeof(struct ql_mpi_coredump);
-	memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
+	strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
 		sizeof(mpi_coredump->mpi_global_header.idString));
 
 	/* Get generic NIC reg dump */
@@ -1255,7 +1255,7 @@ static void ql_gen_reg_dump(struct ql_ad
 		sizeof(struct mpi_coredump_global_header);
 	mpi_coredump->mpi_global_header.imageSize =
 		sizeof(struct ql_reg_dump);
-	memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
+	strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
 		sizeof(mpi_coredump->mpi_global_header.idString));
 
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/qualcomm/qca_spi.c linux-libre-4.1.52-gnu/drivers/net/ethernet/qualcomm/qca_spi.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/qualcomm/qca_spi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/qualcomm/qca_spi.c	2018-05-27 22:26:45.000000000 -0400
@@ -296,8 +296,9 @@ qcaspi_receive(struct qcaspi *qca)
 
 	/* Allocate rx SKB if we don't have one available. */
 	if (!qca->rx_skb) {
-		qca->rx_skb = netdev_alloc_skb(net_dev,
-					       net_dev->mtu + VLAN_ETH_HLEN);
+		qca->rx_skb = netdev_alloc_skb_ip_align(net_dev,
+							net_dev->mtu +
+							VLAN_ETH_HLEN);
 		if (!qca->rx_skb) {
 			netdev_dbg(net_dev, "out of RX resources\n");
 			qca->stats.out_of_mem++;
@@ -377,7 +378,7 @@ qcaspi_receive(struct qcaspi *qca)
 					qca->rx_skb, qca->rx_skb->dev);
 				qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
 				netif_rx_ni(qca->rx_skb);
-				qca->rx_skb = netdev_alloc_skb(net_dev,
+				qca->rx_skb = netdev_alloc_skb_ip_align(net_dev,
 					net_dev->mtu + VLAN_ETH_HLEN);
 				if (!qca->rx_skb) {
 					netdev_dbg(net_dev, "out of RX resources\n");
@@ -759,7 +760,8 @@ qcaspi_netdev_init(struct net_device *de
 	if (!qca->rx_buffer)
 		return -ENOBUFS;
 
-	qca->rx_skb = netdev_alloc_skb(dev, qca->net_dev->mtu + VLAN_ETH_HLEN);
+	qca->rx_skb = netdev_alloc_skb_ip_align(dev, qca->net_dev->mtu +
+						VLAN_ETH_HLEN);
 	if (!qca->rx_skb) {
 		kfree(qca->rx_buffer);
 		netdev_info(qca->net_dev, "Failed to allocate RX sk_buff.\n");
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/renesas/sh_eth.c linux-libre-4.1.52-gnu/drivers/net/ethernet/renesas/sh_eth.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/renesas/sh_eth.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/renesas/sh_eth.c	2018-05-27 22:26:45.000000000 -0400
@@ -3217,7 +3217,7 @@ static int sh_eth_drv_probe(struct platf
 	/* MDIO bus init */
 	ret = sh_mdio_init(mdp, pd);
 	if (ret) {
-		dev_err(&ndev->dev, "failed to initialise MDIO\n");
+		dev_err(&pdev->dev, "failed to initialise MDIO\n");
 		goto out_release;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ethernet/ti/cpsw.c linux-libre-4.1.52-gnu/drivers/net/ethernet/ti/cpsw.c
--- linux-libre-4.1.51-gnu/drivers/net/ethernet/ti/cpsw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ethernet/ti/cpsw.c	2018-05-27 22:26:45.000000000 -0400
@@ -291,6 +291,10 @@ struct cpsw_ss_regs {
 /* Bit definitions for the CPSW1_TS_SEQ_LTYPE register */
 #define CPSW_V1_SEQ_ID_OFS_SHIFT	16
 
+#define CPSW_MAX_BLKS_TX		15
+#define CPSW_MAX_BLKS_TX_SHIFT		4
+#define CPSW_MAX_BLKS_RX		5
+
 struct cpsw_host_regs {
 	u32	max_blks;
 	u32	blk_cnt;
@@ -1126,11 +1130,23 @@ static void cpsw_slave_open(struct cpsw_
 	switch (priv->version) {
 	case CPSW_VERSION_1:
 		slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP);
+		/* Increase RX FIFO size to 5 for supporting fullduplex
+		 * flow control mode
+		 */
+		slave_write(slave,
+			    (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
+			    CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS);
 		break;
 	case CPSW_VERSION_2:
 	case CPSW_VERSION_3:
 	case CPSW_VERSION_4:
 		slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP);
+		/* Increase RX FIFO size to 5 for supporting fullduplex
+		 * flow control mode
+		 */
+		slave_write(slave,
+			    (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
+			    CPSW_MAX_BLKS_RX, CPSW2_MAX_BLKS);
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/hamradio/hdlcdrv.c linux-libre-4.1.52-gnu/drivers/net/hamradio/hdlcdrv.c
--- linux-libre-4.1.51-gnu/drivers/net/hamradio/hdlcdrv.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/hamradio/hdlcdrv.c	2018-05-27 22:26:45.000000000 -0400
@@ -574,6 +574,8 @@ static int hdlcdrv_ioctl(struct net_devi
 	case HDLCDRVCTL_CALIBRATE:
 		if(!capable(CAP_SYS_RAWIO))
 			return -EPERM;
+		if (s->par.bitrate <= 0)
+			return -EINVAL;
 		if (bi.data.calibrate > INT_MAX / s->par.bitrate)
 			return -EINVAL;
 		s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ipvlan/ipvlan_core.c linux-libre-4.1.52-gnu/drivers/net/ipvlan/ipvlan_core.c
--- linux-libre-4.1.51-gnu/drivers/net/ipvlan/ipvlan_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ipvlan/ipvlan_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -275,6 +275,10 @@ static int ipvlan_rcv_frame(struct ipvl_
 		if (dev_forward_skb(ipvlan->dev, skb) == NET_RX_SUCCESS)
 			success = true;
 	} else {
+		if (!ether_addr_equal_64bits(eth_hdr(skb)->h_dest,
+					     ipvlan->phy_dev->dev_addr))
+			skb->pkt_type = PACKET_OTHERHOST;
+
 		ret = RX_HANDLER_ANOTHER;
 		success = true;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/phy/phy.c linux-libre-4.1.52-gnu/drivers/net/phy/phy.c
--- linux-libre-4.1.51-gnu/drivers/net/phy/phy.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/phy/phy.c	2018-05-27 22:26:45.000000000 -0400
@@ -123,6 +123,12 @@ static inline int phy_aneg_done(struct p
 	if (phydev->drv->aneg_done)
 		return phydev->drv->aneg_done(phydev);
 
+	/* Avoid genphy_aneg_done() if the Clause 45 PHY does not
+	 * implement Clause 22 registers
+	 */
+	if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
+		return -EINVAL;
+
 	return genphy_aneg_done(phydev);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ppp/pppoe.c linux-libre-4.1.52-gnu/drivers/net/ppp/pppoe.c
--- linux-libre-4.1.51-gnu/drivers/net/ppp/pppoe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ppp/pppoe.c	2018-05-27 22:26:45.000000000 -0400
@@ -638,6 +638,10 @@ static int pppoe_connect(struct socket *
 	lock_sock(sk);
 
 	error = -EINVAL;
+
+	if (sockaddr_len != sizeof(struct sockaddr_pppox))
+		goto end;
+
 	if (sp->sa_protocol != PX_PROTO_OE)
 		goto end;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/ppp/pptp.c linux-libre-4.1.52-gnu/drivers/net/ppp/pptp.c
--- linux-libre-4.1.51-gnu/drivers/net/ppp/pptp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/ppp/pptp.c	2018-05-27 22:26:45.000000000 -0400
@@ -502,7 +502,6 @@ static int pptp_connect(struct socket *s
 	po->chan.mtu = dst_mtu(&rt->dst);
 	if (!po->chan.mtu)
 		po->chan.mtu = PPP_MRU;
-	ip_rt_put(rt);
 	po->chan.mtu -= PPTP_HEADER_OVERHEAD;
 
 	po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/slip/slhc.c linux-libre-4.1.52-gnu/drivers/net/slip/slhc.c
--- linux-libre-4.1.51-gnu/drivers/net/slip/slhc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/slip/slhc.c	2018-05-27 22:26:45.000000000 -0400
@@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp,
 		if(x < 0 || x > comp->rslot_limit)
 			goto bad;
 
+		/* Check if the cstate is initialized */
+		if (!comp->rstate[x].initialized)
+			goto bad;
+
 		comp->flags &=~ SLF_TOSS;
 		comp->recv_current = x;
 	} else {
@@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, u
 	if (cs->cs_tcp.doff > 5)
 	  memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
 	cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
+	cs->initialized = true;
 	/* Put headers back on packet
 	 * Neither header checksum is recalculated
 	 */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/team/team.c linux-libre-4.1.52-gnu/drivers/net/team/team.c
--- linux-libre-4.1.51-gnu/drivers/net/team/team.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/team/team.c	2018-05-27 22:26:45.000000000 -0400
@@ -247,6 +247,17 @@ static void __team_option_inst_mark_remo
 	}
 }
 
+static bool __team_option_inst_tmp_find(const struct list_head *opts,
+					const struct team_option_inst *needle)
+{
+	struct team_option_inst *opt_inst;
+
+	list_for_each_entry(opt_inst, opts, tmp_list)
+		if (opt_inst == needle)
+			return true;
+	return false;
+}
+
 static int __team_options_register(struct team *team,
 				   const struct team_option *option,
 				   size_t option_count)
@@ -1034,14 +1045,11 @@ static void team_port_leave(struct team
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
+static int __team_port_enable_netpoll(struct team_port *port)
 {
 	struct netpoll *np;
 	int err;
 
-	if (!team->dev->npinfo)
-		return 0;
-
 	np = kzalloc(sizeof(*np), GFP_KERNEL);
 	if (!np)
 		return -ENOMEM;
@@ -1055,6 +1063,14 @@ static int team_port_enable_netpoll(stru
 	return err;
 }
 
+static int team_port_enable_netpoll(struct team_port *port)
+{
+	if (!port->team->dev->npinfo)
+		return 0;
+
+	return __team_port_enable_netpoll(port);
+}
+
 static void team_port_disable_netpoll(struct team_port *port)
 {
 	struct netpoll *np = port->np;
@@ -1069,7 +1085,7 @@ static void team_port_disable_netpoll(st
 	kfree(np);
 }
 #else
-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
+static int team_port_enable_netpoll(struct team_port *port)
 {
 	return 0;
 }
@@ -1176,7 +1192,7 @@ static int team_port_add(struct team *te
 		goto err_vids_add;
 	}
 
-	err = team_port_enable_netpoll(team, port);
+	err = team_port_enable_netpoll(port);
 	if (err) {
 		netdev_err(dev, "Failed to enable netpoll on device %s\n",
 			   portname);
@@ -1884,7 +1900,7 @@ static int team_netpoll_setup(struct net
 
 	mutex_lock(&team->lock);
 	list_for_each_entry(port, &team->port_list, list) {
-		err = team_port_enable_netpoll(team, port);
+		err = __team_port_enable_netpoll(port);
 		if (err) {
 			__team_netpoll_cleanup(team);
 			break;
@@ -2371,7 +2387,7 @@ send_done:
 	if (!nlh) {
 		err = __send_and_alloc_skb(&skb, team, portid, send_func);
 		if (err)
-			goto errout;
+			return err;
 		goto send_done;
 	}
 
@@ -2535,6 +2551,14 @@ static int team_nl_cmd_options_set(struc
 			if (err)
 				goto team_put;
 			opt_inst->changed = true;
+
+			/* dumb/evil user-space can send us duplicate opt,
+			 * keep only the last one
+			 */
+			if (__team_option_inst_tmp_find(&opt_inst_list,
+							opt_inst))
+				continue;
+
 			list_add(&opt_inst->tmp_list, &opt_inst_list);
 		}
 		if (!opt_found) {
@@ -2651,7 +2675,7 @@ send_done:
 	if (!nlh) {
 		err = __send_and_alloc_skb(&skb, team, portid, send_func);
 		if (err)
-			goto errout;
+			return err;
 		goto send_done;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/usb/cdc_ether.c linux-libre-4.1.52-gnu/drivers/net/usb/cdc_ether.c
--- linux-libre-4.1.51-gnu/drivers/net/usb/cdc_ether.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/usb/cdc_ether.c	2018-05-27 22:26:45.000000000 -0400
@@ -751,6 +751,12 @@ static const struct usb_device_id	produc
 				      USB_CDC_PROTO_NONE),
 	.driver_info = (unsigned long)&wwan_info,
 }, {
+	/* Cinterion AHS3 modem by GEMALTO */
+	USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0055, USB_CLASS_COMM,
+				      USB_CDC_SUBCLASS_ETHERNET,
+				      USB_CDC_PROTO_NONE),
+	.driver_info = (unsigned long)&wwan_info,
+}, {
 	/* Telit modules */
 	USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/usb/qmi_wwan.c linux-libre-4.1.52-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-4.1.51-gnu/drivers/net/usb/qmi_wwan.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/usb/qmi_wwan.c	2018-05-27 22:26:45.000000000 -0400
@@ -674,6 +674,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x05c6, 0x9080, 8)},
 	{QMI_FIXED_INTF(0x05c6, 0x9083, 3)},
 	{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
+	{QMI_FIXED_INTF(0x05c6, 0x90b2, 3)},    /* ublox R410M */
 	{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
 	{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
 	{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/veth.c linux-libre-4.1.52-gnu/drivers/net/veth.c
--- linux-libre-4.1.51-gnu/drivers/net/veth.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/veth.c	2018-05-27 22:26:45.000000000 -0400
@@ -397,6 +397,9 @@ static int veth_newlink(struct net *src_
 	if (ifmp && (dev->ifindex != 0))
 		peer->ifindex = ifmp->ifi_index;
 
+	peer->gso_max_size = dev->gso_max_size;
+	peer->gso_max_segs = dev->gso_max_segs;
+
 	err = register_netdevice(peer);
 	put_net(net);
 	net = NULL;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/virtio_net.c linux-libre-4.1.52-gnu/drivers/net/virtio_net.c
--- linux-libre-4.1.51-gnu/drivers/net/virtio_net.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/virtio_net.c	2018-05-27 22:26:45.000000000 -0400
@@ -852,7 +852,7 @@ static int xmit_skb(struct send_queue *s
 	struct virtio_net_hdr_mrg_rxbuf *hdr;
 	const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
 	struct virtnet_info *vi = sq->vq->vdev->priv;
-	unsigned num_sg;
+	int num_sg;
 	unsigned hdr_len = vi->hdr_len;
 	bool can_push;
 
@@ -905,11 +905,16 @@ static int xmit_skb(struct send_queue *s
 	if (can_push) {
 		__skb_push(skb, hdr_len);
 		num_sg = skb_to_sgvec(skb, sq->sg, 0, skb->len);
+		if (unlikely(num_sg < 0))
+			return num_sg;
 		/* Pull header back to avoid skew in tx bytes calculations. */
 		__skb_pull(skb, hdr_len);
 	} else {
 		sg_set_buf(sq->sg, hdr, hdr_len);
-		num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1;
+		num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len);
+		if (unlikely(num_sg < 0))
+			return num_sg;
+		num_sg++;
 	}
 	return virtqueue_add_outbuf(sq->vq, sq->sg, num_sg, skb, GFP_ATOMIC);
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/vmxnet3/vmxnet3_drv.c linux-libre-4.1.52-gnu/drivers/net/vmxnet3/vmxnet3_drv.c
--- linux-libre-4.1.51-gnu/drivers/net/vmxnet3/vmxnet3_drv.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/vmxnet3/vmxnet3_drv.c	2018-05-27 22:26:45.000000000 -0400
@@ -2655,6 +2655,11 @@ vmxnet3_force_close(struct vmxnet3_adapt
 	/* we need to enable NAPI, otherwise dev_close will deadlock */
 	for (i = 0; i < adapter->num_rx_queues; i++)
 		napi_enable(&adapter->rx_queue[i].napi);
+	/*
+	 * Need to clear the quiesce bit to ensure that vmxnet3_close
+	 * can quiesce the device properly
+	 */
+	clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
 	dev_close(adapter->netdev);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/vxlan.c linux-libre-4.1.52-gnu/drivers/net/vxlan.c
--- linux-libre-4.1.51-gnu/drivers/net/vxlan.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/vxlan.c	2018-05-27 22:26:45.000000000 -0400
@@ -1001,7 +1001,7 @@ static bool vxlan_snoop(struct net_devic
 			return false;
 
 		/* Don't migrate static entries, drop packets */
-		if (f->state & NUD_NOARP)
+		if (f->state & (NUD_PERMANENT | NUD_NOARP))
 			return true;
 
 		if (net_ratelimit())
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wan/pc300too.c linux-libre-4.1.52-gnu/drivers/net/wan/pc300too.c
--- linux-libre-4.1.51-gnu/drivers/net/wan/pc300too.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wan/pc300too.c	2018-05-27 22:26:45.000000000 -0400
@@ -347,6 +347,7 @@ static int pc300_pci_init_one(struct pci
 	    card->rambase == NULL) {
 		pr_err("ioremap() failed\n");
 		pc300_pci_remove_one(pdev);
+		return -ENOMEM;
 	}
 
 	/* PLX PCI 9050 workaround for local configuration register read bug */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath10k/debug.c linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath10k/debug.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath10k/debug.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath10k/debug.c	2018-05-27 22:26:45.000000000 -0400
@@ -1853,6 +1853,15 @@ static ssize_t ath10k_write_simulate_rad
 					   size_t count, loff_t *ppos)
 {
 	struct ath10k *ar = file->private_data;
+	struct ath10k_vif *arvif;
+
+	/* Just check for for the first vif alone, as all the vifs will be
+	 * sharing the same channel and if the channel is disabled, all the
+	 * vifs will share the same 'is_started' state.
+	 */
+	arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
+	if (!arvif->is_started)
+		return -EINVAL;
 
 	ieee80211_radar_detected(ar->hw);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath10k/mac.c linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath10k/mac.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath10k/mac.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath10k/mac.c	2018-05-27 22:26:45.000000000 -0400
@@ -4001,9 +4001,8 @@ static void ath10k_sta_rc_update_wk(stru
 				    sta->addr, smps, err);
 	}
 
-	if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
-	    changed & IEEE80211_RC_NSS_CHANGED) {
-		ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
+	if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
+		ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
 			   sta->addr);
 
 		err = ath10k_station_assoc(ar, arvif->vif, sta, true);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath5k/debug.c linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath5k/debug.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath5k/debug.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath5k/debug.c	2018-05-27 22:26:45.000000000 -0400
@@ -939,7 +939,10 @@ static int open_file_eeprom(struct inode
 	}
 
 	for (i = 0; i < eesize; ++i) {
-		AR5K_EEPROM_READ(i, val);
+		if (!ath5k_hw_nvram_read(ah, i, &val)) {
+			ret = -EIO;
+			goto freebuf;
+		}
 		buf[i] = val;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath9k/hw.c linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath9k/hw.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ath/ath9k/hw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ath/ath9k/hw.c	2018-05-27 22:26:45.000000000 -0400
@@ -1593,6 +1593,10 @@ bool ath9k_hw_check_alive(struct ath_hw
 	int count = 50;
 	u32 reg, last_val;
 
+	/* Check if chip failed to wake up */
+	if (REG_READ(ah, AR_CFG) == 0xdeadbeef)
+		return false;
+
 	if (AR_SREV_9300(ah))
 		return !ath9k_hw_detect_mac_hang(ah);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ath/regd.c linux-libre-4.1.52-gnu/drivers/net/wireless/ath/regd.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ath/regd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ath/regd.c	2018-05-27 22:26:45.000000000 -0400
@@ -254,8 +254,12 @@ bool ath_is_49ghz_allowed(u16 regdomain)
 EXPORT_SYMBOL(ath_is_49ghz_allowed);
 
 /* Frequency is one where radar detection is required */
-static bool ath_is_radar_freq(u16 center_freq)
+static bool ath_is_radar_freq(u16 center_freq,
+			      struct ath_regulatory *reg)
+
 {
+	if (reg->country_code == CTRY_INDIA)
+		return (center_freq >= 5500 && center_freq <= 5700);
 	return (center_freq >= 5260 && center_freq <= 5700);
 }
 
@@ -306,7 +310,7 @@ __ath_reg_apply_beaconing_flags(struct w
 				enum nl80211_reg_initiator initiator,
 				struct ieee80211_channel *ch)
 {
-	if (ath_is_radar_freq(ch->center_freq) ||
+	if (ath_is_radar_freq(ch->center_freq, reg) ||
 	    (ch->flags & IEEE80211_CHAN_RADAR))
 		return;
 
@@ -395,8 +399,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip
 	}
 }
 
-/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
-static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
+/* Always apply Radar/DFS rules on freq range 5500 MHz - 5700 MHz */
+static void ath_reg_apply_radar_flags(struct wiphy *wiphy,
+				      struct ath_regulatory *reg)
 {
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_channel *ch;
@@ -409,7 +414,7 @@ static void ath_reg_apply_radar_flags(st
 
 	for (i = 0; i < sband->n_channels; i++) {
 		ch = &sband->channels[i];
-		if (!ath_is_radar_freq(ch->center_freq))
+		if (!ath_is_radar_freq(ch->center_freq, reg))
 			continue;
 		/* We always enable radar detection/DFS on this
 		 * frequency range. Additionally we also apply on
@@ -505,7 +510,7 @@ void ath_reg_notifier_apply(struct wiphy
 	struct ath_common *common = container_of(reg, struct ath_common,
 						 regulatory);
 	/* We always apply this */
-	ath_reg_apply_radar_flags(wiphy);
+	ath_reg_apply_radar_flags(wiphy, reg);
 
 	/*
 	 * This would happen when we have sent a custom regulatory request
@@ -653,7 +658,7 @@ ath_regd_init_wiphy(struct ath_regulator
 	}
 
 	wiphy_apply_custom_regulatory(wiphy, regd);
-	ath_reg_apply_radar_flags(wiphy);
+	ath_reg_apply_radar_flags(wiphy, reg);
 	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ath/wil6210/main.c linux-libre-4.1.52-gnu/drivers/net/wireless/ath/wil6210/main.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ath/wil6210/main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ath/wil6210/main.c	2018-05-27 22:26:45.000000000 -0400
@@ -118,9 +118,15 @@ void wil_memcpy_fromio_32(void *dst, con
 	u32 *d = dst;
 	const volatile u32 __iomem *s = src;
 
-	/* size_t is unsigned, if (count%4 != 0) it will wrap */
-	for (count += 4; count > 4; count -= 4)
+	for (; count >= 4; count -= 4)
 		*d++ = __raw_readl(s++);
+
+	if (unlikely(count)) {
+		/* count can be 1..3 */
+		u32 tmp = __raw_readl(s);
+
+		memcpy(d, &tmp, count);
+	}
 }
 
 void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
@@ -129,8 +135,16 @@ void wil_memcpy_toio_32(volatile void __
 	volatile u32 __iomem *d = dst;
 	const u32 *s = src;
 
-	for (count += 4; count > 4; count -= 4)
+	for (; count >= 4; count -= 4)
 		__raw_writel(*s++, d++);
+
+	if (unlikely(count)) {
+		/* count can be 1..3 */
+		u32 tmp = 0;
+
+		memcpy(&tmp, s, count);
+		__raw_writel(tmp, d);
+	}
 }
 
 static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c linux-libre-4.1.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/brcm80211/brcmfmac/p2p.c	2018-05-27 22:26:45.000000000 -0400
@@ -460,25 +460,23 @@ static int brcmf_p2p_set_firmware(struct
  * @dev_addr: optional device address.
  *
  * P2P needs mac addresses for P2P device and interface. If no device
- * address it specified, these are derived from the primary net device, ie.
- * the permanent ethernet address of the device.
+ * address it specified, these are derived from a random ethernet
+ * address.
  */
 static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
 {
-	struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
-	bool local_admin = false;
+	bool random_addr = false;
 
-	if (!dev_addr || is_zero_ether_addr(dev_addr)) {
-		dev_addr = pri_ifp->mac_addr;
-		local_admin = true;
-	}
+	if (!dev_addr || is_zero_ether_addr(dev_addr))
+		random_addr = true;
 
-	/* Generate the P2P Device Address.  This consists of the device's
-	 * primary MAC address with the locally administered bit set.
+	/* Generate the P2P Device Address obtaining a random ethernet
+	 * address with the locally administered bit set.
 	 */
-	memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
-	if (local_admin)
-		p2p->dev_addr[0] |= 0x02;
+	if (random_addr)
+		eth_random_addr(p2p->dev_addr);
+	else
+		memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
 
 	/* Generate the P2P Interface Address.  If the discovery and connection
 	 * BSSCFGs need to simultaneously co-exist, then this address must be
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/mac80211_hwsim.c linux-libre-4.1.52-gnu/drivers/net/wireless/mac80211_hwsim.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/mac80211_hwsim.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/mac80211_hwsim.c	2018-05-27 22:26:45.000000000 -0400
@@ -699,16 +699,21 @@ static int hwsim_fops_ps_write(void *dat
 	    val != PS_MANUAL_POLL)
 		return -EINVAL;
 
-	old_ps = data->ps;
-	data->ps = val;
-
-	local_bh_disable();
 	if (val == PS_MANUAL_POLL) {
+		if (data->ps != PS_ENABLED)
+			return -EINVAL;
+		local_bh_disable();
 		ieee80211_iterate_active_interfaces_atomic(
 			data->hw, IEEE80211_IFACE_ITER_NORMAL,
 			hwsim_send_ps_poll, data);
-		data->ps_poll_pending = true;
-	} else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
+		local_bh_enable();
+		return 0;
+	}
+	old_ps = data->ps;
+	data->ps = val;
+
+	local_bh_disable();
+	if (old_ps == PS_DISABLED && val != PS_DISABLED) {
 		ieee80211_iterate_active_interfaces_atomic(
 			data->hw, IEEE80211_IFACE_ITER_NORMAL,
 			hwsim_send_nullfunc_ps, data);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ray_cs.c linux-libre-4.1.52-gnu/drivers/net/wireless/ray_cs.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ray_cs.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ray_cs.c	2018-05-27 22:26:45.000000000 -0400
@@ -247,7 +247,10 @@ static const UCHAR b4_default_startup_pa
 	0x04, 0x08,		/* Noise gain, limit offset */
 	0x28, 0x28,		/* det rssi, med busy offsets */
 	7,			/* det sync thresh */
-	0, 2, 2			/* test mode, min, max */
+	0, 2, 2,		/* test mode, min, max */
+	0,			/* rx/tx delay */
+	0, 0, 0, 0, 0, 0,	/* current BSS id */
+	0			/* hop set */
 };
 
 /*===========================================================================*/
@@ -598,7 +601,7 @@ static void init_startup_params(ray_dev_
 	 *    a_beacon_period = hops    a_beacon_period = KuS
 	 *//* 64ms = 010000 */
 	if (local->fw_ver == 0x55) {
-		memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms,
+		memcpy(&local->sparm.b4, b4_default_startup_parms,
 		       sizeof(struct b4_startup_params));
 		/* Translate sane kus input values to old build 4/5 format */
 		/* i = hop time in uS truncated to 3 bytes */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/rndis_wlan.c linux-libre-4.1.52-gnu/drivers/net/wireless/rndis_wlan.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/rndis_wlan.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/rndis_wlan.c	2018-05-27 22:26:45.000000000 -0400
@@ -3425,6 +3425,10 @@ static int rndis_wlan_bind(struct usbnet
 
 	/* because rndis_command() sleeps we need to use workqueue */
 	priv->workqueue = create_singlethread_workqueue("rndis_wlan");
+	if (!priv->workqueue) {
+		wiphy_free(wiphy);
+		return -ENOMEM;
+	}
 	INIT_WORK(&priv->work, rndis_wlan_worker);
 	INIT_DELAYED_WORK(&priv->dev_poller_work, rndis_device_poller);
 	INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/rtl818x/rtl8187/dev.c linux-libre-4.1.52-gnu/drivers/net/wireless/rtl818x/rtl8187/dev.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/rtl818x/rtl8187/dev.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/rtl818x/rtl8187/dev.c	2018-05-27 22:26:45.000000000 -0400
@@ -1454,6 +1454,7 @@ static int rtl8187_probe(struct usb_inte
 		goto err_free_dev;
 	}
 	mutex_init(&priv->io_mutex);
+	mutex_init(&priv->conf_mutex);
 
 	SET_IEEE80211_DEV(dev, &intf->dev);
 	usb_set_intfdata(intf, dev);
@@ -1627,7 +1628,6 @@ static int rtl8187_probe(struct usb_inte
 		printk(KERN_ERR "rtl8187: Cannot register device\n");
 		goto err_free_dmabuf;
 	}
-	mutex_init(&priv->conf_mutex);
 	skb_queue_head_init(&priv->b_tx_status.queue);
 
 	wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/pci.c linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/pci.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/pci.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/pci.c	2018-05-27 22:26:45.000000000 -0400
@@ -1576,7 +1576,14 @@ int rtl_pci_reset_trx_ring(struct ieee80
 				dev_kfree_skb_irq(skb);
 				ring->idx = (ring->idx + 1) % ring->entries;
 			}
+
+			if (rtlpriv->use_new_trx_flow) {
+				rtlpci->tx_ring[i].cur_tx_rp = 0;
+				rtlpci->tx_ring[i].cur_tx_wp = 0;
+			}
+
 			ring->idx = 0;
+			ring->entries = rtlpci->txringcount[i];
 		}
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c	2018-05-27 22:26:45.000000000 -0400
@@ -664,7 +664,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct i
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct sk_buff *skb = NULL;
-
+	bool rtstatus;
 	u32 totalpacketlen;
 	u8 u1rsvdpageloc[5] = { 0 };
 	bool b_dlok = false;
@@ -727,7 +727,9 @@ void rtl92ee_set_fw_rsvdpagepkt(struct i
 	memcpy((u8 *)skb_put(skb, totalpacketlen),
 	       &reserved_page_packet, totalpacketlen);
 
-	b_dlok = true;
+	rtstatus = rtl_cmd_send_packet(hw, skb);
+	if (rtstatus)
+		b_dlok = true;
 
 	if (b_dlok) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c	2018-05-27 22:26:45.000000000 -0400
@@ -2490,9 +2490,9 @@ void rtl8821ae_dm_txpower_tracking_callb
 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
 			rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p];
 
-			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-				 "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
-				 rtldm->thermalvalue, thermal_value);
+		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+			 "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
+			 rtldm->thermalvalue, thermal_value);
 		/*Record last Power Tracking Thermal Value*/
 		rtldm->thermalvalue = thermal_value;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c	2018-05-27 22:26:45.000000000 -0400
@@ -1377,6 +1377,7 @@ static void _rtl8821ae_get_wakeup_reason
 
 	ppsc->wakeup_reason = 0;
 
+	do_gettimeofday(&ts);
 	rtlhal->last_suspend_sec = ts.tv_sec;
 
 	switch (fw_reason) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/wireless/ti/wl1251/main.c linux-libre-4.1.52-gnu/drivers/net/wireless/ti/wl1251/main.c
--- linux-libre-4.1.51-gnu/drivers/net/wireless/ti/wl1251/main.c	2018-03-28 09:56:57.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/wireless/ti/wl1251/main.c	2018-05-29 04:43:53.000000000 -0400
@@ -1201,8 +1201,7 @@ static void wl1251_op_bss_info_changed(s
 		WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
 
 		enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc;
-		wl1251_acx_arp_ip_filter(wl, enable, addr);
-
+		ret = wl1251_acx_arp_ip_filter(wl, enable, addr);
 		if (ret < 0)
 			goto out_sleep;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/net/xen-netfront.c linux-libre-4.1.52-gnu/drivers/net/xen-netfront.c
--- linux-libre-4.1.51-gnu/drivers/net/xen-netfront.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/net/xen-netfront.c	2018-05-27 22:26:45.000000000 -0400
@@ -1986,7 +1986,10 @@ static void netback_changed(struct xenbu
 	case XenbusStateInitialised:
 	case XenbusStateReconfiguring:
 	case XenbusStateReconfigured:
+		break;
+
 	case XenbusStateUnknown:
+		wake_up_all(&module_unload_q);
 		break;
 
 	case XenbusStateInitWait:
@@ -2117,7 +2120,9 @@ static int xennet_remove(struct xenbus_d
 		xenbus_switch_state(dev, XenbusStateClosing);
 		wait_event(module_unload_q,
 			   xenbus_read_driver_state(dev->otherend) ==
-			   XenbusStateClosing);
+			   XenbusStateClosing ||
+			   xenbus_read_driver_state(dev->otherend) ==
+			   XenbusStateUnknown);
 
 		xenbus_switch_state(dev, XenbusStateClosed);
 		wait_event(module_unload_q,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/of/device.c linux-libre-4.1.52-gnu/drivers/of/device.c
--- linux-libre-4.1.51-gnu/drivers/of/device.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/of/device.c	2018-05-27 22:26:45.000000000 -0400
@@ -210,7 +210,7 @@ ssize_t of_device_get_modalias(struct de
 			str[i] = '_';
 	}
 
-	return tsize;
+	return repend;
 }
 EXPORT_SYMBOL_GPL(of_device_get_modalias);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/parport/parport_pc.c linux-libre-4.1.52-gnu/drivers/parport/parport_pc.c
--- linux-libre-4.1.51-gnu/drivers/parport/parport_pc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/parport/parport_pc.c	2018-05-27 22:26:45.000000000 -0400
@@ -2646,6 +2646,7 @@ enum parport_pc_pci_cards {
 	netmos_9901,
 	netmos_9865,
 	quatech_sppxp100,
+	wch_ch382l,
 };
 
 
@@ -2708,6 +2709,7 @@ static struct parport_pc_pci {
 	/* netmos_9901 */               { 1, { { 0, -1 }, } },
 	/* netmos_9865 */               { 1, { { 0, -1 }, } },
 	/* quatech_sppxp100 */		{ 1, { { 0, 1 }, } },
+	/* wch_ch382l */		{ 1, { { 2, -1 }, } },
 };
 
 static const struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2797,6 +2799,8 @@ static const struct pci_device_id parpor
 	/* Quatech SPPXP-100 Parallel port PCI ExpressCard */
 	{ PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },
+	/* WCH CH382L PCI-E single parallel port card */
+	{ 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l },
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pci/hotplug/acpiphp_glue.c linux-libre-4.1.52-gnu/drivers/pci/hotplug/acpiphp_glue.c
--- linux-libre-4.1.51-gnu/drivers/pci/hotplug/acpiphp_glue.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pci/hotplug/acpiphp_glue.c	2018-05-27 22:26:45.000000000 -0400
@@ -587,6 +587,7 @@ static unsigned int get_slot_status(stru
 {
 	unsigned long long sta = 0;
 	struct acpiphp_func *func;
+	u32 dvid;
 
 	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_STA) {
@@ -597,19 +598,27 @@ static unsigned int get_slot_status(stru
 			if (ACPI_SUCCESS(status) && sta)
 				break;
 		} else {
-			u32 dvid;
-
-			pci_bus_read_config_dword(slot->bus,
-						  PCI_DEVFN(slot->device,
-							    func->function),
-						  PCI_VENDOR_ID, &dvid);
-			if (dvid != 0xffffffff) {
+			if (pci_bus_read_dev_vendor_id(slot->bus,
+					PCI_DEVFN(slot->device, func->function),
+					&dvid, 0)) {
 				sta = ACPI_STA_ALL;
 				break;
 			}
 		}
 	}
 
+	if (!sta) {
+		/*
+		 * Check for the slot itself since it may be that the
+		 * ACPI slot is a device below PCIe upstream port so in
+		 * that case it may not even be reachable yet.
+		 */
+		if (pci_bus_read_dev_vendor_id(slot->bus,
+				PCI_DEVFN(slot->device, 0), &dvid, 0)) {
+			sta = ACPI_STA_ALL;
+		}
+	}
+
 	return (unsigned int)sta;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pci/pci-driver.c linux-libre-4.1.52-gnu/drivers/pci/pci-driver.c
--- linux-libre-4.1.51-gnu/drivers/pci/pci-driver.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pci/pci-driver.c	2018-05-27 22:26:45.000000000 -0400
@@ -450,8 +450,6 @@ static void pci_device_shutdown(struct d
 
 	if (drv && drv->shutdown)
 		drv->shutdown(pci_dev);
-	pci_msi_shutdown(pci_dev);
-	pci_msix_shutdown(pci_dev);
 
 #ifdef CONFIG_KEXEC
 	/*
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pci/probe.c linux-libre-4.1.52-gnu/drivers/pci/probe.c
--- linux-libre-4.1.51-gnu/drivers/pci/probe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pci/probe.c	2018-05-27 22:26:45.000000000 -0400
@@ -227,7 +227,7 @@ int __pci_read_base(struct pci_dev *dev,
 			res->flags |= IORESOURCE_ROM_ENABLE;
 		l64 = l & PCI_ROM_ADDRESS_MASK;
 		sz64 = sz & PCI_ROM_ADDRESS_MASK;
-		mask64 = (u32)PCI_ROM_ADDRESS_MASK;
+		mask64 = PCI_ROM_ADDRESS_MASK;
 	}
 
 	if (res->flags & IORESOURCE_MEM_64) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pci/quirks.c linux-libre-4.1.52-gnu/drivers/pci/quirks.c
--- linux-libre-4.1.51-gnu/drivers/pci/quirks.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pci/quirks.c	2018-05-27 22:26:45.000000000 -0400
@@ -3645,6 +3645,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_M
 			 quirk_dma_func1_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642,
 			 quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645,
+			 quirk_dma_func1_alias);
 /* https://bugs.gentoo.org/show_bug.cgi?id=497630 */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
 			 PCI_DEVICE_ID_JMICRON_JMB388_ESD,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pci/setup-res.c linux-libre-4.1.52-gnu/drivers/pci/setup-res.c
--- linux-libre-4.1.51-gnu/drivers/pci/setup-res.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pci/setup-res.c	2018-05-27 22:26:45.000000000 -0400
@@ -59,7 +59,7 @@ static void pci_std_update_resource(stru
 		mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
 		new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
 	} else if (resno == PCI_ROM_RESOURCE) {
-		mask = (u32)PCI_ROM_ADDRESS_MASK;
+		mask = PCI_ROM_ADDRESS_MASK;
 	} else {
 		mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
 		new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pinctrl/core.c linux-libre-4.1.52-gnu/drivers/pinctrl/core.c
--- linux-libre-4.1.51-gnu/drivers/pinctrl/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pinctrl/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -977,19 +977,16 @@ struct pinctrl_state *pinctrl_lookup_sta
 EXPORT_SYMBOL_GPL(pinctrl_lookup_state);
 
 /**
- * pinctrl_select_state() - select/activate/program a pinctrl state to HW
+ * pinctrl_commit_state() - select/activate/program a pinctrl state to HW
  * @p: the pinctrl handle for the device that requests configuration
  * @state: the state handle to select/activate/program
  */
-int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
+static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
 {
 	struct pinctrl_setting *setting, *setting2;
 	struct pinctrl_state *old_state = p->state;
 	int ret;
 
-	if (p->state == state)
-		return 0;
-
 	if (p->state) {
 		/*
 		 * For each pinmux setting in the old state, forget SW's record
@@ -1053,6 +1050,19 @@ unapply_new_state:
 
 	return ret;
 }
+
+/**
+ * pinctrl_select_state() - select/activate/program a pinctrl state to HW
+ * @p: the pinctrl handle for the device that requests configuration
+ * @state: the state handle to select/activate/program
+ */
+int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
+{
+	if (p->state == state)
+		return 0;
+
+	return pinctrl_commit_state(p, state);
+}
 EXPORT_SYMBOL_GPL(pinctrl_select_state);
 
 static void devm_pinctrl_release(struct device *dev, void *res)
@@ -1221,7 +1231,7 @@ void pinctrl_unregister_map(struct pinct
 int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
 {
 	if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
-		return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
+		return pinctrl_commit_state(pctldev->p, pctldev->hog_sleep);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
@@ -1233,7 +1243,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
 int pinctrl_force_default(struct pinctrl_dev *pctldev)
 {
 	if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
-		return pinctrl_select_state(pctldev->p, pctldev->hog_default);
+		return pinctrl_commit_state(pctldev->p, pctldev->hog_default);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pinctrl_force_default);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/platform/x86/asus-nb-wmi.c linux-libre-4.1.52-gnu/drivers/platform/x86/asus-nb-wmi.c
--- linux-libre-4.1.51-gnu/drivers/platform/x86/asus-nb-wmi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/platform/x86/asus-nb-wmi.c	2018-05-27 22:26:45.000000000 -0400
@@ -101,6 +101,15 @@ static const struct dmi_system_id asus_q
 	},
 	{
 		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X302UA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"),
+		},
+		.driver_data = &quirk_asus_wapf4,
+	},
+	{
+		.callback = dmi_matched,
 		.ident = "ASUSTeK COMPUTER INC. X401U",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/power/pda_power.c linux-libre-4.1.52-gnu/drivers/power/pda_power.c
--- linux-libre-4.1.51-gnu/drivers/power/pda_power.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/power/pda_power.c	2018-05-27 22:26:45.000000000 -0400
@@ -30,9 +30,9 @@ static inline unsigned int get_irq_flags
 static struct device *dev;
 static struct pda_power_pdata *pdata;
 static struct resource *ac_irq, *usb_irq;
-static struct timer_list charger_timer;
-static struct timer_list supply_timer;
-static struct timer_list polling_timer;
+static struct delayed_work charger_work;
+static struct delayed_work polling_work;
+static struct delayed_work supply_work;
 static int polling;
 static struct power_supply *pda_psy_ac, *pda_psy_usb;
 
@@ -140,7 +140,7 @@ static void update_charger(void)
 	}
 }
 
-static void supply_timer_func(unsigned long unused)
+static void supply_work_func(struct work_struct *work)
 {
 	if (ac_status == PDA_PSY_TO_CHANGE) {
 		ac_status = new_ac_status;
@@ -161,11 +161,12 @@ static void psy_changed(void)
 	 * Okay, charger set. Now wait a bit before notifying supplicants,
 	 * charge power should stabilize.
 	 */
-	mod_timer(&supply_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_charger));
+	cancel_delayed_work(&supply_work);
+	schedule_delayed_work(&supply_work,
+			      msecs_to_jiffies(pdata->wait_for_charger));
 }
 
-static void charger_timer_func(unsigned long unused)
+static void charger_work_func(struct work_struct *work)
 {
 	update_status();
 	psy_changed();
@@ -184,13 +185,14 @@ static irqreturn_t power_changed_isr(int
 	 * Wait a bit before reading ac/usb line status and setting charger,
 	 * because ac/usb status readings may lag from irq.
 	 */
-	mod_timer(&charger_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_status));
+	cancel_delayed_work(&charger_work);
+	schedule_delayed_work(&charger_work,
+			      msecs_to_jiffies(pdata->wait_for_status));
 
 	return IRQ_HANDLED;
 }
 
-static void polling_timer_func(unsigned long unused)
+static void polling_work_func(struct work_struct *work)
 {
 	int changed = 0;
 
@@ -211,8 +213,9 @@ static void polling_timer_func(unsigned
 	if (changed)
 		psy_changed();
 
-	mod_timer(&polling_timer,
-		  jiffies + msecs_to_jiffies(pdata->polling_interval));
+	cancel_delayed_work(&polling_work);
+	schedule_delayed_work(&polling_work,
+			      msecs_to_jiffies(pdata->polling_interval));
 }
 
 #if IS_ENABLED(CONFIG_USB_PHY)
@@ -250,8 +253,9 @@ static int otg_handle_notification(struc
 	 * Wait a bit before reading ac/usb line status and setting charger,
 	 * because ac/usb status readings may lag from irq.
 	 */
-	mod_timer(&charger_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_status));
+	cancel_delayed_work(&charger_work);
+	schedule_delayed_work(&charger_work,
+			      msecs_to_jiffies(pdata->wait_for_status));
 
 	return NOTIFY_OK;
 }
@@ -300,8 +304,8 @@ static int pda_power_probe(struct platfo
 	if (!pdata->ac_max_uA)
 		pdata->ac_max_uA = 500000;
 
-	setup_timer(&charger_timer, charger_timer_func, 0);
-	setup_timer(&supply_timer, supply_timer_func, 0);
+	INIT_DELAYED_WORK(&charger_work, charger_work_func);
+	INIT_DELAYED_WORK(&supply_work, supply_work_func);
 
 	ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
 	usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
@@ -385,9 +389,10 @@ static int pda_power_probe(struct platfo
 
 	if (polling) {
 		dev_dbg(dev, "will poll for status\n");
-		setup_timer(&polling_timer, polling_timer_func, 0);
-		mod_timer(&polling_timer,
-			  jiffies + msecs_to_jiffies(pdata->polling_interval));
+		INIT_DELAYED_WORK(&polling_work, polling_work_func);
+		cancel_delayed_work(&polling_work);
+		schedule_delayed_work(&polling_work,
+				      msecs_to_jiffies(pdata->polling_interval));
 	}
 
 	if (ac_irq || usb_irq)
@@ -433,9 +438,9 @@ static int pda_power_remove(struct platf
 		free_irq(ac_irq->start, pda_psy_ac);
 
 	if (polling)
-		del_timer_sync(&polling_timer);
-	del_timer_sync(&charger_timer);
-	del_timer_sync(&supply_timer);
+		cancel_delayed_work_sync(&polling_work);
+	cancel_delayed_work_sync(&charger_work);
+	cancel_delayed_work_sync(&supply_work);
 
 	if (pdata->is_usb_online)
 		power_supply_unregister(pda_psy_usb);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/powercap/powercap_sys.c linux-libre-4.1.52-gnu/drivers/powercap/powercap_sys.c
--- linux-libre-4.1.51-gnu/drivers/powercap/powercap_sys.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/powercap/powercap_sys.c	2018-05-27 22:26:45.000000000 -0400
@@ -538,6 +538,7 @@ struct powercap_zone *powercap_register_
 
 	power_zone->id = result;
 	idr_init(&power_zone->idr);
+	result = -ENOMEM;
 	power_zone->name = kstrdup(name, GFP_KERNEL);
 	if (!power_zone->name)
 		goto err_name_alloc;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/pwm/pwm-tegra.c linux-libre-4.1.52-gnu/drivers/pwm/pwm-tegra.c
--- linux-libre-4.1.51-gnu/drivers/pwm/pwm-tegra.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/pwm/pwm-tegra.c	2018-05-27 22:26:45.000000000 -0400
@@ -69,6 +69,7 @@ static int tegra_pwm_config(struct pwm_c
 	struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
 	unsigned long long c;
 	unsigned long rate, hz;
+	unsigned long long ns100 = NSEC_PER_SEC;
 	u32 val = 0;
 	int err;
 
@@ -87,9 +88,11 @@ static int tegra_pwm_config(struct pwm_c
 	 * cycles at the PWM clock rate will take period_ns nanoseconds.
 	 */
 	rate = clk_get_rate(pc->clk) >> PWM_DUTY_WIDTH;
-	hz = NSEC_PER_SEC / period_ns;
 
-	rate = (rate + (hz / 2)) / hz;
+	/* Consider precision in PWM_SCALE_WIDTH rate calculation */
+	ns100 *= 100;
+	hz = DIV_ROUND_CLOSEST_ULL(ns100, period_ns);
+	rate = DIV_ROUND_CLOSEST(rate * 100, hz);
 
 	/*
 	 * Since the actual PWM divider is the register's frequency divider
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/rtc/interface.c linux-libre-4.1.52-gnu/drivers/rtc/interface.c
--- linux-libre-4.1.51-gnu/drivers/rtc/interface.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/rtc/interface.c	2018-05-27 22:26:45.000000000 -0400
@@ -262,6 +262,13 @@ int __rtc_read_alarm(struct rtc_device *
 			missing = year;
 	}
 
+	/* Can't proceed if alarm is still invalid after replacing
+	 * missing fields.
+	 */
+	err = rtc_valid_tm(&alarm->time);
+	if (err)
+		goto done;
+
 	/* with luck, no rollover is needed */
 	t_now = rtc_tm_to_time64(&now);
 	t_alm = rtc_tm_to_time64(&alarm->time);
@@ -313,9 +320,9 @@ int __rtc_read_alarm(struct rtc_device *
 		dev_warn(&rtc->dev, "alarm rollover not handled\n");
 	}
 
-done:
 	err = rtc_valid_tm(&alarm->time);
 
+done:
 	if (err) {
 		dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
 			alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/rtc/rtc-ds1374.c linux-libre-4.1.52-gnu/drivers/rtc/rtc-ds1374.c
--- linux-libre-4.1.51-gnu/drivers/rtc/rtc-ds1374.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/rtc/rtc-ds1374.c	2018-05-27 22:26:45.000000000 -0400
@@ -527,6 +527,10 @@ static long ds1374_wdt_ioctl(struct file
 		if (get_user(new_margin, (int __user *)arg))
 			return -EFAULT;
 
+		/* the hardware's tick rate is 4096 Hz, so
+		 * the counter value needs to be scaled accordingly
+		 */
+		new_margin <<= 12;
 		if (new_margin < 1 || new_margin > 16777216)
 			return -EINVAL;
 
@@ -535,7 +539,8 @@ static long ds1374_wdt_ioctl(struct file
 		ds1374_wdt_ping();
 		/* fallthrough */
 	case WDIOC_GETTIMEOUT:
-		return put_user(wdt_margin, (int __user *)arg);
+		/* when returning ... inverse is true */
+		return put_user((wdt_margin >> 12), (int __user *)arg);
 	case WDIOC_SETOPTIONS:
 		if (copy_from_user(&options, (int __user *)arg, sizeof(int)))
 			return -EFAULT;
@@ -543,14 +548,15 @@ static long ds1374_wdt_ioctl(struct file
 		if (options & WDIOS_DISABLECARD) {
 			pr_info("disable watchdog\n");
 			ds1374_wdt_disable();
+			return 0;
 		}
 
 		if (options & WDIOS_ENABLECARD) {
 			pr_info("enable watchdog\n");
 			ds1374_wdt_settimeout(wdt_margin);
 			ds1374_wdt_ping();
+			return 0;
 		}
-
 		return -EINVAL;
 	}
 	return -ENOTTY;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/rtc/rtc-opal.c linux-libre-4.1.52-gnu/drivers/rtc/rtc-opal.c
--- linux-libre-4.1.51-gnu/drivers/rtc/rtc-opal.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/rtc/rtc-opal.c	2018-05-27 22:26:45.000000000 -0400
@@ -150,6 +150,16 @@ static int opal_get_tpo_time(struct devi
 
 	y_m_d = be32_to_cpu(__y_m_d);
 	h_m_s_ms = ((u64)be32_to_cpu(__h_m) << 32);
+
+	/* check if no alarm is set */
+	if (y_m_d == 0 && h_m_s_ms == 0) {
+		pr_debug("No alarm is set\n");
+		rc = -ENOENT;
+		goto exit;
+	} else {
+		pr_debug("Alarm set to %x %llx\n", y_m_d, h_m_s_ms);
+	}
+
 	opal_to_tm(y_m_d, h_m_s_ms, &alarm->time);
 
 exit:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/s390/cio/chsc.c linux-libre-4.1.52-gnu/drivers/s390/cio/chsc.c
--- linux-libre-4.1.51-gnu/drivers/s390/cio/chsc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/s390/cio/chsc.c	2018-05-27 22:26:45.000000000 -0400
@@ -362,6 +362,7 @@ static void chsc_process_sei_link_incide
 
 static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
 {
+	struct channel_path *chp;
 	struct chp_link link;
 	struct chp_id chpid;
 	int status;
@@ -374,10 +375,17 @@ static void chsc_process_sei_res_acc(str
 	chpid.id = sei_area->rsid;
 	/* allocate a new channel path structure, if needed */
 	status = chp_get_status(chpid);
-	if (status < 0)
-		chp_new(chpid);
-	else if (!status)
+	if (!status)
 		return;
+
+	if (status < 0) {
+		chp_new(chpid);
+	} else {
+		chp = chpid_to_chp(chpid);
+		mutex_lock(&chp->lock);
+		chp_update_desc(chp);
+		mutex_unlock(&chp->lock);
+	}
 	memset(&link, 0, sizeof(struct chp_link));
 	link.chpid = chpid;
 	if ((sei_area->vf & 0xc0) != 0) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/s390/cio/qdio_main.c linux-libre-4.1.52-gnu/drivers/s390/cio/qdio_main.c
--- linux-libre-4.1.51-gnu/drivers/s390/cio/qdio_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/s390/cio/qdio_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -126,7 +126,7 @@ static inline int qdio_check_ccq(struct
 static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
 			int start, int count, int auto_ack)
 {
-	int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
+	int rc, tmp_count = count, tmp_start = start, nr = q->nr;
 	unsigned int ccq = 0;
 
 	qperf_inc(q, eqbs);
@@ -149,14 +149,7 @@ again:
 		qperf_inc(q, eqbs_partial);
 		DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
 			tmp_count);
-		/*
-		 * Retry once, if that fails bail out and process the
-		 * extracted buffers before trying again.
-		 */
-		if (!retried++)
-			goto again;
-		else
-			return count - tmp_count;
+		return count - tmp_count;
 	}
 
 	DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
@@ -212,7 +205,10 @@ again:
 	return 0;
 }
 
-/* returns number of examined buffers and their common state in *state */
+/*
+ * Returns number of examined buffers and their common state in *state.
+ * Requested number of buffers-to-examine must be > 0.
+ */
 static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
 				 unsigned char *state, unsigned int count,
 				 int auto_ack, int merge_pending)
@@ -223,17 +219,23 @@ static inline int get_buf_states(struct
 	if (is_qebsm(q))
 		return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
 
-	for (i = 0; i < count; i++) {
-		if (!__state) {
-			__state = q->slsb.val[bufnr];
-			if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
-				__state = SLSB_P_OUTPUT_EMPTY;
-		} else if (merge_pending) {
-			if ((q->slsb.val[bufnr] & __state) != __state)
-				break;
-		} else if (q->slsb.val[bufnr] != __state)
-			break;
+	/* get initial state: */
+	__state = q->slsb.val[bufnr];
+	if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
+		__state = SLSB_P_OUTPUT_EMPTY;
+
+	for (i = 1; i < count; i++) {
 		bufnr = next_buf(bufnr);
+
+		/* merge PENDING into EMPTY: */
+		if (merge_pending &&
+		    q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING &&
+		    __state == SLSB_P_OUTPUT_EMPTY)
+			continue;
+
+		/* stop if next state differs from initial state: */
+		if (q->slsb.val[bufnr] != __state)
+			break;
 	}
 	*state = __state;
 	return i;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/s390/net/qeth_core_main.c linux-libre-4.1.52-gnu/drivers/s390/net/qeth_core_main.c
--- linux-libre-4.1.51-gnu/drivers/s390/net/qeth_core_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/s390/net/qeth_core_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -517,8 +517,7 @@ static inline int qeth_is_cq(struct qeth
 	    queue == card->qdio.no_in_queues - 1;
 }
 
-
-static int qeth_issue_next_read(struct qeth_card *card)
+static int __qeth_issue_next_read(struct qeth_card *card)
 {
 	int rc;
 	struct qeth_cmd_buffer *iob;
@@ -549,6 +548,17 @@ static int qeth_issue_next_read(struct q
 	return rc;
 }
 
+static int qeth_issue_next_read(struct qeth_card *card)
+{
+	int ret;
+
+	spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card)));
+	ret = __qeth_issue_next_read(card);
+	spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card)));
+
+	return ret;
+}
+
 static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
 {
 	struct qeth_reply *reply;
@@ -951,7 +961,7 @@ void qeth_clear_thread_running_bit(struc
 	spin_lock_irqsave(&card->thread_mask_lock, flags);
 	card->thread_running_mask &= ~thread;
 	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
-	wake_up(&card->wait_q);
+	wake_up_all(&card->wait_q);
 }
 EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
 
@@ -1155,6 +1165,7 @@ static void qeth_irq(struct ccw_device *
 		}
 		rc = qeth_get_problem(cdev, irb);
 		if (rc) {
+			card->read_or_write_problem = 1;
 			qeth_clear_ipacmd_list(card);
 			qeth_schedule_recovery(card);
 			goto out;
@@ -1173,7 +1184,7 @@ static void qeth_irq(struct ccw_device *
 		return;
 	if (channel == &card->read &&
 	    channel->state == CH_STATE_UP)
-		qeth_issue_next_read(card);
+		__qeth_issue_next_read(card);
 
 	iob = channel->iob;
 	index = channel->buf_no;
@@ -5017,8 +5028,6 @@ static void qeth_core_free_card(struct q
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 	qeth_clean_channel(&card->read);
 	qeth_clean_channel(&card->write);
-	if (card->dev)
-		free_netdev(card->dev);
 	kfree(card->ip_tbd_list);
 	qeth_free_qdio_buffers(card);
 	unregister_service_level(&card->qeth_service_level);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/s390/net/qeth_l2_main.c linux-libre-4.1.52-gnu/drivers/s390/net/qeth_l2_main.c
--- linux-libre-4.1.51-gnu/drivers/s390/net/qeth_l2_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/s390/net/qeth_l2_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -913,8 +913,8 @@ static void qeth_l2_remove_device(struct
 		qeth_l2_set_offline(cgdev);
 
 	if (card->dev) {
-		netif_napi_del(&card->napi);
 		unregister_netdev(card->dev);
+		free_netdev(card->dev);
 		card->dev = NULL;
 	}
 	return;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/s390/net/qeth_l3_main.c linux-libre-4.1.52-gnu/drivers/s390/net/qeth_l3_main.c
--- linux-libre-4.1.51-gnu/drivers/s390/net/qeth_l3_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/s390/net/qeth_l3_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -3358,8 +3358,8 @@ static void qeth_l3_remove_device(struct
 		qeth_l3_set_offline(cgdev);
 
 	if (card->dev) {
-		netif_napi_del(&card->napi);
 		unregister_netdev(card->dev);
+		free_netdev(card->dev);
 		card->dev = NULL;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/bnx2fc/bnx2fc_fcoe.c linux-libre-4.1.52-gnu/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
--- linux-libre-4.1.51-gnu/drivers/scsi/bnx2fc/bnx2fc_fcoe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/bnx2fc/bnx2fc_fcoe.c	2018-05-27 22:26:45.000000000 -0400
@@ -641,15 +641,17 @@ static struct fc_host_statistics *bnx2fc
 	if (!fw_stats)
 		return NULL;
 
+	mutex_lock(&hba->hba_stats_mutex);
+
 	bnx2fc_stats = fc_get_host_stats(shost);
 
 	init_completion(&hba->stat_req_done);
 	if (bnx2fc_send_stat_req(hba))
-		return bnx2fc_stats;
+		goto unlock_stats_mutex;
 	rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ));
 	if (!rc) {
 		BNX2FC_HBA_DBG(lport, "FW stat req timed out\n");
-		return bnx2fc_stats;
+		goto unlock_stats_mutex;
 	}
 	BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt);
 	bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt;
@@ -671,6 +673,9 @@ static struct fc_host_statistics *bnx2fc
 
 	memcpy(&hba->prev_stats, hba->stats_buffer,
 	       sizeof(struct fcoe_statistics_params));
+
+unlock_stats_mutex:
+	mutex_unlock(&hba->hba_stats_mutex);
 	return bnx2fc_stats;
 }
 
@@ -1303,6 +1308,7 @@ static struct bnx2fc_hba *bnx2fc_hba_cre
 	}
 	spin_lock_init(&hba->hba_lock);
 	mutex_init(&hba->hba_mutex);
+	mutex_init(&hba->hba_stats_mutex);
 
 	hba->cnic = cnic;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/bnx2fc/bnx2fc.h linux-libre-4.1.52-gnu/drivers/scsi/bnx2fc/bnx2fc.h
--- linux-libre-4.1.51-gnu/drivers/scsi/bnx2fc/bnx2fc.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/bnx2fc/bnx2fc.h	2018-05-27 22:26:45.000000000 -0400
@@ -191,6 +191,7 @@ struct bnx2fc_hba {
 	struct bnx2fc_cmd_mgr *cmd_mgr;
 	spinlock_t hba_lock;
 	struct mutex hba_mutex;
+	struct mutex hba_stats_mutex;
 	unsigned long adapter_state;
 		#define ADAPTER_STATE_UP		0
 		#define ADAPTER_STATE_GOING_DOWN	1
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/csiostor/csio_hw.c linux-libre-4.1.52-gnu/drivers/scsi/csiostor/csio_hw.c
--- linux-libre-4.1.51-gnu/drivers/scsi/csiostor/csio_hw.c	2018-03-28 09:59:12.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/csiostor/csio_hw.c	2018-05-29 04:46:08.000000000 -0400
@@ -1769,7 +1769,6 @@ csio_hw_use_fwconfig(struct csio_hw *hw,
 		goto bye;
 	}
 
-	mempool_free(mbp, hw->mb_mempool);
 	if (finicsum != cfcsum) {
 		csio_warn(hw,
 		      "Config File checksum mismatch: csum=%#x, computed=%#x\n",
@@ -1780,6 +1779,10 @@ csio_hw_use_fwconfig(struct csio_hw *hw,
 	rv = csio_hw_validate_caps(hw, mbp);
 	if (rv != 0)
 		goto bye;
+
+	mempool_free(mbp, hw->mb_mempool);
+	mbp = NULL;
+
 	/*
 	 * Note that we're operating with parameters
 	 * not supplied by the driver, rather than from hard-wired
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/ipr.c linux-libre-4.1.52-gnu/drivers/scsi/ipr.c
--- linux-libre-4.1.51-gnu/drivers/scsi/ipr.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/ipr.c	2018-05-27 22:26:45.000000000 -0400
@@ -835,8 +835,10 @@ static void ipr_sata_eh_done(struct ipr_
 
 	qc->err_mask |= AC_ERR_OTHER;
 	sata_port->ioasa.status |= ATA_BUSY;
-	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 	ata_qc_complete(qc);
+	if (ipr_cmd->eh_comp)
+		complete(ipr_cmd->eh_comp);
+	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 }
 
 /**
@@ -5859,8 +5861,10 @@ static void ipr_erp_done(struct ipr_cmnd
 		res->in_erp = 0;
 	}
 	scsi_dma_unmap(ipr_cmd->scsi_cmd);
-	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 	scsi_cmd->scsi_done(scsi_cmd);
+	if (ipr_cmd->eh_comp)
+		complete(ipr_cmd->eh_comp);
+	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 }
 
 /**
@@ -6250,8 +6254,10 @@ static void ipr_erp_start(struct ipr_ioa
 	}
 
 	scsi_dma_unmap(ipr_cmd->scsi_cmd);
-	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 	scsi_cmd->scsi_done(scsi_cmd);
+	if (ipr_cmd->eh_comp)
+		complete(ipr_cmd->eh_comp);
+	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 }
 
 /**
@@ -6277,8 +6283,10 @@ static void ipr_scsi_done(struct ipr_cmn
 		scsi_dma_unmap(scsi_cmd);
 
 		spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags);
-		list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 		scsi_cmd->scsi_done(scsi_cmd);
+		if (ipr_cmd->eh_comp)
+			complete(ipr_cmd->eh_comp);
+		list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 		spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags);
 	} else {
 		spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/libiscsi.c linux-libre-4.1.52-gnu/drivers/scsi/libiscsi.c
--- linux-libre-4.1.51-gnu/drivers/scsi/libiscsi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/libiscsi.c	2018-05-27 22:26:45.000000000 -0400
@@ -1695,6 +1695,15 @@ int iscsi_queuecommand(struct Scsi_Host
 		 */
 		switch (session->state) {
 		case ISCSI_STATE_FAILED:
+			/*
+			 * cmds should fail during shutdown, if the session
+			 * state is bad, allowing completion to happen
+			 */
+			if (unlikely(system_state != SYSTEM_RUNNING)) {
+				reason = FAILURE_SESSION_FAILED;
+				sc->result = DID_NO_CONNECT << 16;
+				break;
+			}
 		case ISCSI_STATE_IN_RECOVERY:
 			reason = FAILURE_SESSION_IN_RECOVERY;
 			sc->result = DID_IMM_RETRY << 16;
@@ -1980,6 +1989,19 @@ static enum blk_eh_timer_return iscsi_eh
 
 	if (session->state != ISCSI_STATE_LOGGED_IN) {
 		/*
+		 * During shutdown, if session is prematurely disconnected,
+		 * recovery won't happen and there will be hung cmds. Not
+		 * handling cmds would trigger EH, also bad in this case.
+		 * Instead, handle cmd, allow completion to happen and let
+		 * upper layer to deal with the result.
+		 */
+		if (unlikely(system_state != SYSTEM_RUNNING)) {
+			sc->result = DID_NO_CONNECT << 16;
+			ISCSI_DBG_EH(session, "sc on shutdown, handled\n");
+			rc = BLK_EH_HANDLED;
+			goto done;
+		}
+		/*
 		 * We are probably in the middle of iscsi recovery so let
 		 * that complete and handle the error.
 		 */
@@ -2083,7 +2105,7 @@ done:
 		task->last_timeout = jiffies;
 	spin_unlock(&session->frwd_lock);
 	ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
-		     "timer reset" : "nh");
+		     "timer reset" : "shutdown or nh");
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/libsas/sas_expander.c linux-libre-4.1.52-gnu/drivers/scsi/libsas/sas_expander.c
--- linux-libre-4.1.51-gnu/drivers/scsi/libsas/sas_expander.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/libsas/sas_expander.c	2018-05-27 22:26:45.000000000 -0400
@@ -282,6 +282,7 @@ static void sas_set_ex_phy(struct domain
 	phy->phy->minimum_linkrate = dr->pmin_linkrate;
 	phy->phy->maximum_linkrate = dr->pmax_linkrate;
 	phy->phy->negotiated_linkrate = phy->linkrate;
+	phy->phy->enabled = (phy->linkrate != SAS_PHY_DISABLED);
 
  skip:
 	if (new_phy)
@@ -675,7 +676,7 @@ int sas_smp_get_phy_events(struct sas_ph
 	res = smp_execute_task(dev, req, RPEL_REQ_SIZE,
 			            resp, RPEL_RESP_SIZE);
 
-	if (!res)
+	if (res)
 		goto out;
 
 	phy->invalid_dword_count = scsi_to_u32(&resp[12]);
@@ -684,6 +685,7 @@ int sas_smp_get_phy_events(struct sas_ph
 	phy->phy_reset_problem_count = scsi_to_u32(&resp[24]);
 
  out:
+	kfree(req);
 	kfree(resp);
 	return res;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/lpfc/lpfc_sli.c linux-libre-4.1.52-gnu/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-4.1.51-gnu/drivers/scsi/lpfc/lpfc_sli.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/lpfc/lpfc_sli.c	2018-05-27 22:26:45.000000000 -0400
@@ -13517,6 +13517,9 @@ lpfc_wq_create(struct lpfc_hba *phba, st
 	case LPFC_Q_CREATE_VERSION_1:
 		bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1,
 		       wq->entry_count);
+		bf_set(lpfc_mbox_hdr_version, &shdr->request,
+		       LPFC_Q_CREATE_VERSION_1);
+
 		switch (wq->entry_size) {
 		default:
 		case 64:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/mac_esp.c linux-libre-4.1.52-gnu/drivers/scsi/mac_esp.c
--- linux-libre-4.1.51-gnu/drivers/scsi/mac_esp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/mac_esp.c	2018-05-27 22:26:45.000000000 -0400
@@ -55,6 +55,7 @@ struct mac_esp_priv {
 	int error;
 };
 static struct esp *esp_chips[2];
+static DEFINE_SPINLOCK(esp_chips_lock);
 
 #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \
 			       platform_get_drvdata((struct platform_device *) \
@@ -562,15 +563,18 @@ static int esp_mac_probe(struct platform
 	}
 
 	host->irq = IRQ_MAC_SCSI;
-	esp_chips[dev->id] = esp;
-	mb();
-	if (esp_chips[!dev->id] == NULL) {
-		err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
-		if (err < 0) {
-			esp_chips[dev->id] = NULL;
-			goto fail_free_priv;
-		}
+
+	/* The request_irq() call is intended to succeed for the first device
+	 * and fail for the second device.
+	 */
+	err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
+	spin_lock(&esp_chips_lock);
+	if (err < 0 && esp_chips[!dev->id] == NULL) {
+		spin_unlock(&esp_chips_lock);
+		goto fail_free_priv;
 	}
+	esp_chips[dev->id] = esp;
+	spin_unlock(&esp_chips_lock);
 
 	err = scsi_esp_register(esp, &dev->dev);
 	if (err)
@@ -579,8 +583,13 @@ static int esp_mac_probe(struct platform
 	return 0;
 
 fail_free_irq:
-	if (esp_chips[!dev->id] == NULL)
+	spin_lock(&esp_chips_lock);
+	esp_chips[dev->id] = NULL;
+	if (esp_chips[!dev->id] == NULL) {
+		spin_unlock(&esp_chips_lock);
 		free_irq(host->irq, esp);
+	} else
+		spin_unlock(&esp_chips_lock);
 fail_free_priv:
 	kfree(mep);
 fail_free_command_block:
@@ -599,9 +608,13 @@ static int esp_mac_remove(struct platfor
 
 	scsi_esp_unregister(esp);
 
+	spin_lock(&esp_chips_lock);
 	esp_chips[dev->id] = NULL;
-	if (!(esp_chips[0] || esp_chips[1]))
+	if (esp_chips[!dev->id] == NULL) {
+		spin_unlock(&esp_chips_lock);
 		free_irq(irq, NULL);
+	} else
+		spin_unlock(&esp_chips_lock);
 
 	kfree(mep);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/scsi_devinfo.c linux-libre-4.1.52-gnu/drivers/scsi/scsi_devinfo.c
--- linux-libre-4.1.51-gnu/drivers/scsi/scsi_devinfo.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/scsi_devinfo.c	2018-05-27 22:26:45.000000000 -0400
@@ -180,7 +180,7 @@ static struct {
 	{"HITACHI", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"HITACHI", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN},	/* HP VA7400 */
-	{"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */
+	{"HP", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, /* HP XP Arrays */
 	{"HP", "NetRAID-4M", NULL, BLIST_FORCELUN},
 	{"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD},
 	{"HP", "C1557A", NULL, BLIST_FORCELUN},
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/sd.c linux-libre-4.1.52-gnu/drivers/scsi/sd.c
--- linux-libre-4.1.51-gnu/drivers/scsi/sd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/sd.c	2018-05-27 22:26:45.000000000 -0400
@@ -1811,6 +1811,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
 				break;	/* standby */
 			if (sshdr.asc == 4 && sshdr.ascq == 0xc)
 				break;	/* unavailable */
+			if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
+				break;	/* sanitize in progress */
 			/*
 			 * Issue command to spin up drive when not ready
 			 */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/ses.c linux-libre-4.1.52-gnu/drivers/scsi/ses.c
--- linux-libre-4.1.51-gnu/drivers/scsi/ses.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/ses.c	2018-05-27 22:26:45.000000000 -0400
@@ -528,7 +528,6 @@ static void ses_enclosure_data_process(s
 					ecomp = &edev->component[components++];
 
 				if (!IS_ERR(ecomp)) {
-					ses_get_power_status(edev, ecomp);
 					if (addl_desc_ptr)
 						ses_process_descriptor(
 							ecomp,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/sg.c linux-libre-4.1.52-gnu/drivers/scsi/sg.c
--- linux-libre-4.1.51-gnu/drivers/scsi/sg.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/sg.c	2018-05-27 22:26:45.000000000 -0400
@@ -535,6 +535,7 @@ sg_read(struct file *filp, char __user *
 	} else
 		count = (old_hdr->result == 0) ? 0 : -EIO;
 	sg_finish_rem_req(srp);
+	sg_remove_request(sfp, srp);
 	retval = count;
 free_old_hdr:
 	kfree(old_hdr);
@@ -575,6 +576,7 @@ sg_new_read(Sg_fd * sfp, char __user *bu
 	}
 err_out:
 	err2 = sg_finish_rem_req(srp);
+	sg_remove_request(sfp, srp);
 	return err ? : err2 ? : count;
 }
 
@@ -674,18 +676,14 @@ sg_write(struct file *filp, const char _
 	 * is a non-zero input_size, so emit a warning.
 	 */
 	if (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
-		static char cmd[TASK_COMM_LEN];
-		if (strcmp(current->comm, cmd)) {
-			printk_ratelimited(KERN_WARNING
-					   "sg_write: data in/out %d/%d bytes "
-					   "for SCSI command 0x%x-- guessing "
-					   "data in;\n   program %s not setting "
-					   "count and/or reply_len properly\n",
-					   old_hdr.reply_len - (int)SZ_SG_HEADER,
-					   input_size, (unsigned int) cmnd[0],
-					   current->comm);
-			strcpy(cmd, current->comm);
-		}
+		printk_ratelimited(KERN_WARNING
+				   "sg_write: data in/out %d/%d bytes "
+				   "for SCSI command 0x%x-- guessing "
+				   "data in;\n   program %s not setting "
+				   "count and/or reply_len properly\n",
+				   old_hdr.reply_len - (int)SZ_SG_HEADER,
+				   input_size, (unsigned int) cmnd[0],
+				   current->comm);
 	}
 	k = sg_common_write(sfp, srp, cmnd, sfp->timeout, blocking);
 	return (k < 0) ? k : count;
@@ -764,6 +762,35 @@ sg_new_write(Sg_fd *sfp, struct file *fi
 	return count;
 }
 
+static bool sg_is_valid_dxfer(sg_io_hdr_t *hp)
+{
+	switch (hp->dxfer_direction) {
+	case SG_DXFER_NONE:
+		if (hp->dxferp || hp->dxfer_len > 0)
+			return false;
+		return true;
+	case SG_DXFER_FROM_DEV:
+		/*
+		 * for SG_DXFER_FROM_DEV we always set dxfer_len to > 0. dxferp
+		 * can either be NULL or != NULL so there's no point in checking
+		 * it either. So just return true.
+		 */
+		return true;
+	case SG_DXFER_TO_DEV:
+	case SG_DXFER_TO_FROM_DEV:
+		if (!hp->dxferp || hp->dxfer_len == 0)
+			return false;
+		return true;
+	case SG_DXFER_UNKNOWN:
+		if ((!hp->dxferp && hp->dxfer_len) ||
+		    (hp->dxferp && hp->dxfer_len == 0))
+			return false;
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int
 sg_common_write(Sg_fd * sfp, Sg_request * srp,
 		unsigned char *cmnd, int timeout, int blocking)
@@ -784,17 +811,22 @@ sg_common_write(Sg_fd * sfp, Sg_request
 			"sg_common_write:  scsi opcode=0x%02x, cmd_size=%d\n",
 			(int) cmnd[0], (int) hp->cmd_len));
 
+	if (!sg_is_valid_dxfer(hp))
+		return -EINVAL;
+
 	k = sg_start_req(srp, cmnd);
 	if (k) {
 		SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp,
 			"sg_common_write: start_req err=%d\n", k));
 		sg_finish_rem_req(srp);
+		sg_remove_request(sfp, srp);
 		return k;	/* probably out of space --> ENOMEM */
 	}
 	if (atomic_read(&sdp->detaching)) {
 		if (srp->bio)
 			blk_end_request_all(srp->rq, -EIO);
 		sg_finish_rem_req(srp);
+		sg_remove_request(sfp, srp);
 		return -ENODEV;
 	}
 
@@ -1284,6 +1316,7 @@ sg_rq_end_io_usercontext(struct work_str
 	struct sg_fd *sfp = srp->parentfp;
 
 	sg_finish_rem_req(srp);
+	sg_remove_request(sfp, srp);
 	kref_put(&sfp->f_ref, sg_remove_sfp);
 }
 
@@ -1828,8 +1861,6 @@ sg_finish_rem_req(Sg_request *srp)
 	else
 		sg_remove_scat(sfp, req_schp);
 
-	sg_remove_request(sfp, srp);
-
 	return ret;
 }
 
@@ -2066,11 +2097,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
 		if ((1 == resp->done) && (!resp->sg_io_owned) &&
 		    ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
 			resp->done = 2;	/* guard against other readers */
-			break;
+			write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+			return resp;
 		}
 	}
 	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
-	return resp;
+	return NULL;
 }
 
 /* always adds to end of list */
@@ -2176,12 +2208,17 @@ sg_remove_sfp_usercontext(struct work_st
 	struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
 	struct sg_device *sdp = sfp->parentdp;
 	Sg_request *srp;
+	unsigned long iflags;
 
 	/* Cleanup any responses which were never read(). */
+	write_lock_irqsave(&sfp->rq_list_lock, iflags);
 	while (!list_empty(&sfp->rq_list)) {
 		srp = list_first_entry(&sfp->rq_list, Sg_request, entry);
 		sg_finish_rem_req(srp);
+		list_del(&srp->entry);
+		srp->parentfp = NULL;
 	}
+	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
 
 	if (sfp->reserve.bufflen > 0) {
 		SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/scsi/virtio_scsi.c linux-libre-4.1.52-gnu/drivers/scsi/virtio_scsi.c
--- linux-libre-4.1.51-gnu/drivers/scsi/virtio_scsi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/scsi/virtio_scsi.c	2018-05-27 22:26:45.000000000 -0400
@@ -28,6 +28,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_devinfo.h>
 #include <linux/seqlock.h>
 
 #define VIRTIO_SCSI_MEMPOOL_SZ 64
@@ -699,6 +700,28 @@ static int virtscsi_device_reset(struct
 	return virtscsi_tmf(vscsi, cmd);
 }
 
+static int virtscsi_device_alloc(struct scsi_device *sdevice)
+{
+	/*
+	 * Passed through SCSI targets (e.g. with qemu's 'scsi-block')
+	 * may have transfer limits which come from the host SCSI
+	 * controller or something on the host side other than the
+	 * target itself.
+	 *
+	 * To make this work properly, the hypervisor can adjust the
+	 * target's VPD information to advertise these limits.  But
+	 * for that to work, the guest has to look at the VPD pages,
+	 * which we won't do by default if it is an SPC-2 device, even
+	 * if it does actually support it.
+	 *
+	 * So, set the blist to always try to read the VPD pages.
+	 */
+	sdevice->sdev_bflags = BLIST_TRY_VPD_PAGES;
+
+	return 0;
+}
+
+
 /**
  * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth
  * @sdev:	Virtscsi target whose queue depth to change
@@ -770,6 +793,7 @@ static struct scsi_host_template virtscs
 	.change_queue_depth = virtscsi_change_queue_depth,
 	.eh_abort_handler = virtscsi_abort,
 	.eh_device_reset_handler = virtscsi_device_reset,
+	.slave_alloc = virtscsi_device_alloc,
 
 	.can_queue = 1024,
 	.dma_boundary = UINT_MAX,
@@ -790,6 +814,7 @@ static struct scsi_host_template virtscs
 	.eh_abort_handler = virtscsi_abort,
 	.eh_device_reset_handler = virtscsi_device_reset,
 
+	.slave_alloc = virtscsi_device_alloc,
 	.can_queue = 1024,
 	.dma_boundary = UINT_MAX,
 	.use_clustering = ENABLE_CLUSTERING,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/spi/spi-dw-mmio.c linux-libre-4.1.52-gnu/drivers/spi/spi-dw-mmio.c
--- linux-libre-4.1.51-gnu/drivers/spi/spi-dw-mmio.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/spi/spi-dw-mmio.c	2018-05-27 22:26:45.000000000 -0400
@@ -121,8 +121,8 @@ static int dw_spi_mmio_remove(struct pla
 {
 	struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
 
-	clk_disable_unprepare(dwsmmio->clk);
 	dw_spi_remove_host(&dwsmmio->dws);
+	clk_disable_unprepare(dwsmmio->clk);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/spi/spi-omap2-mcspi.c linux-libre-4.1.52-gnu/drivers/spi/spi-omap2-mcspi.c
--- linux-libre-4.1.51-gnu/drivers/spi/spi-omap2-mcspi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/spi/spi-omap2-mcspi.c	2018-05-27 22:26:45.000000000 -0400
@@ -436,6 +436,8 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 	int			elements = 0;
 	int			word_len, element_count;
 	struct omap2_mcspi_cs	*cs = spi->controller_state;
+	void __iomem		*chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
+
 	mcspi = spi_master_get_devdata(spi->master);
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 	count = xfer->len;
@@ -496,8 +498,8 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 	if (l & OMAP2_MCSPI_CHCONF_TURBO) {
 		elements--;
 
-		if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
-				   & OMAP2_MCSPI_CHSTAT_RXS)) {
+		if (!mcspi_wait_for_reg_bit(chstat_reg,
+					    OMAP2_MCSPI_CHSTAT_RXS)) {
 			u32 w;
 
 			w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0);
@@ -515,8 +517,7 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 			return count;
 		}
 	}
-	if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
-				& OMAP2_MCSPI_CHSTAT_RXS)) {
+	if (!mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_RXS)) {
 		u32 w;
 
 		w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/spi/spi-sun6i.c linux-libre-4.1.52-gnu/drivers/spi/spi-sun6i.c
--- linux-libre-4.1.51-gnu/drivers/spi/spi-sun6i.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/spi/spi-sun6i.c	2018-05-27 22:26:45.000000000 -0400
@@ -457,7 +457,7 @@ err_free_master:
 
 static int sun6i_spi_remove(struct platform_device *pdev)
 {
-	pm_runtime_disable(&pdev->dev);
+	pm_runtime_force_suspend(&pdev->dev);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/staging/speakup/kobjects.c linux-libre-4.1.52-gnu/drivers/staging/speakup/kobjects.c
--- linux-libre-4.1.51-gnu/drivers/staging/speakup/kobjects.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/staging/speakup/kobjects.c	2018-05-27 22:26:45.000000000 -0400
@@ -830,7 +830,9 @@ static ssize_t message_show(struct kobje
 	struct msg_group_t *group = spk_find_msg_group(attr->attr.name);
 	unsigned long flags;
 
-	BUG_ON(!group);
+	if (WARN_ON(!group))
+		return -EINVAL;
+
 	spin_lock_irqsave(&speakup_info.spinlock, flags);
 	retval = message_show_helper(buf, group->start, group->end);
 	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
@@ -842,7 +844,9 @@ static ssize_t message_store(struct kobj
 {
 	struct msg_group_t *group = spk_find_msg_group(attr->attr.name);
 
-	BUG_ON(!group);
+	if (WARN_ON(!group))
+		return -EINVAL;
+
 	return message_store_helper(buf, count, group);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/staging/wlan-ng/prism2mgmt.c linux-libre-4.1.52-gnu/drivers/staging/wlan-ng/prism2mgmt.c
--- linux-libre-4.1.51-gnu/drivers/staging/wlan-ng/prism2mgmt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/staging/wlan-ng/prism2mgmt.c	2018-05-27 22:26:45.000000000 -0400
@@ -169,7 +169,7 @@ int prism2mgmt_scan(wlandevice_t *wlande
 				     hw->ident_sta_fw.variant) >
 	    HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
 		if (msg->scantype.data != P80211ENUM_scantype_active)
-			word = cpu_to_le16(msg->maxchanneltime.data);
+			word = msg->maxchanneltime.data;
 		else
 			word = 0;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/thunderbolt/nhi.c linux-libre-4.1.52-gnu/drivers/thunderbolt/nhi.c
--- linux-libre-4.1.51-gnu/drivers/thunderbolt/nhi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/thunderbolt/nhi.c	2018-05-27 22:26:45.000000000 -0400
@@ -627,6 +627,7 @@ static const struct dev_pm_ops nhi_pm_op
 					    * we just disable hotplug, the
 					    * pci-tunnels stay alive.
 					    */
+	.thaw_noirq = nhi_resume_noirq,
 	.restore_noirq = nhi_resume_noirq,
 };
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/n_gsm.c linux-libre-4.1.52-gnu/drivers/tty/n_gsm.c
--- linux-libre-4.1.51-gnu/drivers/tty/n_gsm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/n_gsm.c	2018-05-27 22:26:45.000000000 -0400
@@ -137,6 +137,9 @@ struct gsm_dlci {
 	struct mutex mutex;
 
 	/* Link layer */
+	int mode;
+#define DLCI_MODE_ABM		0	/* Normal Asynchronous Balanced Mode */
+#define DLCI_MODE_ADM		1	/* Asynchronous Disconnected Mode */
 	spinlock_t lock;	/* Protects the internal state */
 	struct timer_list t1;	/* Retransmit timer for SABM and UA */
 	int retries;
@@ -1380,7 +1383,13 @@ retry:
 	ctrl->data = data;
 	ctrl->len = clen;
 	gsm->pending_cmd = ctrl;
-	gsm->cretries = gsm->n2;
+
+	/* If DLCI0 is in ADM mode skip retries, it won't respond */
+	if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
+		gsm->cretries = 1;
+	else
+		gsm->cretries = gsm->n2;
+
 	mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
 	gsm_control_transmit(gsm, ctrl);
 	spin_unlock_irqrestore(&gsm->control_lock, flags);
@@ -1467,6 +1476,10 @@ static void gsm_dlci_open(struct gsm_dlc
  *	in which case an opening port goes back to closed and a closing port
  *	is simply put into closed state (any further frames from the other
  *	end will get a DM response)
+ *
+ *	Some control dlci can stay in ADM mode with other dlci working just
+ *	fine. In that case we can just keep the control dlci open after the
+ *	DLCI_OPENING retries time out.
  */
 
 static void gsm_dlci_t1(unsigned long data)
@@ -1480,8 +1493,16 @@ static void gsm_dlci_t1(unsigned long da
 		if (dlci->retries) {
 			gsm_command(dlci->gsm, dlci->addr, SABM|PF);
 			mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
-		} else
+		} else if (!dlci->addr && gsm->control == (DM | PF)) {
+			if (debug & 8)
+				pr_info("DLCI %d opening in ADM mode.\n",
+					dlci->addr);
+			dlci->mode = DLCI_MODE_ADM;
+			gsm_dlci_open(dlci);
+		} else {
 			gsm_dlci_close(dlci);
+		}
+
 		break;
 	case DLCI_CLOSING:
 		dlci->retries--;
@@ -1499,8 +1520,8 @@ static void gsm_dlci_t1(unsigned long da
  *	@dlci: DLCI to open
  *
  *	Commence opening a DLCI from the Linux side. We issue SABM messages
- *	to the modem which should then reply with a UA, at which point we
- *	will move into open state. Opening is done asynchronously with retry
+ *	to the modem which should then reply with a UA or ADM, at which point
+ *	we will move into open state. Opening is done asynchronously with retry
  *	running off timers and the responses.
  */
 
@@ -2871,11 +2892,22 @@ static int gsmtty_modem_update(struct gs
 static int gsm_carrier_raised(struct tty_port *port)
 {
 	struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
+	struct gsm_mux *gsm = dlci->gsm;
+
 	/* Not yet open so no carrier info */
 	if (dlci->state != DLCI_OPEN)
 		return 0;
 	if (debug & 2)
 		return 1;
+
+	/*
+	 * Basic mode with control channel in ADM mode may not respond
+	 * to CMD_MSC at all and modem_rx is empty.
+	 */
+	if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM &&
+	    !dlci->modem_rx)
+		return 1;
+
 	return dlci->modem_rx & TIOCM_CD;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/n_tty.c linux-libre-4.1.52-gnu/drivers/tty/n_tty.c
--- linux-libre-4.1.51-gnu/drivers/tty/n_tty.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/n_tty.c	2018-05-27 22:26:45.000000000 -0400
@@ -2259,6 +2259,12 @@ static ssize_t n_tty_read(struct tty_str
 				}
 				if (tty_hung_up_p(file))
 					break;
+				/*
+				 * Abort readers for ttys which never actually
+				 * get hung up.  See __tty_hangup().
+				 */
+				if (test_bit(TTY_HUPPING, &tty->flags))
+					break;
 				if (!timeout)
 					break;
 				if (file->f_flags & O_NONBLOCK) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/serial/8250/8250_omap.c linux-libre-4.1.52-gnu/drivers/tty/serial/8250/8250_omap.c
--- linux-libre-4.1.51-gnu/drivers/tty/serial/8250/8250_omap.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/serial/8250/8250_omap.c	2018-05-27 22:26:45.000000000 -0400
@@ -612,6 +612,10 @@ static int omap_8250_startup(struct uart
 	up->lsr_saved_flags = 0;
 	up->msr_saved_flags = 0;
 
+	/* Disable DMA for console UART */
+	if (uart_console(port))
+		up->dma = NULL;
+
 	if (up->dma) {
 		ret = serial8250_request_dma(up);
 		if (ret) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/serial/sccnxp.c linux-libre-4.1.52-gnu/drivers/tty/serial/sccnxp.c
--- linux-libre-4.1.51-gnu/drivers/tty/serial/sccnxp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/serial/sccnxp.c	2018-05-27 22:26:45.000000000 -0400
@@ -884,14 +884,19 @@ static int sccnxp_probe(struct platform_
 
 	clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(clk)) {
-		if (PTR_ERR(clk) == -EPROBE_DEFER) {
-			ret = -EPROBE_DEFER;
+		ret = PTR_ERR(clk);
+		if (ret == -EPROBE_DEFER)
 			goto err_out;
-		}
+		uartclk = 0;
+	} else {
+		clk_prepare_enable(clk);
+		uartclk = clk_get_rate(clk);
+	}
+
+	if (!uartclk) {
 		dev_notice(&pdev->dev, "Using default clock frequency\n");
 		uartclk = s->chip->freq_std;
-	} else
-		uartclk = clk_get_rate(clk);
+	}
 
 	/* Check input frequency */
 	if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/tty_io.c linux-libre-4.1.52-gnu/drivers/tty/tty_io.c
--- linux-libre-4.1.51-gnu/drivers/tty/tty_io.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/tty_io.c	2018-05-27 22:26:45.000000000 -0400
@@ -690,6 +690,14 @@ static void __tty_hangup(struct tty_stru
 		return;
 	}
 
+	/*
+	 * Some console devices aren't actually hung up for technical and
+	 * historical reasons, which can lead to indefinite interruptible
+	 * sleep in n_tty_read().  The following explicitly tells
+	 * n_tty_read() to abort readers.
+	 */
+	set_bit(TTY_HUPPING, &tty->flags);
+
 	/* inuse_filps is protected by the single tty lock,
 	   this really needs to change if we want to flush the
 	   workqueue with the lock held */
@@ -745,6 +753,7 @@ static void __tty_hangup(struct tty_stru
 	 * can't yet guarantee all that.
 	 */
 	set_bit(TTY_HUPPED, &tty->flags);
+	clear_bit(TTY_HUPPING, &tty->flags);
 	tty_unlock(tty);
 
 	if (f)
@@ -3151,7 +3160,10 @@ struct tty_struct *alloc_tty_struct(stru
 
 	kref_init(&tty->kref);
 	tty->magic = TTY_MAGIC;
-	tty_ldisc_init(tty);
+	if (tty_ldisc_init(tty)) {
+		kfree(tty);
+		return NULL;
+	}
 	tty->session = NULL;
 	tty->pgrp = NULL;
 	mutex_init(&tty->legacy_mutex);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/tty_ldisc.c linux-libre-4.1.52-gnu/drivers/tty/tty_ldisc.c
--- linux-libre-4.1.51-gnu/drivers/tty/tty_ldisc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/tty_ldisc.c	2018-05-27 22:26:45.000000000 -0400
@@ -171,12 +171,11 @@ static struct tty_ldisc *tty_ldisc_get(s
 			return ERR_CAST(ldops);
 	}
 
-	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
-	if (ld == NULL) {
-		put_ldops(ldops);
-		return ERR_PTR(-ENOMEM);
-	}
-
+	/*
+	 * There is no way to handle allocation failure of only 16 bytes.
+	 * Let's simplify error handling and save more memory.
+	 */
+	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
 	ld->ops = ldops;
 	ld->tty = tty;
 
@@ -800,12 +799,13 @@ void tty_ldisc_release(struct tty_struct
  *	the tty structure is not completely set up when this call is made.
  */
 
-void tty_ldisc_init(struct tty_struct *tty)
+int tty_ldisc_init(struct tty_struct *tty)
 {
 	struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
 	if (IS_ERR(ld))
-		panic("n_tty: init_tty");
+		return PTR_ERR(ld);
 	tty->ldisc = ld;
+	return 0;
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/tty/vt/vt.c linux-libre-4.1.52-gnu/drivers/tty/vt/vt.c
--- linux-libre-4.1.51-gnu/drivers/tty/vt/vt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/tty/vt/vt.c	2018-05-27 22:26:45.000000000 -0400
@@ -1305,6 +1305,11 @@ static void csi_m(struct vc_data *vc)
 			case 3:
 				vc->vc_italic = 1;
 				break;
+			case 21:
+				/*
+				 * No console drivers support double underline, so
+				 * convert it to a single underline.
+				 */
 			case 4:
 				vc->vc_underline = 1;
 				break;
@@ -1341,7 +1346,6 @@ static void csi_m(struct vc_data *vc)
 				vc->vc_disp_ctrl = 1;
 				vc->vc_toggle_meta = 1;
 				break;
-			case 21:
 			case 22:
 				vc->vc_intensity = 1;
 				break;
@@ -1711,7 +1715,7 @@ static void reset_terminal(struct vc_dat
 	default_attr(vc);
 	update_attr(vc);
 
-	vc->vc_tab_stop[0]	= 0x01010100;
+	vc->vc_tab_stop[0]	=
 	vc->vc_tab_stop[1]	=
 	vc->vc_tab_stop[2]	=
 	vc->vc_tab_stop[3]	=
@@ -1754,7 +1758,7 @@ static void do_con_trol(struct tty_struc
 		vc->vc_pos -= (vc->vc_x << 1);
 		while (vc->vc_x < vc->vc_cols - 1) {
 			vc->vc_x++;
-			if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
+			if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31)))
 				break;
 		}
 		vc->vc_pos += (vc->vc_x << 1);
@@ -1814,7 +1818,7 @@ static void do_con_trol(struct tty_struc
 			lf(vc);
 			return;
 		case 'H':
-			vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
+			vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31));
 			return;
 		case 'Z':
 			respond_ID(tty);
@@ -2007,7 +2011,7 @@ static void do_con_trol(struct tty_struc
 			return;
 		case 'g':
 			if (!vc->vc_par[0])
-				vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
+				vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31));
 			else if (vc->vc_par[0] == 3) {
 				vc->vc_tab_stop[0] =
 					vc->vc_tab_stop[1] =
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/chipidea/core.c linux-libre-4.1.52-gnu/drivers/usb/chipidea/core.c
--- linux-libre-4.1.51-gnu/drivers/usb/chipidea/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/chipidea/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -656,7 +656,7 @@ static inline void ci_role_destroy(struc
 {
 	ci_hdrc_gadget_destroy(ci);
 	ci_hdrc_host_destroy(ci);
-	if (ci->is_otg)
+	if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
 		ci_hdrc_otg_destroy(ci);
 }
 
@@ -755,27 +755,35 @@ static int ci_hdrc_probe(struct platform
 	/* initialize role(s) before the interrupt is requested */
 	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
 		ret = ci_hdrc_host_init(ci);
-		if (ret)
-			dev_info(dev, "doesn't support host\n");
+		if (ret) {
+			if (ret == -ENXIO)
+				dev_info(dev, "doesn't support host\n");
+			else
+				goto deinit_phy;
+		}
 	}
 
 	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
 		ret = ci_hdrc_gadget_init(ci);
-		if (ret)
-			dev_info(dev, "doesn't support gadget\n");
+		if (ret) {
+			if (ret == -ENXIO)
+				dev_info(dev, "doesn't support gadget\n");
+			else
+				goto deinit_host;
+		}
 	}
 
 	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
 		dev_err(dev, "no supported roles\n");
 		ret = -ENODEV;
-		goto deinit_phy;
+		goto deinit_gadget;
 	}
 
 	if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
 		ret = ci_hdrc_otg_init(ci);
 		if (ret) {
 			dev_err(dev, "init otg fails, ret = %d\n", ret);
-			goto stop;
+			goto deinit_gadget;
 		}
 	}
 
@@ -835,7 +843,12 @@ static int ci_hdrc_probe(struct platform
 		return 0;
 
 stop:
-	ci_role_destroy(ci);
+	if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
+		ci_hdrc_otg_destroy(ci);
+deinit_gadget:
+	ci_hdrc_gadget_destroy(ci);
+deinit_host:
+	ci_hdrc_host_destroy(ci);
 deinit_phy:
 	ci_usb_phy_exit(ci);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/core/generic.c linux-libre-4.1.52-gnu/drivers/usb/core/generic.c
--- linux-libre-4.1.51-gnu/drivers/usb/core/generic.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/core/generic.c	2018-05-27 22:26:45.000000000 -0400
@@ -208,8 +208,13 @@ static int generic_suspend(struct usb_de
 	if (!udev->parent)
 		rc = hcd_bus_suspend(udev, msg);
 
-	/* Non-root devices don't need to do anything for FREEZE or PRETHAW */
-	else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+	/*
+	 * Non-root USB2 devices don't need to do anything for FREEZE
+	 * or PRETHAW. USB3 devices don't support global suspend and
+	 * needs to be selectively suspended.
+	 */
+	else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+		 && (udev->speed < USB_SPEED_SUPER))
 		rc = 0;
 	else
 		rc = usb_port_suspend(udev, msg);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/core/hcd.c linux-libre-4.1.52-gnu/drivers/usb/core/hcd.c
--- linux-libre-4.1.51-gnu/drivers/usb/core/hcd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/core/hcd.c	2018-05-27 22:26:45.000000000 -0400
@@ -2288,6 +2288,7 @@ void usb_hcd_resume_root_hub (struct usb
 
 	spin_lock_irqsave (&hcd_root_hub_lock, flags);
 	if (hcd->rh_registered) {
+		pm_wakeup_event(&hcd->self.root_hub->dev, 0);
 		set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
 		queue_work(pm_wq, &hcd->wakeup_work);
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/core/hub.c linux-libre-4.1.52-gnu/drivers/usb/core/hub.c
--- linux-libre-4.1.51-gnu/drivers/usb/core/hub.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/core/hub.c	2018-05-27 22:26:45.000000000 -0400
@@ -633,12 +633,17 @@ void usb_wakeup_notification(struct usb_
 		unsigned int portnum)
 {
 	struct usb_hub *hub;
+	struct usb_port *port_dev;
 
 	if (!hdev)
 		return;
 
 	hub = usb_hub_to_struct_hub(hdev);
 	if (hub) {
+		port_dev = hub->ports[portnum - 1];
+		if (port_dev && port_dev->child)
+			pm_wakeup_event(&port_dev->child->dev, 0);
+
 		set_bit(portnum, hub->wakeup_bits);
 		kick_hub_wq(hub);
 	}
@@ -3375,8 +3380,11 @@ int usb_port_resume(struct usb_device *u
 
 	/* Skip the initial Clear-Suspend step for a remote wakeup */
 	status = hub_port_status(hub, port1, &portstatus, &portchange);
-	if (status == 0 && !port_is_suspended(hub, portstatus))
+	if (status == 0 && !port_is_suspended(hub, portstatus)) {
+		if (portchange & USB_PORT_STAT_C_SUSPEND)
+			pm_wakeup_event(&udev->dev, 0);
 		goto SuspendCleared;
+	}
 
 	/* see 7.1.7.7; affects power usage, but not budgeting */
 	if (hub_is_superspeed(hub->hdev))
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/core/quirks.c linux-libre-4.1.52-gnu/drivers/usb/core/quirks.c
--- linux-libre-4.1.51-gnu/drivers/usb/core/quirks.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/core/quirks.c	2018-05-27 22:26:45.000000000 -0400
@@ -45,6 +45,9 @@ static const struct usb_device_id usb_qu
 	{ USB_DEVICE(0x03f0, 0x0701), .driver_info =
 			USB_QUIRK_STRING_FETCH_255 },
 
+	/* HP v222w 16GB Mini USB Drive */
+	{ USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
+
 	/* Creative SB Audigy 2 NX */
 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/dwc3/dwc3-keystone.c linux-libre-4.1.52-gnu/drivers/usb/dwc3/dwc3-keystone.c
--- linux-libre-4.1.51-gnu/drivers/usb/dwc3/dwc3-keystone.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/dwc3/dwc3-keystone.c	2018-05-27 22:26:45.000000000 -0400
@@ -112,6 +112,10 @@ static int kdwc3_probe(struct platform_d
 	dev->dma_mask = &kdwc3_dma_mask;
 
 	kdwc->clk = devm_clk_get(kdwc->dev, "usb");
+	if (IS_ERR(kdwc->clk)) {
+		dev_err(kdwc->dev, "unable to get usb clock\n");
+		return PTR_ERR(kdwc->clk);
+	}
 
 	error = clk_prepare_enable(kdwc->clk);
 	if (error < 0) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/dwc3/dwc3-pci.c linux-libre-4.1.52-gnu/drivers/usb/dwc3/dwc3-pci.c
--- linux-libre-4.1.51-gnu/drivers/usb/dwc3/dwc3-pci.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/dwc3/dwc3-pci.c	2018-05-27 22:26:45.000000000 -0400
@@ -124,7 +124,7 @@ static int dwc3_pci_probe(struct pci_dev
 	ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
 	if (ret) {
 		dev_err(dev, "couldn't add resources to dwc3 device\n");
-		return ret;
+		goto err;
 	}
 
 	pci_set_drvdata(pci, dwc3);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/function/f_hid.c linux-libre-4.1.52-gnu/drivers/usb/gadget/function/f_hid.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/function/f_hid.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/function/f_hid.c	2018-05-27 22:26:45.000000000 -0400
@@ -223,6 +223,13 @@ static ssize_t f_hidg_read(struct file *
 	/* pick the first one */
 	list = list_first_entry(&hidg->completed_out_req,
 				struct f_hidg_req_list, list);
+
+	/*
+	 * Remove this from list to protect it from beign free()
+	 * while host disables our function
+	 */
+	list_del(&list->list);
+
 	req = list->req;
 	count = min_t(unsigned int, count, req->actual - list->pos);
 	spin_unlock_irqrestore(&hidg->spinlock, flags);
@@ -238,15 +245,20 @@ static ssize_t f_hidg_read(struct file *
 	 * call, taking into account its current read position.
 	 */
 	if (list->pos == req->actual) {
-		spin_lock_irqsave(&hidg->spinlock, flags);
-		list_del(&list->list);
 		kfree(list);
-		spin_unlock_irqrestore(&hidg->spinlock, flags);
 
 		req->length = hidg->report_length;
 		ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL);
-		if (ret < 0)
+		if (ret < 0) {
+			free_ep_req(hidg->out_ep, req);
 			return ret;
+		}
+	} else {
+		spin_lock_irqsave(&hidg->spinlock, flags);
+		list_add(&list->list, &hidg->completed_out_req);
+		spin_unlock_irqrestore(&hidg->spinlock, flags);
+
+		wake_up(&hidg->read_queue);
 	}
 
 	return count;
@@ -490,6 +502,7 @@ static void hidg_disable(struct usb_func
 {
 	struct f_hidg *hidg = func_to_hidg(f);
 	struct f_hidg_req_list *list, *next;
+	unsigned long flags;
 
 	usb_ep_disable(hidg->in_ep);
 	hidg->in_ep->driver_data = NULL;
@@ -497,10 +510,13 @@ static void hidg_disable(struct usb_func
 	usb_ep_disable(hidg->out_ep);
 	hidg->out_ep->driver_data = NULL;
 
+	spin_lock_irqsave(&hidg->spinlock, flags);
 	list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
+		free_ep_req(hidg->out_ep, list->req);
 		list_del(&list->list);
 		kfree(list);
 	}
+	spin_unlock_irqrestore(&hidg->spinlock, flags);
 }
 
 static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/function/f_midi.c linux-libre-4.1.52-gnu/drivers/usb/gadget/function/f_midi.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/function/f_midi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/function/f_midi.c	2018-05-27 22:26:45.000000000 -0400
@@ -201,12 +201,6 @@ static inline struct usb_request *midi_a
 	return alloc_ep_req(ep, length, length);
 }
 
-static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
-{
-	kfree(req->buf);
-	usb_ep_free_request(ep, req);
-}
-
 static const uint8_t f_midi_cin_length[] = {
 	0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
 };
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/function/f_sourcesink.c linux-libre-4.1.52-gnu/drivers/usb/gadget/function/f_sourcesink.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/function/f_sourcesink.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/function/f_sourcesink.c	2018-05-27 22:26:45.000000000 -0400
@@ -307,12 +307,6 @@ static inline struct usb_request *ss_all
 	return alloc_ep_req(ep, len, buflen);
 }
 
-void free_ep_req(struct usb_ep *ep, struct usb_request *req)
-{
-	kfree(req->buf);
-	usb_ep_free_request(ep, req);
-}
-
 static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
 {
 	int			value;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/function/g_zero.h linux-libre-4.1.52-gnu/drivers/usb/gadget/function/g_zero.h
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/function/g_zero.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/function/g_zero.h	2018-05-27 22:26:45.000000000 -0400
@@ -59,7 +59,6 @@ void lb_modexit(void);
 int lb_modinit(void);
 
 /* common utilities */
-void free_ep_req(struct usb_ep *ep, struct usb_request *req);
 void disable_endpoints(struct usb_composite_dev *cdev,
 		struct usb_ep *in, struct usb_ep *out,
 		struct usb_ep *iso_in, struct usb_ep *iso_out);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/udc/bdc/bdc_core.c linux-libre-4.1.52-gnu/drivers/usb/gadget/udc/bdc/bdc_core.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/udc/bdc/bdc_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/udc/bdc/bdc_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -476,7 +476,7 @@ static int bdc_probe(struct platform_dev
 	bdc->dev = dev;
 	dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq);
 
-	temp = bdc_readl(bdc->regs, BDC_BDCSC);
+	temp = bdc_readl(bdc->regs, BDC_BDCCAP1);
 	if ((temp & BDC_P64) &&
 			!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
 		dev_dbg(bdc->dev, "Using 64-bit address\n");
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/udc/bdc/bdc_pci.c linux-libre-4.1.52-gnu/drivers/usb/gadget/udc/bdc/bdc_pci.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/udc/bdc/bdc_pci.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/udc/bdc/bdc_pci.c	2018-05-27 22:26:45.000000000 -0400
@@ -82,6 +82,7 @@ static int bdc_pci_probe(struct pci_dev
 	if (ret) {
 		dev_err(&pci->dev,
 			"couldn't add resources to bdc device\n");
+		platform_device_put(bdc);
 		return ret;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/udc/dummy_hcd.c linux-libre-4.1.52-gnu/drivers/usb/gadget/udc/dummy_hcd.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/udc/dummy_hcd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/udc/dummy_hcd.c	2018-05-27 22:26:45.000000000 -0400
@@ -2026,16 +2026,13 @@ static int dummy_hub_control(
 			}
 			break;
 		case USB_PORT_FEAT_POWER:
-			if (hcd->speed == HCD_USB3) {
-				if (dum_hcd->port_status & USB_PORT_STAT_POWER)
-					dev_dbg(dummy_dev(dum_hcd),
-						"power-off\n");
-			} else
-				if (dum_hcd->port_status &
-							USB_SS_PORT_STAT_POWER)
-					dev_dbg(dummy_dev(dum_hcd),
-						"power-off\n");
-			/* FALLS THROUGH */
+			dev_dbg(dummy_dev(dum_hcd), "power-off\n");
+			if (hcd->speed == HCD_USB3)
+				dum_hcd->port_status &= ~USB_SS_PORT_STAT_POWER;
+			else
+				dum_hcd->port_status &= ~USB_PORT_STAT_POWER;
+			set_link_state(dum_hcd);
+			break;
 		default:
 			dum_hcd->port_status &= ~(1 << wValue);
 			set_link_state(dum_hcd);
@@ -2206,14 +2203,13 @@ static int dummy_hub_control(
 				if ((dum_hcd->port_status &
 				     USB_SS_PORT_STAT_POWER) != 0) {
 					dum_hcd->port_status |= (1 << wValue);
-					set_link_state(dum_hcd);
 				}
 			} else
 				if ((dum_hcd->port_status &
 				     USB_PORT_STAT_POWER) != 0) {
 					dum_hcd->port_status |= (1 << wValue);
-					set_link_state(dum_hcd);
 				}
+			set_link_state(dum_hcd);
 		}
 		break;
 	case GetPortErrorCount:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/u_f.c linux-libre-4.1.52-gnu/drivers/usb/gadget/u_f.c
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/u_f.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/u_f.c	2018-05-27 22:26:45.000000000 -0400
@@ -11,16 +11,18 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/usb/gadget.h>
 #include "u_f.h"
+#include <linux/usb/ch9.h>
 
-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len)
+struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len)
 {
 	struct usb_request      *req;
 
 	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
 	if (req) {
 		req->length = len ?: default_len;
+		if (usb_endpoint_dir_out(ep->desc))
+			req->length = usb_ep_align(ep, req->length);
 		req->buf = kmalloc(req->length, GFP_ATOMIC);
 		if (!req->buf) {
 			usb_ep_free_request(ep, req);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/gadget/u_f.h linux-libre-4.1.52-gnu/drivers/usb/gadget/u_f.h
--- linux-libre-4.1.51-gnu/drivers/usb/gadget/u_f.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/gadget/u_f.h	2018-05-27 22:26:45.000000000 -0400
@@ -16,6 +16,8 @@
 #ifndef __U_F_H__
 #define __U_F_H__
 
+#include <linux/usb/gadget.h>
+
 /* Variable Length Array Macros **********************************************/
 #define vla_group(groupname) size_t groupname##__next = 0
 #define vla_group_size(groupname) groupname##__next
@@ -45,8 +47,26 @@
 struct usb_ep;
 struct usb_request;
 
-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len);
-
-#endif /* __U_F_H__ */
+/**
+ * alloc_ep_req - returns a usb_request allocated by the gadget driver and
+ * allocates the request's buffer.
+ *
+ * @ep: the endpoint to allocate a usb_request
+ * @len: usb_requests's buffer suggested size
+ * @default_len: used if @len is not provided, ie, is 0
+ *
+ * In case @ep direction is OUT, the @len will be aligned to ep's
+ * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use
+ * usb_requests's length (req->length) to refer to the allocated buffer size.
+ * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req().
+ */
+struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len);
 
+/* Frees a usb_request previously allocated by alloc_ep_req() */
+static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+{
+	kfree(req->buf);
+	usb_ep_free_request(ep, req);
+}
 
+#endif /* __U_F_H__ */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/host/xhci-plat.c linux-libre-4.1.52-gnu/drivers/usb/host/xhci-plat.c
--- linux-libre-4.1.51-gnu/drivers/usb/host/xhci-plat.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/host/xhci-plat.c	2018-05-27 22:26:45.000000000 -0400
@@ -266,7 +266,6 @@ MODULE_DEVICE_TABLE(of, usb_xhci_of_matc
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
-	.shutdown	= usb_hcd_platform_shutdown,
 	.driver	= {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/musb/musb_gadget_ep0.c linux-libre-4.1.52-gnu/drivers/usb/musb/musb_gadget_ep0.c
--- linux-libre-4.1.51-gnu/drivers/usb/musb/musb_gadget_ep0.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/musb/musb_gadget_ep0.c	2018-05-27 22:26:45.000000000 -0400
@@ -114,15 +114,19 @@ static int service_tx_status_request(
 		}
 
 		is_in = epnum & USB_DIR_IN;
-		if (is_in) {
-			epnum &= 0x0f;
+		epnum &= 0x0f;
+		if (epnum >= MUSB_C_NUM_EPS) {
+			handled = -EINVAL;
+			break;
+		}
+
+		if (is_in)
 			ep = &musb->endpoints[epnum].ep_in;
-		} else {
+		else
 			ep = &musb->endpoints[epnum].ep_out;
-		}
 		regs = musb->endpoints[epnum].regs;
 
-		if (epnum >= MUSB_C_NUM_EPS || !ep->desc) {
+		if (!ep->desc) {
 			handled = -EINVAL;
 			break;
 		}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/musb/musb_host.c linux-libre-4.1.52-gnu/drivers/usb/musb/musb_host.c
--- linux-libre-4.1.51-gnu/drivers/usb/musb/musb_host.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/musb/musb_host.c	2018-05-27 22:26:45.000000000 -0400
@@ -1002,7 +1002,9 @@ static void musb_bulk_nak_timeout(struct
 			/* set tx_reinit and schedule the next qh */
 			ep->tx_reinit = 1;
 		}
-		musb_start_urb(musb, is_in, next_qh);
+
+		if (next_qh)
+			musb_start_urb(musb, is_in, next_qh);
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/serial/cp210x.c linux-libre-4.1.52-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-4.1.51-gnu/drivers/usb/serial/cp210x.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/serial/cp210x.c	2018-05-27 22:26:45.000000000 -0400
@@ -149,6 +149,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */
 	{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
 	{ USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
+	{ USB_DEVICE(0x155A, 0x1006) },	/* ELDAT Easywave RX09 */
 	{ USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */
 	{ USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */
 	{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
@@ -207,6 +208,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
 	{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
 	{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
+	{ USB_DEVICE(0x3923, 0x7A0B) }, /* National Instruments USB Serial Console */
 	{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
 	{ } /* Terminating Entry */
 };
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/serial/ftdi_sio.c linux-libre-4.1.52-gnu/drivers/usb/serial/ftdi_sio.c
--- linux-libre-4.1.51-gnu/drivers/usb/serial/ftdi_sio.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/serial/ftdi_sio.c	2018-05-27 22:26:45.000000000 -0400
@@ -773,6 +773,7 @@ static const struct usb_device_id id_tab
 		.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 	{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
 	{ USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) },
+	{ USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) },
 	{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) },
 	{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) },
 	{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) },
@@ -935,6 +936,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_FHE_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
 	{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
@@ -1904,7 +1906,8 @@ static int ftdi_8u2232c_probe(struct usb
 		return ftdi_jtag_probe(serial);
 
 	if (udev->product &&
-		(!strcmp(udev->product, "BeagleBone/XDS100V2") ||
+		(!strcmp(udev->product, "Arrow USB Blaster") ||
+		 !strcmp(udev->product, "BeagleBone/XDS100V2") ||
 		 !strcmp(udev->product, "SNAP Connect E10")))
 		return ftdi_jtag_probe(serial);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/serial/ftdi_sio_ids.h linux-libre-4.1.52-gnu/drivers/usb/serial/ftdi_sio_ids.h
--- linux-libre-4.1.51-gnu/drivers/usb/serial/ftdi_sio_ids.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/serial/ftdi_sio_ids.h	2018-05-27 22:26:45.000000000 -0400
@@ -903,6 +903,9 @@
 /*
  * RT Systems programming cables for various ham radios
  */
+/* This device uses the VID of FTDI */
+#define RTSYSTEMS_USB_VX8_PID   0x9e50  /* USB-VX8 USB to 7 pin modular plug for Yaesu VX-8 radio */
+
 #define RTSYSTEMS_VID		0x2100	/* Vendor ID */
 #define RTSYSTEMS_USB_S03_PID	0x9001	/* RTS-03 USB to Serial Adapter */
 #define RTSYSTEMS_USB_59_PID	0x9e50	/* USB-59 USB to 8 pin plug */
@@ -1422,6 +1425,12 @@
 #define FTDI_CINTERION_MC55I_PID	0xA951
 
 /*
+ * Product: FirmwareHubEmulator
+ * Manufacturer: Harman Becker Automotive Systems
+ */
+#define FTDI_FHE_PID		0xA9A0
+
+/*
  * Product: Comet Caller ID decoder
  * Manufacturer: Crucible Technologies
  */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/serial/Kconfig linux-libre-4.1.52-gnu/drivers/usb/serial/Kconfig
--- linux-libre-4.1.51-gnu/drivers/usb/serial/Kconfig	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/serial/Kconfig	2018-05-27 22:26:45.000000000 -0400
@@ -62,6 +62,7 @@ config USB_SERIAL_SIMPLE
 		- Fundamental Software dongle.
 		- Google USB serial devices
 		- HP4x calculators
+		- Libtransistor USB console
 		- a number of Motorola phones
 		- Motorola Tetra devices
 		- Novatel Wireless GPS receivers
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/serial/usb-serial-simple.c linux-libre-4.1.52-gnu/drivers/usb/serial/usb-serial-simple.c
--- linux-libre-4.1.51-gnu/drivers/usb/serial/usb-serial-simple.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/serial/usb-serial-simple.c	2018-05-27 22:26:45.000000000 -0400
@@ -66,6 +66,11 @@ DEVICE(flashloader, FLASHLOADER_IDS);
 					0x01) }
 DEVICE(google, GOOGLE_IDS);
 
+/* Libtransistor USB console */
+#define LIBTRANSISTOR_IDS()			\
+	{ USB_DEVICE(0x1209, 0x8b00) }
+DEVICE(libtransistor, LIBTRANSISTOR_IDS);
+
 /* ViVOpay USB Serial Driver */
 #define VIVOPAY_IDS()			\
 	{ USB_DEVICE(0x1d5f, 0x1004) }	/* ViVOpay 8800 */
@@ -113,6 +118,7 @@ static struct usb_serial_driver * const
 	&funsoft_device,
 	&flashloader_device,
 	&google_device,
+	&libtransistor_device,
 	&vivopay_device,
 	&moto_modem_device,
 	&motorola_tetra_device,
@@ -129,6 +135,7 @@ static const struct usb_device_id id_tab
 	FUNSOFT_IDS(),
 	FLASHLOADER_IDS(),
 	GOOGLE_IDS(),
+	LIBTRANSISTOR_IDS(),
 	VIVOPAY_IDS(),
 	MOTO_IDS(),
 	MOTOROLA_TETRA_IDS(),
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/serial/visor.c linux-libre-4.1.52-gnu/drivers/usb/serial/visor.c
--- linux-libre-4.1.51-gnu/drivers/usb/serial/visor.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/serial/visor.c	2018-05-27 22:26:45.000000000 -0400
@@ -338,47 +338,48 @@ static int palm_os_3_probe(struct usb_se
 		goto exit;
 	}
 
-	if (retval == sizeof(*connection_info)) {
-			connection_info = (struct visor_connection_info *)
-							transfer_buffer;
-
-		num_ports = le16_to_cpu(connection_info->num_ports);
-		for (i = 0; i < num_ports; ++i) {
-			switch (
-			   connection_info->connections[i].port_function_id) {
-			case VISOR_FUNCTION_GENERIC:
-				string = "Generic";
-				break;
-			case VISOR_FUNCTION_DEBUGGER:
-				string = "Debugger";
-				break;
-			case VISOR_FUNCTION_HOTSYNC:
-				string = "HotSync";
-				break;
-			case VISOR_FUNCTION_CONSOLE:
-				string = "Console";
-				break;
-			case VISOR_FUNCTION_REMOTE_FILE_SYS:
-				string = "Remote File System";
-				break;
-			default:
-				string = "unknown";
-				break;
-			}
-			dev_info(dev, "%s: port %d, is for %s use\n",
-				serial->type->description,
-				connection_info->connections[i].port, string);
-		}
+	if (retval != sizeof(*connection_info)) {
+		dev_err(dev, "Invalid connection information received from device\n");
+		retval = -ENODEV;
+		goto exit;
 	}
-	/*
-	* Handle devices that report invalid stuff here.
-	*/
+
+	connection_info = (struct visor_connection_info *)transfer_buffer;
+
+	num_ports = le16_to_cpu(connection_info->num_ports);
+
+	/* Handle devices that report invalid stuff here. */
 	if (num_ports == 0 || num_ports > 2) {
 		dev_warn(dev, "%s: No valid connect info available\n",
 			serial->type->description);
 		num_ports = 2;
 	}
 
+	for (i = 0; i < num_ports; ++i) {
+		switch (connection_info->connections[i].port_function_id) {
+		case VISOR_FUNCTION_GENERIC:
+			string = "Generic";
+			break;
+		case VISOR_FUNCTION_DEBUGGER:
+			string = "Debugger";
+			break;
+		case VISOR_FUNCTION_HOTSYNC:
+			string = "HotSync";
+			break;
+		case VISOR_FUNCTION_CONSOLE:
+			string = "Console";
+			break;
+		case VISOR_FUNCTION_REMOTE_FILE_SYS:
+			string = "Remote File System";
+			break;
+		default:
+			string = "unknown";
+			break;
+		}
+		dev_info(dev, "%s: port %d, is for %s use\n",
+			serial->type->description,
+			connection_info->connections[i].port, string);
+	}
 	dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
 		num_ports);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/storage/ene_ub6250.c linux-libre-4.1.52-gnu/drivers/usb/storage/ene_ub6250.c
--- linux-libre-4.1.51-gnu/drivers/usb/storage/ene_ub6250.c	2018-03-28 09:59:45.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/storage/ene_ub6250.c	2018-05-29 04:46:41.000000000 -0400
@@ -1945,6 +1945,8 @@ static int ene_load_bincode(struct us_da
 	bcb->CDB[0] = 0xEF;
 
 	result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
+	if (us->srb != NULL)
+		scsi_set_resid(us->srb, 0);
 	info->BIN_FLAG = flag;
 	kfree(buf);
 
@@ -2298,21 +2300,22 @@ static int ms_scsi_irp(struct us_data *u
 
 static int ene_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-	int result = 0;
+	int result = USB_STOR_XFER_GOOD;
 	struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
 
 	/*US_DEBUG(usb_stor_show_command(us, srb)); */
 	scsi_set_resid(srb, 0);
-	if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) {
+	if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready)))
 		result = ene_init(us);
-	} else {
+	if (result == USB_STOR_XFER_GOOD) {
+		result = USB_STOR_TRANSPORT_ERROR;
 		if (info->SD_Status.Ready)
 			result = sd_scsi_irp(us, srb);
 
 		if (info->MS_Status.Ready)
 			result = ms_scsi_irp(us, srb);
 	}
-	return 0;
+	return result;
 }
 
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/usbip/stub_main.c linux-libre-4.1.52-gnu/drivers/usb/usbip/stub_main.c
--- linux-libre-4.1.51-gnu/drivers/usb/usbip/stub_main.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/usbip/stub_main.c	2018-05-27 22:26:45.000000000 -0400
@@ -201,7 +201,12 @@ static ssize_t rebind_store(struct devic
 	if (!bid)
 		return -ENODEV;
 
+	/* device_attach() callers should hold parent lock for USB */
+	if (bid->udev->dev.parent)
+		device_lock(bid->udev->dev.parent);
 	ret = device_attach(&bid->udev->dev);
+	if (bid->udev->dev.parent)
+		device_unlock(bid->udev->dev.parent);
 	if (ret < 0) {
 		dev_err(&bid->udev->dev, "rebind failed\n");
 		return ret;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/usb/usbip/usbip_common.h linux-libre-4.1.52-gnu/drivers/usb/usbip/usbip_common.h
--- linux-libre-4.1.51-gnu/drivers/usb/usbip/usbip_common.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/usb/usbip/usbip_common.h	2018-05-27 22:26:45.000000000 -0400
@@ -248,7 +248,7 @@ enum usbip_side {
 #define	SDEV_EVENT_ERROR_SUBMIT	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	SDEV_EVENT_ERROR_MALLOC	(USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 
-#define	VDEV_EVENT_REMOVED	(USBIP_EH_SHUTDOWN | USBIP_EH_BYE)
+#define	VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
 #define	VDEV_EVENT_DOWN		(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	VDEV_EVENT_ERROR_TCP	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	VDEV_EVENT_ERROR_MALLOC	(USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/vfio/pci/vfio_pci_config.c linux-libre-4.1.52-gnu/drivers/vfio/pci/vfio_pci_config.c
--- linux-libre-4.1.51-gnu/drivers/vfio/pci/vfio_pci_config.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/vfio/pci/vfio_pci_config.c	2018-05-27 22:26:45.000000000 -0400
@@ -685,6 +685,62 @@ static int __init init_pci_cap_pcix_perm
 	return 0;
 }
 
+static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos,
+				 int count, struct perm_bits *perm,
+				 int offset, __le32 val)
+{
+	__le16 *ctrl = (__le16 *)(vdev->vconfig + pos -
+				  offset + PCI_EXP_DEVCTL);
+	int readrq = le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ;
+
+	count = vfio_default_config_write(vdev, pos, count, perm, offset, val);
+	if (count < 0)
+		return count;
+
+	/*
+	 * The FLR bit is virtualized, if set and the device supports PCIe
+	 * FLR, issue a reset_function.  Regardless, clear the bit, the spec
+	 * requires it to be always read as zero.  NB, reset_function might
+	 * not use a PCIe FLR, we don't have that level of granularity.
+	 */
+	if (*ctrl & cpu_to_le16(PCI_EXP_DEVCTL_BCR_FLR)) {
+		u32 cap;
+		int ret;
+
+		*ctrl &= ~cpu_to_le16(PCI_EXP_DEVCTL_BCR_FLR);
+
+		ret = pci_user_read_config_dword(vdev->pdev,
+						 pos - offset + PCI_EXP_DEVCAP,
+						 &cap);
+
+		if (!ret && (cap & PCI_EXP_DEVCAP_FLR))
+			pci_try_reset_function(vdev->pdev);
+	}
+
+	/*
+	 * MPS is virtualized to the user, writes do not change the physical
+	 * register since determining a proper MPS value requires a system wide
+	 * device view.  The MRRS is largely independent of MPS, but since the
+	 * user does not have that system-wide view, they might set a safe, but
+	 * inefficiently low value.  Here we allow writes through to hardware,
+	 * but we set the floor to the physical device MPS setting, so that
+	 * we can at least use full TLPs, as defined by the MPS value.
+	 *
+	 * NB, if any devices actually depend on an artificially low MRRS
+	 * setting, this will need to be revisited, perhaps with a quirk
+	 * though pcie_set_readrq().
+	 */
+	if (readrq != (le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ)) {
+		readrq = 128 <<
+			((le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ) >> 12);
+		readrq = max(readrq, pcie_get_mps(vdev->pdev));
+
+		pcie_set_readrq(vdev->pdev, readrq);
+	}
+
+	return count;
+}
+
 /* Permissions for PCI Express capability */
 static int __init init_pci_cap_exp_perm(struct perm_bits *perm)
 {
@@ -692,26 +748,67 @@ static int __init init_pci_cap_exp_perm(
 	if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2))
 		return -ENOMEM;
 
+	perm->writefn = vfio_exp_config_write;
+
 	p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE);
 
 	/*
-	 * Allow writes to device control fields (includes FLR!)
-	 * but not to devctl_phantom which could confuse IOMMU
-	 * or to the ARI bit in devctl2 which is set at probe time
+	 * Allow writes to device control fields, except devctl_phantom,
+	 * which could confuse IOMMU, MPS, which can break communication
+	 * with other physical devices, and the ARI bit in devctl2, which
+	 * is set at probe time.  FLR and MRRS get virtualized via our
+	 * writefn.
 	 */
-	p_setw(perm, PCI_EXP_DEVCTL, NO_VIRT, ~PCI_EXP_DEVCTL_PHANTOM);
+	p_setw(perm, PCI_EXP_DEVCTL,
+	       PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_PAYLOAD |
+	       PCI_EXP_DEVCTL_READRQ, ~PCI_EXP_DEVCTL_PHANTOM);
 	p_setw(perm, PCI_EXP_DEVCTL2, NO_VIRT, ~PCI_EXP_DEVCTL2_ARI);
 	return 0;
 }
 
+static int vfio_af_config_write(struct vfio_pci_device *vdev, int pos,
+				int count, struct perm_bits *perm,
+				int offset, __le32 val)
+{
+	u8 *ctrl = vdev->vconfig + pos - offset + PCI_AF_CTRL;
+
+	count = vfio_default_config_write(vdev, pos, count, perm, offset, val);
+	if (count < 0)
+		return count;
+
+	/*
+	 * The FLR bit is virtualized, if set and the device supports AF
+	 * FLR, issue a reset_function.  Regardless, clear the bit, the spec
+	 * requires it to be always read as zero.  NB, reset_function might
+	 * not use an AF FLR, we don't have that level of granularity.
+	 */
+	if (*ctrl & PCI_AF_CTRL_FLR) {
+		u8 cap;
+		int ret;
+
+		*ctrl &= ~PCI_AF_CTRL_FLR;
+
+		ret = pci_user_read_config_byte(vdev->pdev,
+						pos - offset + PCI_AF_CAP,
+						&cap);
+
+		if (!ret && (cap & PCI_AF_CAP_FLR) && (cap & PCI_AF_CAP_TP))
+			pci_try_reset_function(vdev->pdev);
+	}
+
+	return count;
+}
+
 /* Permissions for Advanced Function capability */
 static int __init init_pci_cap_af_perm(struct perm_bits *perm)
 {
 	if (alloc_perm_bits(perm, pci_cap_length[PCI_CAP_ID_AF]))
 		return -ENOMEM;
 
+	perm->writefn = vfio_af_config_write;
+
 	p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE);
-	p_setb(perm, PCI_AF_CTRL, NO_VIRT, PCI_AF_CTRL_FLR);
+	p_setb(perm, PCI_AF_CTRL, PCI_AF_CTRL_FLR, PCI_AF_CTRL_FLR);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/vhost/vhost.c linux-libre-4.1.52-gnu/drivers/vhost/vhost.c
--- linux-libre-4.1.51-gnu/drivers/vhost/vhost.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/vhost/vhost.c	2018-05-27 22:26:45.000000000 -0400
@@ -96,8 +96,7 @@ int vhost_poll_start(struct vhost_poll *
 	if (mask)
 		vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
 	if (mask & POLLERR) {
-		if (poll->wqh)
-			remove_wait_queue(poll->wqh, &poll->wait);
+		vhost_poll_stop(poll);
 		ret = -EINVAL;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/video/console/vgacon.c linux-libre-4.1.52-gnu/drivers/video/console/vgacon.c
--- linux-libre-4.1.51-gnu/drivers/video/console/vgacon.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/video/console/vgacon.c	2018-05-27 22:26:45.000000000 -0400
@@ -409,7 +409,10 @@ static const char *vgacon_startup(void)
 		vga_video_port_val = VGA_CRT_DM;
 		if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
 			static struct resource ega_console_resource =
-			    { .name = "ega", .start = 0x3B0, .end = 0x3BF };
+			    { .name	= "ega",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3B0,
+			      .end	= 0x3BF };
 			vga_video_type = VIDEO_TYPE_EGAM;
 			vga_vram_size = 0x8000;
 			display_desc = "EGA+";
@@ -417,9 +420,15 @@ static const char *vgacon_startup(void)
 					 &ega_console_resource);
 		} else {
 			static struct resource mda1_console_resource =
-			    { .name = "mda", .start = 0x3B0, .end = 0x3BB };
+			    { .name	= "mda",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3B0,
+			      .end	= 0x3BB };
 			static struct resource mda2_console_resource =
-			    { .name = "mda", .start = 0x3BF, .end = 0x3BF };
+			    { .name	= "mda",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3BF,
+			      .end	= 0x3BF };
 			vga_video_type = VIDEO_TYPE_MDA;
 			vga_vram_size = 0x2000;
 			display_desc = "*MDA";
@@ -441,15 +450,21 @@ static const char *vgacon_startup(void)
 			vga_vram_size = 0x8000;
 
 			if (!screen_info.orig_video_isVGA) {
-				static struct resource ega_console_resource
-				    = { .name = "ega", .start = 0x3C0, .end = 0x3DF };
+				static struct resource ega_console_resource =
+				    { .name	= "ega",
+				      .flags	= IORESOURCE_IO,
+				      .start	= 0x3C0,
+				      .end	= 0x3DF };
 				vga_video_type = VIDEO_TYPE_EGAC;
 				display_desc = "EGA";
 				request_resource(&ioport_resource,
 						 &ega_console_resource);
 			} else {
-				static struct resource vga_console_resource
-				    = { .name = "vga+", .start = 0x3C0, .end = 0x3DF };
+				static struct resource vga_console_resource =
+				    { .name	= "vga+",
+				      .flags	= IORESOURCE_IO,
+				      .start	= 0x3C0,
+				      .end	= 0x3DF };
 				vga_video_type = VIDEO_TYPE_VGAC;
 				display_desc = "VGA+";
 				request_resource(&ioport_resource,
@@ -493,7 +508,10 @@ static const char *vgacon_startup(void)
 			}
 		} else {
 			static struct resource cga_console_resource =
-			    { .name = "cga", .start = 0x3D4, .end = 0x3D5 };
+			    { .name	= "cga",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3D4,
+			      .end	= 0x3D5 };
 			vga_video_type = VIDEO_TYPE_CGA;
 			vga_vram_size = 0x2000;
 			display_desc = "*CGA";
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/video/fbdev/amba-clcd.c linux-libre-4.1.52-gnu/drivers/video/fbdev/amba-clcd.c
--- linux-libre-4.1.51-gnu/drivers/video/fbdev/amba-clcd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/video/fbdev/amba-clcd.c	2018-05-27 22:26:45.000000000 -0400
@@ -759,8 +759,8 @@ static int clcdfb_of_dma_setup(struct cl
 	if (err)
 		return err;
 
-	framesize = fb->panel->mode.xres * fb->panel->mode.yres *
-			fb->panel->bpp / 8;
+	framesize = PAGE_ALIGN(fb->panel->mode.xres * fb->panel->mode.yres *
+			fb->panel->bpp / 8);
 	fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
 			&dma, GFP_KERNEL);
 	if (!fb->fb.screen_base)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/video/fbdev/sm501fb.c linux-libre-4.1.52-gnu/drivers/video/fbdev/sm501fb.c
--- linux-libre-4.1.51-gnu/drivers/video/fbdev/sm501fb.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/video/fbdev/sm501fb.c	2018-05-27 22:26:45.000000000 -0400
@@ -1600,6 +1600,7 @@ static int sm501fb_start(struct sm501fb_
 	info->fbmem = ioremap(res->start, resource_size(res));
 	if (info->fbmem == NULL) {
 		dev_err(dev, "cannot remap framebuffer\n");
+		ret = -ENXIO;
 		goto err_mem_res;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/video/fbdev/udlfb.c linux-libre-4.1.52-gnu/drivers/video/fbdev/udlfb.c
--- linux-libre-4.1.51-gnu/drivers/video/fbdev/udlfb.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/video/fbdev/udlfb.c	2018-05-27 22:26:45.000000000 -0400
@@ -1487,15 +1487,25 @@ static struct device_attribute fb_device
 static int dlfb_select_std_channel(struct dlfb_data *dev)
 {
 	int ret;
-	u8 set_def_chn[] = {	   0x57, 0xCD, 0xDC, 0xA7,
+	void *buf;
+	static const u8 set_def_chn[] = {
+				0x57, 0xCD, 0xDC, 0xA7,
 				0x1C, 0x88, 0x5E, 0x15,
 				0x60, 0xFE, 0xC6, 0x97,
 				0x16, 0x3D, 0x47, 0xF2  };
 
+	buf = kmemdup(set_def_chn, sizeof(set_def_chn), GFP_KERNEL);
+
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
 			NR_USB_REQUEST_CHANNEL,
 			(USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
-			set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
+			buf, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
+
+	kfree(buf);
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/video/fbdev/vfb.c linux-libre-4.1.52-gnu/drivers/video/fbdev/vfb.c
--- linux-libre-4.1.51-gnu/drivers/video/fbdev/vfb.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/video/fbdev/vfb.c	2018-05-27 22:26:45.000000000 -0400
@@ -284,8 +284,23 @@ static int vfb_check_var(struct fb_var_s
  */
 static int vfb_set_par(struct fb_info *info)
 {
+	switch (info->var.bits_per_pixel) {
+	case 1:
+		info->fix.visual = FB_VISUAL_MONO01;
+		break;
+	case 8:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+	case 16:
+	case 24:
+	case 32:
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
+	}
+
 	info->fix.line_length = get_line_length(info->var.xres_virtual,
 						info->var.bits_per_pixel);
+
 	return 0;
 }
 
@@ -526,6 +541,8 @@ static int vfb_probe(struct platform_dev
 		goto err2;
 	platform_set_drvdata(dev, info);
 
+	vfb_set_par(info);
+
 	fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n",
 		videomemorysize >> 10);
 	return 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/video/hdmi.c linux-libre-4.1.52-gnu/drivers/video/hdmi.c
--- linux-libre-4.1.51-gnu/drivers/video/hdmi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/video/hdmi.c	2018-05-27 22:26:45.000000000 -0400
@@ -321,6 +321,17 @@ int hdmi_vendor_infoframe_init(struct hd
 }
 EXPORT_SYMBOL(hdmi_vendor_infoframe_init);
 
+static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame)
+{
+	/* for side by side (half) we also need to provide 3D_Ext_Data */
+	if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
+		return 6;
+	else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
+		return 5;
+	else
+		return 4;
+}
+
 /**
  * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer
  * @frame: HDMI infoframe
@@ -341,19 +352,11 @@ ssize_t hdmi_vendor_infoframe_pack(struc
 	u8 *ptr = buffer;
 	size_t length;
 
-	/* empty info frame */
-	if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID)
-		return -EINVAL;
-
 	/* only one of those can be supplied */
 	if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
 		return -EINVAL;
 
-	/* for side by side (half) we also need to provide 3D_Ext_Data */
-	if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
-		frame->length = 6;
-	else
-		frame->length = 5;
+	frame->length = hdmi_vendor_infoframe_length(frame);
 
 	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
 
@@ -372,14 +375,16 @@ ssize_t hdmi_vendor_infoframe_pack(struc
 	ptr[5] = 0x0c;
 	ptr[6] = 0x00;
 
-	if (frame->vic) {
-		ptr[7] = 0x1 << 5;	/* video format */
-		ptr[8] = frame->vic;
-	} else {
+	if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
 		ptr[7] = 0x2 << 5;	/* video format */
 		ptr[8] = (frame->s3d_struct & 0xf) << 4;
 		if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
 			ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
+	} else if (frame->vic) {
+		ptr[7] = 0x1 << 5;	/* video format */
+		ptr[8] = frame->vic;
+	} else {
+		ptr[7] = 0x0 << 5;	/* video format */
 	}
 
 	hdmi_infoframe_set_checksum(buffer, length);
@@ -1161,7 +1166,7 @@ hdmi_vendor_any_infoframe_unpack(union h
 
 	if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
 	    ptr[1] != 1 ||
-	    (ptr[2] != 5 && ptr[2] != 6))
+	    (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
 		return -EINVAL;
 
 	length = ptr[2];
@@ -1189,16 +1194,22 @@ hdmi_vendor_any_infoframe_unpack(union h
 
 	hvf->length = length;
 
-	if (hdmi_video_format == 0x1) {
-		hvf->vic = ptr[4];
-	} else if (hdmi_video_format == 0x2) {
+	if (hdmi_video_format == 0x2) {
+		if (length != 5 && length != 6)
+			return -EINVAL;
 		hvf->s3d_struct = ptr[4] >> 4;
 		if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) {
-			if (length == 6)
-				hvf->s3d_ext_data = ptr[5] >> 4;
-			else
+			if (length != 6)
 				return -EINVAL;
+			hvf->s3d_ext_data = ptr[5] >> 4;
 		}
+	} else if (hdmi_video_format == 0x1) {
+		if (length != 5)
+			return -EINVAL;
+		hvf->vic = ptr[4];
+	} else {
+		if (length != 4)
+			return -EINVAL;
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/drivers/watchdog/f71808e_wdt.c linux-libre-4.1.52-gnu/drivers/watchdog/f71808e_wdt.c
--- linux-libre-4.1.51-gnu/drivers/watchdog/f71808e_wdt.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/drivers/watchdog/f71808e_wdt.c	2018-05-27 22:26:45.000000000 -0400
@@ -450,7 +450,7 @@ static bool watchdog_is_running(void)
 
 	is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
 		&& (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF)
-			& F71808FG_FLAG_WD_EN);
+			& BIT(F71808FG_FLAG_WD_EN));
 
 	superio_exit(watchdog.sioaddr);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/aio.c linux-libre-4.1.52-gnu/fs/aio.c
--- linux-libre-4.1.51-gnu/fs/aio.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/aio.c	2018-05-27 22:26:45.000000000 -0400
@@ -68,9 +68,9 @@ struct aio_ring {
 #define AIO_RING_PAGES	8
 
 struct kioctx_table {
-	struct rcu_head	rcu;
-	unsigned	nr;
-	struct kioctx	*table[];
+	struct rcu_head		rcu;
+	unsigned		nr;
+	struct kioctx __rcu	*table[];
 };
 
 struct kioctx_cpu {
@@ -115,7 +115,8 @@ struct kioctx {
 	struct page		**ring_pages;
 	long			nr_pages;
 
-	struct work_struct	free_work;
+	struct rcu_head		free_rcu;
+	struct work_struct	free_work;	/* see free_ioctx() */
 
 	/*
 	 * signals when all in-flight requests are done
@@ -327,7 +328,7 @@ static int aio_ring_remap(struct file *f
 	for (i = 0; i < table->nr; i++) {
 		struct kioctx *ctx;
 
-		ctx = table->table[i];
+		ctx = rcu_dereference(table->table[i]);
 		if (ctx && ctx->aio_ring_file == file) {
 			if (!atomic_read(&ctx->dead)) {
 				ctx->user_id = ctx->mmap_base = vma->vm_start;
@@ -559,6 +560,12 @@ static int kiocb_cancel(struct aio_kiocb
 	return cancel(&kiocb->common);
 }
 
+/*
+ * free_ioctx() should be RCU delayed to synchronize against the RCU
+ * protected lookup_ioctx() and also needs process context to call
+ * aio_free_ring(), so the double bouncing through kioctx->free_rcu and
+ * ->free_work.
+ */
 static void free_ioctx(struct work_struct *work)
 {
 	struct kioctx *ctx = container_of(work, struct kioctx, free_work);
@@ -572,6 +579,14 @@ static void free_ioctx(struct work_struc
 	kmem_cache_free(kioctx_cachep, ctx);
 }
 
+static void free_ioctx_rcufn(struct rcu_head *head)
+{
+	struct kioctx *ctx = container_of(head, struct kioctx, free_rcu);
+
+	INIT_WORK(&ctx->free_work, free_ioctx);
+	schedule_work(&ctx->free_work);
+}
+
 static void free_ioctx_reqs(struct percpu_ref *ref)
 {
 	struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
@@ -580,8 +595,8 @@ static void free_ioctx_reqs(struct percp
 	if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count))
 		complete(&ctx->rq_wait->comp);
 
-	INIT_WORK(&ctx->free_work, free_ioctx);
-	schedule_work(&ctx->free_work);
+	/* Synchronize against RCU protected table->table[] dereferences */
+	call_rcu(&ctx->free_rcu, free_ioctx_rcufn);
 }
 
 /*
@@ -622,9 +637,9 @@ static int ioctx_add_table(struct kioctx
 	while (1) {
 		if (table)
 			for (i = 0; i < table->nr; i++)
-				if (!table->table[i]) {
+				if (!rcu_access_pointer(table->table[i])) {
 					ctx->id = i;
-					table->table[i] = ctx;
+					rcu_assign_pointer(table->table[i], ctx);
 					spin_unlock(&mm->ioctx_lock);
 
 					/* While kioctx setup is in progress,
@@ -799,11 +814,11 @@ static int kill_ioctx(struct mm_struct *
 	}
 
 	table = rcu_dereference_raw(mm->ioctx_table);
-	WARN_ON(ctx != table->table[ctx->id]);
-	table->table[ctx->id] = NULL;
+	WARN_ON(ctx != rcu_access_pointer(table->table[ctx->id]));
+	RCU_INIT_POINTER(table->table[ctx->id], NULL);
 	spin_unlock(&mm->ioctx_lock);
 
-	/* percpu_ref_kill() will do the necessary call_rcu() */
+	/* free_ioctx_reqs() will do the necessary RCU synchronization */
 	wake_up_all(&ctx->wait);
 
 	/*
@@ -845,7 +860,8 @@ void exit_aio(struct mm_struct *mm)
 
 	skipped = 0;
 	for (i = 0; i < table->nr; ++i) {
-		struct kioctx *ctx = table->table[i];
+		struct kioctx *ctx =
+			rcu_dereference_protected(table->table[i], true);
 
 		if (!ctx) {
 			skipped++;
@@ -1034,7 +1050,7 @@ static struct kioctx *lookup_ioctx(unsig
 	if (!table || id >= table->nr)
 		goto out;
 
-	ctx = table->table[id];
+	ctx = rcu_dereference(table->table[id]);
 	if (ctx && ctx->user_id == ctx_id) {
 		percpu_ref_get(&ctx->users);
 		ret = ctx;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/autofs4/root.c linux-libre-4.1.52-gnu/fs/autofs4/root.c
--- linux-libre-4.1.51-gnu/fs/autofs4/root.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/autofs4/root.c	2018-05-27 22:26:45.000000000 -0400
@@ -746,7 +746,7 @@ static int autofs4_dir_mkdir(struct inod
 
 	autofs4_del_active(dentry);
 
-	inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555);
+	inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode);
 	if (!inode)
 		return -ENOMEM;
 	d_add(dentry, inode);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/btrfs/extent_io.c linux-libre-4.1.52-gnu/fs/btrfs/extent_io.c
--- linux-libre-4.1.51-gnu/fs/btrfs/extent_io.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/btrfs/extent_io.c	2018-05-27 22:26:45.000000000 -0400
@@ -2466,7 +2466,7 @@ int end_extent_writepage(struct page *pa
 	if (!uptodate) {
 		ClearPageUptodate(page);
 		SetPageError(page);
-		ret = ret < 0 ? ret : -EIO;
+		ret = err < 0 ? err : -EIO;
 		mapping_set_error(page->mapping, ret);
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/btrfs/send.c linux-libre-4.1.52-gnu/fs/btrfs/send.c
--- linux-libre-4.1.51-gnu/fs/btrfs/send.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/btrfs/send.c	2018-05-27 22:26:45.000000000 -0400
@@ -4759,13 +4759,19 @@ static int is_extent_unchanged(struct se
 	while (key.offset < ekey->offset + left_len) {
 		ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
 		right_type = btrfs_file_extent_type(eb, ei);
-		if (right_type != BTRFS_FILE_EXTENT_REG) {
+		if (right_type != BTRFS_FILE_EXTENT_REG &&
+		    right_type != BTRFS_FILE_EXTENT_INLINE) {
 			ret = 0;
 			goto out;
 		}
 
 		right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
-		right_len = btrfs_file_extent_num_bytes(eb, ei);
+		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
+			right_len = btrfs_file_extent_inline_len(eb, slot, ei);
+			right_len = PAGE_ALIGN(right_len);
+		} else {
+			right_len = btrfs_file_extent_num_bytes(eb, ei);
+		}
 		right_offset = btrfs_file_extent_offset(eb, ei);
 		right_gen = btrfs_file_extent_generation(eb, ei);
 
@@ -4779,6 +4785,19 @@ static int is_extent_unchanged(struct se
 			goto out;
 		}
 
+		/*
+		 * We just wanted to see if when we have an inline extent, what
+		 * follows it is a regular extent (wanted to check the above
+		 * condition for inline extents too). This should normally not
+		 * happen but it's possible for example when we have an inline
+		 * compressed extent representing data with a size matching
+		 * the page size (currently the same as sector size).
+		 */
+		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
+			ret = 0;
+			goto out;
+		}
+
 		left_offset_fixed = left_offset;
 		if (key.offset < ekey->offset) {
 			/* Fix the right offset for 2a and 7. */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/btrfs/volumes.c linux-libre-4.1.52-gnu/fs/btrfs/volumes.c
--- linux-libre-4.1.51-gnu/fs/btrfs/volumes.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/btrfs/volumes.c	2018-05-27 22:26:45.000000000 -0400
@@ -4370,10 +4370,13 @@ static int __btrfs_alloc_chunk(struct bt
 	if (devs_max && ndevs > devs_max)
 		ndevs = devs_max;
 	/*
-	 * the primary goal is to maximize the number of stripes, so use as many
-	 * devices as possible, even if the stripes are not maximum sized.
+	 * The primary goal is to maximize the number of stripes, so use as
+	 * many devices as possible, even if the stripes are not maximum sized.
+	 *
+	 * The DUP profile stores more than one stripe per device, the
+	 * max_avail is the total size so we have to adjust.
 	 */
-	stripe_size = devices_info[ndevs-1].max_avail;
+	stripe_size = div_u64(devices_info[ndevs - 1].max_avail, dev_stripes);
 	num_stripes = ndevs * dev_stripes;
 
 	/*
@@ -4413,8 +4416,6 @@ static int __btrfs_alloc_chunk(struct bt
 			stripe_size = devices_info[ndevs-1].max_avail;
 	}
 
-	stripe_size = div_u64(stripe_size, dev_stripes);
-
 	/* align to BTRFS_STRIPE_LEN */
 	stripe_size = div_u64(stripe_size, raid_stripe_len);
 	stripe_size *= raid_stripe_len;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/cifs/dir.c linux-libre-4.1.52-gnu/fs/cifs/dir.c
--- linux-libre-4.1.51-gnu/fs/cifs/dir.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/cifs/dir.c	2018-05-27 22:26:45.000000000 -0400
@@ -673,6 +673,9 @@ int cifs_mknod(struct inode *inode, stru
 		goto mknod_out;
 	}
 
+	if (!S_ISCHR(mode) && !S_ISBLK(mode))
+		goto mknod_out;
+
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
 		goto mknod_out;
 
@@ -681,10 +684,8 @@ int cifs_mknod(struct inode *inode, stru
 
 	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
 	if (buf == NULL) {
-		kfree(full_path);
 		rc = -ENOMEM;
-		free_xid(xid);
-		return rc;
+		goto mknod_out;
 	}
 
 	if (backup_cred(cifs_sb))
@@ -731,7 +732,7 @@ int cifs_mknod(struct inode *inode, stru
 		pdev->minor = cpu_to_le64(MINOR(device_number));
 		rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
 							&bytes_written, iov, 1);
-	} /* else if (S_ISFIFO) */
+	}
 	tcon->ses->server->ops->close(xid, tcon, &fid);
 	d_drop(direntry);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/cifs/file.c linux-libre-4.1.52-gnu/fs/cifs/file.c
--- linux-libre-4.1.51-gnu/fs/cifs/file.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/cifs/file.c	2018-05-27 22:26:45.000000000 -0400
@@ -582,7 +582,7 @@ cifs_relock_file(struct cifsFileInfo *cf
 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 	int rc = 0;
 
-	down_read(&cinode->lock_sem);
+	down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING);
 	if (cinode->can_cache_brlcks) {
 		/* can cache locks - no need to relock */
 		up_read(&cinode->lock_sem);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/cifs/netmisc.c linux-libre-4.1.52-gnu/fs/cifs/netmisc.c
--- linux-libre-4.1.51-gnu/fs/cifs/netmisc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/cifs/netmisc.c	2018-05-27 22:26:45.000000000 -0400
@@ -980,10 +980,10 @@ struct timespec cnvrtDosUnixTm(__le16 le
 		cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
 	days = sd->Day;
 	month = sd->Month;
-	if ((days > 31) || (month > 12)) {
+	if (days < 1 || days > 31 || month < 1 || month > 12) {
 		cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days);
-		if (month > 12)
-			month = 12;
+		days = clamp(days, 1, 31);
+		month = clamp(month, 1, 12);
 	}
 	month -= 1;
 	days += total_days_of_prev_months[month];
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/cifs/sess.c linux-libre-4.1.52-gnu/fs/cifs/sess.c
--- linux-libre-4.1.51-gnu/fs/cifs/sess.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/cifs/sess.c	2018-05-27 22:26:45.000000000 -0400
@@ -344,13 +344,12 @@ void build_ntlmssp_negotiate_blob(unsign
 	/* BB is NTLMV2 session security format easier to use here? */
 	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |
 		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
-	if (ses->server->sign) {
+		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
+		NTLMSSP_NEGOTIATE_SEAL;
+	if (ses->server->sign)
 		flags |= NTLMSSP_NEGOTIATE_SIGN;
-		if (!ses->server->session_estab ||
-				ses->ntlmssp->sesskey_per_smbsess)
-			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
-	}
+	if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
+		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 
 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
 
@@ -407,13 +406,12 @@ int build_ntlmssp_auth_blob(unsigned cha
 	flags = NTLMSSP_NEGOTIATE_56 |
 		NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
 		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
-	if (ses->server->sign) {
+		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
+		NTLMSSP_NEGOTIATE_SEAL;
+	if (ses->server->sign)
 		flags |= NTLMSSP_NEGOTIATE_SIGN;
-		if (!ses->server->session_estab ||
-				ses->ntlmssp->sesskey_per_smbsess)
-			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
-	}
+	if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
+		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 
 	tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/cifs/smb2pdu.c linux-libre-4.1.52-gnu/fs/cifs/smb2pdu.c
--- linux-libre-4.1.51-gnu/fs/cifs/smb2pdu.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/cifs/smb2pdu.c	2018-05-27 22:26:45.000000000 -0400
@@ -754,10 +754,8 @@ ssetup_exit:
 
 	if (!rc) {
 		mutex_lock(&server->srv_mutex);
-		if (server->sign && server->ops->generate_signingkey) {
+		if (server->ops->generate_signingkey) {
 			rc = server->ops->generate_signingkey(ses);
-			kfree(ses->auth_key.response);
-			ses->auth_key.response = NULL;
 			if (rc) {
 				cifs_dbg(FYI,
 					"SMB3 session key generation failed\n");
@@ -779,10 +777,6 @@ ssetup_exit:
 	}
 
 keygen_exit:
-	if (!server->sign) {
-		kfree(ses->auth_key.response);
-		ses->auth_key.response = NULL;
-	}
 	if (spnego_key) {
 		key_invalidate(spnego_key);
 		key_put(spnego_key);
@@ -921,15 +915,19 @@ SMB2_tcon(const unsigned int xid, struct
 		goto tcon_exit;
 	}
 
-	if (rsp->ShareType & SMB2_SHARE_TYPE_DISK)
+	switch (rsp->ShareType) {
+	case SMB2_SHARE_TYPE_DISK:
 		cifs_dbg(FYI, "connection to disk share\n");
-	else if (rsp->ShareType & SMB2_SHARE_TYPE_PIPE) {
+		break;
+	case SMB2_SHARE_TYPE_PIPE:
 		tcon->ipc = true;
 		cifs_dbg(FYI, "connection to pipe share\n");
-	} else if (rsp->ShareType & SMB2_SHARE_TYPE_PRINT) {
-		tcon->print = true;
+		break;
+	case SMB2_SHARE_TYPE_PRINT:
+		tcon->ipc = true;
 		cifs_dbg(FYI, "connection to printer\n");
-	} else {
+		break;
+	default:
 		cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
 		rc = -EOPNOTSUPP;
 		goto tcon_error_exit;
@@ -1353,6 +1351,9 @@ SMB2_ioctl(const unsigned int xid, struc
 	} else
 		iov[0].iov_len = get_rfc1002_length(req) + 4;
 
+	/* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+	if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+		req->hdr.Flags |= SMB2_FLAGS_SIGNED;
 
 	rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
 	rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/compat_ioctl.c linux-libre-4.1.52-gnu/fs/compat_ioctl.c
--- linux-libre-4.1.51-gnu/fs/compat_ioctl.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/compat_ioctl.c	2018-05-27 22:26:45.000000000 -0400
@@ -811,7 +811,7 @@ static int compat_ioctl_preallocate(stru
  */
 #define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff)
 
-#define COMPATIBLE_IOCTL(cmd) XFORM(cmd),
+#define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd),
 /* ioctl should not be warned about even if it's not implemented.
    Valid reasons to use this:
    - It is implemented with ->compat_ioctl on some device, but programs
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/dcache.c linux-libre-4.1.52-gnu/fs/dcache.c
--- linux-libre-4.1.51-gnu/fs/dcache.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/dcache.c	2018-05-27 22:26:45.000000000 -0400
@@ -607,11 +607,16 @@ again:
 		spin_unlock(&parent->d_lock);
 		goto again;
 	}
-	rcu_read_unlock();
-	if (parent != dentry)
+	if (parent != dentry) {
 		spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
-	else
+		if (unlikely(dentry->d_lockref.count < 0)) {
+			spin_unlock(&parent->d_lock);
+			parent = NULL;
+		}
+	} else {
 		parent = NULL;
+	}
+	rcu_read_unlock();
 	return parent;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/ext4/file.c linux-libre-4.1.52-gnu/fs/ext4/file.c
--- linux-libre-4.1.51-gnu/fs/ext4/file.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/ext4/file.c	2018-05-27 22:26:45.000000000 -0400
@@ -351,7 +351,7 @@ static int ext4_find_unwritten_pgoff(str
 		int i, num;
 		unsigned long nr_pages;
 
-		num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
+		num = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
 		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
 					  (pgoff_t)num);
 		if (nr_pages == 0)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/ext4/inode.c linux-libre-4.1.52-gnu/fs/ext4/inode.c
--- linux-libre-4.1.51-gnu/fs/ext4/inode.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/ext4/inode.c	2018-05-27 22:26:45.000000000 -0400
@@ -1476,6 +1476,8 @@ static void mpage_release_unused_pages(s
 			BUG_ON(!PageLocked(page));
 			BUG_ON(PageWriteback(page));
 			if (invalidate) {
+				if (page_mapped(page))
+					clear_page_dirty_for_io(page);
 				block_invalidatepage(page, 0, PAGE_CACHE_SIZE);
 				ClearPageUptodate(page);
 			}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/ext4/super.c linux-libre-4.1.52-gnu/fs/ext4/super.c
--- linux-libre-4.1.51-gnu/fs/ext4/super.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/ext4/super.c	2018-05-27 22:26:45.000000000 -0400
@@ -2126,6 +2126,8 @@ static int ext4_check_descriptors(struct
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 				 "Block bitmap for group %u overlaps "
 				 "superblock", i);
+			if (!(sb->s_flags & MS_RDONLY))
+				return 0;
 		}
 		if (block_bitmap < first_block || block_bitmap > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -2138,6 +2140,8 @@ static int ext4_check_descriptors(struct
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 				 "Inode bitmap for group %u overlaps "
 				 "superblock", i);
+			if (!(sb->s_flags & MS_RDONLY))
+				return 0;
 		}
 		if (inode_bitmap < first_block || inode_bitmap > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -2150,6 +2154,8 @@ static int ext4_check_descriptors(struct
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 				 "Inode table for group %u overlaps "
 				 "superblock", i);
+			if (!(sb->s_flags & MS_RDONLY))
+				return 0;
 		}
 		if (inode_table < first_block ||
 		    inode_table + sbi->s_itb_per_group - 1 > last_block) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/jbd2/journal.c linux-libre-4.1.52-gnu/fs/jbd2/journal.c
--- linux-libre-4.1.51-gnu/fs/jbd2/journal.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/jbd2/journal.c	2018-05-27 22:26:45.000000000 -0400
@@ -275,11 +275,11 @@ loop:
 	goto loop;
 
 end_loop:
-	write_unlock(&journal->j_state_lock);
 	del_timer_sync(&journal->j_commit_timer);
 	journal->j_task = NULL;
 	wake_up(&journal->j_wait_done_commit);
 	jbd_debug(1, "Journal thread exiting.\n");
+	write_unlock(&journal->j_state_lock);
 	return 0;
 }
 
@@ -923,7 +923,7 @@ out:
 }
 
 /*
- * This is a variaon of __jbd2_update_log_tail which checks for validity of
+ * This is a variation of __jbd2_update_log_tail which checks for validity of
  * provided log tail and locks j_checkpoint_mutex. So it is safe against races
  * with other threads updating log tail.
  */
@@ -1399,6 +1399,9 @@ int jbd2_journal_update_sb_log_tail(jour
 	journal_superblock_t *sb = journal->j_superblock;
 	int ret;
 
+	if (is_journal_aborted(journal))
+		return -EIO;
+
 	BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
 	jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n",
 		  tail_block, tail_tid);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/jbd2/transaction.c linux-libre-4.1.52-gnu/fs/jbd2/transaction.c
--- linux-libre-4.1.51-gnu/fs/jbd2/transaction.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/jbd2/transaction.c	2018-05-27 22:26:45.000000000 -0400
@@ -515,6 +515,7 @@ int jbd2_journal_start_reserved(handle_t
 	 */
 	ret = start_this_handle(journal, handle, GFP_NOFS);
 	if (ret < 0) {
+		handle->h_journal = journal;
 		jbd2_journal_free_reserved(handle);
 		return ret;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/jffs2/super.c linux-libre-4.1.52-gnu/fs/jffs2/super.c
--- linux-libre-4.1.51-gnu/fs/jffs2/super.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/jffs2/super.c	2018-05-27 22:26:45.000000000 -0400
@@ -345,7 +345,7 @@ static void jffs2_put_super (struct supe
 static void jffs2_kill_sb(struct super_block *sb)
 {
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-	if (!(sb->s_flags & MS_RDONLY))
+	if (c && !(sb->s_flags & MS_RDONLY))
 		jffs2_stop_garbage_collect_thread(c);
 	kill_mtd_super(sb);
 	kfree(c);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/lockd/svc.c linux-libre-4.1.52-gnu/fs/lockd/svc.c
--- linux-libre-4.1.51-gnu/fs/lockd/svc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/lockd/svc.c	2018-05-27 22:26:45.000000000 -0400
@@ -129,6 +129,8 @@ lockd(void *vrqstp)
 {
 	int		err = 0;
 	struct svc_rqst *rqstp = vrqstp;
+	struct net *net = &init_net;
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
 
 	/* try_to_freeze() is called from svc_recv() */
 	set_freezable();
@@ -173,6 +175,8 @@ lockd(void *vrqstp)
 	if (nlmsvc_ops)
 		nlmsvc_invalidate_all();
 	nlm_shutdown_hosts();
+	cancel_delayed_work_sync(&ln->grace_period_end);
+	locks_end_grace(&ln->lockd_manager);
 	return 0;
 }
 
@@ -267,8 +271,6 @@ static void lockd_down_net(struct svc_se
 	if (ln->nlmsvc_users) {
 		if (--ln->nlmsvc_users == 0) {
 			nlm_shutdown_hosts_net(net);
-			cancel_delayed_work_sync(&ln->grace_period_end);
-			locks_end_grace(&ln->lockd_manager);
 			svc_shutdown_net(serv, net);
 			dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net);
 		}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/namei.c linux-libre-4.1.52-gnu/fs/namei.c
--- linux-libre-4.1.51-gnu/fs/namei.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/namei.c	2018-05-27 22:26:45.000000000 -0400
@@ -219,9 +219,10 @@ getname_kernel(const char * filename)
 	if (len <= EMBEDDED_NAME_MAX) {
 		result->name = (char *)result->iname;
 	} else if (len <= PATH_MAX) {
+		const size_t size = offsetof(struct filename, iname[1]);
 		struct filename *tmp;
 
-		tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+		tmp = kmalloc(size, GFP_KERNEL);
 		if (unlikely(!tmp)) {
 			__putname(result);
 			return ERR_PTR(-ENOMEM);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/namespace.c linux-libre-4.1.52-gnu/fs/namespace.c
--- linux-libre-4.1.51-gnu/fs/namespace.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/namespace.c	2018-05-27 22:26:45.000000000 -0400
@@ -1007,7 +1007,8 @@ static struct mount *clone_mnt(struct mo
 			goto out_free;
 	}
 
-	mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED);
+	mnt->mnt.mnt_flags = old->mnt.mnt_flags;
+	mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
 	/* Don't allow unprivileged users to change mount flags */
 	if (flag & CL_UNPRIVILEGED) {
 		mnt->mnt.mnt_flags |= MNT_LOCK_ATIME;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/ncpfs/ncplib_kernel.c linux-libre-4.1.52-gnu/fs/ncpfs/ncplib_kernel.c
--- linux-libre-4.1.51-gnu/fs/ncpfs/ncplib_kernel.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/ncpfs/ncplib_kernel.c	2018-05-27 22:26:45.000000000 -0400
@@ -980,6 +980,10 @@ ncp_read_kernel(struct ncp_server *serve
 		goto out;
 	}
 	*bytes_read = ncp_reply_be16(server, 0);
+	if (*bytes_read > to_read) {
+		result = -EINVAL;
+		goto out;
+	}
 	source = ncp_reply_data(server, 2 + (offset & 1));
 
 	memcpy(target, source, *bytes_read);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfs/direct.c linux-libre-4.1.52-gnu/fs/nfs/direct.c
--- linux-libre-4.1.51-gnu/fs/nfs/direct.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfs/direct.c	2018-05-27 22:26:45.000000000 -0400
@@ -86,9 +86,9 @@ struct nfs_direct_req {
 	struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX];
 	int			mirror_count;
 
+	loff_t			io_start;	/* Start offset for I/O */
 	ssize_t			count,		/* bytes actually processed */
 				bytes_left,	/* bytes left to be sent */
-				io_start,	/* start of IO */
 				error;		/* any reported error */
 	struct completion	completion;	/* wait for i/o completion */
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfs/flexfilelayout/flexfilelayout.c linux-libre-4.1.52-gnu/fs/nfs/flexfilelayout/flexfilelayout.c
--- linux-libre-4.1.51-gnu/fs/nfs/flexfilelayout/flexfilelayout.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfs/flexfilelayout/flexfilelayout.c	2018-05-27 22:26:45.000000000 -0400
@@ -307,6 +307,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_
 			goto out_err_free;
 
 		/* fh */
+		rc = -EIO;
 		p = xdr_inline_decode(&stream, 4);
 		if (!p)
 			goto out_err_free;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfs/nfs4proc.c linux-libre-4.1.52-gnu/fs/nfs/nfs4proc.c
--- linux-libre-4.1.51-gnu/fs/nfs/nfs4proc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfs/nfs4proc.c	2018-05-27 22:26:45.000000000 -0400
@@ -7531,6 +7531,12 @@ static int nfs41_reclaim_complete_handle
 		/* fall through */
 	case -NFS4ERR_RETRY_UNCACHED_REP:
 		return -EAGAIN;
+	case -NFS4ERR_BADSESSION:
+	case -NFS4ERR_DEADSESSION:
+	case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+		nfs4_schedule_session_recovery(clp->cl_session,
+				task->tk_status);
+		break;
 	default:
 		nfs4_schedule_lease_recovery(clp);
 	}
@@ -7609,7 +7615,6 @@ static int nfs41_proc_reclaim_complete(s
 	if (status == 0)
 		status = task->tk_status;
 	rpc_put_task(task);
-	return 0;
 out:
 	dprintk("<-- %s status=%d\n", __func__, status);
 	return status;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfs/nfs4state.c linux-libre-4.1.52-gnu/fs/nfs/nfs4state.c
--- linux-libre-4.1.51-gnu/fs/nfs/nfs4state.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfs/nfs4state.c	2018-05-27 22:26:45.000000000 -0400
@@ -1591,13 +1591,14 @@ static void nfs4_state_start_reclaim_reb
 	nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
 }
 
-static void nfs4_reclaim_complete(struct nfs_client *clp,
+static int nfs4_reclaim_complete(struct nfs_client *clp,
 				 const struct nfs4_state_recovery_ops *ops,
 				 struct rpc_cred *cred)
 {
 	/* Notify the server we're done reclaiming our state */
 	if (ops->reclaim_complete)
-		(void)ops->reclaim_complete(clp, cred);
+		return ops->reclaim_complete(clp, cred);
+	return 0;
 }
 
 static void nfs4_clear_reclaim_server(struct nfs_server *server)
@@ -1644,13 +1645,16 @@ static void nfs4_state_end_reclaim_reboo
 {
 	const struct nfs4_state_recovery_ops *ops;
 	struct rpc_cred *cred;
+	int err;
 
 	if (!nfs4_state_clear_reclaim_reboot(clp))
 		return;
 	ops = clp->cl_mvops->reboot_recovery_ops;
 	cred = nfs4_get_clid_cred(clp);
-	nfs4_reclaim_complete(clp, ops, cred);
+	err = nfs4_reclaim_complete(clp, ops, cred);
 	put_rpccred(cred);
+	if (err == -NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
+		set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
 }
 
 static void nfs_delegation_clear_all(struct nfs_client *clp)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfs/pagelist.c linux-libre-4.1.52-gnu/fs/nfs/pagelist.c
--- linux-libre-4.1.51-gnu/fs/nfs/pagelist.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfs/pagelist.c	2018-05-27 22:26:45.000000000 -0400
@@ -1277,8 +1277,10 @@ void nfs_pageio_cond_complete(struct nfs
 		mirror = &desc->pg_mirrors[midx];
 		if (!list_empty(&mirror->pg_list)) {
 			prev = nfs_list_entry(mirror->pg_list.prev);
-			if (index != prev->wb_index + 1)
-				nfs_pageio_complete_mirror(desc, midx);
+			if (index != prev->wb_index + 1) {
+				nfs_pageio_complete(desc);
+				break;
+			}
 		}
 	}
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfsd/nfs4proc.c linux-libre-4.1.52-gnu/fs/nfsd/nfs4proc.c
--- linux-libre-4.1.51-gnu/fs/nfsd/nfs4proc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfsd/nfs4proc.c	2018-05-27 22:26:45.000000000 -0400
@@ -1256,14 +1256,14 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
 	const struct nfsd4_layout_ops *ops;
 	struct nfs4_layout_stateid *ls;
 	__be32 nfserr;
-	int accmode;
+	int accmode = NFSD_MAY_READ_IF_EXEC;
 
 	switch (lgp->lg_seg.iomode) {
 	case IOMODE_READ:
-		accmode = NFSD_MAY_READ;
+		accmode |= NFSD_MAY_READ;
 		break;
 	case IOMODE_RW:
-		accmode = NFSD_MAY_READ | NFSD_MAY_WRITE;
+		accmode |= NFSD_MAY_READ | NFSD_MAY_WRITE;
 		break;
 	default:
 		dprintk("%s: invalid iomode %d\n",
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/nfsd/vfs.c linux-libre-4.1.52-gnu/fs/nfsd/vfs.c
--- linux-libre-4.1.51-gnu/fs/nfsd/vfs.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/nfsd/vfs.c	2018-05-27 22:26:45.000000000 -0400
@@ -92,6 +92,12 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, s
 	err = follow_down(&path);
 	if (err < 0)
 		goto out;
+	if (path.mnt == exp->ex_path.mnt && path.dentry == dentry &&
+	    nfsd_mountpoint(dentry, exp) == 2) {
+		/* This is only a mountpoint in some other namespace */
+		path_put(&path);
+		goto out;
+	}
 
 	exp2 = rqst_exp_get_by_name(rqstp, &path);
 	if (IS_ERR(exp2)) {
@@ -165,16 +171,26 @@ static int nfsd_lookup_parent(struct svc
 /*
  * For nfsd purposes, we treat V4ROOT exports as though there was an
  * export at *every* directory.
+ * We return:
+ * '1' if this dentry *must* be an export point,
+ * '2' if it might be, if there is really a mount here, and
+ * '0' if there is no chance of an export point here.
  */
 int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
 {
-	if (d_mountpoint(dentry))
+	if (!d_inode(dentry))
+		return 0;
+	if (exp->ex_flags & NFSEXP_V4ROOT)
 		return 1;
 	if (nfsd4_is_junction(dentry))
 		return 1;
-	if (!(exp->ex_flags & NFSEXP_V4ROOT))
-		return 0;
-	return d_inode(dentry) != NULL;
+	if (d_mountpoint(dentry))
+		/*
+		 * Might only be a mountpoint in a different namespace,
+		 * but we need to check.
+		 */
+		return 2;
+	return 0;
 }
 
 __be32
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/notify/fanotify/fanotify.c linux-libre-4.1.52-gnu/fs/notify/fanotify/fanotify.c
--- linux-libre-4.1.51-gnu/fs/notify/fanotify/fanotify.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/notify/fanotify/fanotify.c	2018-05-27 22:26:45.000000000 -0400
@@ -92,7 +92,7 @@ static bool fanotify_should_send_event(s
 				       u32 event_mask,
 				       void *data, int data_type)
 {
-	__u32 marks_mask, marks_ignored_mask;
+	__u32 marks_mask = 0, marks_ignored_mask = 0;
 	struct path *path = data;
 
 	pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p"
@@ -108,24 +108,20 @@ static bool fanotify_should_send_event(s
 	    !d_can_lookup(path->dentry))
 		return false;
 
-	if (inode_mark && vfsmnt_mark) {
-		marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
-		marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
-	} else if (inode_mark) {
-		/*
-		 * if the event is for a child and this inode doesn't care about
-		 * events on the child, don't send it!
-		 */
-		if ((event_mask & FS_EVENT_ON_CHILD) &&
-		    !(inode_mark->mask & FS_EVENT_ON_CHILD))
-			return false;
-		marks_mask = inode_mark->mask;
-		marks_ignored_mask = inode_mark->ignored_mask;
-	} else if (vfsmnt_mark) {
-		marks_mask = vfsmnt_mark->mask;
-		marks_ignored_mask = vfsmnt_mark->ignored_mask;
-	} else {
-		BUG();
+	/*
+	 * if the event is for a child and this inode doesn't care about
+	 * events on the child, don't send it!
+	 */
+	if (inode_mark &&
+	    (!(event_mask & FS_EVENT_ON_CHILD) ||
+	     (inode_mark->mask & FS_EVENT_ON_CHILD))) {
+		marks_mask |= inode_mark->mask;
+		marks_ignored_mask |= inode_mark->ignored_mask;
+	}
+
+	if (vfsmnt_mark) {
+		marks_mask |= vfsmnt_mark->mask;
+		marks_ignored_mask |= vfsmnt_mark->ignored_mask;
 	}
 
 	if (d_is_dir(path->dentry) &&
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/overlayfs/inode.c linux-libre-4.1.52-gnu/fs/overlayfs/inode.c
--- linux-libre-4.1.51-gnu/fs/overlayfs/inode.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/overlayfs/inode.c	2018-05-27 22:26:45.000000000 -0400
@@ -274,6 +274,16 @@ ssize_t ovl_getxattr(struct dentry *dent
 	return vfs_getxattr(realpath.dentry, name, value, size);
 }
 
+static bool ovl_can_list(const char *s)
+{
+	/* List all non-trusted xatts */
+	if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
+		return true;
+
+	/* Never list trusted.overlay, list other trusted for superuser only */
+	return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN);
+}
+
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
 {
 	struct path realpath;
@@ -298,7 +308,7 @@ ssize_t ovl_listxattr(struct dentry *den
 			return -EIO;
 
 		len -= slen;
-		if (ovl_is_private_xattr(s)) {
+		if (!ovl_can_list(s)) {
 			res -= slen;
 			memmove(s, s + slen, len);
 		} else {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/reiserfs/journal.c linux-libre-4.1.52-gnu/fs/reiserfs/journal.c
--- linux-libre-4.1.51-gnu/fs/reiserfs/journal.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/reiserfs/journal.c	2018-05-27 22:26:45.000000000 -0400
@@ -1961,7 +1961,7 @@ static int do_journal_release(struct rei
 	 * will be requeued because superblock is being shutdown and doesn't
 	 * have MS_ACTIVE set.
 	 */
-	cancel_delayed_work_sync(&REISERFS_SB(sb)->old_work);
+	reiserfs_cancel_old_flush(sb);
 	/* wait for all commits to finish */
 	cancel_delayed_work_sync(&SB_JOURNAL(sb)->j_work);
 
@@ -2643,7 +2643,7 @@ static int journal_init_dev(struct super
 	if (IS_ERR(journal->j_dev_bd)) {
 		result = PTR_ERR(journal->j_dev_bd);
 		journal->j_dev_bd = NULL;
-		reiserfs_warning(super,
+		reiserfs_warning(super, "sh-457",
 				 "journal_init_dev: Cannot open '%s': %i",
 				 jdev_name, result);
 		return result;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/reiserfs/reiserfs.h linux-libre-4.1.52-gnu/fs/reiserfs/reiserfs.h
--- linux-libre-4.1.51-gnu/fs/reiserfs/reiserfs.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/reiserfs/reiserfs.h	2018-05-27 22:26:45.000000000 -0400
@@ -2948,6 +2948,7 @@ int reiserfs_allocate_list_bitmaps(struc
 				   struct reiserfs_list_bitmap *, unsigned int);
 
 void reiserfs_schedule_old_flush(struct super_block *s);
+void reiserfs_cancel_old_flush(struct super_block *s);
 void add_save_link(struct reiserfs_transaction_handle *th,
 		   struct inode *inode, int truncate);
 int remove_save_link(struct inode *inode, int truncate);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/reiserfs/super.c linux-libre-4.1.52-gnu/fs/reiserfs/super.c
--- linux-libre-4.1.51-gnu/fs/reiserfs/super.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/reiserfs/super.c	2018-05-27 22:26:45.000000000 -0400
@@ -89,7 +89,9 @@ static void flush_old_commits(struct wor
 	s = sbi->s_journal->j_work_sb;
 
 	spin_lock(&sbi->old_work_lock);
-	sbi->work_queued = 0;
+	/* Avoid clobbering the cancel state... */
+	if (sbi->work_queued == 1)
+		sbi->work_queued = 0;
 	spin_unlock(&sbi->old_work_lock);
 
 	reiserfs_sync_fs(s, 1);
@@ -116,21 +118,22 @@ void reiserfs_schedule_old_flush(struct
 	spin_unlock(&sbi->old_work_lock);
 }
 
-static void cancel_old_flush(struct super_block *s)
+void reiserfs_cancel_old_flush(struct super_block *s)
 {
 	struct reiserfs_sb_info *sbi = REISERFS_SB(s);
 
-	cancel_delayed_work_sync(&REISERFS_SB(s)->old_work);
 	spin_lock(&sbi->old_work_lock);
-	sbi->work_queued = 0;
+	/* Make sure no new flushes will be queued */
+	sbi->work_queued = 2;
 	spin_unlock(&sbi->old_work_lock);
+	cancel_delayed_work_sync(&REISERFS_SB(s)->old_work);
 }
 
 static int reiserfs_freeze(struct super_block *s)
 {
 	struct reiserfs_transaction_handle th;
 
-	cancel_old_flush(s);
+	reiserfs_cancel_old_flush(s);
 
 	reiserfs_write_lock(s);
 	if (!(s->s_flags & MS_RDONLY)) {
@@ -151,7 +154,13 @@ static int reiserfs_freeze(struct super_
 
 static int reiserfs_unfreeze(struct super_block *s)
 {
+	struct reiserfs_sb_info *sbi = REISERFS_SB(s);
+
 	reiserfs_allow_writes(s);
+	spin_lock(&sbi->old_work_lock);
+	/* Allow old_work to run again */
+	sbi->work_queued = 0;
+	spin_unlock(&sbi->old_work_lock);
 	return 0;
 }
 
@@ -2177,7 +2186,7 @@ error_unlocked:
 	if (sbi->commit_wq)
 		destroy_workqueue(sbi->commit_wq);
 
-	cancel_delayed_work_sync(&REISERFS_SB(s)->old_work);
+	reiserfs_cancel_old_flush(s);
 
 	reiserfs_free_bitmap_cache(s);
 	if (SB_BUFFER_WITH_SB(s))
diff -druNp --no-dereference linux-libre-4.1.51-gnu/fs/ubifs/super.c linux-libre-4.1.52-gnu/fs/ubifs/super.c
--- linux-libre-4.1.51-gnu/fs/ubifs/super.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/fs/ubifs/super.c	2018-05-27 22:26:45.000000000 -0400
@@ -1724,8 +1724,11 @@ static void ubifs_remount_ro(struct ubif
 
 	dbg_save_space_info(c);
 
-	for (i = 0; i < c->jhead_cnt; i++)
-		ubifs_wbuf_sync(&c->jheads[i].wbuf);
+	for (i = 0; i < c->jhead_cnt; i++) {
+		err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+		if (err)
+			ubifs_ro_mode(c, err);
+	}
 
 	c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
 	c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
@@ -1791,8 +1794,11 @@ static void ubifs_put_super(struct super
 			int err;
 
 			/* Synchronize write-buffers */
-			for (i = 0; i < c->jhead_cnt; i++)
-				ubifs_wbuf_sync(&c->jheads[i].wbuf);
+			for (i = 0; i < c->jhead_cnt; i++) {
+				err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+				if (err)
+					ubifs_ro_mode(c, err);
+			}
 
 			/*
 			 * We are being cleanly unmounted which means the
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/compiler-clang.h linux-libre-4.1.52-gnu/include/linux/compiler-clang.h
--- linux-libre-4.1.51-gnu/include/linux/compiler-clang.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/compiler-clang.h	2018-05-27 22:26:45.000000000 -0400
@@ -10,3 +10,8 @@
 #undef uninitialized_var
 #define uninitialized_var(x) x = *(&(x))
 #endif
+
+/* same as gcc, this was present in clang-2.6 so we can assume it works
+ * with any version that can compile the kernel
+ */
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/cpumask.h linux-libre-4.1.52-gnu/include/linux/cpumask.h
--- linux-libre-4.1.51-gnu/include/linux/cpumask.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/cpumask.h	2018-05-27 22:26:45.000000000 -0400
@@ -661,6 +661,11 @@ void alloc_bootmem_cpumask_var(cpumask_v
 void free_cpumask_var(cpumask_var_t mask);
 void free_bootmem_cpumask_var(cpumask_var_t mask);
 
+static inline bool cpumask_available(cpumask_var_t mask)
+{
+	return mask != NULL;
+}
+
 #else
 typedef struct cpumask cpumask_var_t[1];
 
@@ -701,6 +706,11 @@ static inline void free_cpumask_var(cpum
 static inline void free_bootmem_cpumask_var(cpumask_var_t mask)
 {
 }
+
+static inline bool cpumask_available(cpumask_var_t mask)
+{
+	return true;
+}
 #endif /* CONFIG_CPUMASK_OFFSTACK */
 
 /* It's common to want to use cpu_all_mask in struct member initializers,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/hid.h linux-libre-4.1.52-gnu/include/linux/hid.h
--- linux-libre-4.1.51-gnu/include/linux/hid.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/hid.h	2018-05-27 22:26:45.000000000 -0400
@@ -793,7 +793,7 @@ extern int hidinput_connect(struct hid_d
 extern void hidinput_disconnect(struct hid_device *);
 
 int hid_set_field(struct hid_field *, unsigned, __s32);
-int hid_input_report(struct hid_device *, int type, u8 *, int, int);
+int hid_input_report(struct hid_device *, int type, u8 *, u32, int);
 int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 unsigned int hidinput_count_leds(struct hid_device *hid);
@@ -1096,13 +1096,13 @@ static inline void hid_hw_wait(struct hi
  *
  * @report: the report we want to know the length
  */
-static inline int hid_report_len(struct hid_report *report)
+static inline u32 hid_report_len(struct hid_report *report)
 {
 	/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
 	return ((report->size - 1) >> 3) + 1 + (report->id > 0);
 }
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 		int interrupt);
 
 /* HID quirks API */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/if_vlan.h linux-libre-4.1.52-gnu/include/linux/if_vlan.h
--- linux-libre-4.1.51-gnu/include/linux/if_vlan.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/if_vlan.h	2018-05-27 22:26:45.000000000 -0400
@@ -585,7 +585,7 @@ static inline bool skb_vlan_tagged(const
  * Returns true if the skb is tagged with multiple vlan headers, regardless
  * of whether it is hardware accelerated or not.
  */
-static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
+static inline bool skb_vlan_tagged_multi(struct sk_buff *skb)
 {
 	__be16 protocol = skb->protocol;
 
@@ -596,6 +596,9 @@ static inline bool skb_vlan_tagged_multi
 			   protocol != htons(ETH_P_8021AD)))
 			return false;
 
+		if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+			return false;
+
 		veh = (struct vlan_ethhdr *)skb->data;
 		protocol = veh->h_vlan_encapsulated_proto;
 	}
@@ -613,7 +616,7 @@ static inline bool skb_vlan_tagged_multi
  *
  * Returns features without unsafe ones if the skb has multiple tags.
  */
-static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
+static inline netdev_features_t vlan_features_check(struct sk_buff *skb,
 						    netdev_features_t features)
 {
 	if (skb_vlan_tagged_multi(skb)) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/jiffies.h linux-libre-4.1.52-gnu/include/linux/jiffies.h
--- linux-libre-4.1.51-gnu/include/linux/jiffies.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/jiffies.h	2018-05-27 22:26:45.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef _LINUX_JIFFIES_H
 #define _LINUX_JIFFIES_H
 
+#include <linux/cache.h>
 #include <linux/math64.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -62,19 +63,17 @@ extern int register_refined_jiffies(long
 /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
 #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
 
-/* some arch's have a small-data section that can be accessed register-relative
- * but that can only take up to, say, 4-byte variables. jiffies being part of
- * an 8-byte variable may not be correctly accessed unless we force the issue
- */
-#define __jiffy_data  __attribute__((section(".data")))
+#ifndef __jiffy_arch_data
+#define __jiffy_arch_data
+#endif
 
 /*
  * The 64-bit value is not atomic - you MUST NOT read it
  * without sampling the sequence number in jiffies_lock.
  * get_jiffies_64() will do this for you as appropriate.
  */
-extern u64 __jiffy_data jiffies_64;
-extern unsigned long volatile __jiffy_data jiffies;
+extern u64 __cacheline_aligned_in_smp jiffies_64;
+extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies;
 
 #if (BITS_PER_LONG < 64)
 u64 get_jiffies_64(void);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/llist.h linux-libre-4.1.52-gnu/include/linux/llist.h
--- linux-libre-4.1.51-gnu/include/linux/llist.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/llist.h	2018-05-27 22:26:45.000000000 -0400
@@ -88,6 +88,23 @@ static inline void init_llist_head(struc
 	container_of(ptr, type, member)
 
 /**
+ * member_address_is_nonnull - check whether the member address is not NULL
+ * @ptr:	the object pointer (struct type * that contains the llist_node)
+ * @member:	the name of the llist_node within the struct.
+ *
+ * This macro is conceptually the same as
+ *	&ptr->member != NULL
+ * but it works around the fact that compilers can decide that taking a member
+ * address is never a NULL pointer.
+ *
+ * Real objects that start at a high address and have a member at NULL are
+ * unlikely to exist, but such pointers may be returned e.g. by the
+ * container_of() macro.
+ */
+#define member_address_is_nonnull(ptr, member)	\
+	((uintptr_t)(ptr) + offsetof(typeof(*(ptr)), member) != 0)
+
+/**
  * llist_for_each - iterate over some deleted entries of a lock-less list
  * @pos:	the &struct llist_node to use as a loop cursor
  * @node:	the first entry of deleted list entries
@@ -121,7 +138,7 @@ static inline void init_llist_head(struc
  */
 #define llist_for_each_entry(pos, node, member)				\
 	for ((pos) = llist_entry((node), typeof(*(pos)), member);	\
-	     &(pos)->member != NULL;					\
+	     member_address_is_nonnull(pos, member);			\
 	     (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
 
 /**
@@ -143,7 +160,7 @@ static inline void init_llist_head(struc
  */
 #define llist_for_each_entry_safe(pos, n, node, member)			       \
 	for (pos = llist_entry((node), typeof(*pos), member);		       \
-	     &pos->member != NULL &&					       \
+	     member_address_is_nonnull(pos, member) &&			       \
 	        (n = llist_entry(pos->member.next, typeof(*n), member), true); \
 	     pos = n)
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/mlx4/qp.h linux-libre-4.1.52-gnu/include/linux/mlx4/qp.h
--- linux-libre-4.1.51-gnu/include/linux/mlx4/qp.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/mlx4/qp.h	2018-05-27 22:26:45.000000000 -0400
@@ -450,6 +450,7 @@ struct mlx4_update_qp_params {
 	u16	rate_val;
 };
 
+struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn);
 int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
 		   enum mlx4_update_qp_attr attr,
 		   struct mlx4_update_qp_params *params);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/mtd/flashchip.h linux-libre-4.1.52-gnu/include/linux/mtd/flashchip.h
--- linux-libre-4.1.51-gnu/include/linux/mtd/flashchip.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/mtd/flashchip.h	2018-05-27 22:26:45.000000000 -0400
@@ -85,6 +85,7 @@ struct flchip {
 	unsigned int write_suspended:1;
 	unsigned int erase_suspended:1;
 	unsigned long in_progress_block_addr;
+	unsigned long in_progress_block_mask;
 
 	struct mutex mutex;
 	wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/netfilter/x_tables.h linux-libre-4.1.52-gnu/include/linux/netfilter/x_tables.h
--- linux-libre-4.1.51-gnu/include/linux/netfilter/x_tables.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/netfilter/x_tables.h	2018-05-27 22:26:45.000000000 -0400
@@ -247,6 +247,8 @@ unsigned int *xt_alloc_entry_offsets(uns
 bool xt_find_jump_offset(const unsigned int *offsets,
 			 unsigned int target, unsigned int size);
 
+int xt_check_proc_name(const char *name, unsigned int size);
+
 int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
 		   bool inv_proto);
 int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/pagemap.h linux-libre-4.1.52-gnu/include/linux/pagemap.h
--- linux-libre-4.1.51-gnu/include/linux/pagemap.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/pagemap.h	2018-05-27 22:26:45.000000000 -0400
@@ -146,7 +146,7 @@ static inline int page_cache_get_specula
 
 #ifdef CONFIG_TINY_RCU
 # ifdef CONFIG_PREEMPT_COUNT
-	VM_BUG_ON(!in_atomic());
+	VM_BUG_ON(!in_atomic() && !irqs_disabled());
 # endif
 	/*
 	 * Preempt must be disabled here - we rely on rcu_read_lock doing
@@ -184,7 +184,7 @@ static inline int page_cache_add_specula
 
 #if !defined(CONFIG_SMP) && defined(CONFIG_TREE_RCU)
 # ifdef CONFIG_PREEMPT_COUNT
-	VM_BUG_ON(!in_atomic());
+	VM_BUG_ON(!in_atomic() && !irqs_disabled());
 # endif
 	VM_BUG_ON_PAGE(page_count(page) == 0, page);
 	atomic_add(count, &page->_count);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/platform_data/isl9305.h linux-libre-4.1.52-gnu/include/linux/platform_data/isl9305.h
--- linux-libre-4.1.51-gnu/include/linux/platform_data/isl9305.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/platform_data/isl9305.h	2018-05-27 22:26:45.000000000 -0400
@@ -24,7 +24,7 @@
 struct regulator_init_data;
 
 struct isl9305_pdata {
-	struct regulator_init_data *init_data[ISL9305_MAX_REGULATOR];
+	struct regulator_init_data *init_data[ISL9305_MAX_REGULATOR + 1];
 };
 
 #endif
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/skbuff.h linux-libre-4.1.52-gnu/include/linux/skbuff.h
--- linux-libre-4.1.51-gnu/include/linux/skbuff.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/skbuff.h	2018-05-27 22:26:45.000000000 -0400
@@ -847,10 +847,10 @@ struct sk_buff *skb_realloc_headroom(str
 				     unsigned int headroom);
 struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom,
 				int newtailroom, gfp_t priority);
-int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg,
-			int offset, int len);
-int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset,
-		 int len);
+int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg,
+				     int offset, int len);
+int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg,
+			      int offset, int len);
 int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer);
 int skb_pad(struct sk_buff *skb, int pad);
 #define dev_kfree_skb(a)	consume_skb(a)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/tty.h linux-libre-4.1.52-gnu/include/linux/tty.h
--- linux-libre-4.1.51-gnu/include/linux/tty.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/tty.h	2018-05-27 22:26:45.000000000 -0400
@@ -343,6 +343,7 @@ struct tty_file_private {
 #define TTY_PTY_LOCK 		16	/* pty private */
 #define TTY_NO_WRITE_SPLIT 	17	/* Preserve write boundaries to driver */
 #define TTY_HUPPED 		18	/* Post driver->hangup() */
+#define TTY_HUPPING		19	/* Hangup in progress */
 #define TTY_LDISC_HALTED	22	/* Line discipline is halted */
 
 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
@@ -581,7 +582,7 @@ extern int tty_unregister_ldisc(int disc
 extern int tty_set_ldisc(struct tty_struct *tty, int ldisc);
 extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
 extern void tty_ldisc_release(struct tty_struct *tty);
-extern void tty_ldisc_init(struct tty_struct *tty);
+extern int __must_check tty_ldisc_init(struct tty_struct *tty);
 extern void tty_ldisc_deinit(struct tty_struct *tty);
 extern void tty_ldisc_begin(void);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/usb/gadget.h linux-libre-4.1.52-gnu/include/linux/usb/gadget.h
--- linux-libre-4.1.51-gnu/include/linux/usb/gadget.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/usb/gadget.h	2018-05-27 22:26:45.000000000 -0400
@@ -586,8 +586,20 @@ static inline struct usb_gadget *dev_to_
 
 
 /**
+ * usb_ep_align - returns @len aligned to ep's maxpacketsize.
+ * @ep: the endpoint whose maxpacketsize is used to align @len
+ * @len: buffer size's length to align to @ep's maxpacketsize
+ *
+ * This helper is used to align buffer's size to an ep's maxpacketsize.
+ */
+static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
+{
+	return round_up(len, (size_t)le16_to_cpu(ep->desc->wMaxPacketSize));
+}
+
+/**
  * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget
- *	requires quirk_ep_out_aligned_size, otherwise reguens len.
+ *	requires quirk_ep_out_aligned_size, otherwise returns len.
  * @g: controller to check for quirk
  * @ep: the endpoint whose maxpacketsize is used to align @len
  * @len: buffer size's length to align to @ep's maxpacketsize
@@ -598,8 +610,7 @@ static inline struct usb_gadget *dev_to_
 static inline size_t
 usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len)
 {
-	return !g->quirk_ep_out_aligned_size ? len :
-			round_up(len, (size_t)ep->desc->wMaxPacketSize);
+	return g->quirk_ep_out_aligned_size ? usb_ep_align(ep, len) : len;
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/linux/virtio.h linux-libre-4.1.52-gnu/include/linux/virtio.h
--- linux-libre-4.1.51-gnu/include/linux/virtio.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/linux/virtio.h	2018-05-27 22:26:45.000000000 -0400
@@ -124,6 +124,9 @@ int virtio_device_freeze(struct virtio_d
 int virtio_device_restore(struct virtio_device *dev);
 #endif
 
+#define virtio_device_for_each_vq(vdev, vq) \
+	list_for_each_entry(vq, &vdev->vqs, list)
+
 /**
  * virtio_driver - operations for a virtio I/O driver
  * @driver: underlying device driver (populate name and owner).
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/net/cfg80211.h linux-libre-4.1.52-gnu/include/net/cfg80211.h
--- linux-libre-4.1.51-gnu/include/net/cfg80211.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/net/cfg80211.h	2018-05-27 22:26:45.000000000 -0400
@@ -929,9 +929,9 @@ enum rate_info_flags {
  * @RATE_INFO_BW_160: 160 MHz bandwidth
  */
 enum rate_info_bw {
+	RATE_INFO_BW_20 = 0,
 	RATE_INFO_BW_5,
 	RATE_INFO_BW_10,
-	RATE_INFO_BW_20,
 	RATE_INFO_BW_40,
 	RATE_INFO_BW_80,
 	RATE_INFO_BW_160,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/net/inet_timewait_sock.h linux-libre-4.1.52-gnu/include/net/inet_timewait_sock.h
--- linux-libre-4.1.51-gnu/include/net/inet_timewait_sock.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/net/inet_timewait_sock.h	2018-05-27 22:26:45.000000000 -0400
@@ -55,6 +55,7 @@ struct inet_timewait_sock {
 #define tw_family		__tw_common.skc_family
 #define tw_state		__tw_common.skc_state
 #define tw_reuse		__tw_common.skc_reuse
+#define tw_reuseport		__tw_common.skc_reuseport
 #define tw_ipv6only		__tw_common.skc_ipv6only
 #define tw_bound_dev_if		__tw_common.skc_bound_dev_if
 #define tw_node			__tw_common.skc_nulls_node
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/net/nexthop.h linux-libre-4.1.52-gnu/include/net/nexthop.h
--- linux-libre-4.1.51-gnu/include/net/nexthop.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/net/nexthop.h	2018-05-27 22:26:45.000000000 -0400
@@ -6,7 +6,7 @@
 
 static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining)
 {
-	return remaining >= sizeof(*rtnh) &&
+	return remaining >= (int)sizeof(*rtnh) &&
 	       rtnh->rtnh_len >= sizeof(*rtnh) &&
 	       rtnh->rtnh_len <= remaining;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/net/slhc_vj.h linux-libre-4.1.52-gnu/include/net/slhc_vj.h
--- linux-libre-4.1.51-gnu/include/net/slhc_vj.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/net/slhc_vj.h	2018-05-27 22:26:45.000000000 -0400
@@ -127,6 +127,7 @@ typedef __u32 int32;
  */
 struct cstate {
 	byte_t	cs_this;	/* connection id number (xmit) */
+	bool	initialized;	/* true if initialized */
 	struct cstate *next;	/* next in ring (xmit) */
 	struct iphdr cs_ip;	/* ip/tcp hdr from most recent packet */
 	struct tcphdr cs_tcp;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/net/tcp.h linux-libre-4.1.52-gnu/include/net/tcp.h
--- linux-libre-4.1.51-gnu/include/net/tcp.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/net/tcp.h	2018-05-27 22:26:45.000000000 -0400
@@ -1123,9 +1123,11 @@ void tcp_select_initial_window(int __spa
 
 static inline int tcp_win_from_space(int space)
 {
-	return sysctl_tcp_adv_win_scale<=0 ?
-		(space>>(-sysctl_tcp_adv_win_scale)) :
-		space - (space>>sysctl_tcp_adv_win_scale);
+	int tcp_adv_win_scale = sysctl_tcp_adv_win_scale;
+
+	return tcp_adv_win_scale <= 0 ?
+		(space>>(-tcp_adv_win_scale)) :
+		space - (space>>tcp_adv_win_scale);
 }
 
 /* Note: caller must be prepared to deal with negative returns */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/net/x25.h linux-libre-4.1.52-gnu/include/net/x25.h
--- linux-libre-4.1.51-gnu/include/net/x25.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/net/x25.h	2018-05-27 22:26:45.000000000 -0400
@@ -298,10 +298,10 @@ void x25_check_rbuf(struct sock *);
 
 /* sysctl_net_x25.c */
 #ifdef CONFIG_SYSCTL
-void x25_register_sysctl(void);
+int x25_register_sysctl(void);
 void x25_unregister_sysctl(void);
 #else
-static inline void x25_register_sysctl(void) {};
+static inline int x25_register_sysctl(void) { return 0; };
 static inline void x25_unregister_sysctl(void) {};
 #endif /* CONFIG_SYSCTL */
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/rdma/ib_addr.h linux-libre-4.1.52-gnu/include/rdma/ib_addr.h
--- linux-libre-4.1.51-gnu/include/rdma/ib_addr.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/rdma/ib_addr.h	2018-05-27 22:26:45.000000000 -0400
@@ -109,6 +109,8 @@ int rdma_copy_addr(struct rdma_dev_addr
 	      const unsigned char *dst_dev_addr);
 
 int rdma_addr_size(struct sockaddr *addr);
+int rdma_addr_size_in6(struct sockaddr_in6 *addr);
+int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr);
 
 int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id);
 int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *smac,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/sound/control.h linux-libre-4.1.52-gnu/include/sound/control.h
--- linux-libre-4.1.51-gnu/include/sound/control.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/sound/control.h	2018-05-27 22:26:45.000000000 -0400
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/nospec.h>
 #include <sound/asound.h>
 
 #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
@@ -147,12 +148,14 @@ int snd_ctl_get_preferred_subdevice(stru
 
 static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
-	return id->numid - kctl->id.numid;
+	unsigned int ioff = id->numid - kctl->id.numid;
+	return array_index_nospec(ioff, kctl->count);
 }
 
 static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
-	return id->index - kctl->id.index;
+	unsigned int ioff = id->index - kctl->id.index;
+	return array_index_nospec(ioff, kctl->count);
 }
 
 static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/sound/pcm_oss.h linux-libre-4.1.52-gnu/include/sound/pcm_oss.h
--- linux-libre-4.1.51-gnu/include/sound/pcm_oss.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/sound/pcm_oss.h	2018-05-27 22:26:45.000000000 -0400
@@ -57,6 +57,7 @@ struct snd_pcm_oss_runtime {
 	char *buffer;				/* vmallocated period */
 	size_t buffer_used;			/* used length from period buffer */
 	struct mutex params_lock;
+	atomic_t rw_ref;		/* concurrent read/write accesses */
 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
 	struct snd_pcm_plugin *plugin_first;
 	struct snd_pcm_plugin *plugin_last;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/uapi/linux/pci_regs.h linux-libre-4.1.52-gnu/include/uapi/linux/pci_regs.h
--- linux-libre-4.1.51-gnu/include/uapi/linux/pci_regs.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/uapi/linux/pci_regs.h	2018-05-27 22:26:45.000000000 -0400
@@ -106,7 +106,7 @@
 #define PCI_SUBSYSTEM_ID	0x2e
 #define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
 #define  PCI_ROM_ADDRESS_ENABLE	0x01
-#define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
+#define PCI_ROM_ADDRESS_MASK	(~0x7ffU)
 
 #define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/include/uapi/linux/usb/audio.h linux-libre-4.1.52-gnu/include/uapi/linux/usb/audio.h
--- linux-libre-4.1.51-gnu/include/uapi/linux/usb/audio.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/include/uapi/linux/usb/audio.h	2018-05-27 22:26:45.000000000 -0400
@@ -369,7 +369,7 @@ static inline __u8 uac_processing_unit_b
 {
 	return (protocol == UAC_VERSION_1) ?
 		desc->baSourceID[desc->bNrInPins + 4] :
-		desc->baSourceID[desc->bNrInPins + 6];
+		2; /* in UAC2, this value is constant */
 }
 
 static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
@@ -377,7 +377,7 @@ static inline __u8 *uac_processing_unit_
 {
 	return (protocol == UAC_VERSION_1) ?
 		&desc->baSourceID[desc->bNrInPins + 5] :
-		&desc->baSourceID[desc->bNrInPins + 7];
+		&desc->baSourceID[desc->bNrInPins + 6];
 }
 
 static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/ipc/shm.c linux-libre-4.1.52-gnu/ipc/shm.c
--- linux-libre-4.1.51-gnu/ipc/shm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/ipc/shm.c	2018-05-27 22:26:45.000000000 -0400
@@ -198,6 +198,12 @@ static int __shm_open(struct vm_area_str
 	if (IS_ERR(shp))
 		return PTR_ERR(shp);
 
+	if (shp->shm_file != sfd->file) {
+		/* ID was reused */
+		shm_unlock(shp);
+		return -EINVAL;
+	}
+
 	shp->shm_atim = get_seconds();
 	shp->shm_lprid = task_tgid_vnr(current);
 	shp->shm_nattch++;
@@ -414,8 +420,9 @@ static int shm_mmap(struct file *file, s
 	int ret;
 
 	/*
-	 * In case of remap_file_pages() emulation, the file can represent
-	 * removed IPC ID: propogate shm_lock() error to caller.
+	 * In case of remap_file_pages() emulation, the file can represent an
+	 * IPC ID that was removed, and possibly even reused by another shm
+	 * segment already.  Propagate this case as an error to caller.
 	 */
 	ret =__shm_open(vma);
 	if (ret)
@@ -439,6 +446,7 @@ static int shm_release(struct inode *ino
 	struct shm_file_data *sfd = shm_file_data(file);
 
 	put_ipc_ns(sfd->ns);
+	fput(sfd->file);
 	shm_file_data(file) = NULL;
 	kfree(sfd);
 	return 0;
@@ -1198,7 +1206,16 @@ long do_shmat(int shmid, char __user *sh
 	file->f_mapping = shp->shm_file->f_mapping;
 	sfd->id = shp->shm_perm.id;
 	sfd->ns = get_ipc_ns(ns);
-	sfd->file = shp->shm_file;
+	/*
+	 * We need to take a reference to the real shm file to prevent the
+	 * pointer from becoming stale in cases where the lifetime of the outer
+	 * file extends beyond that of the shm segment.  It's not usually
+	 * possible, but it can happen during remap_file_pages() emulation as
+	 * that unmaps the memory, then does ->mmap() via file reference only.
+	 * We'll deny the ->mmap() if the shm segment was since removed, but to
+	 * detect shm ID reuse we need to compare the file pointers.
+	 */
+	sfd->file = get_file(shp->shm_file);
 	sfd->vm_ops = NULL;
 
 	err = security_mmap_file(file, prot, flags);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/bpf/arraymap.c linux-libre-4.1.52-gnu/kernel/bpf/arraymap.c
--- linux-libre-4.1.51-gnu/kernel/bpf/arraymap.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/bpf/arraymap.c	2018-05-27 22:26:45.000000000 -0400
@@ -75,7 +75,7 @@ static void *array_map_lookup_elem(struc
 static int array_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
 {
 	struct bpf_array *array = container_of(map, struct bpf_array, map);
-	u32 index = *(u32 *)key;
+	u32 index = key ? *(u32 *)key : U32_MAX;
 	u32 *next = (u32 *)next_key;
 
 	if (index >= array->map.max_entries) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/bpf/hashtab.c linux-libre-4.1.52-gnu/kernel/bpf/hashtab.c
--- linux-libre-4.1.51-gnu/kernel/bpf/hashtab.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/bpf/hashtab.c	2018-05-27 22:26:45.000000000 -0400
@@ -149,12 +149,15 @@ static int htab_map_get_next_key(struct
 	struct hlist_head *head;
 	struct htab_elem *l, *next_l;
 	u32 hash, key_size;
-	int i;
+	int i = 0;
 
 	WARN_ON_ONCE(!rcu_read_lock_held());
 
 	key_size = map->key_size;
 
+	if (!key)
+		goto find_first_elem;
+
 	hash = htab_map_hash(key, key_size);
 
 	head = select_bucket(htab, hash);
@@ -162,10 +165,8 @@ static int htab_map_get_next_key(struct
 	/* lookup the key */
 	l = lookup_elem_raw(head, hash, key, key_size);
 
-	if (!l) {
-		i = 0;
+	if (!l)
 		goto find_first_elem;
-	}
 
 	/* key was found, get next key in the same bucket */
 	next_l = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&l->hash_node)),
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/bpf/syscall.c linux-libre-4.1.52-gnu/kernel/bpf/syscall.c
--- linux-libre-4.1.51-gnu/kernel/bpf/syscall.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/bpf/syscall.c	2018-05-27 22:26:45.000000000 -0400
@@ -311,14 +311,18 @@ static int map_get_next_key(union bpf_at
 	if (IS_ERR(map))
 		return PTR_ERR(map);
 
-	err = -ENOMEM;
-	key = kmalloc(map->key_size, GFP_USER);
-	if (!key)
-		goto err_put;
+	if (ukey) {
+		err = -ENOMEM;
+		key = kmalloc(map->key_size, GFP_USER);
+		if (!key)
+			goto err_put;
 
-	err = -EFAULT;
-	if (copy_from_user(key, ukey, map->key_size) != 0)
-		goto free_key;
+		err = -EFAULT;
+		if (copy_from_user(key, ukey, map->key_size) != 0)
+			goto free_key;
+	} else {
+		key = NULL;
+	}
 
 	err = -ENOMEM;
 	next_key = kmalloc(map->key_size, GFP_USER);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/events/callchain.c linux-libre-4.1.52-gnu/kernel/events/callchain.c
--- linux-libre-4.1.51-gnu/kernel/events/callchain.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/events/callchain.c	2018-05-27 22:26:45.000000000 -0400
@@ -107,14 +107,8 @@ int get_callchain_buffers(void)
 		goto exit;
 	}
 
-	if (count > 1) {
-		/* If the allocation failed, give up */
-		if (!callchain_cpus_entries)
-			err = -ENOMEM;
-		goto exit;
-	}
-
-	err = alloc_callchain_buffers();
+	if (count == 1)
+		err = alloc_callchain_buffers();
 exit:
 	if (err)
 		atomic_dec(&nr_callchain_events);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/events/core.c linux-libre-4.1.52-gnu/kernel/events/core.c
--- linux-libre-4.1.51-gnu/kernel/events/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/events/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -5107,9 +5107,6 @@ static void perf_output_read_one(struct
 	__output_copy(handle, values, n * sizeof(u64));
 }
 
-/*
- * XXX PERF_FORMAT_GROUP vs inherited events seems difficult.
- */
 static void perf_output_read_group(struct perf_output_handle *handle,
 			    struct perf_event *event,
 			    u64 enabled, u64 running)
@@ -5154,6 +5151,13 @@ static void perf_output_read_group(struc
 #define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\
 				 PERF_FORMAT_TOTAL_TIME_RUNNING)
 
+/*
+ * XXX PERF_SAMPLE_READ vs inherited events seems difficult.
+ *
+ * The problem is that its both hard and excessively expensive to iterate the
+ * child list, not to mention that its impossible to IPI the children running
+ * on another CPU, from interrupt/NMI context.
+ */
 static void perf_output_read(struct perf_output_handle *handle,
 			     struct perf_event *event)
 {
@@ -7630,9 +7634,10 @@ perf_event_alloc(struct perf_event_attr
 	local64_set(&hwc->period_left, hwc->sample_period);
 
 	/*
-	 * we currently do not support PERF_FORMAT_GROUP on inherited events
+	 * We currently do not support PERF_SAMPLE_READ on inherited events.
+	 * See perf_output_read().
 	 */
-	if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
+	if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ))
 		goto err_ns;
 
 	if (!has_branch_stack(event))
@@ -7800,9 +7805,9 @@ static int perf_copy_attr(struct perf_ev
 		 * __u16 sample size limit.
 		 */
 		if (attr->sample_stack_user >= USHRT_MAX)
-			ret = -EINVAL;
+			return -EINVAL;
 		else if (!IS_ALIGNED(attr->sample_stack_user, sizeof(u64)))
-			ret = -EINVAL;
+			return -EINVAL;
 	}
 
 	if (attr->sample_type & PERF_SAMPLE_REGS_INTR)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/events/hw_breakpoint.c linux-libre-4.1.52-gnu/kernel/events/hw_breakpoint.c
--- linux-libre-4.1.51-gnu/kernel/events/hw_breakpoint.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/events/hw_breakpoint.c	2018-05-27 22:26:45.000000000 -0400
@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_break
  * modify_user_hw_breakpoint - modify a user-space hardware breakpoint
  * @bp: the breakpoint structure to modify
  * @attr: new breakpoint attributes
- * @triggered: callback to trigger when we hit the breakpoint
- * @tsk: pointer to 'task_struct' of the process to which the address belongs
  */
 int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
 {
-	u64 old_addr = bp->attr.bp_addr;
-	u64 old_len = bp->attr.bp_len;
-	int old_type = bp->attr.bp_type;
-	int err = 0;
-
 	/*
 	 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
 	 * will not be possible to raise IPIs that invoke __perf_event_disable.
@@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct per
 	bp->attr.bp_addr = attr->bp_addr;
 	bp->attr.bp_type = attr->bp_type;
 	bp->attr.bp_len = attr->bp_len;
+	bp->attr.disabled = 1;
 
-	if (attr->disabled)
-		goto end;
-
-	err = validate_hw_breakpoint(bp);
-	if (!err)
-		perf_event_enable(bp);
+	if (!attr->disabled) {
+		int err = validate_hw_breakpoint(bp);
 
-	if (err) {
-		bp->attr.bp_addr = old_addr;
-		bp->attr.bp_type = old_type;
-		bp->attr.bp_len = old_len;
-		if (!bp->attr.disabled)
-			perf_event_enable(bp);
+		if (err)
+			return err;
 
-		return err;
+		perf_event_enable(bp);
+		bp->attr.disabled = 0;
 	}
 
-end:
-	bp->attr.disabled = attr->disabled;
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/futex.c linux-libre-4.1.52-gnu/kernel/futex.c
--- linux-libre-4.1.51-gnu/kernel/futex.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/futex.c	2018-05-27 22:26:45.000000000 -0400
@@ -400,6 +400,7 @@ get_futex_key(u32 __user *uaddr, int fsh
 	unsigned long address = (unsigned long)uaddr;
 	struct mm_struct *mm = current->mm;
 	struct page *page, *page_head;
+	struct address_space *mapping;
 	int err, ro = 0;
 
 	/*
@@ -478,7 +479,19 @@ again:
 	}
 #endif
 
-	lock_page(page_head);
+	/*
+	 * The treatment of mapping from this point on is critical. The page
+	 * lock protects many things but in this context the page lock
+	 * stabilizes mapping, prevents inode freeing in the shared
+	 * file-backed region case and guards against movement to swap cache.
+	 *
+	 * Strictly speaking the page lock is not needed in all cases being
+	 * considered here and page lock forces unnecessarily serialization
+	 * From this point on, mapping will be re-verified if necessary and
+	 * page lock will be acquired only if it is unavoidable
+	 */
+
+	mapping = READ_ONCE(page_head->mapping);
 
 	/*
 	 * If page_head->mapping is NULL, then it cannot be a PageAnon
@@ -495,18 +508,31 @@ again:
 	 * shmem_writepage move it from filecache to swapcache beneath us:
 	 * an unlikely race, but we do need to retry for page_head->mapping.
 	 */
-	if (!page_head->mapping) {
-		int shmem_swizzled = PageSwapCache(page_head);
+	if (unlikely(!mapping)) {
+		int shmem_swizzled;
+
+		/*
+		 * Page lock is required to identify which special case above
+		 * applies. If this is really a shmem page then the page lock
+		 * will prevent unexpected transitions.
+		 */
+		lock_page(page);
+		shmem_swizzled = PageSwapCache(page) || page->mapping;
 		unlock_page(page_head);
 		put_page(page_head);
+
 		if (shmem_swizzled)
 			goto again;
+
 		return -EFAULT;
 	}
 
 	/*
 	 * Private mappings are handled in a simple way.
 	 *
+	 * If the futex key is stored on an anonymous page, then the associated
+	 * object is the mm which is implicitly pinned by the calling process.
+	 *
 	 * NOTE: When userspace waits on a MAP_SHARED mapping, even if
 	 * it's a read-only handle, it's expected that futexes attach to
 	 * the object not the particular process.
@@ -524,16 +550,74 @@ again:
 		key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */
 		key->private.mm = mm;
 		key->private.address = address;
+
+		get_futex_key_refs(key); /* implies smp_mb(); (B) */
+
 	} else {
+		struct inode *inode;
+
+		/*
+		 * The associated futex object in this case is the inode and
+		 * the page->mapping must be traversed. Ordinarily this should
+		 * be stabilised under page lock but it's not strictly
+		 * necessary in this case as we just want to pin the inode, not
+		 * update the radix tree or anything like that.
+		 *
+		 * The RCU read lock is taken as the inode is finally freed
+		 * under RCU. If the mapping still matches expectations then the
+		 * mapping->host can be safely accessed as being a valid inode.
+		 */
+		rcu_read_lock();
+
+		if (READ_ONCE(page_head->mapping) != mapping) {
+			rcu_read_unlock();
+			put_page(page_head);
+
+			goto again;
+		}
+
+		inode = READ_ONCE(mapping->host);
+		if (!inode) {
+			rcu_read_unlock();
+			put_page(page_head);
+
+			goto again;
+		}
+
+		/*
+		 * Take a reference unless it is about to be freed. Previously
+		 * this reference was taken by ihold under the page lock
+		 * pinning the inode in place so i_lock was unnecessary. The
+		 * only way for this check to fail is if the inode was
+		 * truncated in parallel so warn for now if this happens.
+		 *
+		 * We are not calling into get_futex_key_refs() in file-backed
+		 * cases, therefore a successful atomic_inc return below will
+		 * guarantee that get_futex_key() will still imply smp_mb(); (B).
+		 */
+		if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) {
+			rcu_read_unlock();
+			put_page(page_head);
+
+			goto again;
+		}
+
+		/* Should be impossible but lets be paranoid for now */
+		if (WARN_ON_ONCE(inode->i_mapping != mapping)) {
+			err = -EFAULT;
+			rcu_read_unlock();
+			iput(inode);
+
+			goto out;
+		}
+
 		key->both.offset |= FUT_OFF_INODE; /* inode-based key */
-		key->shared.inode = page_head->mapping->host;
+		key->shared.inode = inode;
 		key->shared.pgoff = basepage_index(page);
+		rcu_read_unlock();
 	}
 
-	get_futex_key_refs(key); /* implies MB (B) */
-
 out:
-	unlock_page(page_head);
 	put_page(page_head);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/irq/manage.c linux-libre-4.1.52-gnu/kernel/irq/manage.c
--- linux-libre-4.1.51-gnu/kernel/irq/manage.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/irq/manage.c	2018-05-27 22:26:45.000000000 -0400
@@ -1095,8 +1095,10 @@ __setup_irq(unsigned int irq, struct irq
 		 * set the trigger type must match. Also all must
 		 * agree on ONESHOT.
 		 */
+		unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data);
+
 		if (!((old->flags & new->flags) & IRQF_SHARED) ||
-		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
+		    (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
 		    ((old->flags ^ new->flags) & IRQF_ONESHOT))
 			goto mismatch;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/kprobes.c linux-libre-4.1.52-gnu/kernel/kprobes.c
--- linux-libre-4.1.51-gnu/kernel/kprobes.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/kprobes.c	2018-05-27 22:26:45.000000000 -0400
@@ -125,7 +125,7 @@ static void *alloc_insn_page(void)
 	return module_alloc(PAGE_SIZE);
 }
 
-static void free_insn_page(void *page)
+void __weak free_insn_page(void *page)
 {
 	module_memfree(page);
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/pid.c linux-libre-4.1.52-gnu/kernel/pid.c
--- linux-libre-4.1.51-gnu/kernel/pid.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/pid.c	2018-05-27 22:26:45.000000000 -0400
@@ -322,8 +322,10 @@ struct pid *alloc_pid(struct pid_namespa
 	}
 
 	if (unlikely(is_child_reaper(pid))) {
-		if (pid_ns_prepare_proc(ns))
+		if (pid_ns_prepare_proc(ns)) {
+			disable_pid_allocation(ns);
 			goto out_free;
+		}
 	}
 
 	get_pid_ns(ns);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/printk/braille.c linux-libre-4.1.52-gnu/kernel/printk/braille.c
--- linux-libre-4.1.51-gnu/kernel/printk/braille.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/printk/braille.c	2018-05-27 22:26:45.000000000 -0400
@@ -2,12 +2,13 @@
 
 #include <linux/kernel.h>
 #include <linux/console.h>
+#include <linux/errno.h>
 #include <linux/string.h>
 
 #include "console_cmdline.h"
 #include "braille.h"
 
-char *_braille_console_setup(char **str, char **brl_options)
+int _braille_console_setup(char **str, char **brl_options)
 {
 	if (!memcmp(*str, "brl,", 4)) {
 		*brl_options = "";
@@ -15,14 +16,14 @@ char *_braille_console_setup(char **str,
 	} else if (!memcmp(str, "brl=", 4)) {
 		*brl_options = *str + 4;
 		*str = strchr(*brl_options, ',');
-		if (!*str)
+		if (!*str) {
 			pr_err("need port name after brl=\n");
-		else
-			*((*str)++) = 0;
-	} else
-		return NULL;
+			return -EINVAL;
+		}
+		*((*str)++) = 0;
+	}
 
-	return *str;
+	return 0;
 }
 
 int
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/printk/braille.h linux-libre-4.1.52-gnu/kernel/printk/braille.h
--- linux-libre-4.1.51-gnu/kernel/printk/braille.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/printk/braille.h	2018-05-27 22:26:45.000000000 -0400
@@ -9,7 +9,14 @@ braille_set_options(struct console_cmdli
 	c->brl_options = brl_options;
 }
 
-char *
+/*
+ * Setup console according to braille options.
+ * Return -EINVAL on syntax error, 0 on success (or no braille option was
+ * actually given).
+ * Modifies str to point to the serial options
+ * Sets brl_options to the parsed braille options.
+ */
+int
 _braille_console_setup(char **str, char **brl_options);
 
 int
@@ -25,10 +32,10 @@ braille_set_options(struct console_cmdli
 {
 }
 
-static inline char *
+static inline int
 _braille_console_setup(char **str, char **brl_options)
 {
-	return NULL;
+	return 0;
 }
 
 static inline int
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/resource.c linux-libre-4.1.52-gnu/kernel/resource.c
--- linux-libre-4.1.51-gnu/kernel/resource.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/resource.c	2018-05-27 22:26:45.000000000 -0400
@@ -600,7 +600,8 @@ static int __find_resource(struct resour
 			alloc.start = constraint->alignf(constraint->alignf_data, &avail,
 					size, constraint->align);
 			alloc.end = alloc.start + size - 1;
-			if (resource_contains(&avail, &alloc)) {
+			if (alloc.start <= alloc.end &&
+			    resource_contains(&avail, &alloc)) {
 				new->start = alloc.start;
 				new->end = alloc.end;
 				return 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/sched/core.c linux-libre-4.1.52-gnu/kernel/sched/core.c
--- linux-libre-4.1.51-gnu/kernel/sched/core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/sched/core.c	2018-05-27 22:26:45.000000000 -0400
@@ -578,7 +578,8 @@ void resched_cpu(int cpu)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&rq->lock, flags);
-	resched_curr(rq);
+	if (cpu_online(cpu) || cpu == smp_processor_id())
+		resched_curr(rq);
 	raw_spin_unlock_irqrestore(&rq->lock, flags);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/time/sched_clock.c linux-libre-4.1.52-gnu/kernel/time/sched_clock.c
--- linux-libre-4.1.51-gnu/kernel/time/sched_clock.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/time/sched_clock.c	2018-05-27 22:26:45.000000000 -0400
@@ -205,6 +205,11 @@ sched_clock_register(u64 (*read)(void),
 
 	update_clock_read_data(&rd);
 
+	if (sched_clock_timer.function != NULL) {
+		/* update timeout for clock wrap */
+		hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
+	}
+
 	r = rate;
 	if (r >= 4000000) {
 		r /= 1000000;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/time/timer_list.c linux-libre-4.1.52-gnu/kernel/time/timer_list.c
--- linux-libre-4.1.51-gnu/kernel/time/timer_list.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/time/timer_list.c	2018-05-27 22:26:45.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
+#include <linux/nmi.h>
 
 #include <asm/uaccess.h>
 
@@ -91,6 +92,9 @@ print_active_timers(struct seq_file *m,
 
 next_one:
 	i = 0;
+
+	touch_nmi_watchdog();
+
 	raw_spin_lock_irqsave(&base->cpu_base->lock, flags);
 
 	curr = timerqueue_getnext(&base->active);
@@ -202,6 +206,8 @@ print_tickdevice(struct seq_file *m, str
 {
 	struct clock_event_device *dev = td->evtdev;
 
+	touch_nmi_watchdog();
+
 	SEQ_printf(m, "Tick Device: mode:     %d\n", td->mode);
 	if (cpu < 0)
 		SEQ_printf(m, "Broadcast device\n");
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/trace/trace_kprobe.c linux-libre-4.1.52-gnu/kernel/trace/trace_kprobe.c
--- linux-libre-4.1.51-gnu/kernel/trace/trace_kprobe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/trace/trace_kprobe.c	2018-05-27 22:26:45.000000000 -0400
@@ -611,7 +611,7 @@ static int create_trace_kprobe(int argc,
 	bool is_return = false, is_delete = false;
 	char *symbol = NULL, *event = NULL, *group = NULL;
 	char *arg;
-	unsigned long offset = 0;
+	long offset = 0;
 	void *addr = NULL;
 	char buf[MAX_EVENT_NAME_LEN];
 
@@ -679,7 +679,7 @@ static int create_trace_kprobe(int argc,
 		symbol = argv[1];
 		/* TODO: support .init module functions */
 		ret = traceprobe_split_symbol_offset(symbol, &offset);
-		if (ret) {
+		if (ret || offset < 0 || offset > UINT_MAX) {
 			pr_info("Failed to parse either an address or a symbol.\n");
 			return ret;
 		}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/trace/trace_probe.c linux-libre-4.1.52-gnu/kernel/trace/trace_probe.c
--- linux-libre-4.1.51-gnu/kernel/trace/trace_probe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/trace/trace_probe.c	2018-05-27 22:26:45.000000000 -0400
@@ -293,7 +293,7 @@ static fetch_func_t get_fetch_size_funct
 }
 
 /* Split symbol and offset. */
-int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
+int traceprobe_split_symbol_offset(char *symbol, long *offset)
 {
 	char *tmp;
 	int ret;
@@ -301,13 +301,11 @@ int traceprobe_split_symbol_offset(char
 	if (!offset)
 		return -EINVAL;
 
-	tmp = strchr(symbol, '+');
+	tmp = strpbrk(symbol, "+-");
 	if (tmp) {
-		/* skip sign because kstrtoul doesn't accept '+' */
-		ret = kstrtoul(tmp + 1, 0, offset);
+		ret = kstrtol(tmp, 0, offset);
 		if (ret)
 			return ret;
-
 		*tmp = '\0';
 	} else
 		*offset = 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/trace/trace_probe.h linux-libre-4.1.52-gnu/kernel/trace/trace_probe.h
--- linux-libre-4.1.51-gnu/kernel/trace/trace_probe.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/trace/trace_probe.h	2018-05-27 22:26:45.000000000 -0400
@@ -335,7 +335,7 @@ extern int traceprobe_conflict_field_nam
 extern void traceprobe_update_arg(struct probe_arg *arg);
 extern void traceprobe_free_probe_arg(struct probe_arg *arg);
 
-extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
+extern int traceprobe_split_symbol_offset(char *symbol, long *offset);
 
 extern ssize_t traceprobe_probes_write(struct file *file,
 		const char __user *buffer, size_t count, loff_t *ppos,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/trace/trace_uprobe.c linux-libre-4.1.52-gnu/kernel/trace/trace_uprobe.c
--- linux-libre-4.1.51-gnu/kernel/trace/trace_uprobe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/trace/trace_uprobe.c	2018-05-27 22:26:45.000000000 -0400
@@ -149,6 +149,8 @@ static void FETCH_FUNC_NAME(memory, stri
 		return;
 
 	ret = strncpy_from_user(dst, src, maxlen);
+	if (ret == maxlen)
+		dst[--ret] = '\0';
 
 	if (ret < 0) {	/* Failed to fetch string */
 		((u8 *)get_rloc_data(dest))[0] = '\0';
diff -druNp --no-dereference linux-libre-4.1.51-gnu/kernel/tracepoint.c linux-libre-4.1.52-gnu/kernel/tracepoint.c
--- linux-libre-4.1.51-gnu/kernel/tracepoint.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/kernel/tracepoint.c	2018-05-27 22:26:45.000000000 -0400
@@ -185,7 +185,7 @@ static int tracepoint_add_func(struct tr
 			lockdep_is_held(&tracepoints_mutex));
 	old = func_add(&tp_funcs, func);
 	if (IS_ERR(old)) {
-		WARN_ON_ONCE(1);
+		WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
 		return PTR_ERR(old);
 	}
 
@@ -218,7 +218,7 @@ static int tracepoint_remove_func(struct
 			lockdep_is_held(&tracepoints_mutex));
 	old = func_remove(&tp_funcs, func);
 	if (IS_ERR(old)) {
-		WARN_ON_ONCE(1);
+		WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
 		return PTR_ERR(old);
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/lib/kobject.c linux-libre-4.1.52-gnu/lib/kobject.c
--- linux-libre-4.1.51-gnu/lib/kobject.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/lib/kobject.c	2018-05-27 22:26:45.000000000 -0400
@@ -234,14 +234,12 @@ static int kobject_add_internal(struct k
 
 		/* be noisy on error issues */
 		if (error == -EEXIST)
-			WARN(1, "%s failed for %s with "
-			     "-EEXIST, don't try to register things with "
-			     "the same name in the same directory.\n",
-			     __func__, kobject_name(kobj));
+			pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
+			       __func__, kobject_name(kobj));
 		else
-			WARN(1, "%s failed for %s (error: %d parent: %s)\n",
-			     __func__, kobject_name(kobj), error,
-			     parent ? kobject_name(parent) : "'none'");
+			pr_err("%s failed for %s (error: %d parent: %s)\n",
+			       __func__, kobject_name(kobj), error,
+			       parent ? kobject_name(parent) : "'none'");
 	} else
 		kobj->state_in_sysfs = 1;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/Makefile linux-libre-4.1.52-gnu/Makefile
--- linux-libre-4.1.51-gnu/Makefile	2018-03-28 09:43:19.000000000 -0400
+++ linux-libre-4.1.52-gnu/Makefile	2018-05-29 04:30:24.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 1
-SUBLEVEL = 51
+SUBLEVEL = 52
 EXTRAVERSION = -gnu
 NAME = Series 4800
 
@@ -772,6 +772,15 @@ KBUILD_CFLAGS += $(call cc-disable-warni
 # disable invalid "can't wrap" optimizations for signed / pointers
 KBUILD_CFLAGS	+= $(call cc-option,-fno-strict-overflow)
 
+# clang sets -fmerge-all-constants by default as optimization, but this
+# is non-conforming behavior for C and in fact breaks the kernel, so we
+# need to disable it here generally.
+KBUILD_CFLAGS	+= $(call cc-option,-fno-merge-all-constants)
+
+# for gcc -fno-merge-all-constants disables everything, but it is fine
+# to have actual conforming behavior enabled.
+KBUILD_CFLAGS	+= $(call cc-option,-fmerge-constants)
+
 # Make sure -fstack-check isn't enabled (like gentoo apparently did)
 KBUILD_CFLAGS  += $(call cc-option,-fno-stack-check,)
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/mm/percpu.c linux-libre-4.1.52-gnu/mm/percpu.c
--- linux-libre-4.1.51-gnu/mm/percpu.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/mm/percpu.c	2018-05-27 22:26:45.000000000 -0400
@@ -68,6 +68,7 @@
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
 #include <linux/kmemleak.h>
+#include <linux/sched.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/8021q/vlan_dev.c linux-libre-4.1.52-gnu/net/8021q/vlan_dev.c
--- linux-libre-4.1.51-gnu/net/8021q/vlan_dev.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/8021q/vlan_dev.c	2018-05-27 22:26:45.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/net_tstamp.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/phy.h>
 #include <net/arp.h>
 
 #include "vlan.h"
@@ -559,8 +560,7 @@ static int vlan_dev_init(struct net_devi
 			   NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM |
 			   NETIF_F_ALL_FCOE;
 
-	dev->features |= real_dev->vlan_features | NETIF_F_LLTX |
-			 NETIF_F_GSO_SOFTWARE;
+	dev->features |= dev->hw_features | NETIF_F_LLTX;
 	dev->gso_max_size = real_dev->gso_max_size;
 	if (dev->features & NETIF_F_VLAN_FEATURES)
 		netdev_warn(real_dev, "VLAN features are set incorrectly.  Q-in-Q configurations may not work correctly.\n");
@@ -655,8 +655,11 @@ static int vlan_ethtool_get_ts_info(stru
 {
 	const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
 	const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops;
+	struct phy_device *phydev = vlan->real_dev->phydev;
 
-	if (ops->get_ts_info) {
+	if (phydev && phydev->drv && phydev->drv->ts_info) {
+		 return phydev->drv->ts_info(phydev, info);
+	} else if (ops->get_ts_info) {
 		return ops->get_ts_info(vlan->real_dev, info);
 	} else {
 		info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/batman-adv/bridge_loop_avoidance.c linux-libre-4.1.52-gnu/net/batman-adv/bridge_loop_avoidance.c
--- linux-libre-4.1.51-gnu/net/batman-adv/bridge_loop_avoidance.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/batman-adv/bridge_loop_avoidance.c	2018-05-27 22:26:45.000000000 -0400
@@ -1589,10 +1589,22 @@ int batadv_bla_tx(struct batadv_priv *ba
 		/* if yes, the client has roamed and we have
 		 * to unclaim it.
 		 */
-		batadv_handle_unclaim(bat_priv, primary_if,
-				      primary_if->net_dev->dev_addr,
-				      ethhdr->h_source, vid);
-		goto allow;
+		if (batadv_has_timed_out(claim->lasttime, 100)) {
+			/* only unclaim if the last claim entry is
+			 * older than 100 ms to make sure we really
+			 * have a roaming client here.
+			 */
+			batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_tx(): Roaming client %pM detected. Unclaim it.\n",
+				   ethhdr->h_source);
+			batadv_handle_unclaim(bat_priv, primary_if,
+					      primary_if->net_dev->dev_addr,
+					      ethhdr->h_source, vid);
+			goto allow;
+		} else {
+			batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_tx(): Race for claim %pM detected. Drop packet.\n",
+				   ethhdr->h_source);
+			goto handled;
+		}
 	}
 
 	/* check if it is a multicast/broadcast frame */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/bluetooth/hci_core.c linux-libre-4.1.52-gnu/net/bluetooth/hci_core.c
--- linux-libre-4.1.51-gnu/net/bluetooth/hci_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/bluetooth/hci_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -663,6 +663,7 @@ static void hci_set_event_mask_page_2(st
 {
 	struct hci_dev *hdev = req->hdev;
 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	bool changed = false;
 
 	/* If Connectionless Slave Broadcast master role is supported
 	 * enable all necessary events for it.
@@ -672,6 +673,7 @@ static void hci_set_event_mask_page_2(st
 		events[1] |= 0x80;	/* Synchronization Train Complete */
 		events[2] |= 0x10;	/* Slave Page Response Timeout */
 		events[2] |= 0x20;	/* CSB Channel Map Change */
+		changed = true;
 	}
 
 	/* If Connectionless Slave Broadcast slave role is supported
@@ -682,13 +684,24 @@ static void hci_set_event_mask_page_2(st
 		events[2] |= 0x02;	/* CSB Receive */
 		events[2] |= 0x04;	/* CSB Timeout */
 		events[2] |= 0x08;	/* Truncated Page Complete */
+		changed = true;
 	}
 
 	/* Enable Authenticated Payload Timeout Expired event if supported */
-	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
+	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) {
 		events[2] |= 0x80;
+		changed = true;
+	}
 
-	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
+	/* Some Broadcom based controllers indicate support for Set Event
+	 * Mask Page 2 command, but then actually do not support it. Since
+	 * the default value is all bits set to zero, the command is only
+	 * required if the event mask has to be changed. In case no change
+	 * to the event mask is needed, skip this command.
+	 */
+	if (changed)
+		hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2,
+			    sizeof(events), events);
 }
 
 static void hci_init3_req(struct hci_request *req, unsigned long opt)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/bluetooth/smp.c linux-libre-4.1.52-gnu/net/bluetooth/smp.c
--- linux-libre-4.1.51-gnu/net/bluetooth/smp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/bluetooth/smp.c	2018-05-27 22:26:45.000000000 -0400
@@ -2250,8 +2250,14 @@ static u8 smp_cmd_security_req(struct l2
 	else
 		sec_level = authreq_to_seclevel(auth);
 
-	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
+	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) {
+		/* If link is already encrypted with sufficient security we
+		 * still need refresh encryption as per Core Spec 5.0 Vol 3,
+		 * Part H 2.4.6
+		 */
+		smp_ltk_encrypt(conn, hcon->sec_level);
 		return 0;
+	}
 
 	if (sec_level > hcon->pending_sec_level)
 		hcon->pending_sec_level = sec_level;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/bridge/netfilter/ebt_among.c linux-libre-4.1.52-gnu/net/bridge/netfilter/ebt_among.c
--- linux-libre-4.1.51-gnu/net/bridge/netfilter/ebt_among.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/bridge/netfilter/ebt_among.c	2018-05-27 22:26:45.000000000 -0400
@@ -177,6 +177,28 @@ static bool poolsize_invalid(const struc
 	return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple));
 }
 
+static bool wormhash_offset_invalid(int off, unsigned int len)
+{
+	if (off == 0) /* not present */
+		return false;
+
+	if (off < (int)sizeof(struct ebt_among_info) ||
+	    off % __alignof__(struct ebt_mac_wormhash))
+		return true;
+
+	off += sizeof(struct ebt_mac_wormhash);
+
+	return off > len;
+}
+
+static bool wormhash_sizes_valid(const struct ebt_mac_wormhash *wh, int a, int b)
+{
+	if (a == 0)
+		a = sizeof(struct ebt_among_info);
+
+	return ebt_mac_wormhash_size(wh) + a == b;
+}
+
 static int ebt_among_mt_check(const struct xt_mtchk_param *par)
 {
 	const struct ebt_among_info *info = par->matchinfo;
@@ -189,6 +211,10 @@ static int ebt_among_mt_check(const stru
 	if (expected_length > em->match_size)
 		return -EINVAL;
 
+	if (wormhash_offset_invalid(info->wh_dst_ofs, em->match_size) ||
+	    wormhash_offset_invalid(info->wh_src_ofs, em->match_size))
+		return -EINVAL;
+
 	wh_dst = ebt_among_wh_dst(info);
 	if (poolsize_invalid(wh_dst))
 		return -EINVAL;
@@ -201,6 +227,14 @@ static int ebt_among_mt_check(const stru
 	if (poolsize_invalid(wh_src))
 		return -EINVAL;
 
+	if (info->wh_src_ofs < info->wh_dst_ofs) {
+		if (!wormhash_sizes_valid(wh_src, info->wh_src_ofs, info->wh_dst_ofs))
+			return -EINVAL;
+	} else {
+		if (!wormhash_sizes_valid(wh_dst, info->wh_dst_ofs, info->wh_src_ofs))
+			return -EINVAL;
+	}
+
 	expected_length += ebt_mac_wormhash_size(wh_src);
 
 	if (em->match_size != EBT_ALIGN(expected_length)) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ceph/messenger.c linux-libre-4.1.52-gnu/net/ceph/messenger.c
--- linux-libre-4.1.51-gnu/net/ceph/messenger.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ceph/messenger.c	2018-05-27 22:26:45.000000000 -0400
@@ -2518,6 +2518,11 @@ static int try_write(struct ceph_connect
 	int ret = 1;
 
 	dout("try_write start %p state %lu\n", con, con->state);
+	if (con->state != CON_STATE_PREOPEN &&
+	    con->state != CON_STATE_CONNECTING &&
+	    con->state != CON_STATE_NEGOTIATING &&
+	    con->state != CON_STATE_OPEN)
+		return 0;
 
 more:
 	dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
@@ -2543,6 +2548,8 @@ more:
 	}
 
 more_kvec:
+	BUG_ON(!con->sock);
+
 	/* kvec data queued? */
 	if (con->out_kvec_left) {
 		ret = write_partial_kvec(con);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ceph/osdmap.c linux-libre-4.1.52-gnu/net/ceph/osdmap.c
--- linux-libre-4.1.51-gnu/net/ceph/osdmap.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ceph/osdmap.c	2018-05-27 22:26:45.000000000 -0400
@@ -295,6 +295,7 @@ static struct crush_map *crush_decode(vo
 		u32 yes;
 		struct crush_rule *r;
 
+		err = -EINVAL;
 		ceph_decode_32_safe(p, end, yes, bad);
 		if (!yes) {
 			dout("crush_decode NO rule %d off %x %p to %p\n",
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/core/dev_addr_lists.c linux-libre-4.1.52-gnu/net/core/dev_addr_lists.c
--- linux-libre-4.1.51-gnu/net/core/dev_addr_lists.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/core/dev_addr_lists.c	2018-05-27 22:26:45.000000000 -0400
@@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netde
 		return -EINVAL;
 
 	list_for_each_entry(ha, &list->list, list) {
-		if (!memcmp(ha->addr, addr, addr_len) &&
-		    ha->type == addr_type) {
+		if (ha->type == addr_type &&
+		    !memcmp(ha->addr, addr, addr_len)) {
 			if (global) {
 				/* check if addr is already used as global */
 				if (ha->global_use)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/core/dev.c linux-libre-4.1.52-gnu/net/core/dev.c
--- linux-libre-4.1.51-gnu/net/core/dev.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/core/dev.c	2018-05-27 22:26:45.000000000 -0400
@@ -957,7 +957,7 @@ bool dev_valid_name(const char *name)
 {
 	if (*name == '\0')
 		return false;
-	if (strlen(name) >= IFNAMSIZ)
+	if (strnlen(name, IFNAMSIZ) == IFNAMSIZ)
 		return false;
 	if (!strcmp(name, ".") || !strcmp(name, ".."))
 		return false;
@@ -2430,7 +2430,7 @@ __be16 skb_network_protocol(struct sk_bu
 		if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr))))
 			return 0;
 
-		eth = (struct ethhdr *)skb_mac_header(skb);
+		eth = (struct ethhdr *)skb->data;
 		type = eth->h_proto;
 	}
 
@@ -2621,7 +2621,7 @@ netdev_features_t passthru_features_chec
 }
 EXPORT_SYMBOL(passthru_features_check);
 
-static netdev_features_t dflt_features_check(const struct sk_buff *skb,
+static netdev_features_t dflt_features_check(struct sk_buff *skb,
 					     struct net_device *dev,
 					     netdev_features_t features)
 {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/core/neighbour.c linux-libre-4.1.52-gnu/net/core/neighbour.c
--- linux-libre-4.1.51-gnu/net/core/neighbour.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/core/neighbour.c	2018-05-27 22:26:45.000000000 -0400
@@ -54,7 +54,8 @@ do {						\
 static void neigh_timer_handler(unsigned long arg);
 static void __neigh_notify(struct neighbour *n, int type, int flags);
 static void neigh_update_notify(struct neighbour *neigh);
-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
+static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
+				    struct net_device *dev);
 
 #ifdef CONFIG_PROC_FS
 static const struct file_operations neigh_stat_seq_fops;
@@ -254,8 +255,7 @@ int neigh_ifdown(struct neigh_table *tbl
 {
 	write_lock_bh(&tbl->lock);
 	neigh_flush_dev(tbl, dev);
-	pneigh_ifdown(tbl, dev);
-	write_unlock_bh(&tbl->lock);
+	pneigh_ifdown_and_unlock(tbl, dev);
 
 	del_timer_sync(&tbl->proxy_timer);
 	pneigh_queue_purge(&tbl->proxy_queue);
@@ -641,9 +641,10 @@ int pneigh_delete(struct neigh_table *tb
 	return -ENOENT;
 }
 
-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
+static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
+				    struct net_device *dev)
 {
-	struct pneigh_entry *n, **np;
+	struct pneigh_entry *n, **np, *freelist = NULL;
 	u32 h;
 
 	for (h = 0; h <= PNEIGH_HASHMASK; h++) {
@@ -651,16 +652,23 @@ static int pneigh_ifdown(struct neigh_ta
 		while ((n = *np) != NULL) {
 			if (!dev || n->dev == dev) {
 				*np = n->next;
-				if (tbl->pdestructor)
-					tbl->pdestructor(n);
-				if (n->dev)
-					dev_put(n->dev);
-				kfree(n);
+				n->next = freelist;
+				freelist = n;
 				continue;
 			}
 			np = &n->next;
 		}
 	}
+	write_unlock_bh(&tbl->lock);
+	while ((n = freelist)) {
+		freelist = n->next;
+		n->next = NULL;
+		if (tbl->pdestructor)
+			tbl->pdestructor(n);
+		if (n->dev)
+			dev_put(n->dev);
+		kfree(n);
+	}
 	return -ENOENT;
 }
 
@@ -1127,10 +1135,6 @@ int neigh_update(struct neighbour *neigh
 		lladdr = neigh->ha;
 	}
 
-	if (new & NUD_CONNECTED)
-		neigh->confirmed = jiffies;
-	neigh->updated = jiffies;
-
 	/* If entry was valid and address is not changed,
 	   do not change entry state, if new one is STALE.
 	 */
@@ -1154,6 +1158,16 @@ int neigh_update(struct neighbour *neigh
 		}
 	}
 
+	/* Update timestamps only once we know we will make a change to the
+	 * neighbour entry. Otherwise we risk to move the locktime window with
+	 * noop updates and ignore relevant ARP updates.
+	 */
+	if (new != old || lladdr != neigh->ha) {
+		if (new & NUD_CONNECTED)
+			neigh->confirmed = jiffies;
+		neigh->updated = jiffies;
+	}
+
 	if (new != old) {
 		neigh_del_timer(neigh);
 		if (new & NUD_IN_TIMER)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/core/net_namespace.c linux-libre-4.1.52-gnu/net/core/net_namespace.c
--- linux-libre-4.1.51-gnu/net/core/net_namespace.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/core/net_namespace.c	2018-05-27 22:26:45.000000000 -0400
@@ -268,6 +268,25 @@ out_undo:
 	goto out;
 }
 
+static int __net_init net_defaults_init_net(struct net *net)
+{
+	net->core.sysctl_somaxconn = SOMAXCONN;
+	return 0;
+}
+
+static struct pernet_operations net_defaults_ops = {
+	.init = net_defaults_init_net,
+};
+
+static __init int net_defaults_init(void)
+{
+	if (register_pernet_subsys(&net_defaults_ops))
+		panic("Cannot initialize net default settings");
+
+	return 0;
+}
+
+core_initcall(net_defaults_init);
 
 #ifdef CONFIG_NET_NS
 static struct kmem_cache *net_cachep;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/core/skbuff.c linux-libre-4.1.52-gnu/net/core/skbuff.c
--- linux-libre-4.1.51-gnu/net/core/skbuff.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/core/skbuff.c	2018-05-27 22:26:45.000000000 -0400
@@ -875,6 +875,7 @@ static struct sk_buff *__skb_clone(struc
 	n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
 	n->cloned = 1;
 	n->nohdr = 0;
+	n->peeked = 0;
 	n->destructor = NULL;
 	C(tail);
 	C(end);
@@ -2587,7 +2588,8 @@ void skb_split(struct sk_buff *skb, stru
 {
 	int pos = skb_headlen(skb);
 
-	skb_shinfo(skb1)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
+	skb_shinfo(skb1)->tx_flags |= skb_shinfo(skb)->tx_flags &
+				      SKBTX_SHARED_FRAG;
 	if (len < pos)	/* Split line is inside header. */
 		skb_split_inside_header(skb, skb1, len, pos);
 	else		/* Second chunk has no header, nothing to copy. */
@@ -3133,8 +3135,8 @@ struct sk_buff *skb_segment(struct sk_bu
 		skb_copy_from_linear_data_offset(head_skb, offset,
 						 skb_put(nskb, hsize), hsize);
 
-		skb_shinfo(nskb)->tx_flags = skb_shinfo(head_skb)->tx_flags &
-			SKBTX_SHARED_FRAG;
+		skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
+					      SKBTX_SHARED_FRAG;
 
 		while (pos < offset + len) {
 			if (i >= nfrags) {
@@ -3347,24 +3349,18 @@ void __init skb_init(void)
 						NULL);
 }
 
-/**
- *	skb_to_sgvec - Fill a scatter-gather list from a socket buffer
- *	@skb: Socket buffer containing the buffers to be mapped
- *	@sg: The scatter-gather list to map into
- *	@offset: The offset into the buffer's contents to start mapping
- *	@len: Length of buffer space to be mapped
- *
- *	Fill the specified scatter-gather list with mappings/pointers into a
- *	region of the buffer space attached to a socket buffer.
- */
 static int
-__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
+__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len,
+	       unsigned int recursion_level)
 {
 	int start = skb_headlen(skb);
 	int i, copy = start - offset;
 	struct sk_buff *frag_iter;
 	int elt = 0;
 
+	if (unlikely(recursion_level >= 24))
+		return -EMSGSIZE;
+
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
@@ -3383,6 +3379,8 @@ __skb_to_sgvec(struct sk_buff *skb, stru
 		end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);
 		if ((copy = end - offset) > 0) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			if (unlikely(elt && sg_is_last(&sg[elt - 1])))
+				return -EMSGSIZE;
 
 			if (copy > len)
 				copy = len;
@@ -3397,16 +3395,22 @@ __skb_to_sgvec(struct sk_buff *skb, stru
 	}
 
 	skb_walk_frags(skb, frag_iter) {
-		int end;
+		int end, ret;
 
 		WARN_ON(start > offset + len);
 
 		end = start + frag_iter->len;
 		if ((copy = end - offset) > 0) {
+			if (unlikely(elt && sg_is_last(&sg[elt - 1])))
+				return -EMSGSIZE;
+
 			if (copy > len)
 				copy = len;
-			elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start,
-					      copy);
+			ret = __skb_to_sgvec(frag_iter, sg+elt, offset - start,
+					      copy, recursion_level + 1);
+			if (unlikely(ret < 0))
+				return ret;
+			elt += ret;
 			if ((len -= copy) == 0)
 				return elt;
 			offset += copy;
@@ -3417,6 +3421,31 @@ __skb_to_sgvec(struct sk_buff *skb, stru
 	return elt;
 }
 
+/**
+ *	skb_to_sgvec - Fill a scatter-gather list from a socket buffer
+ *	@skb: Socket buffer containing the buffers to be mapped
+ *	@sg: The scatter-gather list to map into
+ *	@offset: The offset into the buffer's contents to start mapping
+ *	@len: Length of buffer space to be mapped
+ *
+ *	Fill the specified scatter-gather list with mappings/pointers into a
+ *	region of the buffer space attached to a socket buffer. Returns either
+ *	the number of scatterlist items used, or -EMSGSIZE if the contents
+ *	could not fit.
+ */
+int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
+{
+	int nsg = __skb_to_sgvec(skb, sg, offset, len, 0);
+
+	if (nsg <= 0)
+		return nsg;
+
+	sg_mark_end(&sg[nsg - 1]);
+
+	return nsg;
+}
+EXPORT_SYMBOL_GPL(skb_to_sgvec);
+
 /* As compared with skb_to_sgvec, skb_to_sgvec_nomark only map skb to given
  * sglist without mark the sg which contain last skb data as the end.
  * So the caller can mannipulate sg list as will when padding new data after
@@ -3439,19 +3468,11 @@ __skb_to_sgvec(struct sk_buff *skb, stru
 int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg,
 			int offset, int len)
 {
-	return __skb_to_sgvec(skb, sg, offset, len);
+	return __skb_to_sgvec(skb, sg, offset, len, 0);
 }
 EXPORT_SYMBOL_GPL(skb_to_sgvec_nomark);
 
-int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
-{
-	int nsg = __skb_to_sgvec(skb, sg, offset, len);
 
-	sg_mark_end(&sg[nsg - 1]);
-
-	return nsg;
-}
-EXPORT_SYMBOL_GPL(skb_to_sgvec);
 
 /**
  *	skb_cow_data - Check that a socket buffer's data buffers are writable
@@ -3589,7 +3610,7 @@ int sock_queue_err_skb(struct sock *sk,
 
 	skb_queue_tail(&sk->sk_error_queue, skb);
 	if (!sock_flag(sk, SOCK_DEAD))
-		sk->sk_data_ready(sk);
+		sk->sk_error_report(sk);
 	return 0;
 }
 EXPORT_SYMBOL(sock_queue_err_skb);
@@ -3733,7 +3754,8 @@ void __skb_tstamp_tx(struct sk_buff *ori
 		return;
 
 	if (tsonly) {
-		skb_shinfo(skb)->tx_flags = skb_shinfo(orig_skb)->tx_flags;
+		skb_shinfo(skb)->tx_flags |= skb_shinfo(orig_skb)->tx_flags &
+					     SKBTX_ANY_TSTAMP;
 		skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/core/sysctl_net_core.c linux-libre-4.1.52-gnu/net/core/sysctl_net_core.c
--- linux-libre-4.1.51-gnu/net/core/sysctl_net_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/core/sysctl_net_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -423,8 +423,6 @@ static __net_init int sysctl_core_net_in
 {
 	struct ctl_table *tbl;
 
-	net->core.sysctl_somaxconn = SOMAXCONN;
-
 	tbl = netns_core_table;
 	if (!net_eq(net, &init_net)) {
 		tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/dccp/ipv4.c linux-libre-4.1.52-gnu/net/dccp/ipv4.c
--- linux-libre-4.1.51-gnu/net/dccp/ipv4.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/dccp/ipv4.c	2018-05-27 22:26:45.000000000 -0400
@@ -642,6 +642,7 @@ int dccp_v4_conn_request(struct sock *sk
 	ireq = inet_rsk(req);
 	sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
 	sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
+	ireq->ir_mark = inet_request_mark(sk, skb);
 	ireq->ireq_family = AF_INET;
 	ireq->ir_iif = sk->sk_bound_dev_if;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/dccp/ipv6.c linux-libre-4.1.52-gnu/net/dccp/ipv6.c
--- linux-libre-4.1.51-gnu/net/dccp/ipv6.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/dccp/ipv6.c	2018-05-27 22:26:45.000000000 -0400
@@ -375,6 +375,7 @@ static int dccp_v6_conn_request(struct s
 	ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
 	ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
 	ireq->ireq_family = AF_INET6;
+	ireq->ir_mark = inet_request_mark(sk, skb);
 
 	if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) ||
 	    np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/dccp/proto.c linux-libre-4.1.52-gnu/net/dccp/proto.c
--- linux-libre-4.1.51-gnu/net/dccp/proto.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/dccp/proto.c	2018-05-27 22:26:45.000000000 -0400
@@ -790,6 +790,11 @@ int dccp_sendmsg(struct sock *sk, struct
 	if (skb == NULL)
 		goto out_release;
 
+	if (sk->sk_state == DCCP_CLOSED) {
+		rc = -ENOTCONN;
+		goto out_discard;
+	}
+
 	skb_reserve(skb, sk->sk_prot->max_header);
 	rc = memcpy_from_msg(skb_put(skb, len), msg, len);
 	if (rc != 0)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/dns_resolver/dns_key.c linux-libre-4.1.52-gnu/net/dns_resolver/dns_key.c
--- linux-libre-4.1.51-gnu/net/dns_resolver/dns_key.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/dns_resolver/dns_key.c	2018-05-27 22:26:45.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/ratelimit.h>
 #include <linux/kernel.h>
 #include <linux/keyctl.h>
 #include <linux/err.h>
@@ -91,9 +92,9 @@ dns_resolver_preparse(struct key_prepars
 
 			next_opt = memchr(opt, '#', end - opt) ?: end;
 			opt_len = next_opt - opt;
-			if (!opt_len) {
-				printk(KERN_WARNING
-				       "Empty option to dns_resolver key\n");
+			if (opt_len <= 0 || opt_len > 128) {
+				pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n",
+						    opt_len);
 				return -EINVAL;
 			}
 
@@ -127,10 +128,8 @@ dns_resolver_preparse(struct key_prepars
 			}
 
 		bad_option_value:
-			printk(KERN_WARNING
-			       "Option '%*.*s' to dns_resolver key:"
-			       " bad/missing value\n",
-			       opt_nlen, opt_nlen, opt);
+			pr_warn_ratelimited("Option '%*.*s' to dns_resolver key: bad/missing value\n",
+					    opt_nlen, opt_nlen, opt);
 			return -EINVAL;
 		} while (opt = next_opt + 1, opt < end);
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ieee802154/socket.c linux-libre-4.1.52-gnu/net/ieee802154/socket.c
--- linux-libre-4.1.51-gnu/net/ieee802154/socket.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ieee802154/socket.c	2018-05-27 22:26:45.000000000 -0400
@@ -310,12 +310,12 @@ static int raw_sendmsg(struct sock *sk,
 	skb->sk  = sk;
 	skb->protocol = htons(ETH_P_IEEE802154);
 
-	dev_put(dev);
-
 	err = dev_queue_xmit(skb);
 	if (err > 0)
 		err = net_xmit_errno(err);
 
+	dev_put(dev);
+
 	return err ?: size;
 
 out_skb:
@@ -697,12 +697,12 @@ static int dgram_sendmsg(struct sock *sk
 	skb->sk  = sk;
 	skb->protocol = htons(ETH_P_IEEE802154);
 
-	dev_put(dev);
-
 	err = dev_queue_xmit(skb);
 	if (err > 0)
 		err = net_xmit_errno(err);
 
+	dev_put(dev);
+
 	return err ?: size;
 
 out_skb:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/inet_timewait_sock.c linux-libre-4.1.52-gnu/net/ipv4/inet_timewait_sock.c
--- linux-libre-4.1.51-gnu/net/ipv4/inet_timewait_sock.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/inet_timewait_sock.c	2018-05-27 22:26:45.000000000 -0400
@@ -212,6 +212,7 @@ struct inet_timewait_sock *inet_twsk_all
 		tw->tw_dport	    = inet->inet_dport;
 		tw->tw_family	    = sk->sk_family;
 		tw->tw_reuse	    = sk->sk_reuse;
+		tw->tw_reuseport    = sk->sk_reuseport;
 		tw->tw_hash	    = sk->sk_hash;
 		tw->tw_ipv6only	    = 0;
 		tw->tw_transparent  = inet->transparent;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/ip_sockglue.c linux-libre-4.1.52-gnu/net/ipv4/ip_sockglue.c
--- linux-libre-4.1.51-gnu/net/ipv4/ip_sockglue.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/ip_sockglue.c	2018-05-27 22:26:45.000000000 -0400
@@ -239,7 +239,8 @@ int ip_cmsg_send(struct net *net, struct
 			src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
 			if (!ipv6_addr_v4mapped(&src_info->ipi6_addr))
 				return -EINVAL;
-			ipc->oif = src_info->ipi6_ifindex;
+			if (src_info->ipi6_ifindex)
+				ipc->oif = src_info->ipi6_ifindex;
 			ipc->addr = src_info->ipi6_addr.s6_addr32[3];
 			continue;
 		}
@@ -262,7 +263,8 @@ int ip_cmsg_send(struct net *net, struct
 			if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo)))
 				return -EINVAL;
 			info = (struct in_pktinfo *)CMSG_DATA(cmsg);
-			ipc->oif = info->ipi_ifindex;
+			if (info->ipi_ifindex)
+				ipc->oif = info->ipi_ifindex;
 			ipc->addr = info->ipi_spec_dst.s_addr;
 			break;
 		}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/ip_tunnel.c linux-libre-4.1.52-gnu/net/ipv4/ip_tunnel.c
--- linux-libre-4.1.51-gnu/net/ipv4/ip_tunnel.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/ip_tunnel.c	2018-05-27 22:26:45.000000000 -0400
@@ -301,13 +301,14 @@ static struct net_device *__ip_tunnel_cr
 	struct net_device *dev;
 	char name[IFNAMSIZ];
 
-	if (parms->name[0])
+	err = -E2BIG;
+	if (parms->name[0]) {
+		if (!dev_valid_name(parms->name))
+			goto failed;
 		strlcpy(name, parms->name, IFNAMSIZ);
-	else {
-		if (strlen(ops->kind) > (IFNAMSIZ - 3)) {
-			err = -E2BIG;
+	} else {
+		if (strlen(ops->kind) > (IFNAMSIZ - 3))
 			goto failed;
-		}
 		strlcpy(name, ops->kind, IFNAMSIZ);
 		strncat(name, "%d", 2);
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/netfilter/nf_nat_h323.c linux-libre-4.1.52-gnu/net/ipv4/netfilter/nf_nat_h323.c
--- linux-libre-4.1.51-gnu/net/ipv4/netfilter/nf_nat_h323.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/netfilter/nf_nat_h323.c	2018-05-27 22:26:45.000000000 -0400
@@ -252,16 +252,16 @@ static int nat_rtp_rtcp(struct sk_buff *
 	if (set_h245_addr(skb, protoff, data, dataoff, taddr,
 			  &ct->tuplehash[!dir].tuple.dst.u3,
 			  htons((port & htons(1)) ? nated_port + 1 :
-						    nated_port)) == 0) {
-		/* Save ports */
-		info->rtp_port[i][dir] = rtp_port;
-		info->rtp_port[i][!dir] = htons(nated_port);
-	} else {
+						    nated_port))) {
 		nf_ct_unexpect_related(rtp_exp);
 		nf_ct_unexpect_related(rtcp_exp);
 		return -1;
 	}
 
+	/* Save ports */
+	info->rtp_port[i][dir] = rtp_port;
+	info->rtp_port[i][!dir] = htons(nated_port);
+
 	/* Success */
 	pr_debug("nf_nat_h323: expect RTP %pI4:%hu->%pI4:%hu\n",
 		 &rtp_exp->tuple.src.u3.ip,
@@ -370,15 +370,15 @@ static int nat_h245(struct sk_buff *skb,
 	/* Modify signal */
 	if (set_h225_addr(skb, protoff, data, dataoff, taddr,
 			  &ct->tuplehash[!dir].tuple.dst.u3,
-			  htons(nated_port)) == 0) {
-		/* Save ports */
-		info->sig_port[dir] = port;
-		info->sig_port[!dir] = htons(nated_port);
-	} else {
+			  htons(nated_port))) {
 		nf_ct_unexpect_related(exp);
 		return -1;
 	}
 
+	/* Save ports */
+	info->sig_port[dir] = port;
+	info->sig_port[!dir] = htons(nated_port);
+
 	pr_debug("nf_nat_q931: expect H.245 %pI4:%hu->%pI4:%hu\n",
 		 &exp->tuple.src.u3.ip,
 		 ntohs(exp->tuple.src.u.tcp.port),
@@ -462,24 +462,27 @@ static int nat_q931(struct sk_buff *skb,
 	/* Modify signal */
 	if (set_h225_addr(skb, protoff, data, 0, &taddr[idx],
 			  &ct->tuplehash[!dir].tuple.dst.u3,
-			  htons(nated_port)) == 0) {
-		/* Save ports */
-		info->sig_port[dir] = port;
-		info->sig_port[!dir] = htons(nated_port);
-
-		/* Fix for Gnomemeeting */
-		if (idx > 0 &&
-		    get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
-		    (ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
-			set_h225_addr(skb, protoff, data, 0, &taddr[0],
-				      &ct->tuplehash[!dir].tuple.dst.u3,
-				      info->sig_port[!dir]);
-		}
-	} else {
+			  htons(nated_port))) {
 		nf_ct_unexpect_related(exp);
 		return -1;
 	}
 
+	/* Save ports */
+	info->sig_port[dir] = port;
+	info->sig_port[!dir] = htons(nated_port);
+
+	/* Fix for Gnomemeeting */
+	if (idx > 0 &&
+	    get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
+	    (ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
+		if (set_h225_addr(skb, protoff, data, 0, &taddr[0],
+				  &ct->tuplehash[!dir].tuple.dst.u3,
+				  info->sig_port[!dir])) {
+			nf_ct_unexpect_related(exp);
+			return -1;
+		}
+	}
+
 	/* Success */
 	pr_debug("nf_nat_ras: expect Q.931 %pI4:%hu->%pI4:%hu\n",
 		 &exp->tuple.src.u3.ip,
@@ -550,9 +553,9 @@ static int nat_callforwarding(struct sk_
 	}
 
 	/* Modify signal */
-	if (!set_h225_addr(skb, protoff, data, dataoff, taddr,
-			   &ct->tuplehash[!dir].tuple.dst.u3,
-			   htons(nated_port)) == 0) {
+	if (set_h225_addr(skb, protoff, data, dataoff, taddr,
+			  &ct->tuplehash[!dir].tuple.dst.u3,
+			  htons(nated_port))) {
 		nf_ct_unexpect_related(exp);
 		return -1;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/raw.c linux-libre-4.1.52-gnu/net/ipv4/raw.c
--- linux-libre-4.1.51-gnu/net/ipv4/raw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/raw.c	2018-05-27 22:26:45.000000000 -0400
@@ -496,11 +496,16 @@ static int raw_sendmsg(struct sock *sk,
 	int err;
 	struct ip_options_data opt_copy;
 	struct raw_frag_vec rfv;
+	int hdrincl;
 
 	err = -EMSGSIZE;
 	if (len > 0xFFFF)
 		goto out;
 
+	/* hdrincl should be READ_ONCE(inet->hdrincl)
+	 * but READ_ONCE() doesn't work with bit fields
+	 */
+	hdrincl = inet->hdrincl;
 	/*
 	 *	Check the flags.
 	 */
@@ -575,7 +580,7 @@ static int raw_sendmsg(struct sock *sk,
 		/* Linux does not mangle headers on raw sockets,
 		 * so that IP options + IP_HDRINCL is non-sense.
 		 */
-		if (inet->hdrincl)
+		if (hdrincl)
 			goto done;
 		if (ipc.opt->opt.srr) {
 			if (!daddr)
@@ -597,12 +602,12 @@ static int raw_sendmsg(struct sock *sk,
 
 	flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
 			   RT_SCOPE_UNIVERSE,
-			   inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
+			   hdrincl ? IPPROTO_RAW : sk->sk_protocol,
 			   inet_sk_flowi_flags(sk) |
-			    (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
+			    (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
 			   daddr, saddr, 0, 0);
 
-	if (!inet->hdrincl) {
+	if (!hdrincl) {
 		rfv.msg = msg;
 		rfv.hlen = 0;
 
@@ -627,7 +632,7 @@ static int raw_sendmsg(struct sock *sk,
 		goto do_confirm;
 back_from_confirm:
 
-	if (inet->hdrincl)
+	if (hdrincl)
 		err = raw_send_hdrinc(sk, &fl4, msg, len,
 				      &rt, msg->msg_flags);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/tcp.c linux-libre-4.1.52-gnu/net/ipv4/tcp.c
--- linux-libre-4.1.51-gnu/net/ipv4/tcp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/tcp.c	2018-05-27 22:26:45.000000000 -0400
@@ -2416,7 +2416,7 @@ static int do_tcp_setsockopt(struct sock
 	case TCP_REPAIR_QUEUE:
 		if (!tp->repair)
 			err = -EPERM;
-		else if (val < TCP_QUEUES_NR)
+		else if ((unsigned int)val < TCP_QUEUES_NR)
 			tp->repair_queue = val;
 		else
 			err = -EINVAL;
@@ -2548,8 +2548,10 @@ static int do_tcp_setsockopt(struct sock
 
 #ifdef CONFIG_TCP_MD5SIG
 	case TCP_MD5SIG:
-		/* Read the IP->Key mappings from userspace */
-		err = tp->af_specific->md5_parse(sk, optval, optlen);
+		if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
+			err = tp->af_specific->md5_parse(sk, optval, optlen);
+		else
+			err = -EINVAL;
 		break;
 #endif
 	case TCP_USER_TIMEOUT:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv4/tcp_input.c linux-libre-4.1.52-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.1.51-gnu/net/ipv4/tcp_input.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv4/tcp_input.c	2018-05-27 22:26:45.000000000 -0400
@@ -3819,11 +3819,8 @@ const u8 *tcp_parse_md5sig_option(const
 	int length = (th->doff << 2) - sizeof(*th);
 	const u8 *ptr = (const u8 *)(th + 1);
 
-	/* If the TCP option is too short, we can short cut */
-	if (length < TCPOLEN_MD5SIG)
-		return NULL;
-
-	while (length > 0) {
+	/* If not enough data remaining, we can short cut */
+	while (length >= TCPOLEN_MD5SIG) {
 		int opcode = *ptr++;
 		int opsize;
 
@@ -5417,10 +5414,6 @@ void tcp_finish_connect(struct sock *sk,
 	else
 		tp->pred_flags = 0;
 
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
-	}
 }
 
 static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
@@ -5484,6 +5477,7 @@ static int tcp_rcv_synsent_state_process
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_fastopen_cookie foc = { .len = -1 };
 	int saved_clamp = tp->rx_opt.mss_clamp;
+	bool fastopen_fail;
 
 	tcp_parse_options(skb, &tp->rx_opt, 0, &foc);
 	if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
@@ -5586,10 +5580,15 @@ static int tcp_rcv_synsent_state_process
 
 		tcp_finish_connect(sk, skb);
 
-		if ((tp->syn_fastopen || tp->syn_data) &&
-		    tcp_rcv_fastopen_synack(sk, skb, &foc))
-			return -1;
+		fastopen_fail = (tp->syn_fastopen || tp->syn_data) &&
+				tcp_rcv_fastopen_synack(sk, skb, &foc);
 
+		if (!sock_flag(sk, SOCK_DEAD)) {
+			sk->sk_state_change(sk);
+			sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
+		}
+		if (fastopen_fail)
+			return -1;
 		if (sk->sk_write_pending ||
 		    icsk->icsk_accept_queue.rskq_defer_accept ||
 		    icsk->icsk_ack.pingpong) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv6/addrconf.c linux-libre-4.1.52-gnu/net/ipv6/addrconf.c
--- linux-libre-4.1.51-gnu/net/ipv6/addrconf.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv6/addrconf.c	2018-05-27 22:26:45.000000000 -0400
@@ -886,7 +886,10 @@ ipv6_add_addr(struct inet6_dev *idev, co
 	INIT_HLIST_NODE(&ifa->addr_lst);
 	ifa->scope = scope;
 	ifa->prefix_len = pfxlen;
-	ifa->flags = flags | IFA_F_TENTATIVE;
+	ifa->flags = flags;
+	/* No need to add the TENTATIVE flag for addresses with NODAD */
+	if (!(flags & IFA_F_NODAD))
+		ifa->flags |= IFA_F_TENTATIVE;
 	ifa->valid_lft = valid_lft;
 	ifa->prefered_lft = prefered_lft;
 	ifa->cstamp = ifa->tstamp = jiffies;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv6/ip6_gre.c linux-libre-4.1.52-gnu/net/ipv6/ip6_gre.c
--- linux-libre-4.1.51-gnu/net/ipv6/ip6_gre.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv6/ip6_gre.c	2018-05-27 22:26:45.000000000 -0400
@@ -319,11 +319,13 @@ static struct ip6_tnl *ip6gre_tunnel_loc
 	if (t || !create)
 		return t;
 
-	if (parms->name[0])
+	if (parms->name[0]) {
+		if (!dev_valid_name(parms->name))
+			return NULL;
 		strlcpy(name, parms->name, IFNAMSIZ);
-	else
+	} else {
 		strcpy(name, "ip6gre%d");
-
+	}
 	dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN,
 			   ip6gre_tunnel_setup);
 	if (!dev)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv6/ip6_tunnel.c linux-libre-4.1.52-gnu/net/ipv6/ip6_tunnel.c
--- linux-libre-4.1.51-gnu/net/ipv6/ip6_tunnel.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv6/ip6_tunnel.c	2018-05-27 22:26:45.000000000 -0400
@@ -316,13 +316,16 @@ static struct ip6_tnl *ip6_tnl_create(st
 	struct net_device *dev;
 	struct ip6_tnl *t;
 	char name[IFNAMSIZ];
-	int err = -ENOMEM;
+	int err = -E2BIG;
 
-	if (p->name[0])
+	if (p->name[0]) {
+		if (!dev_valid_name(p->name))
+			goto failed;
 		strlcpy(name, p->name, IFNAMSIZ);
-	else
+	} else {
 		sprintf(name, "ip6tnl%%d");
-
+	}
+	err = -ENOMEM;
 	dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN,
 			   ip6_tnl_dev_setup);
 	if (!dev)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv6/ip6_vti.c linux-libre-4.1.52-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.1.51-gnu/net/ipv6/ip6_vti.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv6/ip6_vti.c	2018-05-27 22:26:45.000000000 -0400
@@ -212,10 +212,13 @@ static struct ip6_tnl *vti6_tnl_create(s
 	char name[IFNAMSIZ];
 	int err;
 
-	if (p->name[0])
+	if (p->name[0]) {
+		if (!dev_valid_name(p->name))
+			goto failed;
 		strlcpy(name, p->name, IFNAMSIZ);
-	else
+	} else {
 		sprintf(name, "ip6_vti%%d");
+	}
 
 	dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, vti6_dev_setup);
 	if (!dev)
@@ -614,6 +617,7 @@ static void vti6_link_config(struct ip6_
 {
 	struct net_device *dev = t->dev;
 	struct __ip6_tnl_parm *p = &t->parms;
+	struct net_device *tdev = NULL;
 
 	memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
 	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -626,6 +630,25 @@ static void vti6_link_config(struct ip6_
 		dev->flags |= IFF_POINTOPOINT;
 	else
 		dev->flags &= ~IFF_POINTOPOINT;
+
+	if (p->flags & IP6_TNL_F_CAP_XMIT) {
+		int strict = (ipv6_addr_type(&p->raddr) &
+			      (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
+		struct rt6_info *rt = rt6_lookup(t->net,
+						 &p->raddr, &p->laddr,
+						 p->link, strict);
+
+		if (rt)
+			tdev = rt->dst.dev;
+		ip6_rt_put(rt);
+	}
+
+	if (!tdev && p->link)
+		tdev = __dev_get_by_index(t->net, p->link);
+
+	if (tdev)
+		dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
+				 IPV6_MIN_MTU);
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv6/ndisc.c linux-libre-4.1.52-gnu/net/ipv6/ndisc.c
--- linux-libre-4.1.51-gnu/net/ipv6/ndisc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv6/ndisc.c	2018-05-27 22:26:45.000000000 -0400
@@ -1452,7 +1452,8 @@ static void ndisc_fill_redirect_hdr_opti
 	*(opt++) = (rd_len >> 3);
 	opt += 6;
 
-	memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8);
+	skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt,
+		      rd_len - 8);
 }
 
 void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
@@ -1655,6 +1656,8 @@ static int ndisc_netdev_event(struct not
 	case NETDEV_CHANGEADDR:
 		neigh_changeaddr(&nd_tbl, dev);
 		fib6_run_gc(0, net, false);
+		/* fallthrough */
+	case NETDEV_UP:
 		idev = in6_dev_get(dev);
 		if (!idev)
 			break;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/ipv6/sit.c linux-libre-4.1.52-gnu/net/ipv6/sit.c
--- linux-libre-4.1.51-gnu/net/ipv6/sit.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/ipv6/sit.c	2018-05-27 22:26:45.000000000 -0400
@@ -244,11 +244,13 @@ static struct ip_tunnel *ipip6_tunnel_lo
 	if (!create)
 		goto failed;
 
-	if (parms->name[0])
+	if (parms->name[0]) {
+		if (!dev_valid_name(parms->name))
+			goto failed;
 		strlcpy(name, parms->name, IFNAMSIZ);
-	else
+	} else {
 		strcpy(name, "sit%d");
-
+	}
 	dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN,
 			   ipip6_tunnel_setup);
 	if (!dev)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/iucv/af_iucv.c linux-libre-4.1.52-gnu/net/iucv/af_iucv.c
--- linux-libre-4.1.51-gnu/net/iucv/af_iucv.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/iucv/af_iucv.c	2018-05-27 22:26:45.000000000 -0400
@@ -2382,9 +2382,11 @@ static int afiucv_iucv_init(void)
 	af_iucv_dev->driver = &af_iucv_driver;
 	err = device_register(af_iucv_dev);
 	if (err)
-		goto out_driver;
+		goto out_iucv_dev;
 	return 0;
 
+out_iucv_dev:
+	put_device(af_iucv_dev);
 out_driver:
 	driver_unregister(&af_iucv_driver);
 out_iucv:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/key/af_key.c linux-libre-4.1.52-gnu/net/key/af_key.c
--- linux-libre-4.1.51-gnu/net/key/af_key.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/key/af_key.c	2018-05-27 22:26:45.000000000 -0400
@@ -3301,7 +3301,7 @@ static struct xfrm_policy *pfkey_compile
 		p += pol->sadb_x_policy_len*8;
 		sec_ctx = (struct sadb_x_sec_ctx *)p;
 		if (len < pol->sadb_x_policy_len*8 +
-		    sec_ctx->sadb_x_sec_len) {
+		    sec_ctx->sadb_x_sec_len*8) {
 			*dir = -EINVAL;
 			goto out;
 		}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/l2tp/l2tp_core.c linux-libre-4.1.52-gnu/net/l2tp/l2tp_core.c
--- linux-libre-4.1.51-gnu/net/l2tp/l2tp_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/l2tp/l2tp_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -1521,9 +1521,14 @@ int l2tp_tunnel_create(struct net *net,
 		encap = cfg->encap;
 
 	/* Quick sanity checks */
+	err = -EPROTONOSUPPORT;
+	if (sk->sk_type != SOCK_DGRAM) {
+		pr_debug("tunl %hu: fd %d wrong socket type\n",
+			 tunnel_id, fd);
+		goto err;
+	}
 	switch (encap) {
 	case L2TP_ENCAPTYPE_UDP:
-		err = -EPROTONOSUPPORT;
 		if (sk->sk_protocol != IPPROTO_UDP) {
 			pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
 			       tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
@@ -1531,7 +1536,6 @@ int l2tp_tunnel_create(struct net *net,
 		}
 		break;
 	case L2TP_ENCAPTYPE_IP:
-		err = -EPROTONOSUPPORT;
 		if (sk->sk_protocol != IPPROTO_L2TP) {
 			pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
 			       tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/l2tp/l2tp_netlink.c linux-libre-4.1.52-gnu/net/l2tp/l2tp_netlink.c
--- linux-libre-4.1.51-gnu/net/l2tp/l2tp_netlink.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/l2tp/l2tp_netlink.c	2018-05-27 22:26:45.000000000 -0400
@@ -725,6 +725,8 @@ static int l2tp_nl_session_send(struct s
 
 	if ((session->ifname[0] &&
 	     nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
+	    (session->offset &&
+	     nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) ||
 	    (session->cookie_len &&
 	     nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
 		     &session->cookie[0])) ||
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/l2tp/l2tp_ppp.c linux-libre-4.1.52-gnu/net/l2tp/l2tp_ppp.c
--- linux-libre-4.1.51-gnu/net/l2tp/l2tp_ppp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/l2tp/l2tp_ppp.c	2018-05-27 22:26:45.000000000 -0400
@@ -606,6 +606,13 @@ static int pppol2tp_connect(struct socke
 	lock_sock(sk);
 
 	error = -EINVAL;
+
+	if (sockaddr_len != sizeof(struct sockaddr_pppol2tp) &&
+	    sockaddr_len != sizeof(struct sockaddr_pppol2tpv3) &&
+	    sockaddr_len != sizeof(struct sockaddr_pppol2tpin6) &&
+	    sockaddr_len != sizeof(struct sockaddr_pppol2tpv3in6))
+		goto end;
+
 	if (sp->sa_protocol != PX_PROTO_OL2TP)
 		goto end;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/llc/af_llc.c linux-libre-4.1.52-gnu/net/llc/af_llc.c
--- linux-libre-4.1.51-gnu/net/llc/af_llc.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/llc/af_llc.c	2018-05-27 22:26:45.000000000 -0400
@@ -197,9 +197,19 @@ static int llc_ui_release(struct socket
 		llc->laddr.lsap, llc->daddr.lsap);
 	if (!llc_send_disc(sk))
 		llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
-	if (!sock_flag(sk, SOCK_ZAPPED))
+	if (!sock_flag(sk, SOCK_ZAPPED)) {
+		struct llc_sap *sap = llc->sap;
+
+		/* Hold this for release_sock(), so that llc_backlog_rcv()
+		 * could still use it.
+		 */
+		llc_sap_hold(sap);
 		llc_sap_remove_socket(llc->sap, sk);
-	release_sock(sk);
+		release_sock(sk);
+		llc_sap_put(sap);
+	} else {
+		release_sock(sk);
+	}
 	if (llc->dev)
 		dev_put(llc->dev);
 	sock_put(sk);
@@ -309,6 +319,8 @@ static int llc_ui_bind(struct socket *so
 	int rc = -EINVAL;
 
 	dprintk("%s: binding %02X\n", __func__, addr->sllc_sap);
+
+	lock_sock(sk);
 	if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)))
 		goto out;
 	rc = -EAFNOSUPPORT;
@@ -380,6 +392,7 @@ static int llc_ui_bind(struct socket *so
 out_put:
 	llc_sap_put(sap);
 out:
+	release_sock(sk);
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/mac80211/iface.c linux-libre-4.1.52-gnu/net/mac80211/iface.c
--- linux-libre-4.1.51-gnu/net/mac80211/iface.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/mac80211/iface.c	2018-05-27 22:26:45.000000000 -0400
@@ -1418,7 +1418,7 @@ static void ieee80211_setup_sdata(struct
 		break;
 	case NL80211_IFTYPE_UNSPECIFIED:
 	case NUM_NL80211_IFTYPES:
-		BUG();
+		WARN_ON(1);
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/mac80211/mlme.c linux-libre-4.1.52-gnu/net/mac80211/mlme.c
--- linux-libre-4.1.51-gnu/net/mac80211/mlme.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/mac80211/mlme.c	2018-05-27 22:26:45.000000000 -0400
@@ -4321,6 +4321,10 @@ static int ieee80211_prep_connection(str
 	if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
 		return -EINVAL;
 
+	/* If a reconfig is happening, bail out */
+	if (local->in_reconfig)
+		return -EBUSY;
+
 	if (assoc) {
 		rcu_read_lock();
 		have_sta = sta_info_get(sdata, cbss->bssid);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/mac80211/status.c linux-libre-4.1.52-gnu/net/mac80211/status.c
--- linux-libre-4.1.51-gnu/net/mac80211/status.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/mac80211/status.c	2018-05-27 22:26:45.000000000 -0400
@@ -193,6 +193,7 @@ static void ieee80211_frame_acked(struct
 	}
 
 	if (ieee80211_is_action(mgmt->frame_control) &&
+	    !ieee80211_has_protected(mgmt->frame_control) &&
 	    mgmt->u.action.category == WLAN_CATEGORY_HT &&
 	    mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS &&
 	    ieee80211_sdata_running(sdata)) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netfilter/nf_conntrack_netlink.c linux-libre-4.1.52-gnu/net/netfilter/nf_conntrack_netlink.c
--- linux-libre-4.1.51-gnu/net/netfilter/nf_conntrack_netlink.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netfilter/nf_conntrack_netlink.c	2018-05-27 22:26:45.000000000 -0400
@@ -855,8 +855,13 @@ restart:
 	}
 out:
 	local_bh_enable();
-	if (last)
+	if (last) {
+		/* nf ct hash resize happened, now clear the leftover. */
+		if ((struct nf_conn *)cb->args[1] == last)
+			cb->args[1] = 0;
+
 		nf_ct_put(last);
+	}
 
 	return skb->len;
 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netfilter/nfnetlink_queue_core.c linux-libre-4.1.52-gnu/net/netfilter/nfnetlink_queue_core.c
--- linux-libre-4.1.51-gnu/net/netfilter/nfnetlink_queue_core.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netfilter/nfnetlink_queue_core.c	2018-05-27 22:26:45.000000000 -0400
@@ -993,10 +993,8 @@ nfqnl_recv_verdict(struct sock *ctnl, st
 	struct net *net = sock_net(ctnl);
 	struct nfnl_queue_net *q = nfnl_queue_pernet(net);
 
-	queue = instance_lookup(q, queue_num);
-	if (!queue)
-		queue = verdict_instance_lookup(q, queue_num,
-						NETLINK_CB(skb).portid);
+	queue = verdict_instance_lookup(q, queue_num,
+					NETLINK_CB(skb).portid);
 	if (IS_ERR(queue))
 		return PTR_ERR(queue);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netfilter/x_tables.c linux-libre-4.1.52-gnu/net/netfilter/x_tables.c
--- linux-libre-4.1.51-gnu/net/netfilter/x_tables.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netfilter/x_tables.c	2018-05-27 22:26:45.000000000 -0400
@@ -367,6 +367,36 @@ textify_hooks(char *buf, size_t size, un
 	return buf;
 }
 
+/**
+ * xt_check_proc_name - check that name is suitable for /proc file creation
+ *
+ * @name: file name candidate
+ * @size: length of buffer
+ *
+ * some x_tables modules wish to create a file in /proc.
+ * This function makes sure that the name is suitable for this
+ * purpose, it checks that name is NUL terminated and isn't a 'special'
+ * name, like "..".
+ *
+ * returns negative number on error or 0 if name is useable.
+ */
+int xt_check_proc_name(const char *name, unsigned int size)
+{
+	if (name[0] == '\0')
+		return -EINVAL;
+
+	if (strnlen(name, size) == size)
+		return -ENAMETOOLONG;
+
+	if (strcmp(name, ".") == 0 ||
+	    strcmp(name, "..") == 0 ||
+	    strchr(name, '/'))
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(xt_check_proc_name);
+
 int xt_check_match(struct xt_mtchk_param *par,
 		   unsigned int size, u_int8_t proto, bool inv_proto)
 {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netfilter/xt_hashlimit.c linux-libre-4.1.52-gnu/net/netfilter/xt_hashlimit.c
--- linux-libre-4.1.51-gnu/net/netfilter/xt_hashlimit.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netfilter/xt_hashlimit.c	2018-05-27 22:26:45.000000000 -0400
@@ -668,8 +668,9 @@ static int hashlimit_mt_check(const stru
 
 	if (info->cfg.gc_interval == 0 || info->cfg.expire == 0)
 		return -EINVAL;
-	if (info->name[sizeof(info->name)-1] != '\0')
-		return -EINVAL;
+	ret = xt_check_proc_name(info->name, sizeof(info->name));
+	if (ret)
+		return ret;
 	if (par->family == NFPROTO_IPV4) {
 		if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
 			return -EINVAL;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netfilter/xt_recent.c linux-libre-4.1.52-gnu/net/netfilter/xt_recent.c
--- linux-libre-4.1.51-gnu/net/netfilter/xt_recent.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netfilter/xt_recent.c	2018-05-27 22:26:45.000000000 -0400
@@ -364,9 +364,9 @@ static int recent_mt_check(const struct
 			info->hit_count, XT_RECENT_MAX_NSTAMPS - 1);
 		return -EINVAL;
 	}
-	if (info->name[0] == '\0' ||
-	    strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
-		return -EINVAL;
+	ret = xt_check_proc_name(info->name, sizeof(info->name));
+	if (ret)
+		return ret;
 
 	if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot)
 		nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netlink/af_netlink.c linux-libre-4.1.52-gnu/net/netlink/af_netlink.c
--- linux-libre-4.1.51-gnu/net/netlink/af_netlink.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netlink/af_netlink.c	2018-05-27 22:26:45.000000000 -0400
@@ -1635,6 +1635,9 @@ static int netlink_connect(struct socket
 	if (addr->sa_family != AF_NETLINK)
 		return -EINVAL;
 
+	if (alen < sizeof(struct sockaddr_nl))
+		return -EINVAL;
+
 	if ((nladdr->nl_groups || nladdr->nl_pid) &&
 	    !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
 		return -EPERM;
@@ -2385,6 +2388,8 @@ static int netlink_sendmsg(struct socket
 
 	if (msg->msg_namelen) {
 		err = -EINVAL;
+		if (msg->msg_namelen < sizeof(struct sockaddr_nl))
+			goto out;
 		if (addr->nl_family != AF_NETLINK)
 			goto out;
 		dst_portid = addr->nl_pid;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/netlink/genetlink.c linux-libre-4.1.52-gnu/net/netlink/genetlink.c
--- linux-libre-4.1.51-gnu/net/netlink/genetlink.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/netlink/genetlink.c	2018-05-27 22:26:45.000000000 -0400
@@ -1143,7 +1143,7 @@ static int genlmsg_mcast(struct sk_buff
 	if (!err)
 		delivered = true;
 	else if (err != -ESRCH)
-		goto error;
+		return err;
 	return delivered ? 0 : -ESRCH;
  error:
 	kfree_skb(skb);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/packet/af_packet.c linux-libre-4.1.52-gnu/net/packet/af_packet.c
--- linux-libre-4.1.51-gnu/net/packet/af_packet.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/packet/af_packet.c	2018-05-27 22:26:45.000000000 -0400
@@ -2652,6 +2652,7 @@ static int packet_release(struct socket
 
 	packet_flush_mclist(sk);
 
+	lock_sock(sk);
 	if (po->rx_ring.pg_vec) {
 		memset(&req_u, 0, sizeof(req_u));
 		packet_set_ring(sk, &req_u, 1, 0);
@@ -2661,6 +2662,7 @@ static int packet_release(struct socket
 		memset(&req_u, 0, sizeof(req_u));
 		packet_set_ring(sk, &req_u, 1, 1);
 	}
+	release_sock(sk);
 
 	fanout_release(sk);
 
@@ -3320,6 +3322,7 @@ packet_setsockopt(struct socket *sock, i
 		union tpacket_req_u req_u;
 		int len;
 
+		lock_sock(sk);
 		switch (po->tp_version) {
 		case TPACKET_V1:
 		case TPACKET_V2:
@@ -3330,14 +3333,21 @@ packet_setsockopt(struct socket *sock, i
 			len = sizeof(req_u.req3);
 			break;
 		}
-		if (optlen < len)
-			return -EINVAL;
-		if (pkt_sk(sk)->has_vnet_hdr)
-			return -EINVAL;
-		if (copy_from_user(&req_u.req, optval, len))
-			return -EFAULT;
-		return packet_set_ring(sk, &req_u, 0,
-			optname == PACKET_TX_RING);
+		if (optlen < len) {
+			ret = -EINVAL;
+		} else {
+			if (pkt_sk(sk)->has_vnet_hdr) {
+				ret = -EINVAL;
+			} else {
+				if (copy_from_user(&req_u.req, optval, len))
+					ret = -EFAULT;
+				else
+					ret = packet_set_ring(sk, &req_u, 0,
+							      optname == PACKET_TX_RING);
+			}
+		}
+		release_sock(sk);
+		return ret;
 	}
 	case PACKET_COPY_THRESH:
 	{
@@ -3847,7 +3857,6 @@ static int packet_set_ring(struct sock *
 	/* Added to avoid minimal code churn */
 	struct tpacket_req *req = &req_u->req;
 
-	lock_sock(sk);
 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
 		WARN(1, "Tx-ring is not supported.\n");
@@ -3983,7 +3992,6 @@ static int packet_set_ring(struct sock *
 	if (pg_vec)
 		free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
-	release_sock(sk);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/rxrpc/rxkad.c linux-libre-4.1.52-gnu/net/rxrpc/rxkad.c
--- linux-libre-4.1.51-gnu/net/rxrpc/rxkad.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/rxrpc/rxkad.c	2018-05-27 22:26:45.000000000 -0400
@@ -209,7 +209,7 @@ static int rxkad_secure_packet_encrypt(c
 	struct sk_buff *trailer;
 	unsigned int len;
 	u16 check;
-	int nsg;
+	int nsg, err;
 
 	sp = rxrpc_skb(skb);
 
@@ -240,7 +240,9 @@ static int rxkad_secure_packet_encrypt(c
 	len &= ~(call->conn->size_align - 1);
 
 	sg_init_table(sg, nsg);
-	skb_to_sgvec(skb, sg, 0, len);
+	err = skb_to_sgvec(skb, sg, 0, len);
+	if (unlikely(err < 0))
+		return err;
 	crypto_blkcipher_encrypt_iv(&desc, sg, sg, len);
 
 	_leave(" = 0");
@@ -336,7 +338,7 @@ static int rxkad_verify_packet_auth(cons
 	struct sk_buff *trailer;
 	u32 data_size, buf;
 	u16 check;
-	int nsg;
+	int nsg, ret;
 
 	_enter("");
 
@@ -348,7 +350,9 @@ static int rxkad_verify_packet_auth(cons
 		goto nomem;
 
 	sg_init_table(sg, nsg);
-	skb_to_sgvec(skb, sg, 0, 8);
+	ret = skb_to_sgvec(skb, sg, 0, 8);
+	if (unlikely(ret < 0))
+		return ret;
 
 	/* start the decryption afresh */
 	memset(&iv, 0, sizeof(iv));
@@ -411,7 +415,7 @@ static int rxkad_verify_packet_encrypt(c
 	struct sk_buff *trailer;
 	u32 data_size, buf;
 	u16 check;
-	int nsg;
+	int nsg, ret;
 
 	_enter(",{%d}", skb->len);
 
@@ -430,7 +434,12 @@ static int rxkad_verify_packet_encrypt(c
 	}
 
 	sg_init_table(sg, nsg);
-	skb_to_sgvec(skb, sg, 0, skb->len);
+	ret = skb_to_sgvec(skb, sg, 0, skb->len);
+	if (unlikely(ret < 0)) {
+		if (sg != _sg)
+			kfree(sg);
+		return ret;
+	}
 
 	/* decrypt from the session key */
 	token = call->conn->key->payload.data;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/sched/act_api.c linux-libre-4.1.52-gnu/net/sched/act_api.c
--- linux-libre-4.1.51-gnu/net/sched/act_api.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/sched/act_api.c	2018-05-27 22:26:45.000000000 -0400
@@ -93,8 +93,10 @@ static int tcf_dump_walker(struct sk_buf
 			a->order = n_i;
 
 			nest = nla_nest_start(skb, a->order);
-			if (nest == NULL)
+			if (nest == NULL) {
+				index--;
 				goto nla_put_failure;
+			}
 			err = tcf_action_dump_1(skb, a, 0, 0);
 			if (err < 0) {
 				index--;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/sched/act_csum.c linux-libre-4.1.52-gnu/net/sched/act_csum.c
--- linux-libre-4.1.51-gnu/net/sched/act_csum.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/sched/act_csum.c	2018-05-27 22:26:45.000000000 -0400
@@ -176,6 +176,9 @@ static int tcf_csum_ipv4_tcp(struct sk_b
 	struct tcphdr *tcph;
 	const struct iphdr *iph;
 
+	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+		return 1;
+
 	tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph));
 	if (tcph == NULL)
 		return 0;
@@ -197,6 +200,9 @@ static int tcf_csum_ipv6_tcp(struct sk_b
 	struct tcphdr *tcph;
 	const struct ipv6hdr *ip6h;
 
+	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+		return 1;
+
 	tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph));
 	if (tcph == NULL)
 		return 0;
@@ -220,6 +226,9 @@ static int tcf_csum_ipv4_udp(struct sk_b
 	const struct iphdr *iph;
 	u16 ul;
 
+	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+		return 1;
+
 	/*
 	 * Support both UDP and UDPLITE checksum algorithms, Don't use
 	 * udph->len to get the real length without any protocol check,
@@ -273,6 +282,9 @@ static int tcf_csum_ipv6_udp(struct sk_b
 	const struct ipv6hdr *ip6h;
 	u16 ul;
 
+	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+		return 1;
+
 	/*
 	 * Support both UDP and UDPLITE checksum algorithms, Don't use
 	 * udph->len to get the real length without any protocol check,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/sctp/ipv6.c linux-libre-4.1.52-gnu/net/sctp/ipv6.c
--- linux-libre-4.1.51-gnu/net/sctp/ipv6.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/sctp/ipv6.c	2018-05-27 22:26:45.000000000 -0400
@@ -496,46 +496,49 @@ static void sctp_v6_to_addr(union sctp_a
 	addr->v6.sin6_scope_id = 0;
 }
 
-/* Compare addresses exactly.
- * v4-mapped-v6 is also in consideration.
- */
-static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
-			    const union sctp_addr *addr2)
+static int __sctp_v6_cmp_addr(const union sctp_addr *addr1,
+			      const union sctp_addr *addr2)
 {
 	if (addr1->sa.sa_family != addr2->sa.sa_family) {
 		if (addr1->sa.sa_family == AF_INET &&
 		    addr2->sa.sa_family == AF_INET6 &&
-		    ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
-			if (addr2->v6.sin6_port == addr1->v4.sin_port &&
-			    addr2->v6.sin6_addr.s6_addr32[3] ==
-			    addr1->v4.sin_addr.s_addr)
-				return 1;
-		}
+		    ipv6_addr_v4mapped(&addr2->v6.sin6_addr) &&
+		    addr2->v6.sin6_addr.s6_addr32[3] ==
+		    addr1->v4.sin_addr.s_addr)
+			return 1;
+
 		if (addr2->sa.sa_family == AF_INET &&
 		    addr1->sa.sa_family == AF_INET6 &&
-		    ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
-			if (addr1->v6.sin6_port == addr2->v4.sin_port &&
-			    addr1->v6.sin6_addr.s6_addr32[3] ==
-			    addr2->v4.sin_addr.s_addr)
-				return 1;
-		}
+		    ipv6_addr_v4mapped(&addr1->v6.sin6_addr) &&
+		    addr1->v6.sin6_addr.s6_addr32[3] ==
+		    addr2->v4.sin_addr.s_addr)
+			return 1;
+
 		return 0;
 	}
-	if (addr1->v6.sin6_port != addr2->v6.sin6_port)
-		return 0;
+
 	if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
 		return 0;
+
 	/* If this is a linklocal address, compare the scope_id. */
-	if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-		if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
-		    (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) {
-			return 0;
-		}
-	}
+	if ((ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
+	    addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
+	    addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)
+		return 0;
 
 	return 1;
 }
 
+/* Compare addresses exactly.
+ * v4-mapped-v6 is also in consideration.
+ */
+static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
+			    const union sctp_addr *addr2)
+{
+	return __sctp_v6_cmp_addr(addr1, addr2) &&
+	       addr1->v6.sin6_port == addr2->v6.sin6_port;
+}
+
 /* Initialize addr struct to INADDR_ANY. */
 static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
 {
@@ -700,8 +703,10 @@ static int sctp_v6_addr_to_user(struct s
 			sctp_v6_map_v4(addr);
 	}
 
-	if (addr->sa.sa_family == AF_INET)
+	if (addr->sa.sa_family == AF_INET) {
+		memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero));
 		return sizeof(struct sockaddr_in);
+	}
 	return sizeof(struct sockaddr_in6);
 }
 
@@ -818,8 +823,8 @@ static int sctp_inet6_cmp_addr(const uni
 			       const union sctp_addr *addr2,
 			       struct sctp_sock *opt)
 {
-	struct sctp_af *af1, *af2;
 	struct sock *sk = sctp_opt2sk(opt);
+	struct sctp_af *af1, *af2;
 
 	af1 = sctp_get_af_specific(addr1->sa.sa_family);
 	af2 = sctp_get_af_specific(addr2->sa.sa_family);
@@ -835,10 +840,7 @@ static int sctp_inet6_cmp_addr(const uni
 	if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
 		return 1;
 
-	if (addr1->sa.sa_family != addr2->sa.sa_family)
-		return 0;
-
-	return af1->cmp_addr(addr1, addr2);
+	return __sctp_v6_cmp_addr(addr1, addr2);
 }
 
 /* Verify that the provided sockaddr looks bindable.   Common verification,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/sctp/socket.c linux-libre-4.1.52-gnu/net/sctp/socket.c
--- linux-libre-4.1.51-gnu/net/sctp/socket.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/sctp/socket.c	2018-05-27 22:26:45.000000000 -0400
@@ -335,11 +335,14 @@ static struct sctp_af *sctp_sockaddr_af(
 	if (!opt->pf->af_supported(addr->sa.sa_family, opt))
 		return NULL;
 
-	/* V4 mapped address are really of AF_INET family */
-	if (addr->sa.sa_family == AF_INET6 &&
-	    ipv6_addr_v4mapped(&addr->v6.sin6_addr) &&
-	    !opt->pf->af_supported(AF_INET, opt))
-		return NULL;
+	if (addr->sa.sa_family == AF_INET6) {
+		if (len < SIN6_LEN_RFC2133)
+			return NULL;
+		/* V4 mapped address are really of AF_INET family */
+		if (ipv6_addr_v4mapped(&addr->v6.sin6_addr) &&
+		    !opt->pf->af_supported(AF_INET, opt))
+			return NULL;
+	}
 
 	/* If we get this far, af is valid. */
 	af = sctp_get_af_specific(addr->sa.sa_family);
@@ -1512,7 +1515,7 @@ static void sctp_close(struct sock *sk,
 
 	pr_debug("%s: sk:%p, timeout:%ld\n", __func__, sk, timeout);
 
-	lock_sock(sk);
+	lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
 	sk->sk_shutdown = SHUTDOWN_MASK;
 	sk->sk_state = SCTP_SS_CLOSING;
 
@@ -1563,7 +1566,7 @@ static void sctp_close(struct sock *sk,
 	 * held and that should be grabbed before socket lock.
 	 */
 	spin_lock_bh(&net->sctp.addr_wq_lock);
-	bh_lock_sock(sk);
+	bh_lock_sock_nested(sk);
 
 	/* Hold the sock, since sk_common_release() will put sock_put()
 	 * and we have just a little more cleanup.
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/sunrpc/rpc_pipe.c linux-libre-4.1.52-gnu/net/sunrpc/rpc_pipe.c
--- linux-libre-4.1.51-gnu/net/sunrpc/rpc_pipe.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/sunrpc/rpc_pipe.c	2018-05-27 22:26:45.000000000 -0400
@@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry
 	struct dentry *clnt_dir = pipe_dentry->d_parent;
 	struct dentry *gssd_dir = clnt_dir->d_parent;
 
+	dget(pipe_dentry);
 	__rpc_rmpipe(d_inode(clnt_dir), pipe_dentry);
 	__rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1);
 	__rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/sunrpc/xprtsock.c linux-libre-4.1.52-gnu/net/sunrpc/xprtsock.c
--- linux-libre-4.1.51-gnu/net/sunrpc/xprtsock.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/sunrpc/xprtsock.c	2018-05-27 22:26:45.000000000 -0400
@@ -2192,7 +2192,12 @@ static void xs_tcp_setup_socket(struct w
 	case -EHOSTUNREACH:
 	case -EADDRINUSE:
 	case -ENOBUFS:
-		/* retry with existing socket, after a delay */
+		/*
+		 * xs_tcp_force_close() wakes tasks with -EIO.
+		 * We need to wake them first to ensure the
+		 * correct error code.
+		 */
+		xprt_wake_pending_tasks(xprt, status);
 		xs_tcp_force_close(xprt);
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/tipc/net.c linux-libre-4.1.52-gnu/net/tipc/net.c
--- linux-libre-4.1.51-gnu/net/tipc/net.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/tipc/net.c	2018-05-27 22:26:45.000000000 -0400
@@ -43,7 +43,8 @@
 
 static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
 	[TIPC_NLA_NET_UNSPEC]	= { .type = NLA_UNSPEC },
-	[TIPC_NLA_NET_ID]	= { .type = NLA_U32 }
+	[TIPC_NLA_NET_ID]	= { .type = NLA_U32 },
+	[TIPC_NLA_NET_ADDR]	= { .type = NLA_U32 },
 };
 
 /*
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/x25/af_x25.c linux-libre-4.1.52-gnu/net/x25/af_x25.c
--- linux-libre-4.1.51-gnu/net/x25/af_x25.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/x25/af_x25.c	2018-05-27 22:26:45.000000000 -0400
@@ -1794,32 +1794,40 @@ void x25_kill_by_neigh(struct x25_neigh
 
 static int __init x25_init(void)
 {
-	int rc = proto_register(&x25_proto, 0);
+	int rc;
 
-	if (rc != 0)
+	rc = proto_register(&x25_proto, 0);
+	if (rc)
 		goto out;
 
 	rc = sock_register(&x25_family_ops);
-	if (rc != 0)
+	if (rc)
 		goto out_proto;
 
 	dev_add_pack(&x25_packet_type);
 
 	rc = register_netdevice_notifier(&x25_dev_notifier);
-	if (rc != 0)
+	if (rc)
 		goto out_sock;
 
-	pr_info("Linux Version 0.2\n");
+	rc = x25_register_sysctl();
+	if (rc)
+		goto out_dev;
 
-	x25_register_sysctl();
 	rc = x25_proc_init();
-	if (rc != 0)
-		goto out_dev;
+	if (rc)
+		goto out_sysctl;
+
+	pr_info("Linux Version 0.2\n");
+
 out:
 	return rc;
+out_sysctl:
+	x25_unregister_sysctl();
 out_dev:
 	unregister_netdevice_notifier(&x25_dev_notifier);
 out_sock:
+	dev_remove_pack(&x25_packet_type);
 	sock_unregister(AF_X25);
 out_proto:
 	proto_unregister(&x25_proto);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/x25/sysctl_net_x25.c linux-libre-4.1.52-gnu/net/x25/sysctl_net_x25.c
--- linux-libre-4.1.51-gnu/net/x25/sysctl_net_x25.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/x25/sysctl_net_x25.c	2018-05-27 22:26:45.000000000 -0400
@@ -73,9 +73,12 @@ static struct ctl_table x25_table[] = {
 	{ 0, },
 };
 
-void __init x25_register_sysctl(void)
+int __init x25_register_sysctl(void)
 {
 	x25_table_header = register_net_sysctl(&init_net, "net/x25", x25_table);
+	if (!x25_table_header)
+		return -ENOMEM;
+	return 0;
 }
 
 void x25_unregister_sysctl(void)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/xfrm/xfrm_ipcomp.c linux-libre-4.1.52-gnu/net/xfrm/xfrm_ipcomp.c
--- linux-libre-4.1.51-gnu/net/xfrm/xfrm_ipcomp.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/xfrm/xfrm_ipcomp.c	2018-05-27 22:26:45.000000000 -0400
@@ -283,7 +283,7 @@ static struct crypto_comp * __percpu *ip
 		struct crypto_comp *tfm;
 
 		/* This can be any valid CPU ID so we don't need locking. */
-		tfm = __this_cpu_read(*pos->tfms);
+		tfm = this_cpu_read(*pos->tfms);
 
 		if (!strcmp(crypto_comp_name(tfm), alg_name)) {
 			pos->users++;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/xfrm/xfrm_policy.c linux-libre-4.1.52-gnu/net/xfrm/xfrm_policy.c
--- linux-libre-4.1.51-gnu/net/xfrm/xfrm_policy.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/xfrm/xfrm_policy.c	2018-05-27 22:26:45.000000000 -0400
@@ -1299,7 +1299,7 @@ EXPORT_SYMBOL(xfrm_policy_delete);
 
 int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 {
-	struct net *net = xp_net(pol);
+	struct net *net = sock_net(sk);
 	struct xfrm_policy *old_pol;
 
 #ifdef CONFIG_XFRM_SUB_POLICY
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/xfrm/xfrm_state.c linux-libre-4.1.52-gnu/net/xfrm/xfrm_state.c
--- linux-libre-4.1.51-gnu/net/xfrm/xfrm_state.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/xfrm/xfrm_state.c	2018-05-27 22:26:45.000000000 -0400
@@ -1208,6 +1208,8 @@ static struct xfrm_state *xfrm_state_clo
 	x->curlft.add_time = orig->curlft.add_time;
 	x->km.state = orig->km.state;
 	x->km.seq = orig->km.seq;
+	x->replay = orig->replay;
+	x->preplay = orig->preplay;
 
 	return x;
 
@@ -1845,6 +1847,18 @@ int xfrm_user_policy(struct sock *sk, in
 	struct xfrm_mgr *km;
 	struct xfrm_policy *pol = NULL;
 
+#ifdef CONFIG_COMPAT
+	if (is_compat_task())
+		return -EOPNOTSUPP;
+#endif
+
+	if (!optval && !optlen) {
+		xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
+		xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
+		__sk_dst_reset(sk);
+		return 0;
+	}
+
 	if (optlen <= 0 || optlen > PAGE_SIZE)
 		return -EMSGSIZE;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/net/xfrm/xfrm_user.c linux-libre-4.1.52-gnu/net/xfrm/xfrm_user.c
--- linux-libre-4.1.51-gnu/net/xfrm/xfrm_user.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/net/xfrm/xfrm_user.c	2018-05-27 22:26:45.000000000 -0400
@@ -120,22 +120,17 @@ static inline int verify_replay(struct x
 	struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
 	struct xfrm_replay_state_esn *rs;
 
-	if (p->flags & XFRM_STATE_ESN) {
-		if (!rt)
-			return -EINVAL;
-
-		rs = nla_data(rt);
+	if (!rt)
+		return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0;
 
-		if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
-			return -EINVAL;
+	rs = nla_data(rt);
 
-		if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
-		    nla_len(rt) != sizeof(*rs))
-			return -EINVAL;
-	}
+	if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+		return -EINVAL;
 
-	if (!rt)
-		return 0;
+	if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
+	    nla_len(rt) != sizeof(*rs))
+		return -EINVAL;
 
 	/* As only ESP and AH support ESN feature. */
 	if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))
@@ -2460,7 +2455,7 @@ static int xfrm_user_rcv_msg(struct sk_b
 
 #ifdef CONFIG_COMPAT
 	if (is_compat_task())
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 #endif
 
 	type = nlh->nlmsg_type;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/scripts/tags.sh linux-libre-4.1.52-gnu/scripts/tags.sh
--- linux-libre-4.1.51-gnu/scripts/tags.sh	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/scripts/tags.sh	2018-05-27 22:26:45.000000000 -0400
@@ -106,6 +106,7 @@ all_compiled_sources()
 		case "$i" in
 			*.[cS])
 				j=${i/\.[cS]/\.o}
+				j="${j#$tree}"
 				if [ -e $j ]; then
 					echo $i
 				fi
diff -druNp --no-dereference linux-libre-4.1.51-gnu/security/apparmor/lsm.c linux-libre-4.1.52-gnu/security/apparmor/lsm.c
--- linux-libre-4.1.51-gnu/security/apparmor/lsm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/security/apparmor/lsm.c	2018-05-27 22:26:45.000000000 -0400
@@ -735,7 +735,7 @@ module_param_named(logsyscall, aa_g_logs
 
 /* Maximum pathname length before accesses will start getting rejected */
 unsigned int aa_g_path_max = 2 * PATH_MAX;
-module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR | S_IWUSR);
+module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR);
 
 /* Determines how paranoid loading of policy is and how much verification
  * on the loaded policy is done.
diff -druNp --no-dereference linux-libre-4.1.51-gnu/security/integrity/ima/ima_appraise.c linux-libre-4.1.52-gnu/security/integrity/ima/ima_appraise.c
--- linux-libre-4.1.51-gnu/security/integrity/ima/ima_appraise.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/security/integrity/ima/ima_appraise.c	2018-05-27 22:26:45.000000000 -0400
@@ -206,7 +206,8 @@ int ima_appraise_measurement(int func, s
 		if (opened & FILE_CREATED)
 			iint->flags |= IMA_NEW_FILE;
 		if ((iint->flags & IMA_NEW_FILE) &&
-		    !(iint->flags & IMA_DIGSIG_REQUIRED))
+		    (!(iint->flags & IMA_DIGSIG_REQUIRED) ||
+		     (inode->i_size == 0)))
 			status = INTEGRITY_PASS;
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/security/selinux/hooks.c linux-libre-4.1.52-gnu/security/selinux/hooks.c
--- linux-libre-4.1.51-gnu/security/selinux/hooks.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/security/selinux/hooks.c	2018-05-27 22:26:45.000000000 -0400
@@ -321,18 +321,6 @@ static void superblock_free_security(str
 	kfree(sbsec);
 }
 
-/* The file system's label must be initialized prior to use. */
-
-static const char *labeling_behaviors[7] = {
-	"uses xattr",
-	"uses transition SIDs",
-	"uses task SIDs",
-	"uses genfs_contexts",
-	"not configured for labeling",
-	"uses mountpoint labeling",
-	"uses native labeling",
-};
-
 static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
 
 static inline int inode_doinit(struct inode *inode)
@@ -444,10 +432,6 @@ static int sb_finish_set_opts(struct sup
 		}
 	}
 
-	if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
-		printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
-		       sb->s_id, sb->s_type->name);
-
 	sbsec->flags |= SE_SBINITIALIZED;
 	if (selinux_is_sblabel_mnt(sb))
 		sbsec->flags |= SBLABEL_MNT;
@@ -4106,10 +4090,18 @@ static int selinux_socket_bind(struct so
 		u32 sid, node_perm;
 
 		if (family == PF_INET) {
+			if (addrlen < sizeof(struct sockaddr_in)) {
+				err = -EINVAL;
+				goto out;
+			}
 			addr4 = (struct sockaddr_in *)address;
 			snum = ntohs(addr4->sin_port);
 			addrp = (char *)&addr4->sin_addr.s_addr;
 		} else {
+			if (addrlen < SIN6_LEN_RFC2133) {
+				err = -EINVAL;
+				goto out;
+			}
 			addr6 = (struct sockaddr_in6 *)address;
 			snum = ntohs(addr6->sin6_port);
 			addrp = (char *)&addr6->sin6_addr.s6_addr;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/security/selinux/ss/services.c linux-libre-4.1.52-gnu/security/selinux/ss/services.c
--- linux-libre-4.1.51-gnu/security/selinux/ss/services.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/security/selinux/ss/services.c	2018-05-27 22:26:45.000000000 -0400
@@ -154,7 +154,7 @@ static int selinux_set_mapping(struct po
 		}
 
 		k = 0;
-		while (p_in->perms && p_in->perms[k]) {
+		while (p_in->perms[k]) {
 			/* An empty permission string skips ahead */
 			if (!*p_in->perms[k]) {
 				k++;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/oss/pcm_oss.c linux-libre-4.1.52-gnu/sound/core/oss/pcm_oss.c
--- linux-libre-4.1.51-gnu/sound/core/oss/pcm_oss.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/oss/pcm_oss.c	2018-05-27 22:26:45.000000000 -0400
@@ -833,8 +833,25 @@ static int choose_rate(struct snd_pcm_su
 	return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
 }
 
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
-				     bool trylock)
+/* parameter locking: returns immediately if tried during streaming */
+static int lock_params(struct snd_pcm_runtime *runtime)
+{
+	if (mutex_lock_interruptible(&runtime->oss.params_lock))
+		return -ERESTARTSYS;
+	if (atomic_read(&runtime->oss.rw_ref)) {
+		mutex_unlock(&runtime->oss.params_lock);
+		return -EBUSY;
+	}
+	return 0;
+}
+
+static void unlock_params(struct snd_pcm_runtime *runtime)
+{
+	mutex_unlock(&runtime->oss.params_lock);
+}
+
+/* call with params_lock held */
+static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_hw_params *params, *sparams;
@@ -848,12 +865,9 @@ static int snd_pcm_oss_change_params(str
 	struct snd_mask sformat_mask;
 	struct snd_mask mask;
 
-	if (trylock) {
-		if (!(mutex_trylock(&runtime->oss.params_lock)))
-			return -EAGAIN;
-	} else if (mutex_lock_interruptible(&runtime->oss.params_lock))
-		return -EINTR;
-	sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
+	if (!runtime->oss.params)
+		return 0;
+	sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
 	sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
 	if (!sw_params || !params || !sparams) {
@@ -991,7 +1005,6 @@ static int snd_pcm_oss_change_params(str
 		goto failure;
 	}
 
-	memset(sw_params, 0, sizeof(*sw_params));
 	if (runtime->oss.trigger) {
 		sw_params->start_threshold = 1;
 	} else {
@@ -1079,6 +1092,23 @@ failure:
 	kfree(sw_params);
 	kfree(params);
 	kfree(sparams);
+	return err;
+}
+
+/* this one takes the lock by itself */
+static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
+				     bool trylock)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int err;
+
+	if (trylock) {
+		if (!(mutex_trylock(&runtime->oss.params_lock)))
+			return -EAGAIN;
+	} else if (mutex_lock_interruptible(&runtime->oss.params_lock))
+		return -ERESTARTSYS;
+
+	err = snd_pcm_oss_change_params_locked(substream);
 	mutex_unlock(&runtime->oss.params_lock);
 	return err;
 }
@@ -1107,6 +1137,10 @@ static int snd_pcm_oss_get_active_substr
 	return 0;
 }
 
+/* call with params_lock held */
+/* NOTE: this always call PREPARE unconditionally no matter whether
+ * runtime->oss.prepare is set or not
+ */
 static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
 {
 	int err;
@@ -1131,8 +1165,6 @@ static int snd_pcm_oss_make_ready(struct
 	struct snd_pcm_runtime *runtime;
 	int err;
 
-	if (substream == NULL)
-		return 0;
 	runtime = substream->runtime;
 	if (runtime->oss.params) {
 		err = snd_pcm_oss_change_params(substream, false);
@@ -1140,6 +1172,29 @@ static int snd_pcm_oss_make_ready(struct
 			return err;
 	}
 	if (runtime->oss.prepare) {
+		if (mutex_lock_interruptible(&runtime->oss.params_lock))
+			return -ERESTARTSYS;
+		err = snd_pcm_oss_prepare(substream);
+		mutex_unlock(&runtime->oss.params_lock);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+/* call with params_lock held */
+static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime;
+	int err;
+
+	runtime = substream->runtime;
+	if (runtime->oss.params) {
+		err = snd_pcm_oss_change_params_locked(substream);
+		if (err < 0)
+			return err;
+	}
+	if (runtime->oss.prepare) {
 		err = snd_pcm_oss_prepare(substream);
 		if (err < 0)
 			return err;
@@ -1367,13 +1422,15 @@ static ssize_t snd_pcm_oss_write1(struct
 	if (atomic_read(&substream->mmap_count))
 		return -ENXIO;
 
-	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
-		return tmp;
+	atomic_inc(&runtime->oss.rw_ref);
 	while (bytes > 0) {
 		if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
 			tmp = -ERESTARTSYS;
 			break;
 		}
+		tmp = snd_pcm_oss_make_ready_locked(substream);
+		if (tmp < 0)
+			goto err;
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			tmp = bytes;
 			if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1429,6 +1486,7 @@ static ssize_t snd_pcm_oss_write1(struct
 		}
 		tmp = 0;
 	}
+	atomic_dec(&runtime->oss.rw_ref);
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
@@ -1474,13 +1532,15 @@ static ssize_t snd_pcm_oss_read1(struct
 	if (atomic_read(&substream->mmap_count))
 		return -ENXIO;
 
-	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
-		return tmp;
+	atomic_inc(&runtime->oss.rw_ref);
 	while (bytes > 0) {
 		if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
 			tmp = -ERESTARTSYS;
 			break;
 		}
+		tmp = snd_pcm_oss_make_ready_locked(substream);
+		if (tmp < 0)
+			goto err;
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			if (runtime->oss.buffer_used == 0) {
 				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1521,6 +1581,7 @@ static ssize_t snd_pcm_oss_read1(struct
 		}
 		tmp = 0;
 	}
+	atomic_dec(&runtime->oss.rw_ref);
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
@@ -1536,10 +1597,12 @@ static int snd_pcm_oss_reset(struct snd_
 			continue;
 		runtime = substream->runtime;
 		snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
+		mutex_lock(&runtime->oss.params_lock);
 		runtime->oss.prepare = 1;
 		runtime->oss.buffer_used = 0;
 		runtime->oss.prev_hw_ptr_period = 0;
 		runtime->oss.period_ptr = 0;
+		mutex_unlock(&runtime->oss.params_lock);
 	}
 	return 0;
 }
@@ -1625,9 +1688,13 @@ static int snd_pcm_oss_sync(struct snd_p
 			goto __direct;
 		if ((err = snd_pcm_oss_make_ready(substream)) < 0)
 			return err;
+		atomic_inc(&runtime->oss.rw_ref);
+		if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+			atomic_dec(&runtime->oss.rw_ref);
+			return -ERESTARTSYS;
+		}
 		format = snd_pcm_oss_format_from(runtime->oss.format);
 		width = snd_pcm_format_physical_width(format);
-		mutex_lock(&runtime->oss.params_lock);
 		if (runtime->oss.buffer_used > 0) {
 #ifdef OSS_DEBUG
 			pcm_dbg(substream->pcm, "sync: buffer_used\n");
@@ -1637,10 +1704,8 @@ static int snd_pcm_oss_sync(struct snd_p
 						   runtime->oss.buffer + runtime->oss.buffer_used,
 						   size);
 			err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
-			if (err < 0) {
-				mutex_unlock(&runtime->oss.params_lock);
-				return err;
-			}
+			if (err < 0)
+				goto unlock;
 		} else if (runtime->oss.period_ptr > 0) {
 #ifdef OSS_DEBUG
 			pcm_dbg(substream->pcm, "sync: period_ptr\n");
@@ -1650,10 +1715,8 @@ static int snd_pcm_oss_sync(struct snd_p
 						   runtime->oss.buffer,
 						   size * 8 / width);
 			err = snd_pcm_oss_sync1(substream, size);
-			if (err < 0) {
-				mutex_unlock(&runtime->oss.params_lock);
-				return err;
-			}
+			if (err < 0)
+				goto unlock;
 		}
 		/*
 		 * The ALSA's period might be a bit large than OSS one.
@@ -1684,7 +1747,11 @@ static int snd_pcm_oss_sync(struct snd_p
 				snd_pcm_lib_writev(substream, buffers, size);
 			}
 		}
+unlock:
 		mutex_unlock(&runtime->oss.params_lock);
+		atomic_dec(&runtime->oss.rw_ref);
+		if (err < 0)
+			return err;
 		/*
 		 * finish sync: drain the buffer
 		 */
@@ -1695,7 +1762,9 @@ static int snd_pcm_oss_sync(struct snd_p
 		substream->f_flags = saved_f_flags;
 		if (err < 0)
 			return err;
+		mutex_lock(&runtime->oss.params_lock);
 		runtime->oss.prepare = 1;
+		mutex_unlock(&runtime->oss.params_lock);
 	}
 
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -1706,8 +1775,10 @@ static int snd_pcm_oss_sync(struct snd_p
 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
 		if (err < 0)
 			return err;
+		mutex_lock(&runtime->oss.params_lock);
 		runtime->oss.buffer_used = 0;
 		runtime->oss.prepare = 1;
+		mutex_unlock(&runtime->oss.params_lock);
 	}
 	return 0;
 }
@@ -1719,6 +1790,8 @@ static int snd_pcm_oss_set_rate(struct s
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		struct snd_pcm_runtime *runtime;
+		int err;
+
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
@@ -1726,10 +1799,14 @@ static int snd_pcm_oss_set_rate(struct s
 			rate = 1000;
 		else if (rate > 192000)
 			rate = 192000;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
 		if (runtime->oss.rate != rate) {
 			runtime->oss.params = 1;
 			runtime->oss.rate = rate;
 		}
+		unlock_params(runtime);
 	}
 	return snd_pcm_oss_get_rate(pcm_oss_file);
 }
@@ -1754,13 +1831,19 @@ static int snd_pcm_oss_set_channels(stru
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		struct snd_pcm_runtime *runtime;
+		int err;
+
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
 		if (runtime->oss.channels != channels) {
 			runtime->oss.params = 1;
 			runtime->oss.channels = channels;
 		}
+		unlock_params(runtime);
 	}
 	return snd_pcm_oss_get_channels(pcm_oss_file);
 }
@@ -1814,10 +1897,9 @@ static int snd_pcm_oss_get_formats(struc
 		return -ENOMEM;
 	_snd_pcm_hw_params_any(params);
 	err = snd_pcm_hw_refine(substream, params);
-	format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 
-	kfree(params);
 	if (err < 0)
-		return err;
+		goto error;
+	format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 	for (fmt = 0; fmt < 32; ++fmt) {
 		if (snd_mask_test(&format_mask, fmt)) {
 			int f = snd_pcm_oss_format_to(fmt);
@@ -1825,12 +1907,16 @@ static int snd_pcm_oss_get_formats(struc
 				formats |= f;
 		}
 	}
-	return formats;
+
+ error:
+	kfree(params);
+	return err < 0 ? err : formats;
 }
 
 static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
 {
 	int formats, idx;
+	int err;
 	
 	if (format != AFMT_QUERY) {
 		formats = snd_pcm_oss_get_formats(pcm_oss_file);
@@ -1844,10 +1930,14 @@ static int snd_pcm_oss_set_format(struct
 			if (substream == NULL)
 				continue;
 			runtime = substream->runtime;
+			err = lock_params(runtime);
+			if (err < 0)
+				return err;
 			if (runtime->oss.format != format) {
 				runtime->oss.params = 1;
 				runtime->oss.format = format;
 			}
+			unlock_params(runtime);
 		}
 	}
 	return snd_pcm_oss_get_format(pcm_oss_file);
@@ -1867,8 +1957,6 @@ static int snd_pcm_oss_set_subdivide1(st
 {
 	struct snd_pcm_runtime *runtime;
 
-	if (substream == NULL)
-		return 0;
 	runtime = substream->runtime;
 	if (subdivide == 0) {
 		subdivide = runtime->oss.subdivision;
@@ -1892,9 +1980,17 @@ static int snd_pcm_oss_set_subdivide(str
 
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_runtime *runtime;
+
 		if (substream == NULL)
 			continue;
-		if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0)
+		runtime = substream->runtime;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
+		err = snd_pcm_oss_set_subdivide1(substream, subdivide);
+		unlock_params(runtime);
+		if (err < 0)
 			return err;
 	}
 	return err;
@@ -1904,8 +2000,6 @@ static int snd_pcm_oss_set_fragment1(str
 {
 	struct snd_pcm_runtime *runtime;
 
-	if (substream == NULL)
-		return 0;
 	runtime = substream->runtime;
 	if (runtime->oss.subdivision || runtime->oss.fragshift)
 		return -EINVAL;
@@ -1925,9 +2019,17 @@ static int snd_pcm_oss_set_fragment(stru
 
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_runtime *runtime;
+
 		if (substream == NULL)
 			continue;
-		if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)
+		runtime = substream->runtime;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
+		err = snd_pcm_oss_set_fragment1(substream, val);
+		unlock_params(runtime);
+		if (err < 0)
 			return err;
 	}
 	return err;
@@ -2011,6 +2113,9 @@ static int snd_pcm_oss_set_trigger(struc
 	}
       	if (psubstream) {
       		runtime = psubstream->runtime;
+		cmd = 0;
+		if (mutex_lock_interruptible(&runtime->oss.params_lock))
+			return -ERESTARTSYS;
 		if (trigger & PCM_ENABLE_OUTPUT) {
 			if (runtime->oss.trigger)
 				goto _skip1;
@@ -2028,13 +2133,19 @@ static int snd_pcm_oss_set_trigger(struc
 			cmd = SNDRV_PCM_IOCTL_DROP;
 			runtime->oss.prepare = 1;
 		}
-		err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
-		if (err < 0)
-			return err;
-	}
  _skip1:
+		mutex_unlock(&runtime->oss.params_lock);
+		if (cmd) {
+			err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
+			if (err < 0)
+				return err;
+		}
+	}
 	if (csubstream) {
       		runtime = csubstream->runtime;
+		cmd = 0;
+		if (mutex_lock_interruptible(&runtime->oss.params_lock))
+			return -ERESTARTSYS;
 		if (trigger & PCM_ENABLE_INPUT) {
 			if (runtime->oss.trigger)
 				goto _skip2;
@@ -2049,11 +2160,14 @@ static int snd_pcm_oss_set_trigger(struc
 			cmd = SNDRV_PCM_IOCTL_DROP;
 			runtime->oss.prepare = 1;
 		}
-		err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
-		if (err < 0)
-			return err;
-	}
  _skip2:
+		mutex_unlock(&runtime->oss.params_lock);
+		if (cmd) {
+			err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
+			if (err < 0)
+				return err;
+		}
+	}
 	return 0;
 }
 
@@ -2305,6 +2419,7 @@ static void snd_pcm_oss_init_substream(s
 	runtime->oss.maxfrags = 0;
 	runtime->oss.subdivision = 0;
 	substream->pcm_release = snd_pcm_oss_release_substream;
+	atomic_set(&runtime->oss.rw_ref, 0);
 }
 
 static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/pcm_compat.c linux-libre-4.1.52-gnu/sound/core/pcm_compat.c
--- linux-libre-4.1.51-gnu/sound/core/pcm_compat.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/pcm_compat.c	2018-05-27 22:26:45.000000000 -0400
@@ -426,6 +426,8 @@ static int snd_pcm_ioctl_xfern_compat(st
 		return -ENOTTY;
 	if (substream->stream != dir)
 		return -EINVAL;
+	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
+		return -EBADFD;
 
 	if ((ch = substream->runtime->channels) > 128)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/pcm_native.c linux-libre-4.1.52-gnu/sound/core/pcm_native.c
--- linux-libre-4.1.51-gnu/sound/core/pcm_native.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/pcm_native.c	2018-05-27 22:26:45.000000000 -0400
@@ -2729,6 +2729,7 @@ static int snd_pcm_sync_ptr(struct snd_p
 	sync_ptr.s.status.hw_ptr = status->hw_ptr;
 	sync_ptr.s.status.tstamp = status->tstamp;
 	sync_ptr.s.status.suspended_state = status->suspended_state;
+	sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
 	snd_pcm_stream_unlock_irq(substream);
 	if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
 		return -EFAULT;
@@ -3410,7 +3411,7 @@ int snd_pcm_lib_default_mmap(struct snd_
 					 area,
 					 substream->runtime->dma_area,
 					 substream->runtime->dma_addr,
-					 area->vm_end - area->vm_start);
+					 substream->runtime->dma_bytes);
 #endif /* CONFIG_X86 */
 	/* mmap with fault handler */
 	area->vm_ops = &snd_pcm_vm_ops_data_fault;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/rawmidi_compat.c linux-libre-4.1.52-gnu/sound/core/rawmidi_compat.c
--- linux-libre-4.1.51-gnu/sound/core/rawmidi_compat.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/rawmidi_compat.c	2018-05-27 22:26:45.000000000 -0400
@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_comp
 	struct snd_rawmidi_params params;
 	unsigned int val;
 
-	if (rfile->output == NULL)
-		return -EINVAL;
 	if (get_user(params.stream, &src->stream) ||
 	    get_user(params.buffer_size, &src->buffer_size) ||
 	    get_user(params.avail_min, &src->avail_min) ||
@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_comp
 	params.no_active_sensing = val;
 	switch (params.stream) {
 	case SNDRV_RAWMIDI_STREAM_OUTPUT:
+		if (!rfile->output)
+			return -EINVAL;
 		return snd_rawmidi_output_params(rfile->output, &params);
 	case SNDRV_RAWMIDI_STREAM_INPUT:
+		if (!rfile->input)
+			return -EINVAL;
 		return snd_rawmidi_input_params(rfile->input, &params);
 	}
 	return -EINVAL;
@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_comp
 	int err;
 	struct snd_rawmidi_status status;
 
-	if (rfile->output == NULL)
-		return -EINVAL;
 	if (get_user(status.stream, &src->stream))
 		return -EFAULT;
 
 	switch (status.stream) {
 	case SNDRV_RAWMIDI_STREAM_OUTPUT:
+		if (!rfile->output)
+			return -EINVAL;
 		err = snd_rawmidi_output_status(rfile->output, &status);
 		break;
 	case SNDRV_RAWMIDI_STREAM_INPUT:
+		if (!rfile->input)
+			return -EINVAL;
 		err = snd_rawmidi_input_status(rfile->input, &status);
 		break;
 	default:
@@ -113,16 +117,18 @@ static int snd_rawmidi_ioctl_status_x32(
 	int err;
 	struct snd_rawmidi_status status;
 
-	if (rfile->output == NULL)
-		return -EINVAL;
 	if (get_user(status.stream, &src->stream))
 		return -EFAULT;
 
 	switch (status.stream) {
 	case SNDRV_RAWMIDI_STREAM_OUTPUT:
+		if (!rfile->output)
+			return -EINVAL;
 		err = snd_rawmidi_output_status(rfile->output, &status);
 		break;
 	case SNDRV_RAWMIDI_STREAM_INPUT:
+		if (!rfile->input)
+			return -EINVAL;
 		err = snd_rawmidi_input_status(rfile->input, &status);
 		break;
 	default:
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_event.c linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_event.c
--- linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_event.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_event.c	2018-05-27 22:26:45.000000000 -0400
@@ -26,6 +26,7 @@
 #include <sound/seq_oss_legacy.h>
 #include "seq_oss_readq.h"
 #include "seq_oss_writeq.h"
+#include <linux/nospec.h>
 
 
 /*
@@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp
 {
 	struct seq_oss_synthinfo *info;
 
-	if (!snd_seq_oss_synth_is_valid(dp, dev))
+	info = snd_seq_oss_synth_info(dp, dev);
+	if (!info)
 		return -ENXIO;
 
-	info = &dp->synths[dev];
 	switch (info->arg.event_passing) {
 	case SNDRV_SEQ_OSS_PROCESS_EVENTS:
 		if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp
 			return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
 		}
 
+		ch = array_index_nospec(ch, info->nr_voices);
 		if (note == 255 && info->ch[ch].note >= 0) {
 			/* volume control */
 			int type;
@@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *d
 {
 	struct seq_oss_synthinfo *info;
 
-	if (!snd_seq_oss_synth_is_valid(dp, dev))
+	info = snd_seq_oss_synth_info(dp, dev);
+	if (!info)
 		return -ENXIO;
 
-	info = &dp->synths[dev];
 	switch (info->arg.event_passing) {
 	case SNDRV_SEQ_OSS_PROCESS_EVENTS:
 		if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *d
 			return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
 		}
 
+		ch = array_index_nospec(ch, info->nr_voices);
 		if (info->ch[ch].note >= 0) {
 			note = info->ch[ch].note;
 			info->ch[ch].vel = 0;
@@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *d
 static int
 set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-	if (! snd_seq_oss_synth_is_valid(dp, dev))
+	if (!snd_seq_oss_synth_info(dp, dev))
 		return -ENXIO;
 	
 	ev->type = type;
@@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *d
 static int
 set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
 {
-	if (! snd_seq_oss_synth_is_valid(dp, dev))
+	if (!snd_seq_oss_synth_info(dp, dev))
 		return -ENXIO;
 	
 	ev->type = type;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_midi.c linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_midi.c
--- linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_midi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_midi.c	2018-05-27 22:26:45.000000000 -0400
@@ -29,6 +29,7 @@
 #include "../seq_lock.h"
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/nospec.h>
 
 
 /*
@@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp,
 {
 	if (dev < 0 || dev >= dp->max_mididev)
 		return NULL;
+	dev = array_index_nospec(dev, dp->max_mididev);
 	return get_mdev(dev);
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_synth.c linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_synth.c
--- linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_synth.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_synth.c	2018-05-27 22:26:45.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/nospec.h>
 
 /*
  * constants
@@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss
 	dp->max_synthdev = 0;
 }
 
-/*
- * check if the specified device is MIDI mapped device
- */
-static int
-is_midi_dev(struct seq_oss_devinfo *dp, int dev)
+static struct seq_oss_synthinfo *
+get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev)
 {
 	if (dev < 0 || dev >= dp->max_synthdev)
-		return 0;
-	if (dp->synths[dev].is_midi)
-		return 1;
-	return 0;
+		return NULL;
+	dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS);
+	return &dp->synths[dev];
 }
 
 /*
@@ -359,14 +356,20 @@ static struct seq_oss_synth *
 get_synthdev(struct seq_oss_devinfo *dp, int dev)
 {
 	struct seq_oss_synth *rec;
-	if (dev < 0 || dev >= dp->max_synthdev)
-		return NULL;
-	if (! dp->synths[dev].opened)
+	struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
+
+	if (!info)
 		return NULL;
-	if (dp->synths[dev].is_midi)
-		return &midi_synth_dev;
-	if ((rec = get_sdev(dev)) == NULL)
+	if (!info->opened)
 		return NULL;
+	if (info->is_midi) {
+		rec = &midi_synth_dev;
+		snd_use_lock_use(&rec->use_lock);
+	} else {
+		rec = get_sdev(dev);
+		if (!rec)
+			return NULL;
+	}
 	if (! rec->opened) {
 		snd_use_lock_free(&rec->use_lock);
 		return NULL;
@@ -402,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_d
 	struct seq_oss_synth *rec;
 	struct seq_oss_synthinfo *info;
 
-	if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
-		return;
-	info = &dp->synths[dev];
-	if (! info->opened)
+	info = get_synthinfo_nospec(dp, dev);
+	if (!info || !info->opened)
 		return;
 	if (info->sysex)
 		info->sysex->len = 0; /* reset sysex */
@@ -454,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_
 			    const char __user *buf, int p, int c)
 {
 	struct seq_oss_synth *rec;
+	struct seq_oss_synthinfo *info;
 	int rc;
 
-	if (dev < 0 || dev >= dp->max_synthdev)
+	info = get_synthinfo_nospec(dp, dev);
+	if (!info)
 		return -ENXIO;
 
-	if (is_midi_dev(dp, dev))
+	if (info->is_midi)
 		return 0;
 	if ((rec = get_synthdev(dp, dev)) == NULL)
 		return -ENXIO;
@@ -467,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_
 	if (rec->oper.load_patch == NULL)
 		rc = -ENXIO;
 	else
-		rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
+		rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
 	snd_use_lock_free(&rec->use_lock);
 	return rc;
 }
 
 /*
- * check if the device is valid synth device
+ * check if the device is valid synth device and return the synth info
  */
-int
-snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
+struct seq_oss_synthinfo *
+snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
 {
 	struct seq_oss_synth *rec;
+
 	rec = get_synthdev(dp, dev);
 	if (rec) {
 		snd_use_lock_free(&rec->use_lock);
-		return 1;
+		return get_synthinfo_nospec(dp, dev);
 	}
-	return 0;
+	return NULL;
 }
 
 
@@ -499,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_d
 	int i, send;
 	unsigned char *dest;
 	struct seq_oss_synth_sysex *sysex;
+	struct seq_oss_synthinfo *info;
 
-	if (! snd_seq_oss_synth_is_valid(dp, dev))
+	info = snd_seq_oss_synth_info(dp, dev);
+	if (!info)
 		return -ENXIO;
 
-	sysex = dp->synths[dev].sysex;
+	sysex = info->sysex;
 	if (sysex == NULL) {
 		sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
 		if (sysex == NULL)
 			return -ENOMEM;
-		dp->synths[dev].sysex = sysex;
+		info->sysex = sysex;
 	}
 
 	send = 0;
@@ -553,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_d
 int
 snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
 {
-	if (! snd_seq_oss_synth_is_valid(dp, dev))
+	struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev);
+
+	if (!info)
 		return -EINVAL;
-	snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
-			      dp->synths[dev].arg.addr.port);
+	snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client,
+			      info->arg.addr.port);
 	return 0;
 }
 
@@ -568,16 +576,18 @@ int
 snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
 {
 	struct seq_oss_synth *rec;
+	struct seq_oss_synthinfo *info;
 	int rc;
 
-	if (is_midi_dev(dp, dev))
+	info = get_synthinfo_nospec(dp, dev);
+	if (!info || info->is_midi)
 		return -ENXIO;
 	if ((rec = get_synthdev(dp, dev)) == NULL)
 		return -ENXIO;
 	if (rec->oper.ioctl == NULL)
 		rc = -ENXIO;
 	else
-		rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
+		rc = rec->oper.ioctl(&info->arg, cmd, addr);
 	snd_use_lock_free(&rec->use_lock);
 	return rc;
 }
@@ -589,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_d
 int
 snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
 {
-	if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
+	struct seq_oss_synthinfo *info;
+
+	info = snd_seq_oss_synth_info(dp, dev);
+	if (!info || info->is_midi)
 		return -ENXIO;
 	ev->type = SNDRV_SEQ_EVENT_OSS;
 	memcpy(ev->data.raw8.d, data, 8);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_synth.h linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_synth.h
--- linux-libre-4.1.51-gnu/sound/core/seq/oss/seq_oss_synth.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/oss/seq_oss_synth.h	2018-05-27 22:26:45.000000000 -0400
@@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct se
 void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
 int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
 				 const char __user *buf, int p, int c);
-int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
+struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp,
+						 int dev);
 int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
 			    struct snd_seq_event *ev);
 int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/seq_clientmgr.c linux-libre-4.1.52-gnu/sound/core/seq/seq_clientmgr.c
--- linux-libre-4.1.51-gnu/sound/core/seq/seq_clientmgr.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/seq_clientmgr.c	2018-05-27 22:26:45.000000000 -0400
@@ -270,12 +270,12 @@ static int seq_free_client1(struct snd_s
 
 	if (!client)
 		return 0;
-	snd_seq_delete_all_ports(client);
-	snd_seq_queue_client_leave(client->number);
 	spin_lock_irqsave(&clients_lock, flags);
 	clienttablock[client->number] = 1;
 	clienttab[client->number] = NULL;
 	spin_unlock_irqrestore(&clients_lock, flags);
+	snd_seq_delete_all_ports(client);
+	snd_seq_queue_client_leave(client->number);
 	snd_use_lock_sync(&client->use_lock);
 	snd_seq_queue_client_termination(client->number);
 	if (client->pool)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/seq_prioq.c linux-libre-4.1.52-gnu/sound/core/seq/seq_prioq.c
--- linux-libre-4.1.51-gnu/sound/core/seq/seq_prioq.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/seq_prioq.c	2018-05-27 22:26:45.000000000 -0400
@@ -87,7 +87,7 @@ void snd_seq_prioq_delete(struct snd_seq
 	if (f->cells > 0) {
 		/* drain prioQ */
 		while (f->cells > 0)
-			snd_seq_cell_free(snd_seq_prioq_cell_out(f));
+			snd_seq_cell_free(snd_seq_prioq_cell_out(f, NULL));
 	}
 	
 	kfree(f);
@@ -214,8 +214,18 @@ int snd_seq_prioq_cell_in(struct snd_seq
 	return 0;
 }
 
+/* return 1 if the current time >= event timestamp */
+static int event_is_ready(struct snd_seq_event *ev, void *current_time)
+{
+	if ((ev->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK)
+		return snd_seq_compare_tick_time(current_time, &ev->time.tick);
+	else
+		return snd_seq_compare_real_time(current_time, &ev->time.time);
+}
+
 /* dequeue cell from prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
+struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f,
+						  void *current_time)
 {
 	struct snd_seq_event_cell *cell;
 	unsigned long flags;
@@ -227,6 +237,8 @@ struct snd_seq_event_cell *snd_seq_prioq
 	spin_lock_irqsave(&f->lock, flags);
 
 	cell = f->head;
+	if (cell && current_time && !event_is_ready(&cell->event, current_time))
+		cell = NULL;
 	if (cell) {
 		f->head = cell->next;
 
@@ -252,18 +264,6 @@ int snd_seq_prioq_avail(struct snd_seq_p
 	return f->cells;
 }
 
-
-/* peek at cell at the head of the prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
-{
-	if (f == NULL) {
-		pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n");
-		return NULL;
-	}
-	return f->head;
-}
-
-
 static inline int prioq_match(struct snd_seq_event_cell *cell,
 			      int client, int timestamp)
 {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/seq_prioq.h linux-libre-4.1.52-gnu/sound/core/seq/seq_prioq.h
--- linux-libre-4.1.51-gnu/sound/core/seq/seq_prioq.h	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/seq_prioq.h	2018-05-27 22:26:45.000000000 -0400
@@ -44,14 +44,12 @@ void snd_seq_prioq_delete(struct snd_seq
 int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell);
 
 /* dequeue cell from prioq */ 
-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f);
+struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f,
+						  void *current_time);
 
 /* return number of events available in prioq */
 int snd_seq_prioq_avail(struct snd_seq_prioq *f);
 
-/* peek at cell at the head of the prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq *f);
-
 /* client left queue */
 void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp);        
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/seq_queue.c linux-libre-4.1.52-gnu/sound/core/seq/seq_queue.c
--- linux-libre-4.1.51-gnu/sound/core/seq/seq_queue.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/seq_queue.c	2018-05-27 22:26:45.000000000 -0400
@@ -277,30 +277,20 @@ void snd_seq_check_queue(struct snd_seq_
 
       __again:
 	/* Process tick queue... */
-	while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) {
-		if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick,
-					      &cell->event.time.tick)) {
-			cell = snd_seq_prioq_cell_out(q->tickq);
-			if (cell)
-				snd_seq_dispatch_event(cell, atomic, hop);
-		} else {
-			/* event remains in the queue */
+	for (;;) {
+		cell = snd_seq_prioq_cell_out(q->tickq,
+					      &q->timer->tick.cur_tick);
+		if (!cell)
 			break;
-		}
+		snd_seq_dispatch_event(cell, atomic, hop);
 	}
 
-
 	/* Process time queue... */
-	while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) {
-		if (snd_seq_compare_real_time(&q->timer->cur_time,
-					      &cell->event.time.time)) {
-			cell = snd_seq_prioq_cell_out(q->timeq);
-			if (cell)
-				snd_seq_dispatch_event(cell, atomic, hop);
-		} else {
-			/* event remains in the queue */
+	for (;;) {
+		cell = snd_seq_prioq_cell_out(q->timeq, &q->timer->cur_time);
+		if (!cell)
 			break;
-		}
+		snd_seq_dispatch_event(cell, atomic, hop);
 	}
 
 	/* free lock */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/core/seq/seq_virmidi.c linux-libre-4.1.52-gnu/sound/core/seq/seq_virmidi.c
--- linux-libre-4.1.51-gnu/sound/core/seq/seq_virmidi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/core/seq/seq_virmidi.c	2018-05-27 22:26:45.000000000 -0400
@@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(s
 			}
 			return;
 		}
+		spin_lock_irqsave(&substream->runtime->lock, flags);
 		if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
 			if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
-				return;
+				goto out;
 			vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
 		}
-		spin_lock_irqsave(&substream->runtime->lock, flags);
 		while (1) {
 			count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
 			if (count <= 0)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/drivers/aloop.c linux-libre-4.1.52-gnu/sound/drivers/aloop.c
--- linux-libre-4.1.51-gnu/sound/drivers/aloop.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/drivers/aloop.c	2018-05-27 22:26:45.000000000 -0400
@@ -192,6 +192,11 @@ static inline void loopback_timer_stop(s
 	dpcm->timer.expires = 0;
 }
 
+static inline void loopback_timer_stop_sync(struct loopback_pcm *dpcm)
+{
+	del_timer_sync(&dpcm->timer);
+}
+
 #define CABLE_VALID_PLAYBACK	(1 << SNDRV_PCM_STREAM_PLAYBACK)
 #define CABLE_VALID_CAPTURE	(1 << SNDRV_PCM_STREAM_CAPTURE)
 #define CABLE_VALID_BOTH	(CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
@@ -291,6 +296,8 @@ static int loopback_trigger(struct snd_p
 		cable->pause |= stream;
 		loopback_timer_stop(dpcm);
 		spin_unlock(&cable->lock);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			loopback_active_notify(dpcm);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -299,6 +306,8 @@ static int loopback_trigger(struct snd_p
 		cable->pause &= ~stream;
 		loopback_timer_start(dpcm);
 		spin_unlock(&cable->lock);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			loopback_active_notify(dpcm);
 		break;
 	default:
 		return -EINVAL;
@@ -326,6 +335,8 @@ static int loopback_prepare(struct snd_p
 	struct loopback_cable *cable = dpcm->cable;
 	int bps, salign;
 
+	loopback_timer_stop_sync(dpcm);
+
 	salign = (snd_pcm_format_width(runtime->format) *
 						runtime->channels) / 8;
 	bps = salign * runtime->rate;
@@ -659,7 +670,9 @@ static void free_cable(struct snd_pcm_su
 		return;
 	if (cable->streams[!substream->stream]) {
 		/* other stream is still alive */
+		spin_lock_irq(&cable->lock);
 		cable->streams[substream->stream] = NULL;
+		spin_unlock_irq(&cable->lock);
 	} else {
 		/* free the cable */
 		loopback->cables[substream->number][dev] = NULL;
@@ -699,7 +712,6 @@ static int loopback_open(struct snd_pcm_
 		loopback->cables[substream->number][dev] = cable;
 	}
 	dpcm->cable = cable;
-	cable->streams[substream->stream] = dpcm;
 
 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 
@@ -731,6 +743,11 @@ static int loopback_open(struct snd_pcm_
 		runtime->hw = loopback_pcm_hardware;
 	else
 		runtime->hw = cable->hw;
+
+	spin_lock_irq(&cable->lock);
+	cable->streams[substream->stream] = dpcm;
+	spin_unlock_irq(&cable->lock);
+
  unlock:
 	if (err < 0) {
 		free_cable(substream);
@@ -745,7 +762,7 @@ static int loopback_close(struct snd_pcm
 	struct loopback *loopback = substream->private_data;
 	struct loopback_pcm *dpcm = substream->runtime->private_data;
 
-	loopback_timer_stop(dpcm);
+	loopback_timer_stop_sync(dpcm);
 	mutex_lock(&loopback->cable_lock);
 	free_cable(substream);
 	mutex_unlock(&loopback->cable_lock);
@@ -815,9 +832,11 @@ static int loopback_rate_shift_get(struc
 {
 	struct loopback *loopback = snd_kcontrol_chip(kcontrol);
 	
+	mutex_lock(&loopback->cable_lock);
 	ucontrol->value.integer.value[0] =
 		loopback->setup[kcontrol->id.subdevice]
 			       [kcontrol->id.device].rate_shift;
+	mutex_unlock(&loopback->cable_lock);
 	return 0;
 }
 
@@ -849,9 +868,11 @@ static int loopback_notify_get(struct sn
 {
 	struct loopback *loopback = snd_kcontrol_chip(kcontrol);
 	
+	mutex_lock(&loopback->cable_lock);
 	ucontrol->value.integer.value[0] =
 		loopback->setup[kcontrol->id.subdevice]
 			       [kcontrol->id.device].notify;
+	mutex_unlock(&loopback->cable_lock);
 	return 0;
 }
 
@@ -863,12 +884,14 @@ static int loopback_notify_put(struct sn
 	int change = 0;
 
 	val = ucontrol->value.integer.value[0] ? 1 : 0;
+	mutex_lock(&loopback->cable_lock);
 	if (val != loopback->setup[kcontrol->id.subdevice]
 				[kcontrol->id.device].notify) {
 		loopback->setup[kcontrol->id.subdevice]
 			[kcontrol->id.device].notify = val;
 		change = 1;
 	}
+	mutex_unlock(&loopback->cable_lock);
 	return change;
 }
 
@@ -876,13 +899,18 @@ static int loopback_active_get(struct sn
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-	struct loopback_cable *cable = loopback->cables
-			[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
+	struct loopback_cable *cable;
+
 	unsigned int val = 0;
 
-	if (cable != NULL)
-		val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
-									1 : 0;
+	mutex_lock(&loopback->cable_lock);
+	cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
+	if (cable != NULL) {
+		unsigned int running = cable->running ^ cable->pause;
+
+		val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
+	}
+	mutex_unlock(&loopback->cable_lock);
 	ucontrol->value.integer.value[0] = val;
 	return 0;
 }
@@ -925,9 +953,11 @@ static int loopback_rate_get(struct snd_
 {
 	struct loopback *loopback = snd_kcontrol_chip(kcontrol);
 	
+	mutex_lock(&loopback->cable_lock);
 	ucontrol->value.integer.value[0] =
 		loopback->setup[kcontrol->id.subdevice]
 			       [kcontrol->id.device].rate;
+	mutex_unlock(&loopback->cable_lock);
 	return 0;
 }
 
@@ -947,9 +977,11 @@ static int loopback_channels_get(struct
 {
 	struct loopback *loopback = snd_kcontrol_chip(kcontrol);
 	
+	mutex_lock(&loopback->cable_lock);
 	ucontrol->value.integer.value[0] =
 		loopback->setup[kcontrol->id.subdevice]
 			       [kcontrol->id.device].channels;
+	mutex_unlock(&loopback->cable_lock);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/drivers/opl3/opl3_synth.c linux-libre-4.1.52-gnu/sound/drivers/opl3/opl3_synth.c
--- linux-libre-4.1.51-gnu/sound/drivers/opl3/opl3_synth.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/drivers/opl3/opl3_synth.c	2018-05-27 22:26:45.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/nospec.h>
 #include <sound/opl3.h>
 #include <sound/asound_fm.h>
 
@@ -448,7 +449,7 @@ static int snd_opl3_set_voice(struct snd
 {
 	unsigned short reg_side;
 	unsigned char op_offset;
-	unsigned char voice_offset;
+	unsigned char voice_offset, voice_op;
 
 	unsigned short opl3_reg;
 	unsigned char reg_val;
@@ -473,7 +474,9 @@ static int snd_opl3_set_voice(struct snd
 		voice_offset = voice->voice - MAX_OPL2_VOICES;
 	}
 	/* Get register offset of operator */
-	op_offset = snd_opl3_regmap[voice_offset][voice->op];
+	voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES);
+	voice_op = array_index_nospec(voice->op, 4);
+	op_offset = snd_opl3_regmap[voice_offset][voice_op];
 
 	reg_val = 0x00;
 	/* Set amplitude modulation (tremolo) effect */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/pci/hda/hda_hwdep.c linux-libre-4.1.52-gnu/sound/pci/hda/hda_hwdep.c
--- linux-libre-4.1.51-gnu/sound/pci/hda/hda_hwdep.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/pci/hda/hda_hwdep.c	2018-05-27 22:26:45.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/compat.h>
+#include <linux/nospec.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
@@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_cod
 	
 	if (get_user(verb, &arg->verb))
 		return -EFAULT;
-	res = get_wcaps(codec, verb >> 24);
+	/* open-code get_wcaps(verb>>24) with nospec */
+	verb >>= 24;
+	if (verb < codec->core.start_nid ||
+	    verb >= codec->core.start_nid + codec->core.num_nodes) {
+		res = 0;
+	} else {
+		verb -= codec->core.start_nid;
+		verb = array_index_nospec(verb, codec->core.num_nodes);
+		res = codec->wcaps[verb];
+	}
 	if (put_user(res, &arg->res))
 		return -EFAULT;
 	return 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/pci/hda/hda_intel.c linux-libre-4.1.52-gnu/sound/pci/hda/hda_intel.c
--- linux-libre-4.1.51-gnu/sound/pci/hda/hda_intel.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/pci/hda/hda_intel.c	2018-05-27 22:26:45.000000000 -0400
@@ -1393,7 +1393,8 @@ static void azx_check_snoop_available(st
 		 */
 		u8 val;
 		pci_read_config_byte(chip->pci, 0x42, &val);
-		if (!(val & 0x80) && chip->pci->revision == 0x30)
+		if (!(val & 0x80) && (chip->pci->revision == 0x30 ||
+				      chip->pci->revision == 0x20))
 			snoop = false;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/pci/hda/patch_realtek.c linux-libre-4.1.52-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-4.1.51-gnu/sound/pci/hda/patch_realtek.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/pci/hda/patch_realtek.c	2018-05-27 22:26:45.000000000 -0400
@@ -3250,8 +3250,12 @@ static void alc269_fixup_mic_mute_hook(v
 	pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
 	pinval &= ~AC_PINCTL_VREFEN;
 	pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
-	if (spec->mute_led_nid)
+	if (spec->mute_led_nid) {
+		/* temporarily power up/down for setting VREF */
+		snd_hda_power_up_pm(codec);
 		snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
+		snd_hda_power_down_pm(codec);
+	}
 }
 
 /* Make sure the led works even in runtime suspend */
@@ -6723,6 +6727,7 @@ enum {
 	ALC668_FIXUP_DELL_DISABLE_AAMIX,
 	ALC668_FIXUP_DELL_XPS13,
 	ALC662_FIXUP_ASUS_Nx50,
+	ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
 	ALC668_FIXUP_ASUS_Nx51,
 };
 
@@ -6970,14 +6975,21 @@ static const struct hda_fixup alc662_fix
 		.chained = true,
 		.chain_id = ALC662_FIXUP_BASS_1A
 	},
+	[ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_headset_mode_alc668,
+		.chain_id = ALC662_FIXUP_BASS_CHMAP
+	},
 	[ALC668_FIXUP_ASUS_Nx51] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
-			{0x1a, 0x90170151}, /* bass speaker */
+			{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
+			{ 0x1a, 0x90170151 }, /* bass speaker */
+			{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
 			{}
 		},
 		.chained = true,
-		.chain_id = ALC662_FIXUP_BASS_CHMAP,
+		.chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
 	},
 };
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/pci/rme9652/hdspm.c linux-libre-4.1.52-gnu/sound/pci/rme9652/hdspm.c
--- linux-libre-4.1.51-gnu/sound/pci/rme9652/hdspm.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/pci/rme9652/hdspm.c	2018-05-27 22:26:45.000000000 -0400
@@ -137,6 +137,7 @@
 #include <linux/pci.h>
 #include <linux/math64.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -5692,40 +5693,43 @@ static int snd_hdspm_channel_info(struct
 		struct snd_pcm_channel_info *info)
 {
 	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+	unsigned int channel = info->channel;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
+		if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
 			dev_info(hdspm->card->dev,
 				 "snd_hdspm_channel_info: output channel out of range (%d)\n",
-				 info->channel);
+				 channel);
 			return -EINVAL;
 		}
 
-		if (hdspm->channel_map_out[info->channel] < 0) {
+		channel = array_index_nospec(channel, hdspm->max_channels_out);
+		if (hdspm->channel_map_out[channel] < 0) {
 			dev_info(hdspm->card->dev,
 				 "snd_hdspm_channel_info: output channel %d mapped out\n",
-				 info->channel);
+				 channel);
 			return -EINVAL;
 		}
 
-		info->offset = hdspm->channel_map_out[info->channel] *
+		info->offset = hdspm->channel_map_out[channel] *
 			HDSPM_CHANNEL_BUFFER_BYTES;
 	} else {
-		if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
+		if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
 			dev_info(hdspm->card->dev,
 				 "snd_hdspm_channel_info: input channel out of range (%d)\n",
-				 info->channel);
+				 channel);
 			return -EINVAL;
 		}
 
-		if (hdspm->channel_map_in[info->channel] < 0) {
+		channel = array_index_nospec(channel, hdspm->max_channels_in);
+		if (hdspm->channel_map_in[channel] < 0) {
 			dev_info(hdspm->card->dev,
 				 "snd_hdspm_channel_info: input channel %d mapped out\n",
-				 info->channel);
+				 channel);
 			return -EINVAL;
 		}
 
-		info->offset = hdspm->channel_map_in[info->channel] *
+		info->offset = hdspm->channel_map_in[channel] *
 			HDSPM_CHANNEL_BUFFER_BYTES;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/pci/rme9652/rme9652.c linux-libre-4.1.52-gnu/sound/pci/rme9652/rme9652.c
--- linux-libre-4.1.51-gnu/sound/pci/rme9652/rme9652.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/pci/rme9652/rme9652.c	2018-05-27 22:26:45.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -2036,9 +2037,10 @@ static int snd_rme9652_channel_info(stru
 	if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
 		return -EINVAL;
 
-	if ((chn = rme9652->channel_map[info->channel]) < 0) {
+	chn = rme9652->channel_map[array_index_nospec(info->channel,
+						      RME9652_NCHANNELS)];
+	if (chn < 0)
 		return -EINVAL;
-	}
 
 	info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
 	info->first = 0;
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/soc/codecs/ssm2602.c linux-libre-4.1.52-gnu/sound/soc/codecs/ssm2602.c
--- linux-libre-4.1.51-gnu/sound/soc/codecs/ssm2602.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/soc/codecs/ssm2602.c	2018-05-27 22:26:45.000000000 -0400
@@ -54,10 +54,17 @@ struct ssm2602_priv {
  * using 2 wire for device control, so we cache them instead.
  * There is no point in caching the reset register
  */
-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
-	0x0097, 0x0097, 0x0079, 0x0079,
-	0x000a, 0x0008, 0x009f, 0x000a,
-	0x0000, 0x0000
+static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = {
+	{ .reg = 0x00, .def = 0x0097 },
+	{ .reg = 0x01, .def = 0x0097 },
+	{ .reg = 0x02, .def = 0x0079 },
+	{ .reg = 0x03, .def = 0x0079 },
+	{ .reg = 0x04, .def = 0x000a },
+	{ .reg = 0x05, .def = 0x0008 },
+	{ .reg = 0x06, .def = 0x009f },
+	{ .reg = 0x07, .def = 0x000a },
+	{ .reg = 0x08, .def = 0x0000 },
+	{ .reg = 0x09, .def = 0x0000 }
 };
 
 
@@ -620,8 +627,8 @@ const struct regmap_config ssm2602_regma
 	.volatile_reg = ssm2602_register_volatile,
 
 	.cache_type = REGCACHE_RBTREE,
-	.reg_defaults_raw = ssm2602_reg,
-	.num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg),
+	.reg_defaults = ssm2602_reg,
+	.num_reg_defaults = ARRAY_SIZE(ssm2602_reg),
 };
 EXPORT_SYMBOL_GPL(ssm2602_regmap_config);
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/soc/fsl/fsl_esai.c linux-libre-4.1.52-gnu/sound/soc/fsl/fsl_esai.c
--- linux-libre-4.1.51-gnu/sound/soc/fsl/fsl_esai.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/soc/fsl/fsl_esai.c	2018-05-27 22:26:45.000000000 -0400
@@ -143,6 +143,13 @@ static int fsl_esai_divisor_cal(struct s
 
 	psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
 
+	/* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
+	if (ratio <= 256) {
+		pm = ratio;
+		fp = 1;
+		goto out;
+	}
+
 	/* Set the max fluctuation -- 0.1% of the max devisor */
 	savesub = (psr ? 1 : 8)  * 256 * maxfp / 1000;
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/soc/intel/atom/sst/sst_stream.c linux-libre-4.1.52-gnu/sound/soc/intel/atom/sst/sst_stream.c
--- linux-libre-4.1.51-gnu/sound/soc/intel/atom/sst/sst_stream.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/soc/intel/atom/sst/sst_stream.c	2018-05-27 22:26:45.000000000 -0400
@@ -221,7 +221,7 @@ int sst_send_byte_stream_mrfld(struct in
 		sst_free_block(sst_drv_ctx, block);
 out:
 	test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id);
-	return 0;
+	return ret;
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/soc/intel/boards/cht_bsw_rt5645.c linux-libre-4.1.52-gnu/sound/soc/intel/boards/cht_bsw_rt5645.c
--- linux-libre-4.1.51-gnu/sound/soc/intel/boards/cht_bsw_rt5645.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/soc/intel/boards/cht_bsw_rt5645.c	2018-05-27 22:26:45.000000000 -0400
@@ -89,6 +89,7 @@ static const struct snd_soc_dapm_widget
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_MIC("Int Mic", NULL),
+	SND_SOC_DAPM_MIC("Int Analog Mic", NULL),
 	SND_SOC_DAPM_SPK("Ext Spk", NULL),
 	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
 			platform_clock_control, SND_SOC_DAPM_POST_PMD),
@@ -99,6 +100,8 @@ static const struct snd_soc_dapm_route c
 	{"IN1N", NULL, "Headset Mic"},
 	{"DMIC L1", NULL, "Int Mic"},
 	{"DMIC R1", NULL, "Int Mic"},
+	{"IN2P", NULL, "Int Analog Mic"},
+	{"IN2N", NULL, "Int Analog Mic"},
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
 	{"Ext Spk", NULL, "SPOL"},
@@ -112,6 +115,9 @@ static const struct snd_soc_dapm_route c
 	{"Headphone", NULL, "Platform Clock"},
 	{"Headset Mic", NULL, "Platform Clock"},
 	{"Int Mic", NULL, "Platform Clock"},
+	{"Int Analog Mic", NULL, "Platform Clock"},
+	{"Int Analog Mic", NULL, "micbias1"},
+	{"Int Analog Mic", NULL, "micbias2"},
 	{"Ext Spk", NULL, "Platform Clock"},
 };
 
@@ -119,6 +125,7 @@ static const struct snd_kcontrol_new cht
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Int Mic"),
+	SOC_DAPM_PIN_SWITCH("Int Analog Mic"),
 	SOC_DAPM_PIN_SWITCH("Ext Spk"),
 };
 
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/soc/nuc900/nuc900-ac97.c linux-libre-4.1.52-gnu/sound/soc/nuc900/nuc900-ac97.c
--- linux-libre-4.1.51-gnu/sound/soc/nuc900/nuc900-ac97.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/soc/nuc900/nuc900-ac97.c	2018-05-27 22:26:45.000000000 -0400
@@ -67,7 +67,7 @@ static unsigned short nuc900_ac97_read(s
 
 	/* polling the AC_R_FINISH */
 	while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH)
-								&& timeout--)
+								&& --timeout)
 		mdelay(1);
 
 	if (!timeout) {
@@ -121,7 +121,7 @@ static void nuc900_ac97_write(struct snd
 
 	/* polling the AC_W_FINISH */
 	while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH)
-								&& timeout--)
+								&& --timeout)
 		mdelay(1);
 
 	if (!timeout)
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/soc/sh/rcar/ssi.c linux-libre-4.1.52-gnu/sound/soc/sh/rcar/ssi.c
--- linux-libre-4.1.51-gnu/sound/soc/sh/rcar/ssi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/soc/sh/rcar/ssi.c	2018-05-27 22:26:45.000000000 -0400
@@ -396,6 +396,13 @@ static irqreturn_t rsnd_ssi_interrupt(in
 		struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
 		u32 *buf = (u32 *)(runtime->dma_area +
 				   rsnd_dai_pointer_offset(io, 0));
+		int shift = 0;
+
+		switch (runtime->sample_bits) {
+		case 32:
+			shift = 8;
+			break;
+		}
 
 		/*
 		 * 8/16/32 data can be assesse to TDR/RDR register
@@ -403,9 +410,9 @@ static irqreturn_t rsnd_ssi_interrupt(in
 		 * see rsnd_ssi_init()
 		 */
 		if (rsnd_io_is_play(io))
-			rsnd_mod_write(mod, SSITDR, *buf);
+			rsnd_mod_write(mod, SSITDR, (*buf) << shift);
 		else
-			*buf = rsnd_mod_read(mod, SSIRDR);
+			*buf = (rsnd_mod_read(mod, SSIRDR) >> shift);
 
 		rsnd_dai_pointer_update(io, sizeof(*buf));
 	}
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/usb/line6/midi.c linux-libre-4.1.52-gnu/sound/usb/line6/midi.c
--- linux-libre-4.1.51-gnu/sound/usb/line6/midi.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/usb/line6/midi.c	2018-05-27 22:26:45.000000000 -0400
@@ -125,7 +125,7 @@ static int send_midi_async(struct usb_li
 	}
 
 	usb_fill_int_urb(urb, line6->usbdev,
-			 usb_sndbulkpipe(line6->usbdev,
+			 usb_sndintpipe(line6->usbdev,
 					 line6->properties->ep_ctrl_w),
 			 transfer_buffer, length, midi_sent, line6,
 			 line6->interval);
diff -druNp --no-dereference linux-libre-4.1.51-gnu/sound/usb/mixer_maps.c linux-libre-4.1.52-gnu/sound/usb/mixer_maps.c
--- linux-libre-4.1.51-gnu/sound/usb/mixer_maps.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/sound/usb/mixer_maps.c	2018-05-27 22:26:45.000000000 -0400
@@ -351,8 +351,11 @@ static struct usbmix_name_map bose_compa
 /*
  * Dell usb dock with ALC4020 codec had a firmware problem where it got
  * screwed up when zero volume is passed; just skip it as a workaround
+ *
+ * Also the extension unit gives an access error, so skip it as well.
  */
 static const struct usbmix_name_map dell_alc4020_map[] = {
+	{ 4, NULL },	/* extension unit */
 	{ 16, NULL },
 	{ 19, NULL },
 	{ 0 }
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/perf/builtin-trace.c linux-libre-4.1.52-gnu/tools/perf/builtin-trace.c
--- linux-libre-4.1.51-gnu/tools/perf/builtin-trace.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/perf/builtin-trace.c	2018-05-27 22:26:45.000000000 -0400
@@ -1023,6 +1023,10 @@ static struct syscall_fmt {
 	{ .name	    = "mlockall",   .errmsg = true,
 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
 	{ .name	    = "mmap",	    .hexret = true,
+/* The standard mmap maps to old_mmap on s390x */
+#if defined(__s390x__)
+	.alias = "old_mmap",
+#endif
 	  .arg_scnprintf = { [0] = SCA_HEX,	  /* addr */
 			     [2] = SCA_MMAP_PROT, /* prot */
 			     [3] = SCA_MMAP_FLAGS, /* flags */
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/perf/tests/code-reading.c linux-libre-4.1.52-gnu/tools/perf/tests/code-reading.c
--- linux-libre-4.1.51-gnu/tools/perf/tests/code-reading.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/perf/tests/code-reading.c	2018-05-27 22:26:45.000000000 -0400
@@ -140,6 +140,8 @@ static int read_object_code(u64 addr, si
 	unsigned char buf2[BUFSZ];
 	size_t ret_len;
 	u64 objdump_addr;
+	const char *objdump_name;
+	char decomp_name[KMOD_DECOMP_LEN];
 	int ret;
 
 	pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
@@ -200,9 +202,25 @@ static int read_object_code(u64 addr, si
 		state->done[state->done_cnt++] = al.map->start;
 	}
 
+	objdump_name = al.map->dso->long_name;
+	if (dso__needs_decompress(al.map->dso)) {
+		if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
+						 decomp_name,
+						 sizeof(decomp_name)) < 0) {
+			pr_debug("decompression failed\n");
+			return -1;
+		}
+
+		objdump_name = decomp_name;
+	}
+
 	/* Read the object code using objdump */
 	objdump_addr = map__rip_2objdump(al.map, al.addr);
-	ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len);
+	ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
+
+	if (dso__needs_decompress(al.map->dso))
+		unlink(objdump_name);
+
 	if (ret > 0) {
 		/*
 		 * The kernel maps are inaccurate - assume objdump is right in
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/perf/util/event.c linux-libre-4.1.52-gnu/tools/perf/util/event.c
--- linux-libre-4.1.51-gnu/tools/perf/util/event.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/perf/util/event.c	2018-05-27 22:26:45.000000000 -0400
@@ -221,8 +221,8 @@ int perf_event__synthesize_mmap_events(s
 	if (machine__is_default_guest(machine))
 		return 0;
 
-	snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
-		 machine->root_dir, pid);
+	snprintf(filename, sizeof(filename), "%s/proc/%d/task/%d/maps",
+		 machine->root_dir, pid, pid);
 
 	fp = fopen(filename, "r");
 	if (fp == NULL) {
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/perf/util/ordered-events.c linux-libre-4.1.52-gnu/tools/perf/util/ordered-events.c
--- linux-libre-4.1.51-gnu/tools/perf/util/ordered-events.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/perf/util/ordered-events.c	2018-05-27 22:26:45.000000000 -0400
@@ -79,7 +79,7 @@ static union perf_event *dup_event(struc
 
 static void free_dup_event(struct ordered_events *oe, union perf_event *event)
 {
-	if (oe->copy_on_queue) {
+	if (event && oe->copy_on_queue) {
 		oe->cur_alloc_size -= event->header.size;
 		free(event);
 	}
@@ -150,6 +150,7 @@ void ordered_events__delete(struct order
 	list_move(&event->list, &oe->cache);
 	oe->nr_events--;
 	free_dup_event(oe, event->event);
+	event->event = NULL;
 }
 
 int ordered_events__queue(struct ordered_events *oe, union perf_event *event,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/perf/util/session.c linux-libre-4.1.52-gnu/tools/perf/util/session.c
--- linux-libre-4.1.51-gnu/tools/perf/util/session.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/perf/util/session.c	2018-05-27 22:26:45.000000000 -0400
@@ -132,8 +132,14 @@ struct perf_session *perf_session__new(s
 			if (perf_session__open(session) < 0)
 				goto out_close;
 
-			perf_session__set_id_hdr_size(session);
-			perf_session__set_comm_exec(session);
+			/*
+			 * set session attributes that are present in perf.data
+			 * but not in pipe-mode.
+			 */
+			if (!file->is_pipe) {
+				perf_session__set_id_hdr_size(session);
+				perf_session__set_comm_exec(session);
+			}
 		}
 	}
 
@@ -146,7 +152,11 @@ struct perf_session *perf_session__new(s
 			pr_warning("Cannot read kernel map\n");
 	}
 
-	if (tool && tool->ordering_requires_timestamps &&
+	/*
+	 * In pipe-mode, evlist is empty until PERF_RECORD_HEADER_ATTR is
+	 * processed, so perf_evlist__sample_id_all is not meaningful here.
+	 */
+	if ((!file || !file->is_pipe) && tool && tool->ordering_requires_timestamps &&
 	    tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) {
 		dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
 		tool->ordered_events = false;
@@ -1193,6 +1203,7 @@ static int __perf_session__process_pipe_
 	buf = malloc(cur_size);
 	if (!buf)
 		return -errno;
+	ordered_events__set_copy_on_queue(oe, true);
 more:
 	event = buf;
 	err = readn(fd, event, sizeof(struct perf_event_header));
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/perf/util/unwind-libdw.c linux-libre-4.1.52-gnu/tools/perf/util/unwind-libdw.c
--- linux-libre-4.1.51-gnu/tools/perf/util/unwind-libdw.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/perf/util/unwind-libdw.c	2018-05-27 22:26:45.000000000 -0400
@@ -37,6 +37,14 @@ static int __report_module(struct addr_l
 		return 0;
 
 	mod = dwfl_addrmodule(ui->dwfl, ip);
+	if (mod) {
+		Dwarf_Addr s;
+
+		dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
+		if (s != al->map->start)
+			mod = 0;
+	}
+
 	if (!mod)
 		mod = dwfl_report_elf(ui->dwfl, dso->short_name,
 				      dso->long_name, -1, al->map->start,
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c linux-libre-4.1.52-gnu/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
--- linux-libre-4.1.51-gnu/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c	2018-05-27 22:26:45.000000000 -0400
@@ -45,12 +45,12 @@ int test_body(void)
 	printf("Check DSCR TM context switch: ");
 	fflush(stdout);
 	for (;;) {
-		rv = 1;
 		asm __volatile__ (
 			/* set a known value into the DSCR */
 			"ld      3, %[dscr1];"
 			"mtspr   %[sprn_dscr], 3;"
 
+			"li      %[rv], 1;"
 			/* start and suspend a transaction */
 			TBEGIN
 			"beq     1f;"
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/testing/selftests/rcutorture/bin/configinit.sh linux-libre-4.1.52-gnu/tools/testing/selftests/rcutorture/bin/configinit.sh
--- linux-libre-4.1.51-gnu/tools/testing/selftests/rcutorture/bin/configinit.sh	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/testing/selftests/rcutorture/bin/configinit.sh	2018-05-27 22:26:45.000000000 -0400
@@ -51,7 +51,7 @@ then
 			mkdir $builddir
 		fi
 	else
-		echo Bad build directory: \"$builddir\"
+		echo Bad build directory: \"$buildloc\"
 		exit 2
 	fi
 fi
diff -druNp --no-dereference linux-libre-4.1.51-gnu/tools/usb/usbip/src/usbipd.c linux-libre-4.1.52-gnu/tools/usb/usbip/src/usbipd.c
--- linux-libre-4.1.51-gnu/tools/usb/usbip/src/usbipd.c	2018-03-27 16:15:21.000000000 -0400
+++ linux-libre-4.1.52-gnu/tools/usb/usbip/src/usbipd.c	2018-05-27 22:26:45.000000000 -0400
@@ -451,7 +451,7 @@ static void set_signal(void)
 	sigaction(SIGTERM, &act, NULL);
 	sigaction(SIGINT, &act, NULL);
 	act.sa_handler = SIG_IGN;
-	sigaction(SIGCLD, &act, NULL);
+	sigaction(SIGCHLD, &act, NULL);
 }
 
 static const char *pid_file;
